2023-02-18
GCC
#
GCC编译
#
#预处理
gcc -E -o hello.i hello.c
#编译(包含预处理)
gcc -S -o hello.s hello.i
#汇编(包含预处理和编译)
gcc -c -o hello.o hello.s
#链接(包含上面的步骤)
gcc -o hello hello.o
预处理
#
- 源文件中以"#“开头的命令被称为预处理命令,如”#include"、"#define"、"#ifdef"等,预处理是将要包含的文件插入到原文件中,将宏定义展开、根据条件选择要使用的代码,最后将结果输出到一个文件中等待后续处理。
编译
#
- 编译是将预处理后的文件翻译成汇编代码,用到的工具为cc1。
汇编
#
- 汇编试讲汇编代码翻译成机器码,在linux上一般表现为ELF目标文件(OBJ文件),用到的工具为as。
链接
#
- 链接是将生成的OBJ代码和系统库的OBJ文件、库文件链接起来,最终生成了可以在特定平台运行的可执行文件,用到的工具为ld或collect2.
常用选项
#
参数 |
描述 |
-E |
预处理 |
-c |
把预处理、编译、汇编都做的,但是不链接 |
-o |
指定输出文件 |
-I |
指定头文件目录 |
-L |
指定链接时使用库文件的目录 |
-l(小L) |
指定链接哪一个库文件,如-labc就是链接libabc.so |
-v |
显示编译器驱动程序、预处理器、编译器办吧等信息。 |
-Wall |
打开所有需要注意的警告信息 |
#include <xxx> //在标准库的目录开始搜索(包括使用-Idir定义的目录)
#include "xxx" //先从用户的工作目录开始搜索,再搜索标准库目录
#创建动态链接库
gcc -shared -o libsub.so sub.o sub1.o
#使用当前目录下得sub库
gcc -o test main.o -lsub -L ./
#运行时需要指定动态库的位置,可以将libsub.so移动到/lib目录下,或者配置一个环境变量
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/xiaox
#生成静态库
ar crs libsub.a sub.o sub2.o
#将静态库打包到程序里
gcc -o tet main.o libsub.a
命令
#
#列出头文件目录、库目录(LIBRARY_PATH)等
echo 'main(){}'| gcc -E -v -
Makefile
#
target : prerequires1 prerequires2 ...
command1
command2
...
变量
#
A := XXX //立即变量
B = XXX //延时变量,在使用时才生效
C += yyy //拼接字符串
D ?= xxx //如果D之前定义过,则此语句无效;如果之前定义值,此语句定义。
A := $(C)
B = $(C)
C = abc
D ?= weidongshan
all:
@echo A = $(A)
@echo B = $(B)
@echo D = $(D)
C += 123
#结果
#A = 立即变量定义式就确定,所以A的值为空
#B = abc 123 延时变量只有在用到时才确定,当执行make时,会解析Makefile里面的所有变量。
#D = weidongshan 因为D在前面没有定义,所以是此值。
通配符
#
*.c
表示所有的.c结尾的文件。
$@
表示target。
$<
表示第一个依赖文件。
$^
表示所有的依赖文件。
假想目标.PHONY
#
- target并非只要求是文件,也可以是个标记(假想目标),声明要采取的动作。
clean :
rm -rf *.o
.PHONY : clean
函数
#
#对于list中的每一个var,执行text的动作
$(foreach var,list,text)
#例
A := a b c
B := $(foreach f, $(A), $(f).c)
all :
@echo B = $(B)
$(filter pattern...,text) # 在text中取出符合patten格式的值
$(filter-out pattern...,text) # 在text中取出不符合patten格式的值
#例
A := a b c dxx
B := $(filter %xx, $(A))
all :
@echo $(B)
#结果为dxx
#如果var中的值匹配pattern,就将它替换为replacement
$(patsubst pattern, replacement, $(var))
#例
files := a.c b.c c.c d.c e.c abc
dep_files := $(patsubst %.c,%.d,$(files))
all :
@echo dep_files = $(dep_files)
#结果为 dep_files = a.d b.d c.d d.d e.d abc
头文件依赖
#
- 通过命令,自动生成依赖的的头文件,当头文件发生变化时,重新生成对应的文件。
#-M获取c.c依赖的头文件
#-MF将依赖输出的c.d的文件
gcc -M -MF c.d c.c
objs = a.o b.o c.o
dep_files := $(patsubst %,.%.d, $(objs))
dep_files := $(wildcard $(dep_files))
test : $(objs)
gcc -o test $^
%.o : %.c
gcc -c -o $@ $< -M -MF .$@.d
ifneq ($(dep_files),)
include $(dep_files)
endif
clean:
rm *.o test
rm $(dep_files)
.PHONY: clean