4--Makefile相关

Makefile知识点备忘

1 Makefile步骤

1.edit (vi)
2.编译 (gcc)
3.项目project (make)
4.setup打包发布 (make)

例如:
1.makedemo文件夹下有3个c文件:func1.c func2.c main.c ,main.c中使用了2个函数分别位于func1.c func2.c中,
2.gcc main.c func1.c func2.c -o mainwork 。
3.执行./mainwork 2 5,则传入参数2 5,并打印结果。

2 Makefile作用(工程文件组织,编译成复杂的程序 | 安装以及卸载程序)

2.1 标题Makefile中rule格式:

targets(目标)prerequisites(依赖)
	command(命令)

2.2 vi一个Makefile,最终是生成第一条rule包含的文件,递归的去调用rule下面的指令

#creat first rule
mainwork1:main.o func1.o func2.o
	gcc main.o func1.o func2.o -o mainwork

main.o:main.c
	gcc -c main.c

func1.o:func1.c
	gcc -c func1.c

func2.o:func2.c
	gcc -c func2.c
  • 源文件:
    main.c func1.c func2.c Makefile

  • make之后目录所包含文件:
    main.c main.o func1.c func1.o func2.c func2.o mainwork(可执行文件) Makefile

  • 若删除mainwork之后,并未修改源文件,再执行make命令,不会再次重新编译,而是直接生成可执行文件mainwork

2.2 make clean 指令

若想删除垃圾文件(伪目标文件):则在Makefile后面自己编写rule

#creat first rule
mainwork1:main.o func1.o func2.o
	gcc main.o func1.o func2.o -o mainwork

main.o:main.c
	gcc -c main.c

func1.o:func1.c
	gcc -c func1.c

func2.o:func2.c
	gcc -c func2.c
clean:
	rm func1.o func2.o main.o 
  • 源文件:
    main.c func1.c func2.c Makefile
  • make之后目录所包含文件:
    main.c main.o func1.c func1.o func2.c func2.o mainwork(可执行文件) Makefile
  • make clean之后目录所包含文件:
    main.c func1.c unc2.c Makefile

2.3 make install与make uninstall 指令

若想安装与卸载依旧是在Makefile文件里面自己编写rule,如果权限不够可以加上sudo。

#creat first rule
mainwork1:main.o func1.o func2.o
	gcc main.o func1.o func2.o -o mainwork

main.o:main.c
	gcc -c main.c

func1.o:func1.c
	gcc -c func1.c

func2.o:func2.c
	gcc -c func2.c
clean:
	rm func1.o func2.o main.o 
install:
	cp mainwork /usr/local/mainwork
uninstall:
	rm /usr/local/mainwork
  • 执行make install之后,路径文件夹中会存在mainwork可执行文件。
  • 执行make uninstall之后,路径文件夹下的mainwork会去除。

2.4 Makefile中变量

2.4.1 用户自定义变量-类似c语言宏

采用MObj = main.o func1.o func2.o,调用则$(MObj)

#creat first rule
MObj  = main.o func1.o func2.o
mainwork1:$(MObj )
	gcc $(MObj ) -o mainwork

main.o:main.c
	gcc -c main.c

func1.o:func1.c
	gcc -c func1.c

func2.o:func2.c
	gcc -c func2.c
clean:
	rm func1.o func2.o main.o 
install:
	cp mainwork /usr/local/mainwork
uninstall:
	rm /usr/local/mainwork
2.4.2 预定义变量,有利于商业软件的开发使用,例如更换编译器gcc之后,只需要将CC=gcc更换即可
#creat first rule
CC= gcc
CFLAGS = -g -c
MObj = main.o func1.o func2.o
mainwork1:$(MObj)
	$(CC)  $(CFLAGS ) $(MObj) -o mainwork

main.o:main.c
	$(CC) $(CFLAGS ) main.c

func1.o:func1.c
	$(CC) $(CFLAGS ) func1.c

func2.o:func2.c
	$(CC) $(CFLAGS ) func2.c
clean:
	rm $(MObj) mainwork
install:
	cp mainwork /usr/local/mainwork
uninstall:
	rm /usr/local/mainwork
2.4.3 自动变量以及环境变量
$*不包含拓展名的目标文件名称
$<第一个依赖文件名称
$?所有时间戳比目标文件晚的依赖文件
$@目标文件完整名称(常用)
$^所有不重复的依赖文件(常用)
#creat first rule
CC= gcc
CFLAGS = -g -c
MObj = main.o func1.o func2.o
mainwork1:$(MObj)
	$(CC)  $(CFLAGS ) $(MObj) -o $@
	
或者:
mainwork1:$(MObj) //$(^)代替了所有的依赖文件
	$(CC)  $(^) -o $@

main.o:main.c
	$(CC) $(CFLAGS ) main.c

func1.o:func1.c
	$(CC) $(CFLAGS ) func1.c

func2.o:func2.c
	$(CC) $(CFLAGS ) func2.c
clean:
	rm $(MObj) $@
install:
	cp mainwork /usr/local/$@
uninstall:
	rm /usr/local/$@

2.5 伪目标

采用伪目标可以防止文件夹下有同名的可执行文件.

#creat first rule
CC= gcc
CFLAGS = -g -c
MObj = main.o func1.o func2.o
mainwork1:$(MObj)
	$(CC)  $(CFLAGS ) $(MObj) -o $@
	
或者:
mainwork1:$(MObj) //$(^)代替了所有的依赖文件
	$(CC)  $(^) -o $@

main.o:main.c
	$(CC) $(CFLAGS ) main.c

func1.o:func1.c
	$(CC) $(CFLAGS ) func1.c

func2.o:func2.c
	$(CC) $(CFLAGS ) func2.c
	
.PHONY: clean
clean:
	rm $(MObj) $@
	
.PHONY: install	
install:
	cp mainwork /usr/local/$@
	
.PHONY: uninstall	
uninstall:
	rm /usr/local/$@

2.6 引用其它Makefile及Makefile嵌套

  • 包含:如果需要包含新的make2.mk文件
    声明include make2.mk即可。
  • 嵌套:文件夹为树状结构,顶级为root,内含一个make嵌套执行子文件夹下的make,生成依赖文件后,返回执行root文件夹下的make。
subsystem:
	cd subdir && gcc -c main.c

等价于:
subsystem:
	gcc -c main.c -Csubdir

2.7 条件判断

条件判断前不需要TAB空格,否则被认为是执行的命令,而非判断条件。

#creat first rule
CC= gcc
CFLAGS = -g -c
MObj = main.o func1.o func2.o
mainwork1:$(MObj)
ifeq($(CC),gcc)  //如果$(cc) == gcc,则。。。否则。。
	$(CC)  $(^) -o $@
else
	$(CC) $^ -o mainwork2
endif
main.o:main.c
	$(CC) $(CFLAGS ) main.c

func1.o:func1.c
	$(CC) $(CFLAGS ) func1.c

func2.o:func2.c
	$(CC) $(CFLAGS ) func2.c
	
.PHONY: clean
clean:
	rm $(MObj) $@
	
.PHONY: install	
install:
	cp mainwork /usr/local/$@
	
.PHONY: uninstall	
uninstall:
	rm /usr/local/$@

2.8 Makefile管理命令

-C dir读入指定目录下面的Makefile
-f file读入当前目录下的file文件为Makefile
-i忽略所有的命令执行错误
-I dir指定被包含的Makefile所在目录(大写i dir)
  • -C dir举例
    如果文件夹为MakeDemo,内含Makefile文件。目前位于makedemo文件夹的上级目录,则执行
				make -C MakeDemo
  • -f file举例
    如果文件夹为MakeDemo,Makefile改名为tc.mk文件。则在MakeDemo文件夹内执行
				make -f tc.mk
  • -I dir举例
    采用include的形式来包含

3 Autotools

由autoscan、aclocal、autoconf、autoheader、automake组成,作用为 扫描→展开宏→生成configure→生成head→生成makefile。

autoscan扫描源代码目录生成configure.scan文件configure.scan包含系统配置的基本选项,均为宏定义,需要将其更名为configure.in
aclocal是一个perl脚本程序,根据configure.in文件内容,自动生成aclocal.m4文件。定义为:aclocal - create aclocal.m4 by scanning configure.ac生成的aclocal.m4是宏展开文件
autoconf用来生成configure文件configure.in文件的内容是宏,宏经过autoconf处理后会变成检查系统特性、环境变量、软件必须参数的shell脚本
autoheader自动生成config.h.in在configure生成config.h时生成in文件
automake使用automake–add-missing 来生成Makefile.inMakefile.am是用来生成Makefile.in的,需要手工书写

需要依赖的程序m4,prel

autotools使用流程
第一步:手工编写Makefile.am这个文件
第二步:在源代码目录树的最高层运行autoscan。然后手动修改configure.scan文件,并改名为configure.ac/configure.in
第三步:运行aclocal,它会根据configure.ac的内容生成aclocal.m4文件
第四步:运行autoconf,它根据configure.ac和aclocal.m4的内容生成configure这个配置脚本文件
第五步:运行automake –add-missing,它根据Makefile.am的内容生成Makefile.in
第六步:运行configure,它会根据Makefile.in的内容生成Makefile这个文件
在这里插入图片描述
在这里插入图片描述

操作示例:
mkdir demo_conf //新建一个文件夹 并且进入,然后vi hello.c如下

#include <stdio.h>
int main()
{
	printf("hello configure\n");
	return 0;
}
  • 执行autoscan生成autoscan.log configure.scan hello.c
    生成的configure.scan内的AC_XXX宏是供autoconfigure使用的。
  • 将configure.scan重命名为configure.acmv configure.scan configure.ac
  • vi configure.ac并修改如下
AC_INIT(hello,1.0,123456@qq.com)//文件名,版本号,bug发送至所写邮箱
AM_INIT_AUTOMAKE(hello,1.0)//新增一个宏在AC_CONFIG_HEADERS([config.h])下,表示需要automake工具生成目标文件。
AC_OUTPUT(Makefile)
  • 执行aclocal生成aclocal.m4,vi aclocal.m4可知相当于展开了AM_INIT_AUTOMAKE
  • 已经有了aclocal.m4与configure.ac,则可以执行autoconf,生成configure文件
  • 手写一个Makefile.am文件,vi Makefile.am
bin_PROGRAMS = hello //生成的程序名
hello_SOURCES = hello.c //依赖的源代码文件名
  • 已经有了Makefile.am与config.h.in 则执行automake --add-missing若缺少NEWS README AUTHORS ChangLog等文件可以自己添加touch NEWS README AUTHORS ChangLog,若缺少config.h.in可以在configure.ac中把configure.h的需求#掉,或者执行autoheader生成config.h.in
  • 执行./configure生成config.status 与Makefile
  • 有了Makefile文件,可以执行make生成hello文件
  • 执行./hello,屏幕输出hello congifure.
  • 执行sudo make install可安装到指定目录下,可以不用在当前文件夹下就可./hello
  • 商业发布执行make dist可生成hello-1.0.tar.gz压缩包
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值