当前位置: 首页 > news >正文

tcc编译器教程6 进一步学习编译gmake源代码

本文以编译gmake为例讲解如何使用tcc进行复杂一点的c代码的编译

1 简介

前面主要讲解了如何编译lua解释器,lua解释器的编译很简单也很容易理解.当然大部分c语言程序编译没那么简单,下面对前面的gmake程序进行编译.

2 gmake源码结构

首先打开之前tcc-busybox-for-win32\gmake文件夹,具体文件如下
在这里插入图片描述
主要有3个文件夹和3个文件,分别为
0.tcc-主要为编译所用的信息
lib-一些相关的c代码
src-主要源码文件夹
AUTHORS-作者信息
COPYING-自述文件
README-自述文件
其中最主要的是src文件夹.

3 初次编译

在tcc-busybox-for-win32文件下有一个makebox.bat其中包含了编译gmake的命令.经过分析编译指令改写为

::使用tcc 执行0.tcc/gmake.tcc.rsp文件编译内容
tcc @0.tcc/gmake.tcc.rsp

将tcc编程环境.bat复制到gmake文件夹下打开,输入上面指令,指令执行成功在上一级目录tcc-busybox-for-win32下面生成make.exe文件,其中@代表tcc编译信息从0.tcc目录下的gmake.tcc.rsp文件载入,该文件内容如下:

-o ../make.exe
-Wall
-D GMAKE_FOR_BUSYBOX-I src
-I lib
-I src/w32/include-D WINDOWS32
-D HAVE_CONFIG_H
-D HAVE_STDINT_H
-D HAVE_STRNICMP
-D HAVE_UMASK
-D WIN32_LEAN_AND_MEAN=-D ftruncate=_chsize
-D _cdecl=src/ar.c
src/arscan.c
src/commands.c
src/default.c
src/dir.c
src/expand.c
src/file.c
src/function.c
src/guile.c
src/hash.c
src/implicit.c
src/job.c
src/load.c
src/main.c
src/misc.c
src/output.c
src/read.c
src/remake.c
src/remote-stub.c
src/rule.c
src/signame.c
src/strcache.c
src/variable.c
src/version.c
src/vpath.c
src/w32/pathstuff.c
src/w32/w32os.c
src/w32/compat/posixfcn.c
src/w32/subproc/misc.c
src/w32/subproc/sub_proc.c
src/w32/subproc/w32err.csrc/w32/compat/dirent.c
src/getopt.c
src/getopt1.clib/fnmatch.c
lib/getloadavg.c
lib/glob.c-luser32
-ladvapi32

4 gmake.tcc.rsp文件内容分析

下面对gmake.tcc.rsp内容进行分析

-o ../make.exe

这个指令设置输出文件为make.exe,位置在上一级目录

-Wall
-D GMAKE_FOR_BUSYBOX-I src
-I lib
-I src/w32/include-D WINDOWS32
-D HAVE_CONFIG_H
-D HAVE_STDINT_H
-D HAVE_STRNICMP
-D HAVE_UMASK
-D WIN32_LEAN_AND_MEAN=-D ftruncate=_chsize
-D _cdecl=

-Wall 为设置打开警告信息
-I 设置包含路径
-D 为设置一些编译常量的值

src/ar.c
src/arscan.c
src/commands.c
src/default.c
src/dir.c
src/expand.c
src/file.c
src/function.c
src/guile.c
src/hash.c
src/implicit.c
src/job.c
src/load.c
src/main.c
src/misc.c
src/output.c
src/read.c
src/remake.c
src/remote-stub.c
src/rule.c
src/signame.c
src/strcache.c
src/variable.c
src/version.c
src/vpath.c
src/w32/pathstuff.c
src/w32/w32os.c
src/w32/compat/posixfcn.c
src/w32/subproc/misc.c
src/w32/subproc/sub_proc.c
src/w32/subproc/w32err.csrc/w32/compat/dirent.c
src/getopt.c
src/getopt1.clib/fnmatch.c
lib/getloadavg.c
lib/glob.c

这些为需要编译的c代码文件

-luser32
-ladvapi32

上面为添加两个链接库

5 编写编译指令

将gmake.tcc.rsp文件内容改为为一行编译指令,如下

