(完整版)浅谈手动书写Makefile与自动生成Makefile
怎样自动生成makefile

怎样自动生成makefile由于毕业设计开发的平台是Linux, 为了在Linux进行,Makefile的编写是必不可少的,为偷懒,我想使用autotools来进行Makefile的自动生成,在阅读大量的资料后,在理解的基础之上,做了一个小实验,过程记录得非常详细!我的平台是:HP 6510B NotebookFedora 8 32 位的Autotools工具的版本均为Fedora 8 完全自带的,尚未进行过升级!为了编译一个简单的源文件main.c,需要自动生成一个makefile,以下是步骤:第一步:----------在/root/project/main目录下创建一个文件main.c,其内容如下:------------------------------------------------#include <stdio.h>int main(int argc, char** argv){printf("Hello, Auto Makefile!\n");return 0;}------------------------------------------------此时状态如下:[root@localhost main]# pwd/root/project/main[root@localhost main]# lsmain.c[root@localhost main]#第二步:----------运行autoscan , 自动创建两个文件:autoscan.log configure.scan此时状态如下:[root@localhost main]# autoscan[root@localhost main]# lsautoscan.log configure.scan main.c[root@localhost main]#第三步:----------修改configure.scan的文件名为configure.in查看configure.in的内容:------------------------------------------------# -*- Autoconf -*-# Process this file with autoconf to produce a configure script.AC_PREREQ(2.61)AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AC_CONFIG_SRCDIR([main.c])AC_CONFIG_HEADER([config.h])# Checks for programs.AC_PROG_CC# Checks for libraries.# Checks for header files.# Checks for typedefs, structures, and compiler characteristics.# Checks for library functions.AC_OUTPUT------------------------------------------------解读以上的文件:------------------------------------------------# -*- Autoconf -*-# Process this file with autoconf to produce a configure script.# AC_PREREQ:# 确保使用的是足够新的Autoconf版本。
Makefile自动生成依赖性详解

makefile详解自动生成依赖性自动生成依赖性在Makefile中,我们的依赖关系可能会需要包含一系列的头文件,比如,如果我们的main.c中有一句“#i nclude "defs.h"”,那么我们的依赖关系应该是:main.o : main.c defs.h但是,如果是一个比较大型的工程,你必需清楚哪些C文件包含了哪些头文件,并且,你在加入或删除头文件时,也需要小心地修改Makefile,这是一个很没有维护性的工作。
为了避免这种繁重而又容易出错的事情,我们可以使用C/C++编译的一个功能。
大多数的C/C++编译器都支持一个“-M”的选项,即自动找寻源文件中包含的头文件,并生成一个依赖关系。
例如,如果我们执行下面的命令:cc -M main.c其输出是:main.o : main.c defs.h于是由编译器自动生成的依赖关系,这样一来,你就不必再手动书写若干文件的依赖关系,而由编译器自动生成了。
需要提醒一句的是,如果你使用GNU的C/C++编译器,你得用“-MM”参数,不然,“-M”参数会把一些标准库的头文件也包含进来。
gcc -M main.c的输出是:main.o: main.c defs.h /usr/include/stdio.h /usr/include/features.h \ /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \/usr/lib/gcc-lib/i486-suse-linux/2.95.3/include/stddef.h \/usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \/usr/include/bits/sched.h /usr/include/libio.h \/usr/include/_G_config.h /usr/include/wchar.h \/usr/include/bits/wchar.h /usr/include/gconv.h \/usr/lib/gcc-lib/i486-suse-linux/2.95.3/include/stdarg.h \/usr/include/bits/stdio_lim.hgcc -MM main.c的输出则是:main.o: main.c defs.h那么,编译器的这个功能如何与我们的Makefile联系在一起呢。
Makefile自动生成依赖文件,并自动编译

