学习makefile的进化历程($@ $^ $< $?)
2011-04-22 23:15
357 查看
#整理:lizhangjie 日期:2010年12月24日
------------------------------------------------------------------------------------------------
前言:
------------------------------------------------------------------------------------------------
学习linux要了解几大工具:shell,gcc,makefile,这里说的主要是makefile以及和makefile及其
相关的gcc(主要是一些常用参数和gcc使用格式)。对这些工具的做一些基础的了解和掌握能使你的工作事半
功倍,也是成为linux C程序员的必经之路。
正文:
------------------------------------------------------------------------------------------------
GNU make主要功能是读进一个文本文件Makefile并根据Makefile的内容执行相应的动作。Makefile默认的文件名
为GNU make、makefile、Makefile。Makefile是文本形式的数据库文件,主要描叙哪些文件(target目标文件)是
从哪些文件(dependency依赖文件)产生,以及使用什么命令来执行这个过程。
内容格式:
目标文件列表 : 依赖文件列表
<TAB>命令列表
目标文件列表: make最终要创建的文件,目标文件之间用空格隔开。
依赖文件列表: 通常是需要编译的目标文件和其他文件。
命令列表: make执行的动作,通常是把指定的文件编译成目标文件的命令。每个命令之前都需要TAB字符。
make语法:
make[选项][目标][宏定义]
[选项]:
-d 显示调试信息
-f 文件名 指定该文件为依赖关系文件;'-'表示make将从标准输入中读取依赖关系
-n 不执行Makefile中的命令,只是显示输出这些命令。
-s 执行Makefile但是不显示任何信息。
下面我们单刀直入,通过例子来了解makefile是怎么写出来的。
------------------------------------------------------------------------------------------------
makefile的最初版本(所有依赖关系都显式地表明):
#Author : lizhangjie Date:2010.12.22
#introduction: compile c sourcefiles into objectfiles and
link objectfiles to targetfiles(executable files)
CC=gcc
CFLAGS = -c
OBJECTS=main.o func1001.o func1002.o func1003.o
test:${OBJECTS}
${CC} -o test ${OBJECTS}
main.o:pub.h main.c
${CC} ${CFLAGS} main.c
func1001.o:func1001.c func.h
${CC} ${CFLAGS} func1001.c
func1002.o:func1002.c func.h
${CC} ${CFLAGS} func1002.c
func1003.o:func1003.c func.h
${CC} ${CFLAGS} func1003.c
clean:
rm -rf *.o
#end of file
-----------------------------------------------------------------------------------------------
makefile进化版本:
说明:
$@ 规则中的目标文件,在不同规则的$@是会变的。
$< 依赖文件集合中的位置处于第一个的依赖文件,会依次变化。
$? 依赖文件中时间戳比目标文件新的依赖文件(一般我们在很多文件中修改了一个,重新编译是make会
根据时间戳(指修改文件的时间记录)决定哪些文件需要重新编译)
$^ 所有依赖文件的集合,在不同规则的$^是会变的。
%.o:%.c(相当于老版的 .c.o) 指示.o文件是目标文件,.c是依赖文件。
#Author : lizhangjie Date:2010.12.22
#introduction: compile c sourcefiles into objectfiles and
link objectfiles to targetfiles(executable files)
CC=gcc
CFLAGS=-c
OBJECTS=main.o func1001.o func1002.o func1003.o
TARGETS=test
all:${TARGETS}
test:${OBJECTS}
${CC} -o $@ $^ #此处$@是test,$^是OBJECTS中所有的.o文件
${OBJECTS}:%.o:%.c #.o文件时由.c文件编译而来的
${CC} ${CFLAGS} $< -o $@ #请执行演示版本,实践是最真实的阐述!
clean:
rm -rf *.o test
#end of file
------------------------------------------------------------------------------------------------
makefile进化版本的演示版本:
作用:演示说明$@ $^ $< $?
注意:请修改func.h文件或其他文件,$?效果才会显现
#Author : lizhangjie Date:2010.12.22
#introduction: compile c sourcefiles into objectfiles and
link objectfiles to targetfiles(executable files)
CC=gcc
CFLAGS=-c
OBJECTS=main.o func1001.o func1002.o func1003.o
TARGETS=test
all:${TARGETS}
test:${OBJECTS}
${CC} -o $@ $^
@echo [print] $@ $^ $<
${OBJECTS}:%.o:%.c
${CC} ${CFLAGS} $< -o $@
@echo [print] $@ $< $^ $?
clean:
rm -rf *.o test
#end of file
注意:
1.使用自动变量让make自己去推导各个源文件的依赖关系的时候,你自己必须十分清楚各个源文件对头文件
的依赖关系,忘记的话可以使用gcc -MM hello.c(查看看hello.c中对哪些头文件有依赖关系)
2.以上所有试验文件都在附录make中,可以尝试执行演示
-----------------------------------------------------------------------------------------------
用makefile编动态库和静态库
_______________________________________________________________________________________________
类别: 静态库 动态库
_______________________________________________________________________________________________
后缀: .a .so
_______________________________________________________________________________________________
形成过程: 使用ar命令使.o文件形成.a 由gcc加上特定参数编译产生
_______________________________________________________________________________________________
命名规则: libmylib.a 挂载时库名为mylib libmylib.so挂载时库名为mylib
libmylib.so.major.minor可以有主版本号和副版本号
_______________________________________________________________________________________________
区别: 被编进目标程序,程序体积会比较大 程序运行时会动态去寻找加载(你可以删除该库,然后
运行程序,ld会报错,找不到该指定的库)
_______________________________________________________________________________________________
静态库的makefile
#Author : lizhangjie Date : 2010.12.24
CC=gcc
AR=ar
CR=cr
CFLAGS=-c
CCFLAGS=-I../include -Wall
OBJECTS=func1001.o func1002.o func1003.o
libmylib.a:${OBJECTS}
${AR} ${CR} $@ $^
%.o:%.c
${CC} ${CCFLAGS} ${CFLAGS} $< -o $@
clean:
rm -rf *.o *.so *.a
#end of file
-----------------------------------------------------------------------------------------------
动态库的makefile
CC=gcc
CCFLAGS=-I../include -Wall -fPIC
SOFLAGS=-shared
CSO=libmylib.so
OBJECTS=func1001.o func1002.o func1003.o
all:${CSO}
libmylib.so:${OBJECTS}
${CC} ${SOFLAGS} -o $@ $^
%.o:%.c
${CC} ${CCFLAGS} -c $< -o $@
clean:
rm -rf *.o *.so *.a
#end of file
注意事项:
动态库的路径问题:
(1)把库拷贝到(系统默认的库文件查找路径)/usr/lib、/usr/local/lib或/lib目录下。
(2)在LD_LIBRARY_PATH环境变量中加上库所在路径。
例如动态库libmylib.so在/home/test/lib目录下,以bash为例,使用命令:
$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/test/lib。或是直接去修改.profile文件中的
LD_LIBRARY_PATH(SELinux是.profile,RedHatLinux是.bash_profile需要根据不同版本的linux具体确定)
(3) 修改/etc/ld.so.conf文件,把库所在的路径加到文件末尾,并执行ldconfig刷新。
这样,加入的目录下的所有库文件都可见。
附录:
------------------------------------------------------------------------------------------------
1.常用的gcc参数选项
gcc sourcefile -o target //将源文件编译成目标文件target,不指定为a.out
gcc -E sourcefile -o target //在target文件中现实预编译处理后的内容
gcc -c sourcefile //生成中间目标文件 默认为sourcefile.o
gcc -w sourcefile //关闭所有警告
gcc -Wall sourcefile //打开所有警告
gcc -Werror //把警告当做错误处理
gcc -MM sourcefile //查看sourcefile依赖关系
gcc fsnytax-only sourcefile //检查语法错误
-o2 //2级优化
-g //debug时使用
-I //指定依赖的头文件的路径
-L //指定挂载库的路径
-l //挂载库
-shared //产生动态库
附件说明:
------------------------------------------------------------------------------------------------
makefile文件夹是演示makefile自动变量的
makefile-1文件夹是演示makefile编译静态库和动态库的,其中lib下面的Makefile是编译静态库的,
Makefile-bak是编译动态库的。
------------------------------------------------------------------------------------------------
参考文档:
《和我一起写makefile》 陈浩 祝东华
《Using the GNU Compiler Collection》 GNU官方英文版本
------------------------------------------------------------------------------------------------
前言:
------------------------------------------------------------------------------------------------
学习linux要了解几大工具:shell,gcc,makefile,这里说的主要是makefile以及和makefile及其
相关的gcc(主要是一些常用参数和gcc使用格式)。对这些工具的做一些基础的了解和掌握能使你的工作事半
功倍,也是成为linux C程序员的必经之路。
正文:
------------------------------------------------------------------------------------------------
GNU make主要功能是读进一个文本文件Makefile并根据Makefile的内容执行相应的动作。Makefile默认的文件名
为GNU make、makefile、Makefile。Makefile是文本形式的数据库文件,主要描叙哪些文件(target目标文件)是
从哪些文件(dependency依赖文件)产生,以及使用什么命令来执行这个过程。
内容格式:
目标文件列表 : 依赖文件列表
<TAB>命令列表
目标文件列表: make最终要创建的文件,目标文件之间用空格隔开。
依赖文件列表: 通常是需要编译的目标文件和其他文件。
命令列表: make执行的动作,通常是把指定的文件编译成目标文件的命令。每个命令之前都需要TAB字符。
make语法:
make[选项][目标][宏定义]
[选项]:
-d 显示调试信息
-f 文件名 指定该文件为依赖关系文件;'-'表示make将从标准输入中读取依赖关系
-n 不执行Makefile中的命令,只是显示输出这些命令。
-s 执行Makefile但是不显示任何信息。
下面我们单刀直入,通过例子来了解makefile是怎么写出来的。
------------------------------------------------------------------------------------------------
makefile的最初版本(所有依赖关系都显式地表明):
#Author : lizhangjie Date:2010.12.22
#introduction: compile c sourcefiles into objectfiles and
link objectfiles to targetfiles(executable files)
CC=gcc
CFLAGS = -c
OBJECTS=main.o func1001.o func1002.o func1003.o
test:${OBJECTS}
${CC} -o test ${OBJECTS}
main.o:pub.h main.c
${CC} ${CFLAGS} main.c
func1001.o:func1001.c func.h
${CC} ${CFLAGS} func1001.c
func1002.o:func1002.c func.h
${CC} ${CFLAGS} func1002.c
func1003.o:func1003.c func.h
${CC} ${CFLAGS} func1003.c
clean:
rm -rf *.o
#end of file
-----------------------------------------------------------------------------------------------
makefile进化版本:
说明:
$@ 规则中的目标文件,在不同规则的$@是会变的。
$< 依赖文件集合中的位置处于第一个的依赖文件,会依次变化。
$? 依赖文件中时间戳比目标文件新的依赖文件(一般我们在很多文件中修改了一个,重新编译是make会
根据时间戳(指修改文件的时间记录)决定哪些文件需要重新编译)
$^ 所有依赖文件的集合,在不同规则的$^是会变的。
%.o:%.c(相当于老版的 .c.o) 指示.o文件是目标文件,.c是依赖文件。
#Author : lizhangjie Date:2010.12.22
#introduction: compile c sourcefiles into objectfiles and
link objectfiles to targetfiles(executable files)
CC=gcc
CFLAGS=-c
OBJECTS=main.o func1001.o func1002.o func1003.o
TARGETS=test
all:${TARGETS}
test:${OBJECTS}
${CC} -o $@ $^ #此处$@是test,$^是OBJECTS中所有的.o文件
${OBJECTS}:%.o:%.c #.o文件时由.c文件编译而来的
${CC} ${CFLAGS} $< -o $@ #请执行演示版本,实践是最真实的阐述!
clean:
rm -rf *.o test
#end of file
------------------------------------------------------------------------------------------------
makefile进化版本的演示版本:
作用:演示说明$@ $^ $< $?
注意:请修改func.h文件或其他文件,$?效果才会显现
#Author : lizhangjie Date:2010.12.22
#introduction: compile c sourcefiles into objectfiles and
link objectfiles to targetfiles(executable files)
CC=gcc
CFLAGS=-c
OBJECTS=main.o func1001.o func1002.o func1003.o
TARGETS=test
all:${TARGETS}
test:${OBJECTS}
${CC} -o $@ $^
@echo [print] $@ $^ $<
${OBJECTS}:%.o:%.c
${CC} ${CFLAGS} $< -o $@
@echo [print] $@ $< $^ $?
clean:
rm -rf *.o test
#end of file
注意:
1.使用自动变量让make自己去推导各个源文件的依赖关系的时候,你自己必须十分清楚各个源文件对头文件
的依赖关系,忘记的话可以使用gcc -MM hello.c(查看看hello.c中对哪些头文件有依赖关系)
2.以上所有试验文件都在附录make中,可以尝试执行演示
-----------------------------------------------------------------------------------------------
用makefile编动态库和静态库
_______________________________________________________________________________________________
类别: 静态库 动态库
_______________________________________________________________________________________________
后缀: .a .so
_______________________________________________________________________________________________
形成过程: 使用ar命令使.o文件形成.a 由gcc加上特定参数编译产生
_______________________________________________________________________________________________
命名规则: libmylib.a 挂载时库名为mylib libmylib.so挂载时库名为mylib
libmylib.so.major.minor可以有主版本号和副版本号
_______________________________________________________________________________________________
区别: 被编进目标程序,程序体积会比较大 程序运行时会动态去寻找加载(你可以删除该库,然后
运行程序,ld会报错,找不到该指定的库)
_______________________________________________________________________________________________
静态库的makefile
#Author : lizhangjie Date : 2010.12.24
CC=gcc
AR=ar
CR=cr
CFLAGS=-c
CCFLAGS=-I../include -Wall
OBJECTS=func1001.o func1002.o func1003.o
libmylib.a:${OBJECTS}
${AR} ${CR} $@ $^
%.o:%.c
${CC} ${CCFLAGS} ${CFLAGS} $< -o $@
clean:
rm -rf *.o *.so *.a
#end of file
-----------------------------------------------------------------------------------------------
动态库的makefile
CC=gcc
CCFLAGS=-I../include -Wall -fPIC
SOFLAGS=-shared
CSO=libmylib.so
OBJECTS=func1001.o func1002.o func1003.o
all:${CSO}
libmylib.so:${OBJECTS}
${CC} ${SOFLAGS} -o $@ $^
%.o:%.c
${CC} ${CCFLAGS} -c $< -o $@
clean:
rm -rf *.o *.so *.a
#end of file
注意事项:
动态库的路径问题:
(1)把库拷贝到(系统默认的库文件查找路径)/usr/lib、/usr/local/lib或/lib目录下。
(2)在LD_LIBRARY_PATH环境变量中加上库所在路径。
例如动态库libmylib.so在/home/test/lib目录下,以bash为例,使用命令:
$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/test/lib。或是直接去修改.profile文件中的
LD_LIBRARY_PATH(SELinux是.profile,RedHatLinux是.bash_profile需要根据不同版本的linux具体确定)
(3) 修改/etc/ld.so.conf文件,把库所在的路径加到文件末尾,并执行ldconfig刷新。
这样,加入的目录下的所有库文件都可见。
附录:
------------------------------------------------------------------------------------------------
1.常用的gcc参数选项
gcc sourcefile -o target //将源文件编译成目标文件target,不指定为a.out
gcc -E sourcefile -o target //在target文件中现实预编译处理后的内容
gcc -c sourcefile //生成中间目标文件 默认为sourcefile.o
gcc -w sourcefile //关闭所有警告
gcc -Wall sourcefile //打开所有警告
gcc -Werror //把警告当做错误处理
gcc -MM sourcefile //查看sourcefile依赖关系
gcc fsnytax-only sourcefile //检查语法错误
-o2 //2级优化
-g //debug时使用
-I //指定依赖的头文件的路径
-L //指定挂载库的路径
-l //挂载库
-shared //产生动态库
附件说明:
------------------------------------------------------------------------------------------------
makefile文件夹是演示makefile自动变量的
makefile-1文件夹是演示makefile编译静态库和动态库的,其中lib下面的Makefile是编译静态库的,
Makefile-bak是编译动态库的。
------------------------------------------------------------------------------------------------
参考文档:
《和我一起写makefile》 陈浩 祝东华
《Using the GNU Compiler Collection》 GNU官方英文版本
相关文章推荐
- ACM学习历程—HDU1716 排列2(dfs && set容器)
- Unity ShaderLab< 一> 学习总结
- ACM学习历程—HDU5700 区间交(树状数组 && 前缀和 && 排序)
- Hello Dojo ! 开始学习Dojo <4>
- C# 泛型List<T>学习总结
- R语言学习笔记之<运行R时给如何参数>
- 【js学习笔记-111】-----<canvas>图形属性
- ACM学习历程—HDU5592 ZYB's Premutation(逆序数 && 树状数组 && 二分)(BestCoder Round #65 1003)
- JavaScript系统学习之二 <事件,对象>
- Linux学习之GCC&GDB,Makefile
- struts-2.3.1+spring-framework-3.2.2+hibernate-4.1.1整合历程<第一部分>(详解)
- Makefile有三个非常有用的变量。分别是$@,$^,$<代表的意义分别是:
- ACM学习历程—HDU5269 ZYB loves Xor I(位运算 && dfs && 排序)(BestCoder Round #44 1002题)
- 在学习泛型时遇到的困惑经常与func<T,U>混淆
- 记录我开发鞋服行业供应链软件的历程<设计表示层>
- <Head First Java>学习笔记--第四章:方法操作实例变量 对象的行为
- Java学习笔记之<JDBC连接MySQL的步骤>
- <<跟我一起写 Makefile>>
- HTML <!DOCTYPE> 标签学习
- Django基础学习<2>