背景:
去年做項目的時候,由於有需要編譯出多個可執行文件的需求,修改了Makefile使其支持生成多個結果(編譯多個含有main函數的文件),但總覺得自己的實現不夠完美。
今年又遇到這樣需求的時候,可在網上找了一圈,發現沒有找到能夠同時編譯得到多個結果的Makefile模板。
目錄結構

可以發現,其中,seeker.c 以及 main.c 中都有 main函數,如果按照以往的編譯方式,是會引起沖突的

如果將編譯的文件寫死而引起的不便又違背了make簡潔的初衷,那么本人是怎么解決這樣的問題的呢?
解決方法:
其實很簡單,只需要
1.在包含main函數的.c文件中,頭尾加上條件宏
2.在makefile中的編譯規則中指定-D選項(條件編譯)
這樣一來,當make時,其他包含了main的宏由於條件編譯而變成了空文件,自然便不會引起多重main函數編譯沖突了。
源碼:
以下是本人的makefile,希望各路大神批評指正。如果有更好的實現,請告知我,謝謝。
模板與demo的網址:https://gitee.com/schips/common_code_for_my_self/tree/master/makefile/makefile_for_apps
$ cat Makefile
# 添加所有的.c文件 SRCS = $(wildcard src/*.c) OBJS = $(SRCS:.c = .o) # 指定 頭文件目錄 INCLUDES = -I ./inc # 指定庫目錄 LIBS = -L ./lib # 指定編譯器 CC = gcc # 指定編譯選項(可選) CCFLAGS = -g -Wall -O0 # 編譯目標列表 OUTPUT1 = target1 OUTPUT2 = target2 # ... OUTPUTLIST=$(OUTPUT1) $(OUTPUT2)
# 將 所有的目標作為一個列表,便於make clean all : $(OUTPUTLIST) # 編譯目標1 $(OUTPUT1) : $(OBJS) @$(CC) $^ -o $@ $(INCLUDES) $(LIBS) -D_$(shell echo $(@)|tr a-z A-Z)_ $(OUTPUT2) : $(OBJS) @$(CC) $^ -o $@ $(INCLUDES) $(LIBS) -D_$(shell echo $(@)|tr a-z A-Z)_ %.o : %.c @$(CC) -c $< $(CCFLAGS) clean: @rm $(OUTPUTLIST) .PHONY:clean
注:紅色的處只是為了使得宏與OUTPUTx的名字保持一致,且不是小寫形式(習慣上,宏使用大寫),這樣一來就不需要修改過多的東西就很方便了。
其他:
項目中使用到的2個帶有main函數的文件頭部(文件最后一行都是 #endif)


