转自 http://blog.csdn.net/xukai871105/article/details/37076119 非常好的学习Linux makefile 等的博客
0.前言
从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己动手写一个makefile总觉得非常吃力。所以特意借助博客总结makefile的相关知识,通过例子说明makefile的具体用法。
例说makefile分为以下几个部分,更多内容请参考【 例说makefile索引博文】
1.只有单个C文件
2.含有多个C文件
3.需要包括头文件路径
4.增加宏定义
5.增加系统共享库
6.增加自定义共享库
7.一个实际的例子
【代码仓库】—— makefile-example
代码仓库位于bitbucket,可借助TortoiseHg(GUI工具)克隆代码或者在网页中直接下载zip包。
【本例说明】
本例将说明如何再makefile文件中增加共享库。
1.gcc复习
增加共享库使用-l前缀,请注意此处必须要小写。
【1】一定情况下,系统默认的搜索库目录位于 /usr/lib 和 lib
【2】若共享库不在系统默认库中,可通过-L参数指定目录。请注意该参数只有在链接过程有效。
2.源文件
源文件非常简单,打印sin(30)的结果。由于使用math库所以需要引入m.a共享库。
请注意,sin函数和cos函数使用弧度制;传入的参数为double类型,printf时需要使用lf前缀。
- #include <stdio.h>
- #include <math.h>
- #define PI 3.14159265
- int main(void)
- {
- double angle = 30.00 ;
- printf("sin(%.2lf)=%.2lf\n", angle, sin(angle * PI / 180));
- return 0;
- }
#include <stdio.h>
#include <math.h>
#define PI 3.14159265
int main(void)
{
double angle = 30.00 ;
printf("sin(%.2lf)=%.2lf\n", angle, sin(angle * PI / 180));
return 0;
}
3.makefile
请替换其中的[tab],并以代码仓库中的makefile文件为主
- # 指令编译器和选项
- CC = gcc
- CFLAGS = -Wall -std=gnu99
-
- # 可执行文件
- TARGET=test
- # C文件
- SRCS = test.c
- # 目标文件
- OBJS = $(SRCS:.c=.o)
-
- # 库文件
- DLIBS = -lm
-
- # 链接为可执行文件
- $(TARGET):$(OBJS)
- # @echo TARGET:$@
- # @echo OBJECTS:$^
- [tab]$(CC) -o $@ $^ $(DLIBS)
-
- clean:
- [tab]rm -rf $(TARGET) $(OBJS)
-
- # 连续动作,请清除再编译链接,最后执行
- exec:clean $(TARGET)
- [tab]@echo 开始执行
- [tab]./$(TARGET)
- [tab]@echo 执行结束
-
- # 编译规则 $@代表目标文件 $< 代表第一个依赖文件
- %.o:%.c
- [tab]$(CC) $(CFLAGS) -o $@ -c $<
# 指令编译器和选项
CC = gcc
CFLAGS = -Wall -std=gnu99
# 可执行文件
TARGET=test
# C文件
SRCS = test.c
# 目标文件
OBJS = $(SRCS:.c=.o)
# 库文件
DLIBS = -lm
# 链接为可执行文件
$(TARGET):$(OBJS)
# @echo TARGET:$@
# @echo OBJECTS:$^
[tab]$(CC) -o $@ $^ $(DLIBS)
clean:
[tab]rm -rf $(TARGET) $(OBJS)
# 连续动作,请清除再编译链接,最后执行
exec:clean $(TARGET)
[tab]@echo 开始执行
[tab]./$(TARGET)
[tab]@echo 执行结束
# 编译规则 $@代表目标文件 $< 代表第一个依赖文件
%.o:%.c
[tab]$(CC) $(CFLAGS) -o $@ -c $<
4.具体说明
【1】DLIBS = -lm 增加共享库。请注意实际的库全名为
libm.so。
【2】$(CC) -o $@ $^ $(DLIBS) 编译时增加共享库。请注意,共享库增加在链接过程即可,不需要在编译过程中增加。
【3】由于libm.so为系统库,所以并不需要指定路径。linux系统中共享库的默认查找路径为/lib和/usr/lib
5.执行过程
【验证】
ldd test
linux-vdso.so.1 => (0x00007fffde960000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ffe55b18000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffe55750000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffe55e38000)
从控制台的输出可以看出,成功链接了系统共享库 libm.so
【编译和链接】
make clean && make
【控制台输出】
rm -rf test test.o
gcc -Wall -std=gnu99 -o test.o -c test.c
gcc -o test test.o
-lm
从控制台输出可以看出,在链接过程中加入了库文件。
【执行】
./test
sin(30.00)=0.50
执行结果正常,符合预期效果。
6.总结
【1】增加系统共享库时使用前缀-l。
【2】系统共享库不需要指定路径。