makefile学习总结

来源:互联网 发布:咫尺网络的区域代理 编辑:程序博客网 时间:2024/05/17 03:36

makefile的使用主要目的是为了将我们对文件的编译步骤写在一个名为Makefile或makefile中,使我们只要通过简单的make便可以执行已经写好的的编译执行步骤。而如果makefile中的一些函数如果使用得好的话,可以使这个Makefile适用于多种情况,具备很好的可移值性。

最简单的makefile如下

hello:hello.c

gcc -o hello hello.c

在这个makefile中,hello 便是目标文件,而 hello.c便是依赖文件,gcc -o hello hello.c便是执行语句,通过执行语句便生成目标文件。

上面的例子是最简单的,当我们想要makefile用于编译更多的文件或者想要makefile有更好的移植性时,这时便一定要学会变量和一些函数的使用。首先要了解一下一些基本符号的使用。

= 是最基本的赋值

:= 是覆盖之前的值
?= 是如果没有被赋值过就赋予等号后面的值
+= 是添加等号后面的值(如a =bb, a+=cc, $(a)=bb cc)

1、“=”
     make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:
            x = foo
            y = $(x) bar
            x = xyz

      在上例中,y的值将会是 xyz bar ,而不是 foo bar 。
2、“:=”
“:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。
            x := foo
            y := $(x) bar
            x := xyz

在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。
PWD =$(shell pwd)   #获取当前地址并附给变量PWD
PATH=$(realpath .)               //获取当前的绝对路径,并赋给PATH。.也可以改为绝对路径,不过个人感觉没意义。

$(C_OBJ_FILES):%.o:$(A)/%.c
@$(CC) $(CFLAGS) -c $< -o $(OBJ_OUTPUT_PATH)/$@ 
些时结果是$(OBJ_OUTPUT_PATH)/$(C_OBJ_FILES)/%.o
被编译的C文件是$(A)/$(C_OBJ_FILES)/%.c

 4、.PHONY:one two
.PHONY:的用法主要是指明:后面的目标为伪目标,即不用生成此目标为件,就算当前有同样的目标文件也不会发生冲突。如clean,哪怕目录下有一个clean, 当我们添加了.PHONY:clean后执行make clean就不会出错。还有另外一个用法详细请看另外一个文件。
5、CWC =  $(wildcard *.c)
CWC就是获取到了当前位置上的所有以.c为后缀的文件的字符串。如果当前有a.c b.c文件,
则$(CWC)="a.c b.c"
CWC= $(wildcard $(SRC_PATH)/*.c)
CWC就是获取到了SRC_PATH位置上的所有以.c为后缀的文件名加上SRC_PATH路径的的字符串。如果当前有a.c b.c文件,, 则$(CWC) = "$(SRC_PATH)/a.c $(SRC_PATH)/b.c"
6、C_OBJ_FILES = $(patsubst $(SRC_PATH)/%.c, $(OBJ_PATH)/%.o, $(C_FILES))
就是将$(C_FILES)中的所有符合$(patsubst $(SRC_PATH)/%.逐个转成$(OBJ_PATH)/%.o。%部分不变。

GCC编译时指定函数库和头文件
1、-I选项向GCC搜索包含文件的路径中增加新目录。
2、-L选项定义库文件
3、如:test.c使用 /home/teacher/lib下的libtest.so库文件,使用/home/teacher/include下的自定义头文件,则编译选项如下:
gcc test.c -L /home/teacher/lib -I/home/teacher/include -ltest -o test
因为函数库的命名规则是lib+名字,使用-l开关指定函数库
加上-static选项表示静态编译库f。
-wall选项允许发出GCC能提供的所有有用的警告。


0 0