您的位置:首页 > 其它

自动变量的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是编译动态库的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: