makefile项目管理

Posted milaiko

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了makefile项目管理相关的知识,希望对你有一定的参考价值。

makefile项目管理

命名 Makefile makefile

touch makefile

创建之后编译makefile文件
按这样的格式进行

目标:依赖文件
    (一个tab缩进)命令

举个例子

hello:hello.cpp
    g++ hello.cpp -o hello

目标:生成的hello
依赖:使用hello.cpp生成的

假设我们写个下面这样的makefile,但是没有hello.o文件,就会报错

hello:hello.o 
    g++ hello.cpp -o 

多文件编译

有三个c文件,add.c sub.c div1.c test.c

a.out:test.c add.c sub.c div1.c 
    gcc test.c add.c sub.c div1.c -o a.out

但是现在只改了add.c,就需要重新编译其他三个文件,实在是资源浪费。

那么要怎样提升工程效率,避免重复,那就只能分步编译

a.out:test.o sub.o div1.o add.o
	gcc test.o sub.o div1.o add.o -o a.out
test.o:test.c
	gcc -c test.c -o test.o
sub.o:sub.c
	gcc -c sub.c -o sub.o
add.o:add.c
	gcc -c add.c -o add.o
div1.o:div1.c	
	gcc -c div1.c -o div1.o

切记,a.out:test.o sub.o div1.o add.o必须放在最前面,最前面的是终极目标。

还可以使用all来指定终极目标

ALL:a.out
a.out:test.o sub.o div1.o add.o
	gcc test.o sub.o div1.o add.o -o a.out
test.o:test.c
	gcc -c test.c -o test.o
sub.o:sub.c
	gcc -c sub.c -o sub.o
add.o:add.c
	gcc -c add.c -o add.o
div1.o:div1.c	
	gcc -c div1.c -o div1.o

两个函数

src = $(wildcard ./*.c): 当前工作目录下的所有.c文件。将文件名组成列表。赋值给变量.c

obj = $(patsubst %.c %.o, $(src)):将参数3中,包含参数1的部分,替换为参数2
src = $(wildcard *.c) #add.c sub.c div1.c test.c
obj = $(patsubst %.c %.o $(src)) #add.c sub.o div1.o test.o 
a.out:$(obj)
	gcc $(obj) -o a.out
test.o:test.c
	gcc -c test.c -o test.o
sub.o:sub.c
	gcc -c sub.c -o sub.o
add.o:add.c
	gcc -c add.c -o add.o
div1.o:div1.c	
	gcc -c div1.c -o div1.o

clean

src = $(wildcard *.c) #add.c sub.c div1.c test.c
obj = $(patsubst %.c %.o $(src)) #add.c sub.o div1.o test.o 
a.out:$(obj)
	gcc $(obj) -o a.out
test.o:test.c
	gcc -c test.c -o test.o
sub.o:sub.c
	gcc -c sub.c -o sub.o
add.o:add.c
	gcc -c add.c -o add.o
div1.o:div1.c	
	gcc -c div1.c -o div1.o
clean:
	-rm -rf 	$(obj) a.out

-rm -rf :删除不存在的文件不报错

make clean -n # 模拟执行

3个自动变量

  • $@:表示规则的命令中,表示规则的目标
  • $^:在规则的命令中,表示所有依赖条件
  • $<:在规则的命令中,表示第一个依赖条件,如果将该变量应用与模式规则中, 它可以将依赖规则列表的依赖项依次取出。
src = $(wildcard *.c) #add.c sub.c div1.c test.c
obj = $(patsubst %.c %.o $(src)) #add.o sub.o div1.o test.o 
a.out:$(obj)
	gcc $^ -o a.out
test.o:test.c
	gcc -c $< -o $@
sub.o:sub.c
	gcc -c $< -o $@
add.o:add.c
	gcc -c $< -o $@
div1.o:div1.c	
	gcc -c $< -o $@
clean:
	-rm -rf 	$(obj) a.out

模式规则

src = $(wildcard *.c) #add.c sub.c div1.c test.c
obj = $(patsubst %.c %.o $(src)) #add.c sub.o div1.o test.o 
a.out:$(obj)
	gcc $^ -o a.out
%.o:%.c
	gcc -c $< -o $@
clean:
	-rm -rf 	$(obj) a.out

静态模式规则

src = $(wildcard *.c) #add.c sub.c div1.c test.c
obj = $(patsubst %.c %.o $(src)) #add.c sub.o div1.o test.o 	
a.out:$(obj)
	gcc $^ -o a.out
%.o:%.c
	gcc -c $< -o $@
%.o:%.s
 	gcc -S $< -o $@ # 假设加入其他的模式规则, obj就会乱套,它不知道使用哪个模式规则的,因此要使用静态模式规则
clean:
	-rm -rf 	$(obj) a.out
src = $(wildcard *.c) #add.c sub.c div1.c test.c
obj = $(patsubst %.c %.o $(src)) #add.c sub.o div1.o test.o 
a.out:$(obj)
	gcc $^ -o a.out
$(obj):%.o:%.c #使用了静态模式规则
	gcc -c $< -o $@
clean:
	-rm -rf 	$(obj) a.out

clean

在当前目录下,有clean文件时,

clean:
	-rm -rf 	$(obj) a.out

该命令不会被执行,因为它会以为clean是目标文件,而非命令。

src = $(wildcard *.c) #add.c sub.c div1.c test.c
obj = $(patsubst %.c %.o $(src)) #add.c sub.o div1.o test.o 
a.out:$(obj)
	gcc $^ -o a.out
$(obj):%.o:%.c #使用了静态模式规则
	gcc -c $< -o $@
clean:
	-rm -rf 	$(obj) a.out
.PHONY: clean ALL # 生成伪目标
src = $(wildcard *.c) #add.c sub.c div1.c test.c
obj = $(patsubst %.c %.o $(src)) #add.c sub.o div1.o test.o 

myArgs = -Wall -g 
a.out:$(obj)
	gcc $^ -o a.out $(myArgs)
$(obj):%.o:%.c #使用了静态模式规则
	gcc -c $< -o $@ $(myArgs)
clean:
	-rm -rf 	$(obj) a.out
.PHONY: clean ALL # 生成伪目标

如果头文件命名为m,想要make这个不想改名,直接加个-f参数即可

make -f m

以上是关于makefile项目管理的主要内容,如果未能解决你的问题,请参考以下文章

Yuchuan_Linux_C编程之六 Makefile项目管理

Makefile项目管理-----在Linux下编译c/c++程序

从头開始写项目Makefile:统一目标输出文件夹

Openssh升级报错,终极解决方法附原因,Your OpenSSL headers do not match your library. 编译Openssh时报错,生成MakeFile文件时报错

如何影响目标的顺序,为 Makefile.am 添加额外的步骤等?

makefile