在当前的C项目中,我们错误地将所有目标文件放在源中的不同文件夹中。一开始管理起来并不复杂,但现在我们需要在特定文件夹中编译一些文件,在另一个文件夹中编译其他文件。
树木看起来像:
运行make
后,我希望将树状修改为:
首先,makefile就像:
CSRC = $(wildcard *.c)
OBJS = $(CSRC:%.c=%.o)
objs1/%.o : %.c
gcc -c -o $@ $<
现在还有file2.c并且它不应该在objs1中编译,file1.o应该在objs1和objs2中,file2.o应该在objs2中。
我使用通用规则,因为项目更大,非常方便。
所以我有两个包含对象名称的变量,一个用于objs1,另一个用于objs2。
我想做点什么
$(OBJS1): %.o %.c
但它会像objs1中的源文件一样,事实并非如此。
那么将通用规则与指定位置组合的方式是什么?
谢谢
答案 0 :(得分:1)
如果您容忍递归make,则可以创建相应的子目录
目标文件的配额只需在子目录中创建即可
适当的CFLAGS
和CPPFLAGS
以及VPATH=../src
在这种情况下,根本不需要编写任何编译方法,例如
<强>生成文件强>
export CC := gcc
objs1: OBJS := file1.o
objs2: OBJS := file1.o file2.o
objs1: CFLAGS := -g
objs1: CPPFLAGS := -I../include
objs2: CFLAGS = -O2
objs2: CPPFLAGS := -I../include -DNDEBUG
.PHONY: all clean objs1 objs2
all: objs1 objs2
objs1 objs2:
mkdir -p $@
$(MAKE) -C $@ $(OBJS) CFLAGS='$(CFLAGS)' CPPFLAGS='$(CPPFLAGS)' VPATH=../src
clean:
rm -fr objs1 objs2
的运行方式如下:
$ make
mkdir -p objs1
make -C objs1 file1.o CFLAGS='-g' CPPFLAGS='-I../include ' VPATH=../src
make[1]: Entering directory '/home/imk/develop/scrap/objs1'
gcc -g -I../include -c -o file1.o ../src/file1.c
make[1]: Leaving directory '/home/imk/develop/scrap/objs1'
mkdir -p objs2
make -C objs2 file1.o file2.o CFLAGS='-O2' CPPFLAGS='-I../include -DNDEBUG' VPATH=../src
make[1]: Entering directory '/home/imk/develop/scrap/objs2'
gcc -O2 -I../include -DNDEBUG -c -o file1.o ../src/file1.c
gcc -O2 -I../include -DNDEBUG -c -o file2.o ../src/file2.c
make[1]: Leaving directory '/home/imk/develop/scrap/objs2'
子目录为.PHONY
非常重要。否则,make
会
认为他们的存在意味着无所事事。
答案 1 :(得分:0)
您可能希望手动指定对象,因为您需要在特定目录中编译特定文件:
objs1 := objs1/file1.o
objs2 := objs2/file1.o objs2/file2.o
$(objs1): CFLAGS += blah1
$(objs2): CFLAGS += blah2
$(objs1): objs1/%.o: src/%.c
$(objs2): objs2/%.o: src/%.c
$(objs1) $(objs2):
$(COMPILE.c) $(OUTPUT_OPTION) $<
如果少量复制令您烦恼,则可以使用二次扩展
.SECONDEXPANSION:
$(objs1) $(objs2): %.o: src/$$(notdir $$*).c
$(COMPILE.c) $(OUTPUT_OPTION) $<