`

MakeFile gcc 用 make 进行巨集编译

阅读更多
(MAKE)makefile中7个核心自动变量
$@ :工作目标文件名
 
$% :档案文件成员结构中的文件名元素
 
$< :第一个必要条件的文件名
 
$? :时间戳在工作目标(的时间戳)之后的所有必要条件,并以空格隔开这些必要条件
 
$^ :所有必要条件的文件名,并以空格隔开这些文件名。这份列表已删掉重复的文件名,因为对大多数的应用而言,比如编译、复制等,并不会用到重复的文件名。
 
$+ :如同$^,代表所有必要条件的文件名,并以空格隔开这些文件名。不过,这个包含重复的文件名。此变量会在特殊的状况下被创建,比如将自变量传递给连接器时重复是有意义的。
 
$* :工作目标的主文件名。一个文件名称是由两部分组成:主文件名和扩展名。
用 make 进行巨集编译
用 make 进行巨集编译
为什么要用 make
main.c :主要的目的是让使用者输入角度资料与呼叫其他三支副程式;
haha.c :输出一堆有的没有的讯息而已;
sin_value.c :计算使用者输入的角度(360) sin 数值;
cos_value.c :计算使用者输入的角度(360) cos 数值。
# 1. 先进行目标档的编译,最终会有四个 *.o 的档名出现:
[root@www ~]#
gcc -c main.c
[root@www ~]# gcc -c haha.c
[root@www ~]# gcc -c sin_value.c
[root@www ~]# gcc -c cos_value.c


# 2. 再进行连结成为执行档,并加入 libm 的数学函式,以产生 main 执行档:
[root@www ~]#
gcc -o main main.o haha.o sin_value.o cos_value.o \
> -lm -L/usr/lib -L/lib

# 3. 本程式的执行结果,必须输入姓名、360 度角的角度值来计算:
[root@www ~]#
./main
Please input your name: tom <==这里先输入名字
Please enter the degree angle (ex> 90): 30 <==输入以 360 度角为主的角度
Hi, Dear tom, nice to meet you. <==这三行为输出的结果喔!
The Sin is: 0.50
The Cos is: 0.87

编译的过程需要进行好多动作啊!而且如果要重新编译,则上述的流程得要重新来一遍,光是找出这些指令就够烦人的了! 如果可以的话,能不能一个步骤就给他完成上面所有的动作呢?那就利用 make 这个工具吧!

先试看看在这个目录下建立一个名为 makefile 的档案,内容如下:
# 1. 先编辑 makefile 这个规则档,内容只要作出 main 这个执行档
[root@www ~]#
vim makefile
main: main.o haha.o sin_value.o cos_value.o
gcc -o main main.o haha.o sin_value.o cos_value.o -lm
# 注意:第二行的 gcc 之前是 按键产生的空格喔!

# 2. 尝试使用 makefile 制订的规则进行编译的行为:
[root@www ~]#
rm -f main *.o
<==先将之前的目标档去除
[root@www ~]#
make
cc -c -o main.o main.c
cc -c -o haha.o haha.c
cc -c -o sin_value.o sin_value.c
cc -c -o cos_value.o cos_value.c
gcc -o main main.o haha.o sin_value.o cos_value.o -lm
# 此时 make 会去读取 makefile 的内容,并根据内容直接去给他编译相关的档案啰!

# 3. 在不删除任何档案的情况下,重新执行一次编译的动作:
[root@www ~]#
make
make: `main' is up to date.
# 看到了吧!是否很方便呢!只会进行更新 (update) 的动作而已。

make 有这些好处:
简化编译时所需要下达的指令;
若在编译完成之后,修改了某个原始码档案,则 make 仅会针对被修改了的档案进行编译,其他的 object file 不会被更动;
最后可以依照相依性来更新 (update) 执行档。