Makefile⾃动⽣成依赖⽂件,并⾃动编译1.关于GCC怎么样⾃动⽣成‘依赖’.⽹上有很多版本,有使⽤“正则法则”实现的,也有其他⽅法实现的.笔者通过⽐较,觉得最简单的还是Linux内核⾥⾯的规则最简单.2.在GCC的命令⾏加⼀条这样的语句就OK了.-Wp,-MD,drivers/leds/.XXX.o.d (其中drivers/leds/.XXX.o.d为依赖⽂件,⾥⾯记录了很多依赖信息) 3.就这么简单,来举个例⼦.Linux内核的⼀条命令cmd_drivers/leds/led-core.o := arm-linux-gcc -Wp,-MD,drivers/leds/.led-core.o.d-nostdinc -isystem /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/include-D__KERNEL__ -Iinclude -include include/linux/autoconf.h-mlittle-endian-Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing-fno-common -Os -marm -fno-omit-frame-pointer-mapcs -mno-sched-prolog -mapcs-32 -mno-thumb-interwork-D__LINUX_ARM_ARCH__=4 -march=armv4t -mtune=arm9tdmi -malignment-traps -msoft-float -Uarm -fno-omit-frame-pointer -fno-optimize-sibling-calls-g -Wdeclaration-after-statement-D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(led_core)"-D"KBUILD_MODNAME=KBUILD_STR(led_core)"-c -o drivers/leds/led-core.o drivers/leds/led-core.c4.⾃⼰来举个例⼦吧!①四个⽂件:def.h hello.c main.c Makefile②四个⽂件的内容分别为def.h:#ifndef __DEF_H#define __DEF_H#define A 5void hello();#endif //__DEF_Hhello.c:#include<stdio.h>#include"def.h"void hello(){printf("hello world!\n");printf("A = %d\n",A);}main.c:#include<stdio.h>#include"def.h"int main(void){hello();return 0;}Makefile:PHONY := testCROSS_COMPILE =CC = $(CROSS_COMPILE)gccCFLAGS := -Wall -Werror -O2 -gLDFLAGS =test: hello.o main.o(CC)(LDFLAGS) -o @^%.o : %.c(CC)(CFLAGS) -c -o @<clean:rm *.o test .*.d③现象在终端输⼊命令:makegcc -Wall -Werror -O2 -g -c -o hello.o hello.cgcc -Wall -Werror -O2 -g -c -o main.o main.cgcc -o test hello.o main.o运⾏:./testhello world!A = 5④来修改⼀个⽂件,把def.h当中的 #define A 5 改为 #define A 10 然后再make⼀下.make: `test' is up to date.⑥来修改⼀下MakefilePHONY := testCROSS_COMPILE =CC = $(CROSS_COMPILE)gccCFLAGS := -Wall -Werror -O2 -gLDFLAGS =test: hello.o main.o(CC)(LDFLAGS) -o @^dep_file = (特别注意:这⾥只能⽤= ,也就是递归展开 ,⽽不能⽤ := ,进⾏直接展开)<读者可以修改观察⼀下现象,就可以知道递归展开 = 与直接展开 := 的区别了,可以感性认识⼀下⼆者的区别.> %.o : %.c(CC)(CFLAGS) -Wp,-MD,$(dep_file) -c -o @<clean:rm *.o test .*.d再来 make ⼀下:提⽰: make: `test' is up to date.那么,make clean 之后,再来make看看:提⽰信息:gcc -Wall -Werror -O2 -g -Wp,-MD,.hello.o.d -c -o hello.o hello.cgcc -Wall -Werror -O2 -g -Wp,-MD,.main.o.d -c -o main.o main.cgcc -o test hello.o main.o执⾏⼀下看看:./testhello world!A = 10⽤ls -al 命令看看: 确实⽣成了“依赖⽂件”.hello.o.d.main.o.d⑦再⼀次修改def.h试试:把def.h当中的 #define A 10 改为 #define A 20 然后再make⼀下.make: `test' is up to date.明明已经⽣成依赖⽂件了,为什么make还会提⽰,说没有更新呢?(后⾯我们⽤:时间轴更新来说明)笔者也折腾了⼀阵,后来发现,是“依赖⽂件”没有"被包含"进Makefile,导致make的“时间轴”没有更新.⑧再来修改Makefile:在Makefile⾥⾯加这么⼀句: include.*.o.d表⽰包含所以的 .d⽂件(依赖⽂件).注意:有的需要写成这种形式-include.*.o.d再⼀次make:提⽰信息:gcc -Wall -Werror -O2 -g -Wp,-MD,.hello.o.d -c -o hello.o hello.cgcc -Wall -Werror -O2 -g -Wp,-MD,.main.o.d -c -o main.o main.cgcc -o test hello.o main.o果然成功了.再来执⾏⼀下: ./testhello world!A = 205.总结在Makefile中,“依赖关系”也是⼀个⽐较重要的规则,尤其是“⾃动⽣成依赖”.这⾥笔者举了个简单的例⼦加以说明.对于Linux,尤其是这种内容,讲起来会⽐较抽象,尽量⾃⼰多去举⼏个例⼦,去实践实践,结果很快就可以出来了,也可以加深理解!6.补充关于,在Makefile中, include 与-include 的区别通过试验,笔者得出 include 与 -include 存在着⽤法上的区别,⽽且内核的Makefile当中,也同时出现过这两种情况.在上个实验当中, ⽤ include.*.o.d出现了如下错误提⽰:Makefile:31: .*.o.d: No such file or directorymake: *** No rule to make target `.*.o.d'. Stop.⽽⽤ -include .*.o.d却解决了问题在⽹上找了⼀篇⽂章:/xiaozhi_su/article/details/4202779指⽰符“include”、“-include”和“sinclude”如果指⽰符“include”指定的⽂件不是以斜线开始(绝对路径,如/usr/src/Makefile...),⽽且当前⽬录下也不存在此⽂件;make将根据⽂件名试图在以下⼏个⽬录下查找:⾸先,查找使⽤命令⾏选项“-I”或者“--include-dir”指定的⽬录,如果找到指定的⽂件,则使⽤这个⽂件;否则,继续依此搜索以下⼏个⽬录(如果其存在):“/usr/gnu/include”、“/usr/local/include”和“/usr/include”。
makefile 写法

makefile 写法makefile是一种用于自动化构建的工具,它可以帮助开发者管理项目中的源代码、依赖关系以及构建过程。
本文将详细介绍makefile的基本语法和使用方法,以及如何根据项目需求编写一个高效的makefile。
在这篇文章中,我们将一步一步回答关于makefile写法的问题。
第一步:什么是makefile及其作用?Makefile是一种文本文件,其中包含一系列的规则,告诉make命令如何编译和链接代码。
它能够根据源代码文件的修改日期来判断哪些文件需要重新编译,从而提高代码的构建效率。
通过makefile,我们可以定义编译器的参数、编译顺序和目标文件等信息,使得项目的构建过程更加简化、自动化。
第二步:makefile的基本语法是什么?Makefile由一系列的规则组成,每个规则都包含目标文件、依赖文件和命令。
下面是一个简单的示例:makefiletarget: dependency1 dependency2command1command2其中,`target`是要生成的目标文件,`dependency1`和`dependency2`是`target`所依赖的文件,`command1`和`command2`是执行的命令。
第三步:如何编写一个最基本的makefile?首先,我们需要确定项目的目标文件和依赖关系。
比如,我们的项目中有两个源代码文件`main.c`和`utility.c`,它们都依赖于一个头文件`utility.h`。
我们的目标是生成一个可执行文件`main`。
makefile# 目标文件main: main.o utility.ogcc -o main main.o utility.o# 依赖关系main.o: main.c utility.hgcc -c main.cutility.o: utility.c utility.hgcc -c utility.c第四步:如何使用变量和函数来简化makefile的编写?在makefile中,我们可以使用变量和函数来简化代码的编写。
嵌入式 linux 自动生成 makefile 步骤

