LinuxC项⽬makefile模板
最近⽐较的系统学习了下makefile,⽹上查了很多资料,但是很多都是⼤同⼩异,没有⼀个称⼼的⼩型 c项⽬的⽐较通⽤的makefile模板。这⾥个⼈总结了⼀个 c项⽬的 makefile 模板,先放上模板,后⾯再具体解释⼏个关键点。
c makefile 参考模板
下⾯的模板⽐较短,源⽂件在 src ⽬录,编译输出在 output ⽬录。这个makefile⽂件保存在src、output同级的⽬录下,shell 中 cd 到这个⽬录执⾏ make 即可, 记得加上 -s 选项,不必要输出所有的命令。这⾥的src和output可以⾃⼰指定保存在相应的变量中。总体的思想就是利⽤源⽂件 .c ⽂件集合推导出所有的.d、.o⽂件, 利⽤ gcc 的 -MM 选项配合 makefile 的 -include 机制⾃动推到头⽂件依赖。
# c makefile template
SRC_DIR    = src
OUTPUT_DIR = output
TARGETS    = mytest.bin
SRCS = $(wildcard $(SRC_DIR)/*.c)
linux重定向DEPS = $(addprefix $(OUTPUT_DIR)/, $(patsubst %.c, %.d, $(notdir $(SRCS))))
OBJS = $(addprefix $(OUTPUT_DIR)/, $(patsubst %.c, %.o, $(notdir $(SRCS))))
CFLAGS  = -Wall -O2
RM      = rm -f -v
.PHONY: all
all: $(OUTPUT_DIR)/$(TARGETS)
$(OUTPUT_DIR)/%.d: $(SRC_DIR)/%.c
$(CC) -MM $(CFLAGS) $< | sed 's,$*\.o[ :]*,$(basename $@).o $@: ,g' > $@; \
echo "compile .d file: $@"
-include $(DEPS)
$(OUTPUT_DIR)/%.o: $(SRC_DIR)/%.c
$(COMPILE.c) $(OUTPUT_OPTION) $<; \
echo "compile .o file: $@"
$(OUTPUT_DIR)/$(TARGETS): $(OBJS)
$(LINK.o) $(OUTPUT_OPTION) $^; \
echo "compile .bin file: $@ OK!"
.PHONY: clean
clean:
$(RM) output/*; \
echo "clean ok!"
⾃动处理头⽂件依赖
利⽤ makefile 的 include 机制配合 GCC 的 -MM 选项来实现。具体可以参考这篇⽂章。makefile执⾏时,会先去include⽂件,如果没有会报warning,加上include前⾯加上-符号就不会告警了,然后make看是否有规则⽣成include⽂件,有就去⽣成,然后重新加载。有更新导致include的⽂件更新了也会重新加载。
这⾥⽣成依赖⽂件时好多资料都是先输出到⼀个临时⽂件中,个⼈感觉也可以不⽤⽣成临时⽂件,直接对字符流⽤管道重定向处理,最终⽣成类似这样的x.o x.d: x.c x.h a.h ... 这样的dependency ⽂件即可。这⾥主要⽤到了 sed 对指定的内容做了替换,⽣成.d⽂件的这个命令显⽰吧makefile的⾃动化命令展开,然后执⾏这个 shell 命令。
makefile中的变量
⾸先看⼀下这篇介绍,。重点理解⼀下变量的定义和展开机制,以及⼀些内置变量的默认值,还有⾃动化变量的⽤法。这⾥只摘录过来⼀些重点:
$@,表⽰规则中的⽬标。
$<,表⽰规则中的第⼀个条件。
$?,表⽰规则中所有⽐⽬标新的条件,组成⼀个列表,以空格分隔。
$^,表⽰规则中的所有条件,组成⼀个列表,以空格分隔。
$*, 表⽰⽬标模式中%所代表的部分。
这⾥重点注意下 $* 是否有包含了⽬录名。不确定的地⽅可以⾃⼰在命令中 echo 出来,明确后再继续编写命令。个⼈在 mac os下测试如下:
gcc -MM src/test.c的输出是test.o: src/test.c src/test.h,前⾯的test.o没有带⽬录名。
这条语句$(OUTPUT_DIR)/%.d: $(SRC_DIR)/%.c 下⾯使⽤的 $* 也没有包括⽬录名只有⽂件名。
⼀些内置变量的值如下:
CC c编译器的名字,缺省值是cc。
CFLAGS c编译器的选项,没有定义。
LD 链接器的名字,缺省值是ld。
LDFLAGS 链接器的选项,没有定义。
TARGET_ARCH 和⽬标平台相关的命令⾏选项,没有定义。
OUTPUT_OPTION 输出的命令⾏选项,缺省值是-o $@。
COMPILE.c 编译.c⽂件的命令⾏,缺省值是$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c。
LINK.o 把.o⽂件链接在⼀起的命令⾏,缺省值是$(CC) $(LDFLAGS) $(TARGET_ARCH)。
LINK.c 把.c⽂件链接在⼀起的命令⾏,缺省值是$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)。
RM 删除命令的名字,缺省值是rm -f。
makefile 中的常⽤函数
常⽤的函数也不是很多,⼤都是字符和⽂件名操作。可以参考 GNU 官⽅⼿册,上⾯的例⼦主要使⽤了⽂件名操作的相关函数,这⾥给出官⽅的说明链接 。
有需要直接Google GUN的官⽅⼿册,也⾮常⽅便。
GCC常⽤选项
编写makefile的话,还需要熟悉,再具体则可以查对应的官⽅的⼿册。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。