makefile 的基本语法与变数
基本的 makefile 规则
是这样的:
标的(target): 目标档1 目标档2
gcc -o 欲建立的执行档 目标档1 目标档2
那个标的 (target) 就是我们想要建立的资讯,而目标档就是具有相关性的 object files ,那建立执行档的语法就是以 按键开头的那一行!特别给他留意喔,‘命令列必须要以 tab 按键作为开头’才行!他的规则基本上是这样的:
在 makefile 当中的 # 代表注解;
需要在命令行 (例如 gcc 这个编译器指令) 的第一个字元;
标的 (target) 与相依档案(就是目标档)之间需以‘:’隔开。
我们以刚刚上一个小节的范例进一步说明,
如果我想要有两个以上的执行动作
时, 例如下达一个指令就直接清除掉所有的目标档与执行档,该如何制作呢?
# 1. 先编辑 makefile 来建立新的规则,此规则的标的名称为 clean :
[root@www ~]#
vi makefile
main: main.o haha.o sin_value.o cos_value.o
gcc -o main main.o haha.o sin_value.o cos_value.o -lm
clean:
rm -f main main.o haha.o sin_value.o cos_value.o
# 2. 以新的标的 (clean) 测试看看执行 make 的结果:
[root@www ~]#
make clean
<==就是这里!透过 make 以 clean 为标的
rm -rf main main.o haha.o sin_value.o cos_value.o

如此一来,我们的 makefile 里面就具有至少两个标的,分别是 main 与 clean ,如果我们想要建立 main 的话,输入‘make main’,如果想要清除有的没的,输入‘make clean’即可啊!而如果想要先清除目标档再编译 main 这个程式的话,就可以这样输入:‘make clean main’,如下所示:
[root@www ~]#
make clean main
rm -rf main main.o haha.o sin_value.o cos_value.o
cc -c -o main.o main.c
cc -c -o haha.o haha.c
cc -c -o sin_value.o sin_value.c
cc -c -o cos_value.o cos_value.c
gcc -o main main.o haha.o sin_value.o cos_value.o -lm
这样就很清楚了吧!但是,你是否会觉得,咦! makefile 里面怎么重复的资料这么多啊!没错!所以我们可以再藉由 shell script 那时学到的‘变数’来更简化 makefile 喔:
[root@www ~]#
vi makefile
LIBS = -lm
OBJS = main.o haha.o sin_value.o cos_value.o
main: ${OBJS}
gcc -o main ${OBJS} ${LIBS}
clean:
rm -f main ${OBJS}

与 bash shell script 的语法有点不太相同,变数的基本语法为:
变数与变数内容以‘=’隔开,同时两边可以具有空格;
变数左边不可以有 ,例如上面范例的第一行 LIBS 左边不可以是 ;
变数与变数内容在‘=’两边不能具有‘:’;
在习惯上,变数最好是以‘大写字母’为主;
运用变数时,以 ${变数} 或 $(变数) 使用;
在该 shell 的环境变数是可以被套用的,例如提到的 CFLAGS 这个变数!
在指令列模式也可以给予变数。
由于 gcc 在进行编译的行为时,会主动的去读取 CFLAGS 这个环境变数,所以,你可以直接在 shell 定义出这个环境变数,也可以在 makefile 档案里面去定义,更可以在指令列当中给予这个咚咚呢!例如:
[root@www ~]#
CFLAGS="-Wall" make clean main
# 这个动作在上 make 进行编译时,会去取用 CFLAGS 的变数内容!
也可以这样:
[root@www ~]#
vi makefile
LIBS = -lm
OBJS = main.o haha.o sin_value.o cos_value.o
CFLAGS = -Wall
main: ${OBJS}
gcc -o main ${OBJS} ${LIBS}
clean:
rm -f main ${OBJS}

咦!我可以利用指令列进行环境变数的输入,也可以在档案内直接指定环境变数,那万一这个 CFLAGS 的内容在指令列与 makefile 里面并不相同时,以那个方式输入的为主?呵呵!问了个好问题啊! 环境变数取用的规则是这样的:
make 指令列后面加上的环境变数为优先;
makefile 里面指定的环境变数第二;
shell 原本具有的环境变数第三。
此外,还有一些特殊的变数需要了解的喔:

$@:代表目前的标的(target)
所以我也可以将 makefile 改成:
[root@www ~]#
vi makefile
LIBS = -lm
OBJS = main.o haha.o sin_value.o cos_value.o
CFLAGS = -Wall
main: ${OBJS}
gcc -o $@ ${OBJS} ${LIBS}
<==那个 $@ 就是 main !
clean:
rm -f main ${OBJS}
这样是否稍微了解了 makefile (也可能是 Makefile) 的基本语法
分享到:
评论