嵌入式linux 自动生成makefile 步骤嵌入式Linux 自动生成Makefile 的步骤通常涉及以下几个关键步骤:1. 配置项目结构:首先,你需要定义你的项目结构。
这通常包括源代码文件、头文件、库文件等。
2. 选择构建系统:有很多构建系统可以用于嵌入式Linux,例如Makefile、CMake、Bazel 等。
在这个例子中,我们将使用Makefile,因为它在嵌入式Linux 社区中非常流行。
3. 编写Makefile:Makefile 定义了如何编译和链接你的项目。
一个基本的Makefile 通常包括以下内容:'CC':C 编译器'CFLAGS':编译器标志'LDFLAGS':链接器标志'SOURCES':源文件列表'OBJECTS':编译后的目标文件列表'TARGET':可执行文件或库的名称4. 构建目标:你可以为不同的目标(例如,用于开发板的二进制文件或用于在宿主机上运行的测试二进制文件)定义不同的构建目标。
例如:'''makefileall: my_programmy_program: main.o util.o$(CC) $(LDFLAGS) main.o util.o -o my_programmain.o: main.c$(CC) $(CFLAGS) -c main.cutil.o: util.c$(CC) $(CFLAGS) -c util.c'''5. 自动工具:有许多工具可以帮助你自动生成Makefile,例如Kconfig、autoconf、automake 等。
这些工具可以帮助你生成配置脚本和Makefile,以适应不同的系统和编译器。
6. 编译和部署:一旦你有了Makefile,你就可以使用'make' 命令来编译你的项目。
自动生成Makefile

自动产生Makefile来源: ChinaUnix博客日期:2007.12.05 13:39(共有0条评论) 我要评论Make工程管理器到此为止,读者已经了解了如何在Linux下使用编辑器编写代码,如何使用Gcc把代码编译成可执行文件,还学习了如何使用Gdb来调试程序,那么,所有的工作看似已经完成了,为什么还需要Make这个工程管理器呢?所谓工程管理器,顾名思义,是指管理较多的文件的。
读者可以试想一下,有一个上百个文件的代码构成的项目,如果其中只有一个或少数几个文件进行了修改,按照之前所学的Gcc编译工具,就不得不把这所有的文件重新编译一遍,因为编译器并不知道哪些文件是最近更新的,而只知道需要包含这些文件才能把源代码编译成可执行文件,于是,程序员就不能不再重新输入数目如此庞大的文件名以完成最后的编译工作。
但是,请读者仔细回想一下本书在3.1.2节中所阐述的编译过程,编译过程是分为编译、汇编、链接不同阶段的,其中编译阶段仅检查语法错误以及函数与变量的声明是否正确声明了,在链接阶段则主要完成是函数链接和全局变量的链接。
因此,那些没有改动的源代码根本不需要重新编译,而只要把它们重新链接进去就可以了。
所以,人们就希望有一个工程管理器能够自动识别更新了的文件代码,同时又不需要重复输入冗长的命令行,这样,Make工程管理器也就应运而生了。
实际上,Make工程管理器也就是个“自动编译管理器”,这里的“自动”是指它能够根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Makefile文件的内容来执行大量的编译工作。
用户只需编写一次简单的编译语句就可以了。
它大大提高了实际项目的工作效率,而且几乎所有Linux下的项目编程均会涉及到它,希望读者能够认真学习本节内容。
3.6.1 Makefile基本结构Makefile是Make读入的惟一配置文件,因此本节的内容实际就是讲述Makefile的编写规则。
手把手教你如何写Makefile

手把手教你如何写Makefile陈皓 2005.04.01一、Makefile的规则在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。
target ... : prerequisites ...commandtarget也就是一个目标文件,可以是Object File,也可以是执行文件。
还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。
(任意的Shell命令)这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites 中的文件,其生成规则定义在command中。
说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。
这就是Makefile的规则。
也就是Makefile中最核心的内容。
说到底,Makefile的东西就是这样一点,好像我的这篇文档也该结束了。
呵呵。
还不尽然,这是Makefile的主线和核心,但要写好一个Makefile还不够,我会以后面一点一点地结合我的工作经验给你慢慢到来。
内容还多着呢。
:)二、一个示例正如前面所说的,如果一个工程有3个头文件,和8个C文件,我们为了完成前面所述的那三个规则,我们的Makefile应该是下面的这个样子的。
edit : main.o kbd.o command.o display.o \insert.o search.o files.o utils.occ -o edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.omain.o : main.c defs.hcc -c main.ckbd.o : kbd.c defs.h command.hcc -c kbd.ccommand.o : command.c defs.h command.hcc -c command.cdisplay.o : display.c defs.h buffer.hcc -c display.cinsert.o : insert.c defs.h buffer.hcc -c insert.csearch.o : search.c defs.h buffer.hcc -c search.cfiles.o : files.c defs.h buffer.h command.hcc -c files.cutils.o : utils.c defs.hcc -c utils.cclean :rm edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.o反斜杠(\)是换行符的意思。
如何写makefile及makefile文件的执行

