自动变量的makefile
2011-02-28 20:18
337 查看
----------------------------------------------------------------------------------------------------
前言:
----------------------------------------------------------------------------------------------------
学习linux要了解几大工具:shell,gcc,makefile,这里说的主要是makefile以及和makefile及其相关的
gcc(主要是一些常用参数和gcc使用格式)。对这些工具的做一些基础的了解和掌握能使你的工作事半功倍,也是
成为linux C程序员的必经之路。
如果GCC基本命令不熟悉,请先看本贴最后附录。
正文:
----------------------------------------------------------------------------------------------------
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的最初版本(所有依赖关系都显式地表明):
----------------------------------------------------------------------------------------------------
#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是依赖文件。
#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文件
%.o:%.c #.o文件时由.c文件编译而来的
${CC} ${CFLAGS} $< -o $@ #请执行演示版本,实践是最真实的阐述!
clean:
rm -rf *.o test
#end of file
复制代码
makefile进化版本的演示版本:
----------------------------------------------------------------------------------------------------
作用:演示说明$@ $^ $< $?
注意:请修改func.h文件或其他文件,$?效果才会显现
#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] $@ $^ $<
%.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挂载时库名为myliblibmylib.so.major.minor
可以有主版本号和副版本号
区别: 被编进目标程序,程序体积会比较大 程序运行时会动态去寻找加载(你可以删除该库,然后
运行程序,ld会报错,找不到该指定的库)
静态库的makefile
----------------------------------------------------------------------------------------------------
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是编译动态库的。
前言:
----------------------------------------------------------------------------------------------------
学习linux要了解几大工具:shell,gcc,makefile,这里说的主要是makefile以及和makefile及其相关的
gcc(主要是一些常用参数和gcc使用格式)。对这些工具的做一些基础的了解和掌握能使你的工作事半功倍,也是
成为linux C程序员的必经之路。
如果GCC基本命令不熟悉,请先看本贴最后附录。
正文:
----------------------------------------------------------------------------------------------------
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的最初版本(所有依赖关系都显式地表明):
----------------------------------------------------------------------------------------------------
#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是依赖文件。
#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文件
%.o:%.c #.o文件时由.c文件编译而来的
${CC} ${CFLAGS} $< -o $@ #请执行演示版本,实践是最真实的阐述!
clean:
rm -rf *.o test
#end of file
复制代码
makefile进化版本的演示版本:
----------------------------------------------------------------------------------------------------
作用:演示说明$@ $^ $< $?
注意:请修改func.h文件或其他文件,$?效果才会显现
#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] $@ $^ $<
%.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挂载时库名为myliblibmylib.so.major.minor
可以有主版本号和副版本号
区别: 被编进目标程序,程序体积会比较大 程序运行时会动态去寻找加载(你可以删除该库,然后
运行程序,ld会报错,找不到该指定的库)
静态库的makefile
----------------------------------------------------------------------------------------------------
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 中常见自动变量和命令行选项
- Makefile 自动变量
- makefile中的自动变量:$@ $^ $? $<
- Makefile 中常见自动变量和命令行选项
- makefile自动变量
- Makefile 中常见自动变量和命令行选项
- linux开发工具--Makefile(1) 简单的Makefile规则和Makefile自动变量
- Makefile 中常见自动变量和命令行选项
- Makefile自动变量 (automatic variable)
- Makefile 中常见自动变量和命令行选项
- makefile编写---单个子目录编译自动变量模板ok
- Makefile 中常见自动变量和命令行选项
- 新手学习记录3:makefile学习实践--自动变量引入
- makefile中的自动变量:$@ $^ $? $<
- makefile提高篇—自动推导和自动化变量
- Makefile 中常见自动变量和命令行选项
- makefile预定义变量、自动变量、隐式规则、模式规则、make命令选项
- Makefile 中常见自动变量和命令行选项
- Makefile 中常见自动变量和命令行选项
- Makefile 中常见自动变量和命令行选项