与Makefile中的目标相关的输出文件夹

时间:2017-01-03 12:14:26

标签: makefile build

我想创建一个Makefile,根据调用的目标,在不同的文件夹中构建对象文件。

例如,我希望当我使用目标make调用target1时,它会在调用时使用名为“obj/t1”和“obj/t2”的文件夹创建对象target2

我创建了这个小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 $@)
    @echo "Compiling $< to obj file: $@"
    touch $@

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 个答案:

答案 0 :(得分:1)

SUB_OBJ_FOLDERtarget1的变量target2确实设置正确,但未在这些目标之外设置。这意味着makefile目标$(OBJ_ROOT_FOLDER)/$(SUB_OBJ_FOLDER)/%.o始终扩展为obj//%.o

假设您将始终将此makefile与一个make target(target1target2)一起使用,解决方案是使用MAKECMDGOALS变量来设置SUB_OBJ_FOLDER 。这将是你的makefile中的变化:

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

如果要在命令行上同时支持target1target2,它将会更复杂,并且需要为每个感兴趣的目标包含一个辅助makefile。