如何写makefile及makefile⽂件的执⾏******************************************************makefile有什么作⽤呢?它可以⽤来做什么呢?makefile有很⼤的功能,可以帮助你完成⼀些⼤型的⼯程。
要想成为专业的⼈⼠,makefile的编写是必须会的。
makefile关系到了整个系统的编译规则。
⼀个⼯程中的源⽂件很多,按类型功能等,放在了不同的⽂件夹中,makedfile就定义了⼀系列的规则,指定哪些⽂件先编译,哪些⽂件后编译,哪些⽂件重新编译等等⼀系列的功能操作。
makefile还有⼀个好处就是能进⾏⾃动化编译,⼀旦makefile写好了之后,只要⼀个make命令,整个⼯程就可以完全⾃动化编译,⼤⼤提⾼了⼯作的效率。
**************************************⼀、Makefile的简单编写**************************************在执⾏make命令时,当前⽂件夹中需要有⼀个makefile⽂件,makefile中编写了怎么去编译和链接这个程序的语句。
makefile的规则:target ... : prerequisites ...command......target是⽬标⽂件,可以是后边编译后⽣成的执⾏⽂件,可以只是⼀个标签。
prerequisites是⽣成target所需要的⽂件或⽬标,就是依赖。
command就是在shell中输⼊make后执⾏的命令这就是⼀个⽂件依赖关系,target依赖于prerequisites中的⽂件,其⽣成规则定义在command中。
target⼀定要⽐prerequisites新,不然的话command多定义的命令就会被执⾏,这就是Makefile的规则,也是Makefile最核⼼的内容。
************举例*************编写add.c、sub.c、mul.c、div.c四个函数,⽤test.c将四个函数实现,然后编写⼀个Makefile编译函数math⽂件夹中的⽂件包括:编写Makefile⽂件:编写完后,make⼀下,观察过程:这时,⽂件夹中的⽂件为:以长列表的形式观察个⽂件:观察可知:target⽂件test之所有⽂件中最新的,如果它不为新,那么在执⾏make命令时,test将会被更新。
makefile详解

makefile详解makefile⼀、初识makefile想要掌握makefile,⾸先需要了解两个概念,⼀个是⽬标(target),另⼀个就是依赖(dependency)。
⽬标就是指要⼲什么,或说运⾏ make 后⽣成什么,⽽依赖是告诉 make 如何去做以实现⽬标。
在 Makefile 中,⽬标和依赖是通过规则(rule)来表达的。
(⼀)、⽬标⾸次编写makefileall:echo "Hello world"上⾯Makefile 中的 all 就是我们的⽬标,⽬标放在‘:’的前⾯,其名字可以是由字⺟和下划线‘_’组成。
echo “Hello World”就是⽣成⽬标的命令,这些命令可以是任何你可以在你的环境中运⾏的命令以及 make 所定义的函数等等。
all ⽬标的定义,其实是定义了如何⽣成 all ⽬标,这我们也称之为规则.makefile定义多个⽬标all:echo "Hello world"test:echo "test game"下⾯是运⾏的结果由此可见,⼀个 Makefile 中可以定义多个⽬标。
调⽤ make 命令时,我们得告诉它我们的⽬标是什么,即要它⼲什么。
当没有指明具体的⽬标是什么时,那么 make 以 Makefile ⽂件中定义的第⼀个⽬标作为这次运⾏的⽬标。
这“第⼀个”⽬标也称之为默认⽬标(和是不是all没有关系)。
当 make 得到⽬标后,先找到定义⽬标的规则,然后运⾏规则中的命令来达到构建⽬标的⽬的。
makefile中取消多余的命令⾏显⽰在上⾯的指令中,多了很多的echo "......"的内容,这部分不是我们所期望的,如果要去掉,需要对上⾯的makefile进⾏⼀个改动,也就是在命令前加上⼀个@,这个符号就是告诉make,在运⾏的时候这⼀⾏命令不显⽰出来。
all:@echo "Hello world"test:@echo "test game"运⾏结果:紧接着对makefile进⾏如下的改动,在all的后⾯加上testall: test@echo "Hello world"test:@echo "test game"运⾏结果如下:如上图所⽰,此时test也被构建了。
makefile 的编写及应用

makefile 的编写及应用Makefile是一种用来管理编译程序的工具,它提供了一种自动化编译的方式,可以根据文件的依赖关系来自动编译相关的文件,从而提高编译的效率。
Makefile的编写通常包括以下几个部分:目标、依赖关系、命令和变量。
一般来说,一个Makefile文件中可以包含多个规则,每个规则由一个或多个目标、依赖关系和命令组成。
其中目标是需要生成的文件,依赖关系是生成目标所需要依赖的其他文件,命令则是生成目标所执行的命令。
一个简单的Makefile示例如下:```# 定义变量CC = gccCFLAGS = -Wall -Wextra# 定义目标和依赖关系target: main.o func.o$(CC) $(CFLAGS) -o target main.o func.omain.o: main.c func.h$(CC) $(CFLAGS) -c main.cfunc.o: func.c func.h$(CC) $(CFLAGS) -c func.c# 定义清理操作clean:rm -f target main.o func.o```在上述示例中,我们定义了两个目标:target和clean。
其中,target这个目标所依赖的是main.o和func.o两个文件,生成目标的命令是使用gcc编译这两个文件,最后生成一个名为target的可执行文件。
clean这个目标用来清理生成的文件。
应用Makefile可以帮助我们自动地完成编译、链接和清理等操作,提高了开发的效率。
可以在命令行中执行`make`命令来根据Makefile文件来生成目标程序,执行`make clean`命令可以清理生成的文件。
总结起来,Makefile的编写及应用包括以下几个步骤:1. 定义变量,用来保存编译器和编译选项等信息;2. 定义目标和依赖关系,用来描述生成文件之间的依赖关系;3. 编写命令,用来执行生成目标的操作;4. 可选地定义清理操作,用来清理生成的文件;5. 在命令行中执行make命令来根据Makefile文件来自动编译生成目标程序。
自动生成Makefile详解