tcc -o make.exe -Wall -D GMAKE_FOR_BUSYBOX -I src -I lib -I src/w32/include -D WINDOWS32 -D HAVE_CONFIG_H -D HAVE_STDINT_H -D HAVE_STRNICMP -D HAVE_UMASK -D WIN32_LEAN_AND_MEAN= -D ftruncate=_chsize -D _cdecl= src/ar.c src/arscan.c src/commands.c src/default.c src/dir.c src/expand.c src/file.c src/function.c src/guile.c src/hash.c src/implicit.c src/job.c src/load.c src/main.c src/misc.c src/output.c src/read.c src/remake.c src/remote-stub.c src/rule.c src/signame.c src/strcache.c src/variable.c src/version.c src/vpath.c src/w32/pathstuff.c src/w32/w32os.c src/w32/compat/posixfcn.c src/w32/subproc/misc.c src/w32/subproc/sub_proc.c src/w32/subproc/w32err.c src/w32/compat/dirent.c src/getopt.c src/getopt1.c lib/fnmatch.c lib/getloadavg.c lib/glob.c -luser32 -ladvapi32

在gmake文件夹下打开tcc编程环境.bat,输入上面指令,指令执行成功生成make.exe文件
但是上面语句写起来还是很繁琐,对其进行修改如下

::设置警告信息和包含路径
set include=-Wall -I src -I lib -I src/w32/include
::设置编译常量
set define= -D GMAKE_FOR_BUSYBOX  -D WINDOWS32 -D HAVE_CONFIG_H -D HAVE_STDINT_H -D HAVE_STRNICMP -D HAVE_UMASK -D WIN32_LEAN_AND_MEAN= -D ftruncate=_chsize -D _cdecl=
::设置编译c代码路径
set src=lib\*.c src\*.c src\w32\*.c src\w32\compat\*.c src\w32\subproc\*.c
::设置链接库
set lib=-luser32 -ladvapi32
::编译指令
tcc %include% %define% %src% %lib% -o make.exe::测试make是否能运行
.\make -v

6 编译和链接

类似的,我们也可以进行拆分成编译和链接两个部分,具体代码如下

::编译主要源码
tcc -c %include% %define% src\*.c
::将main.o移动到lib目录下,主要为了后面编译静态库
move main.o lib\main.o
::将misc.o重命名为misc1.o
::这步很关键,因为后面src\w32\subproc\misc.c也会编译为misc.o,导致这个misc.o被覆盖从而无法编译
move misc.o misc1.o
::编译其他源码
tcc -c %include% %define% lib\*.c
tcc -c %include% %define% src\w32\*.c
tcc -c %include% %define% src\w32\compat\*.c
tcc -c %include% %define% src\w32\subproc\*.c
::对所有obj文件进行链接生成make.exe
tcc lib\main.o *.o %lib% -o make.exe

7 编译静态链接库和动态链接库

参照此前方法编译静态链接库和动态链接库
编译静态链接库

:: 生成静态链接库libmake.a
tcc -r  *.o  -o libmake.a
::使用静态链接库进行链接生成make.exe
tcc lib\main.o libmake.a %lib% -o make.exe

编译动态链接库

:: 生成动态链接库make.dll
:: 注意需包含lib\main.o
tcc -shared -rdynamic lib\main.o *.o %lib% -o make.dll
:: 只需make.def,不需要lib\main.o
tcc  make.def  -o make.exe

http://www.mrgr.cn/news/94120.html

相关文章:

  • go函数详解
  • 【Linux】线程池、单例模式、死锁
  • JVM内存结构笔记01-运行时数据区域
  • golang 高性能的 MySQL 数据导出
  • 下载以后各个软件或者服务器的启动与关闭
  • Docker安装RabbitMQ
  • Qt入门笔记
  • macOS 安装配置 iTerm2 记录
  • 蓝桥杯省赛真题C++B组2024-握手问题
  • MicroPython 智能硬件开发完整指南
  • 计算机三级网络技术备考(5)
  • 基于SpringBoot的“体育购物商城”的设计与实现(源码+数据库+文档+PPT)
  • 《苍穹外卖》SpringBoot后端开发项目核心知识点与常见问题整理(DAY1 to DAY3)
  • JVM内存结构笔记02-堆
  • 利用python生成excel中模板范围对应的shape文件
  • 【大模型统一集成项目】如何封装多个大模型 API 调用
  • [Ai 力扣题单] 数组基本操作篇 27/704
  • 考研数学复习之定积分定义求解数列极限(超详细教程)
  • MySQL 里的“锁”:保护数据的门卫
  • 蓝桥杯备赛-基础训练(四)字符串 day17