Makefile:其他目录中的自动目标

时间:2016-05-27 18:16:08

标签: makefile

在当前的C项目中,我们错误地将所有目标文件放在源中的不同文件夹中。一开始管理起来并不复杂,但现在我们需要在特定文件夹中编译一些文件,在另一个文件夹中编译其他文件。

树木看起来像:

  • objs1
  • OBJS2
  • SRC
    • file1.c中
    • file2.c中

运行make后,我希望将树状修改为:

  • objs1
    • file1.o
  • OBJS2
    • file1.o
    • file2.o

首先,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中的源文件一样,事实并非如此。

那么将通用规则与指定位置组合的方式是什么?

谢谢

2 个答案:

答案 0 :(得分:1)

如果您容忍递归make,则可以创建相应的子目录 目标文件的配额只需在子目录中创建即可 适当的CFLAGSCPPFLAGS以及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) $<