autoconf 和automake生成Makefile文件本文介绍了在linux 系统中,通过Gnu autoconf 和automake 生成Makefile 的方法。
主要探讨了生成Makefile 的来龙去脉及其机理,接着详细介绍了配置Configure.in 的方法及其规则。
引子无论是在Linux还是在Unix环境中,make都是一个非常重要的编译命令。
不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或make install。
利用make工具,我们可以将大型的开发项目分解成为多个更易于管理的模块,对于一个包括几百个源文件的应用程序,使用make和makefile工具就可以轻而易举的理顺各个源文件之间纷繁复杂的相互关系。
但是如果通过查阅make的帮助文档来手工编写Makefile,对任何程序员都是一场挑战。
幸而有GNU 提供的Autoconf及Automake这两套工具使得编写makefile不再是一个难题。
本文将介绍如何利用GNU Autoconf 及Automake 这两套工具来协助我们自动产生Makefile文件,并且让开发出来的软件可以像大多数源码包那样,只需"./configure", "make","make install" 就可以把程序安装到系统中。
模拟需求假设源文件按如下目录存放,如图1所示,运用autoconf和automake生成makefile文件。
图1文件目录结构假设src是我们源文件目录,include目录存放其他库的头文件,lib目录存放用到的库文件,然后开始按模块存放,每个模块都有一个对应的目录,模块下再分子模块,如apple、orange。
每个子目录下又分core,include,shell三个目录,其中core和shell目录存放.c文件,include的存放.h文件,其他类似。
[转]makefile是如何自动生成的
![[转]makefile是如何自动生成的](https://img.taocdn.com/s3/m/337f8d2da7c30c22590102020740be1e650eccc1.png)
[转]makefile是如何自动生成的/uid-20544507-id-3494422.html这段时间要继续研究Jabber服务器,因为要在源码上做一些修改,还要添加一些功能,所以需要修改源码中的makefile文件.之前接触过一些, 也一直也不是太明白,这次借此机会再搞得明白一点儿.以下是找到一篇比较实用,讲得也比较透彻的文章,特此转载一下.GNU make允许将一个软件项目的代码分开放在不同的源文件里,有改动的时候可以只对改动的文件重新编译,然后重新连接,这种编译管理方法提高了生成目标的效率。
make要调用一个makefile文件来实现。
Makefile的编写是使用make的关键问题。
当工程里面包含的很多源文件,库,文件放在不同的子目录时,手动书写makefile文件不方便且容易出错。
一般情况下我们用autoconf和automake自动生成makefile文件。
自动生成makefile流程如图所示为automake,autoconf生成makefile的过程(简化)。
程序源码|autoscan*|configure.scan|编译修改*|makefile.am configure.in --aclocal*--> aclocal.m4\ ____ / \ __________ /\ / \ /automake* autoconf*| |makefile.in configure\ ____ /\ /./configure*|makefile为一个项目源文件生成makefile并make的步骤如下:操作在包含源文件的项目目录下进行。
(1). 运行autoscan,生成文件configure.scan。
(2). 修改configure.scan,改名为configure.in。
(3).运行autoheader,生成文件configure.h.in(现在一般改为configure.ac)。
简单制作Makefile方法

1.在当前目录下创建一个名为hello的子目录。hello这个目录用于存放hello.c这个程序及相关文件。新建一个源程序文件hello.c
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Welcome to use autoconf and automake\n");
通过以上步骤,在源代码所在目录下自动生成了Makefile文件。
configure.in文件
autoconf提用来产生"configure"文件的工具。"configure"是一个Shell脚本,它可以自动设定一些编译参数使程序能够在不同平台上进行编译。autoconf读取configure.in文件然后产生,"configure"这个Shell脚本。
如何使用产生的Makefile文件
执行configure脚本文件所产生的Makefile文件有几个预定的选项可供使用。
l make all:产生设定的目标,即生成所有的可执行文件。使用make也可以达到此目的。
l make clean:删除之前编译时生成的可执行文件及目标文件(形如*.o的中间文件)。
configure.in文件的内容是一系列GNU m4的宏,这些宏经autoconf理后会变成检查系统特性的Shell脚本。configure.in文件中宏的顺序并没有特别的规定,但是每一个configure.in文件必须以宏AC_INIT开头,以宏AC_OUTPUT结束。一般可先用autoscan这个工具扫描原始文件以产生一个configure.scan文件,再对configure.scan作些修改,从而生成configure.in文件
(完整版)浅谈手动书写Makefile与自动生成Makefile

最近一直在搞Makefile文件的编辑,一直想通过自己的心得体会与广大网友分享。
Linux学习者只有参与的大多人当中去,才能体会到乐趣。
同时慢慢培养自己的学习linux的兴趣爱好。
与广大网上爱好者互动。
Linux的GNU计划:Linux下构建自己的开源软件使用的是linux下自己带的强大的工具。
Autoconf libtoolize 和automake .这是开源软件必须的基本工具。
如果使用了autoconf和automake,除了编译应用程序,用户并不需要有这些工具。
使用这些工具的目的是创建能在用户环境使用的、可移植的shell脚本和Makefile文件。
Autoconf实际上是一个工具集,其中包含aclocal、autoheader和autoconf等可执行文件。
这些工具生成一个可移植的shell脚本—configure,configure和软件包一起发布给用户。
它探查编译系统,生成Makefile文件和一个特殊的头文件config.h。
由configure生成的文件能适应用户系统的特定环境。
configure脚本从一个称为Makefile.in的模板文件生成每个Makefile文件。
而Makefile.in 有Makefile.am 生成。
Configure.in 有开发者自己手动修改。
Makefile.am 是由开发者自己手写。
Libtool软件包是第三个重要的GNU工具,它的作用是确定共享库在特定平台上的特性。
因为共享库在不同平台上可能会有所不同。
上述是自动生成Makefile的概括。
以后再细讲。
手动书写Makefile:手动书写顾名思义就是自己跳过configure.Scan configure.in configure Makefile.am Makefile.in 的生成过程。
直接书写Makefile 这种方式只能用于相对简单的源代码。
如有几个,几十个或者上百个源文件时,自己编写Makefile往往是可行的,但是如果我们所编写的源文件有几千,几万,几十万甚至更多时,显然手动书写Makefile不是个明智之举。
如何编写Makefile,一份由浅入深的Makefile全攻略

如何编写Makefile,⼀份由浅⼊深的Makefile全攻略本⽂转载整理⾃陈浩⼤⼤的⽂章(),由于原⽂内容庞⼤,故梳理出⽬录结构以便于学习及查阅参考。
⼀、概述——什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个⼯作,但我觉得要作⼀个好的和professional的程序员,makefile还是要懂。
这就好像现在有这么多的HTML的编辑器,但如果你想成为⼀个专业⼈⼠,你还是要了解HTML 的标识的含义。
特别在Unix下的软件编译,你就不能不⾃⼰写makefile了,会不会写makefile,从⼀个侧⾯说明了⼀个⼈是否具备完成⼤型⼯程的能⼒。
因为,makefile关系到了整个⼯程的编译规则。
⼀个⼯程中的源⽂件不计数,其按类型、功能、模块分别放在若⼲个⽬录中,makefile定义了⼀系列的规则来指定,哪些⽂件需要先编译,哪些⽂件需要后编译,哪些⽂件需要重新编译,甚⾄于进⾏更复杂的功能操作,因为makefile就像⼀个Shell脚本⼀样,其中也可以执⾏操作系统的命令。
makefile带来的好处就是——“⾃动化编译”,⼀旦写好,只需要⼀个make命令,整个⼯程完全⾃动编译,极⼤的提⾼了软件开发的效率。
make是⼀个命令⼯具,是⼀个解释makefile中指令的命令⼯具,⼀般来说,⼤多数的IDE都有这个命令,⽐如:Delphi的make,VisualC++的nmake,Linux下GNU的make。
可见,makefile都成为了⼀种在⼯程⽅⾯的编译⽅法。
现在讲述如何写makefile的⽂章⽐较少,这是我想写这篇⽂章的原因。
当然,不同产商的make各不相同,也有不同的语法,但其本质都是在“⽂件依赖性”上做⽂章,这⾥,我仅对GNU的make进⾏讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。
必竟,这个make是应⽤最为⼴泛的,也是⽤得最多的。
自动生成makefile

自动生成Makefile对于一个UNIX/Linux下C程序员来说,一个比较麻烦的工作就是写自己的Makefile。
可 能你有如下经验:写一个简单的C程序,自己多写几行gcc命令就把程序变成可执行的了;写一个稍微复杂点的程序,源文件个数可能在30个左右,还是写一行 行的gcc命令就麻烦了,你可能想到写个makefile,你可能也在这样做着;但你某一天会发现你写的这个Makefile可能不是一个所有 UNIX/Linux类操作系统下通用的Makefile,比如某人下载了你的程序去他自己电脑上可能make不了。
这样,你就有必要了解并学会运用autoconf和automake了。
autoconf 是一个用于生成可以自动地配置软件源代码包以适应多种UNIX 类系统的shell脚本的工具。
由autoconf生成的配置脚本在运行的时候不需要用户的 手工干预;通常它们甚至不需要手工给出参数以确定系统的类型。
相反,它们对软件包可能需要的各种特征进行独立的测试。
在每个测试之前,它们打印一个单行的 消息以说明它们正在进行的检测,以使得用户不会因为等待脚本执行完毕而焦躁。
因此,它们在混合系统或者从各种常见UNIX变种定制而成的系统中工作的很 好。
你也省了工作,没必要维护文件以储存由各个UNIX变种、各个发行版本所支持的特征的列表。
automake是一个从文件Makefile.am自动生成Makefile.in的工具。
每个Makefile.am基本上是一系列make的宏定义(make规则也会偶尔出现)生成的Makefile.in,服从GNU Makefile标准。
为了生成Makefile.in,automake需要perl。
但是由automake创建的发布完全服从GNU标准,并且在创建中不需要perl。
在开始使用autoconf和automake之前,首先确认你的系统安装有GNU的如下软件:1. automake2. autoconf3. m44. perl5. 如果你需要产生共享库(shared library)则还需要GNU Libtool介绍方法之前大家看一下下面这个图,先记下autoconf和automake工作的几个步骤:步骤解释如下:1、由你的源文件通过autoscan命令生成configure.scan文件,然后修改configure.scan文件并重命名为configure.in2、由aclocal命令生成aclocal.m43、由autoconf命令生成configure4、编辑一个Makefile.am文件并由automake命令生成Makefile.in文件5、运行configure命令生成Makefileautomake支持三种目录层次:flat、shallow和deep。
自己建立makefile

自己建立makefile大头小脑小的嵌入式工程可以使用编译器自动产生makefile,但是对于大的嵌入式工程,使用编译器自动产生makefile可能会使得编译器崩溃,不能满足开发要求。
所以需要自己写makefile。
下面简单介绍GNU makefile工程的建立步骤和简单说明。
一、建立GNU工程选择创建makefile工程:Build工程,产生错误信息,提示没有makefile命令,因为建立的是makefile工程,编译器不会自动产生makefile,这就需要自己手动添加makefile文件。
对比makefile工程和非makefile工程的区别,可以清楚的看到,makefile工程(左图)的C/C++Build-Settings中没有编译优化选项。
非makefile工程(右图)的C/C++Build-Settings中有Tool Settings、Link order、Build Steps、Build Artifact编译器根据非makefile工程的编译配置选项来自动生成makefile主文件和其他目录下的.mk文件Makefile工程则没有这些优化选项,这就要编程者自己来添加makefile住文件和其他目录下的.mk文件。
虽然是自己要写,但是同样增大了makefile命令使用的灵活性。
二、makefile、.mk文件添加说明如果直接看make教程,直接来写makefile、.mk显然难度太多,并且这样要的makefile命令运用需要非常熟悉,并且对具体到自己用的编译器也要非常熟悉。
开始学习阶段,这里可以先借用非makefile工程自动产生的makefile,然后修改mk里面的命令,以满足自己的工程需求。
首先makefile工程先要进行下面设置,在C/C++ Build下,把Build directory 改为:${workspace_loc:/make_notest/iROM}再把iROM文件从非makefile工程中copy过来(这两个工建立时的工程名字、源文件、目录等完全一样)到非makefile工程的根目录下:可以添加几个源文件,试一试添加效果。
cmake makefile使用

cmake makefile使用一、概述CMake和Makefile都是用于管理和构建C/C++项目的工具。
其中,Makefile是Unix/Linux系统下最常用的构建工具之一,而CMake则是一个跨平台的构建工具。
二、Makefile1. Makefile是什么?Makefile是一个文本文件,用于指定如何编译和链接程序。
它包含了编译器需要执行的指令,以及指定源代码文件和目标文件之间的依赖关系。
2. Makefile语法Makefile由一系列规则组成,每个规则包含了以下内容:- 目标文件:需要生成的文件名- 依赖文件:生成目标文件所需要的源代码或其他目标文件- 命令行:生成目标文件所需要执行的命令例如:```target: dependency1 dependency2command1command2```其中,“target”表示目标文件,“dependency1”和“dependency2”表示依赖文件,“command1”和“command2”表示生成目标文件所需执行的命令。
3. Makefile使用方法在Linux系统中,可以使用make命令来读取并执行Makefile中的规则。
make命令会自动检测源代码和目标代码之间的依赖关系,并根据规则自动编译程序。
例如,在当前目录下有一个名为“test.c”的源代码文件,并且在同一目录下有一个名为“Makefile”的文件,其中包含以下规则:test: test.cgcc -o test test.c```则可以使用以下命令来编译程序:```make```4. Makefile的优缺点优点:- Makefile可以自动检测源代码和目标代码之间的依赖关系,只需要编写简单的规则即可。
- Makefile可以在不同的平台上使用,具有很好的可移植性。
缺点:- Makefile语法比较繁琐,需要编写大量的规则。
- Makefile无法自动处理一些复杂的依赖关系,需要手动编写规则。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
最近一直在搞Makefile文件的编辑,一直想通过自己的心得体会与广大网友分享。
Linux学习者只有参与的大多人当中去,才能体会到乐趣。
同时慢慢培养自己的学习linux的兴趣爱好。
与广大网上爱好者互动。
Linux的GNU计划:Linux下构建自己的开源软件使用的是linux下自己带的强大的工具。
Autoconf libtoolize 和automake .这是开源软件必须的基本工具。
如果使用了autoconf和automake,除了编译应用程序,用户并不需要有这些工具。
使用这些工具的目的是创建能在用户环境使用的、可移植的shell脚本和Makefile文件。
Autoconf实际上是一个工具集,其中包含aclocal、autoheader和autoconf等可执行文件。
这些工具生成一个可移植的shell脚本—configure,configure和软件包一起发布给用户。
它探查编译系统,生成Makefile文件和一个特殊的头文件config.h。
由configure生成的文件能适应用户系统的特定环境。
configure脚本从一个称为Makefile.in的模板文件生成每个Makefile文件。
而Makefile.in 有Makefile.am 生成。
Configure.in 有开发者自己手动修改。
Makefile.am 是由开发者自己手写。
Libtool软件包是第三个重要的GNU工具,它的作用是确定共享库在特定平台上的特性。
因为共享库在不同平台上可能会有所不同。
上述是自动生成Makefile的概括。
以后再细讲。
手动书写Makefile:手动书写顾名思义就是自己跳过configure.Scan configure.in configure Makefile.am Makefile.in 的生成过程。
直接书写Makefile 这种方式只能用于相对简单的源代码。
如有几个,几十个或者上百个源文件时,自己编写Makefile往往是可行的,但是如果我们所编写的源文件有几千,几万,几十万甚至更多时,显然手动书写Makefile不是个明智之举。
我们在手动书写Makefile时(此心得面向是略微看过Makefile的编写规则。
如果没看过,可以参考这个文章“大家一起写Makefile”里面有蛮详细的介绍)一个简单的makefile的书写。
我们只需要把握编译选项,链接选项目标依赖文件等给大家分享下自己的自己对编译和链接的领悟(勿拍砖)编译就是将检测各种源文件的语法是否正确。
我们称之为是从.c→到.o的过程。
这个过程中只是检测语法错误。
而链接过程我称之为从.o→.a或者.la 然后从.a(la)到可执行文件的过程。
其中有心的各位会发现.a或者.la 是一个很大的文件。
笔者以为这只是个中间连接文件。
就是把所有的函数。
调用子函数。
以及嵌套调用的函数在中间文件里铺开的过程。
现在以笔者最近的一个例子作为分析进入到Makefile文件的编写中;CROSSCOMPILE :=arm-linux-CC :=$(CROSSCOMPILE)gccLD :=$(CROSSCOMPILE)ldLDFLAGS := -lmCLFAGS := -Wall -02 -c -gCFLAGS += -I $(PWD)OBJS :=bitstream.o\mask.o\mmask.o\mqrspec.o\qren.o\qrencode.o\qrinput.o\qrspec.o\rscode.o\split.o.PHONY:%.o%.o:%.c$(CC) $(CFLAGS) $< -o $@all:$(OBJS)$(CC) $(LDFLAGS) -o qrencode $^.PHONY:cleanclean:rm -rf $(OBJS) qrencode很明显这是个属于极其简单的Makefile文件。
有初学者会认为。
很多我拿到的代码里已经有了Makefile 我干嘛还有学习Makefile编写呢?我觉得对于只想移植。
不想开发的朋友来说或许足够了。
但是对于我们要往深水区来游的小同志来说。
显然Makefile的编写和shellscript 的编写。
很明显是我们的必修课。
这是我们对大工程把握水平的体现。
结束废话:开始分析Makefile的写法:首先进come到我们面前的是CROSSCOMPILE :=arm-linuxCROSSCOMPILE :=这是个变量定义而且是一个可以传递到底层Makefile文件的定义变量。
而且必须是传递到底层。
然而一旦传递的底层。
它必然是个环境变量。
所以可以选择export linux 下的命令来全局化。
所以Makefile中变量的定义是如果需要引入到环境变量中请选择全程大写。
如果仅是这个Makefile中使用。
不会用到子目录Makefile中,请选择小写。
当然即使大写我们也需要配合export后才可传递到底层Makefile按照进程的思想,当前Makefile层是一个进程,调用下一层Makefile的过程就是开启一个新的进程。
调用下一个进程使用include + Makefile文件第二个符号:= 这是个环境变量的定义。
= 表示定义一个新的变量。
:=表示是如果前边定义过了则选择是覆盖之前的定义。
+=表示追加。
?=则是表示如果询问定义,既是如果前边定义了,这里不在定义。
而arm-linux-gcc这里所说的是arm下交叉编译工具而gcc则是linux下的编译工具当然如果选择的是C++ 则是g++ 和arm-linux-g++ 这里采用C语言。
毕竟编译和链接过程跟C++ 类似。
上述二位是非常敬畏的了编译器。
因为linux下它的出现解决了编译工具的问题。
而编译对应的是链接。
链接分别对应的是arm-linux-ld 和ld 当然不同的交叉编译版本不同。
可能略有差别。
只有交叉编译的概念。
如有误解请问伟大的度娘或者强大的360CC以及LD这里定义的是编译器和链接器这里采用可以方便修改的做法。
用的是变量替代。
往下走时是我们的参数传递。
我们知道在linux命令行下使用gcc 或者arm-linux-gcc时我们也会有参数传入,这里就是我们所说的参数传递。
参数传递的意思则是-lm则是告诉编译器如果数学库找不到请到/libs下找。
我们是需要数学库的数学函数位于libm.so库文件中(这些库文件通常位于/lib目录下),-lm选项告诉编译器,我们程序中用到的数学函数要到这个库文件里找一般参数很多我们这里只介绍必须的。
很多是缺省的。
就是了解有这回事。
未必一定要用的-c 告诉编译器你编译的对象是.c-o 告诉编译器编译无错后输出文件格式为.o-static告诉编译器不用动态库,只是使用静态库(动态库和静态库的去一个是.so一个是.a)这个编译后会产生很大的文件。
一般不使用与之对应的这是只是使用动态库–share 这一般是我们的选择。
还有就是-S生成汇编文件-E生成预处理文件-wall 启动警告检测-02 是编译器的级别一共00 01 02 03 四个编译器级别。
-00表示没有优化,-01为缺省值,-03优化级别最高-g 为在编译的时候,产生条是信息-I指定头文件目录$(PWD) 表示执行linux下命令pwd一个生成当前位置的变量。
并替代了。
其余的参数如果有需要的可以自己查看拉。
毕竟编译器是个很强大的。
参数的废话结束了那么我们进入到我们的目标定义目标定义的一个显著符号则是:如ALL:$(OBJS) 这里说明我们这就是编译的总目标Makefile文件里可以定义编译一个目标,也可以定义编译多个目标(设计伪定义)就是下面使用的关键字.PHONYMakefile文件中总是默认第一个定义的目标作为总体的生成目标。
使用上诉关键字后编译器就是知道了这里不是,只是一个伪目标。
通常配合着clean distclean 来使用。
那就是后边的删除Clean:rm –rf $(OBJS) qrencode这里指的是删除所有生成的目标文件rm是linux下一个命令。
不在叙述。
下边进入到奇怪的字符的解释:$ 是一个用了很多遍的字符是一个具有替代功能的字符如$(OBJS)就是替代我们定义的所有的变量。
还有就是$@ 是在编译过程中的所生成的目标文件$<是我们所依赖的文件$(CC) $(CFLAGS) $< -o $@上述的语句就是CC替代arm-linux-gcc CGLAGS 用来替代我们的参数传递$<表示依赖所有的.C 文件–c的参数传递在CFLAGS -o目的是生成.o 文件所以S@则是目标文件还有语句%.o:%.c“%”的意思是匹配零或若干字符就是自动匹配这里的o和c 文件$(CC) $(LDFLAGS) -o qrencode $^这句话的解释则是编译生成qrencode的可执行文件。
$^的意思则是自动依赖所有的文件所以看者不知道是否明白了一个手写Makefile的语法写的过程?其实就是把我们平时写的arm-linux-gcc –c mian.c –o mian.o原理类似。
至于Makefile中的自动查询的方式:我们知道上述是一个隐式的Makefile的编写方式。
Makefile中* 为通配符这个玩过Linux肯定知道。
还有就是换行符\特别声明下如果在命令下加入@ 表示该条命令只是执行但不输出该条命令。
输出执行命令结果。
显式的编写方式往往看者很明白。
但是很繁琐。
隐式的写法就是使用了自动匹配和静态编写的方式写成了上诉的Makefile当然复杂的makefile还会有linux的shell命令的使用还有就是我们的字符命令这里的简单书写个人感觉暂时用不着。
还有就是简单命令的使用如ifeqIf neq#ifdefneElse#end ifVPATH 用于声明代码的路径Vpath %.c fileVpath %.c file1路径声明优先搜索file 和file1Makefile下每条命令下执行正确了都会返回0 错误返回非0 然后检测退出。
Make –t =touch 更新目标文件时间但不进行新的编译。
Make –q =question 如果目标不在。
打印输出。
目标在,不显示Make –f=file指定编译文件这里感觉使用的就是这么几个。
至于字符函数的处理。
笔者的功力真的没有那么深。
暂时手动写Makefile过程中未使用过。
自动生成Makefile的过程为:1.执行autoscane 生成configure.scan2.然后手动修改configure.scan为configure.in 有的平台直接为configure.ac3.修改configure.in 里面的内容。
怎么修改。
下文讲,这给给看客一个大致全过程。