makefile 学习

31 篇文章 0 订阅
target ... : prerequisites ...
	command

prerequisites 中如果有一个以上的文件比 target 文件要新的话, command 所定义的
命令就会被执行。这就是 Makefile 的规则。也就是 Makefile 中最核心的内容。

只要 make 看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果 make 找
到一个 whatever.o,那么 whatever.c,就会是 whatever.o 的依赖文件。并且 cc -c
whatever.c 也会被推导出来
例如

kbd.o command.o files.o : command.h
VPATH = src:../headers

上面的的定义指定两个目录,“src”和“…/headers”, make 会按照这个顺序进行搜索。
目录由“冒号”分隔。(当然,当前目录永远是最高优先搜索的地方)

我们可以连续地使用 vpath(小写) 语句,以指定不同搜索策略。如果连续的 vpath 语句中出现了
相同的,或是被重复了的,那么, make 会按照 vpath 语句的先后
顺序来执行搜索。如:

vpath %.c foo
vpath % blish
vpath %.c bar

其表示“.c”结尾的文件,先在“foo”目录,然后是“blish”,最后是“bar”目录。

变量

$@ 表示目标文件
$^ 表示所有的依赖文件
$< 表示第一个依赖文件
$? 表示比目标还要新的依赖文件列表

%.o:%.c,
%.o 和要找的 test1.o 匹配
得到%=test1。
所以在后面的%.c就表示test1.c了

$(OBJS) : %.o : %.c
    gcc -c $< -o $@

这两条命令的功能就是,大目标是OBJS,这个OBJS就是各种.o文件,然后%.o就是具体的解释,而%.c就是对应同样名字的.c文件,而下面的命令,结合了2个自动化变量,$< 表示依赖对象集中的第一个,$@ 则代表了目标集。所以这个功能就是要遍历所有的.c文件,对所有的.c文件进行编译,然后编译生成对应的.o文件。

目标

一个目标(target)就构成一条规则。目标通常是文件名,指明Make命令所要构建的对象,比如上文的 a.txt 。目标可以是一个文件名,也可以是多个文件名,之间用空格分隔。

除了文件名,目标还可以是某个操作的名字,这称为”伪目标”(phony target)。

clean:
      rm *.o

上面代码的目标是clean,它不是文件名,而是一个操作的名字,属于”伪目标 “,作用是删除对象文件。

$ make  clean

但是,如果当前目录中,正好有一个文件叫做clean,那么这个命令不会执行。因为Make发现clean文件已经存在,就认为没有必要重新构建了,就不会执行指定的rm命令。

为了避免这种情况,可以明确声明clean是”伪目标”,写法如下。

.PHONY: clean

符号

  • ?=
    PREFIX?=/usr/local 如果已经定义过变量PREFIX就保持不变,否则令其为
    /usr/local
  • @ 运行make的时候不显示该命令

example

CFLAGS=-g -O2 -Wall -rdynamic -Wextra -Isrc  -DNDEBUG $(OPTFLAGS)
LIBS=-ldl $(OPTLIBS)
PREFIX?=/usr/local

SOURCES=$(wildcard src/**/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))

TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))

TARGET=build/liblcthw.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))

# The Target Build
all: $(TARGET) $(SO_TARGET) tests

dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
dev: all

$(TARGET): CFLAGS += -fPIC
$(TARGET): build $(OBJECTS)
	ar rcs $@ $(OBJECTS)
	ranlib $@

$(SO_TARGET): $(TARGET) $(OBJECTS)
	$(CC) -shared -o $@ $(OBJECTS)

build:
	@mkdir -p build
	@mkdir -p bin

# The Unit Tests
.PHONY: tests
tests: LDLIBS += $(TARGET)
tests: $(TESTS)
	sh ./tests/runtests.sh

# The Cleaner
clean:
	rm -rf build $(OBJECTS) $(TESTS)
	rm -f tests/tests.log 
	find . -name "*.gc*" -exec rm {} \;
	rm -rf `find . -name "*.dSYM" -print`

# The Install
install: all
	install -d $(DESTDIR)/$(PREFIX)/lib/
	install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/

# The Checker
check:
	@echo Files with potentially dangerous functions.
	@egrep '[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)\
		|stpn?cpy|a?sn?printf|byte_)' $(SOURCES) || true


上述Makefile文件中
TEST_SRC=$(wildcard tests/*_tests.c)
负责找到所有测试文件
TESTS=$(patsubst %.c,%,$(TEST_SRC))
负责利用替换操作生成测试文件的目标,
比如test1.c生成test1.
src内的文件通过生成静态库的方式和测试文件链接
CFLAGS += $(TARGET)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值