相关推荐

    gcc 和makefile 详解

    GNU Make 的主要工作是读进一个文本文件, makefile 。这个文件里主要是有关哪些文件 (‘target’目的文件)是从哪些别的 文件(‘dependencies’依靠文件)中产 生的,用什么命令 来进行 这个产生过程。 gcc/g++...

    GCC开发STM32程序源码(附makefile,编译下载通过)

    调试通过的GCC开发stm32程序源码,使用官方3.5函数库。示例工程是一个简单的流水灯程序。附本工程的makefile...在搭建好的环境下,直接make一下,就能编译整个工程。环境和搭建的方法参见博客GCC开发stm32入门文章。

    实验三 Linux环境编程及GCC、Make

    一、实验目的 1. 掌握系统调用的实现方式并能完成基本的文件读、写,进程管理操作; 2. 掌握GCC的使用方法 ; 3. 掌握MAKEFILE的编写规则,并能使用make完成大型程序的编译、管理。

    Makefile和gcc培训材料

    本资源包,包括了Makefile及GCC编译选项培训.ppt、makefile培训.pptx、Makefile培训1.pptx、make工具及makefile规则.doc、Linux下C编程.ppt等学习资料,是linux开发的好资料

    gcc,make指南,gdb调试GCC程序资料打包

    其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样...

    全面学习make工具,学写makefile,gcc全部的选项详解

    全面学习make工具教程,使用MAKE。学写makefile,对项目工程进行管理;gcc全部的选项详解,绝对最全面的翻译英文版编译手册。所有GCC选项都可找到详细解释.

    ucosV276(实现 makefile,自动编译)

    ucosV276(实现 makefile,自动编译). 编译方法:tools目录下: - make new 全部重编译 - make 或者make remake 重编译修改文件 - make clear 清除编译好的文件

    gcc makefile手册 

    gcc 编译选项 makefile使用手册 

    Linux用Makefile编译C代码

    可是问题又来了,那么多文件,如果每一个文件都要用gcc -c text.c -o text.o来编译又太过于麻烦,尤其是在每一次排错后重新编译的时候让人有一种崩溃的感觉,所以这个时候用Makefile来编译 .C程序的时候会方便很多。...

    Makefile文件arm-none-linux-gnueabi-gcc编译文件

    Makefile文件arm-none-linux-gnueabi-gcc编译文件,linux下多个.C文件统一使用make文件进行编译

    一个通用Makefile的编写

    如果我们用gcc去一个一个编译每一个源文件的话,效率会低很多,但是如果我们可以写一个Makefile,那么只需要执行一个make就OK了,这样大大提高了开发效率。但是Makefile的语法规则众多,而且缺乏参考资料,对于初学...

    如何编写Makefile

    makefile 定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复 杂的功能操作,因为makefile 就像一个Shell 脚本一样,其中也可以执行操作系统的命令。 ...

    gcc使用的参数实例演示编译c程序过程

    用shell脚本写成的gcc简单使用。 其中涉及到5个文件:(1)6.sh为由一个菜单选择各种功能——可以演示编译c程序的过程以及静态与动态函数库的生成及使用。(2)endian.c为一个简单的C函数用于识别机器的内存大小端。...

    LinuxUnix环境下的make和makefile详解

    而且如此多的源文件,如果每次都要键入gcc命令进行编译的话,那对程式员来说简直就是一场灾难。而make工具则可自动完成编译工作,并且能只对程式员在上次编译后修改过的部分进行编译。因此,有效的利用make和...

    GCC编译错误类型

    GCC编译常见的一些 错误类型 可以作为参考

    Makefile在my项目下多层次文件编译源码

    里面包含了实例项目,用于学习多层次文件夹下面Makefile文件的自动编译,使用环境是Ubuntu等linux环境,同时要求的环境是具有gcc编译,同时具有make即可。里面项目代码文件较简单,只简单输出。

    CentOS7升级GCC版本到gcc 8.3.0,解决GLIBCXX-3.4.21 not found 问题

    解决/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21...生成Makefile: $ ../configure --enable-checking=release --enable-languages=c,c++ --disable-multilib 编译: $ make 编译完成之后,安装: $ make install

    gcc make中文手册

    gcc make中文手册,出自网友编译的,好东西

    跟我一起写makefile

    其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样...

    CC++ 通用 Makefile

    本文提供了一个用于对 C/C++ 程序进行编译和连接以产生可执行程序的通用 Makefile。 在使用 Makefile 之前,只需对它进行一些简单的设置即可;而且一经设置,即使以后对源程序文件有所增减一般也不再需要改动 ...

Global site tag (gtag.js) - Google Analytics