2017-01-03 66 views
0

我想创建一个Makefile文件,该文件可以在不同的文件夹中生成目标文件,具体取决于调用的目标是与Makefile中的目标相关的输出文件夹

比如我想与target2调用时,一个名为“obj/t1”和“obj/t2”文件夹中,当我调用make与目标target1它创建的对象。

我创造了这个小的Makefile:

.PHONY=target1 target2 clean setup 

SOURCE_ROOT_FOLDER  := src 
SOURCES     := $(shell find $(SOURCE_ROOT_FOLDER) -iname "*.cpp") 
OBJ_ROOT_FOLDER   := obj 
target1:SUB_OBJ_FOLDER := t1 
target2:SUB_OBJ_FOLDER := t2 

OBJECTS     = $(subst $(SOURCE_ROOT_FOLDER), $(OBJ_ROOT_FOLDER)/$(SUB_OBJ_FOLDER), \ 
          $(SOURCES:.cpp=.o)) 

$(OBJ_ROOT_FOLDER)/$(SUB_OBJ_FOLDER)/%.o: $(SOURCE_ROOT_FOLDER)/%.cpp 
    @echo "Creating subfolder $(OBJ_ROOT_FOLDER)/$(SUB_OBJ_FOLDER)" 
    mkdir -p $(dir [email protected]) 
    @echo "Compiling $< to obj file: [email protected]" 
    touch [email protected] 

target1:   $(OBJECTS) 
    @echo Files $(OBJECTS) have been compiled! 

target2:   $(OBJECTS) 

clean: 
    rm -rf $(OBJ_ROOT_FOLDER) 

setup: 
    @mkdir -p src 
    @mkdir -p src/classA 
    @mkdir -p src/classB 
    @touch src/file.cpp 
    @touch src/classA/fileA.cpp 
    @touch src/classB/fileB.cpp 

可以调用setup目标再现一个简单的假项目的文件夹中,并通过自己执行。

make target1输出是:

Creating subfolder obj/t1 
mkdir -p obj//classB/ 
Compiling src/classB/fileB.cpp to obj file: obj//classB/fileB.o 
touch obj//classB/fileB.o 
Creating subfolder obj/t1 
mkdir -p obj//classA/ 
Compiling src/classA/fileA.cpp to obj file: obj//classA/fileA.o 
touch obj//classA/fileA.o 
Creating subfolder obj/t1 
mkdir -p obj// 
Compiling src/file.cpp to obj file: obj//file.o 
touch obj//file.o 
Files obj/t1/classB/fileB.o obj/t1/classA/fileA.o obj/t1/file.o have been compiled! 

因此,大家可以看到变量SUB_OBJ_FOLDER在配方中以正确的方式设置,但似乎在目标是不确定的(因为@与扩大一个空字符串),即使OBJECTS变量在target1规则中正确扩展(因为您可以检查输出中写入的最终文本)。

所以我不明白为什么变量SUB_OBJ_FOLDER似乎没有使用调用此规则的父目标进行扩展。

回答

1

对于target1target2,您变量SUB_OBJ_FOLDER确实设置正确,但它并未设置在这些目标之外。这意味着生成文件目标$(OBJ_ROOT_FOLDER)/$(SUB_OBJ_FOLDER)/%.o始终扩展为obj//%.o

假设你将永远使用这个Makefile恰好与一个make目标(target1target2),该解决方案是使用MAKECMDGOALS变量设置SUB_OBJ_FOLDER。这将是你的makefile的变化:

#target1:SUB_OBJ_FOLDER := t1 
#target2:SUB_OBJ_FOLDER := t2 
SUB_OBJ_FOLDER := $(MAKECMDGOALS:target%=t%) 

如果你想支持target1target2同时在命令行上,这将是更复杂一点,需要辅助的makefile,你将包括对每个目标出于兴趣。

+0

谢谢!这是一个很好的窍门! ;-) –