我目前的makefile如下,它正确地构建了目标。但是有一次它不能构建目标,那就是当源文件的路径长度变得太长时。因此,我想把我在不同文件夹中的所有源文件收集到一个源目录中,然后再进行make。
有什么线索可以告诉我,如何修改下面的makefile来创建一个扁平的源目录,并使用该目录中的文件来使用make进行构建。
PROJ_DIR := ../
SRC_DIR += $(PROJ_DIR)project
SRC_FILES += $(wildcard $(SRC_DIR)/*/source/*.cpp)
OBJ_DIR := $(PROJ_DIR)TASK
OBJ_FILES += $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
CXXFLAGS := --c++14
CC_INCLUDE_PATH += -I$(PROJ_DIR)project/include
.PHONY: all clean dirs
all: $(OBJ_DIR) $(OBJ_FILES)
"$(COMPILERBIN)"/cc.exe -rvn crackLib.a $(OBJ_FILES)
clean:
@rm -rf crackLib.a $(OBJ_DIR) $(FLAT_INC_DIR)
# Build target for directory creation. Intermediate build files will be placed here.
$(OBJ_DIR):
mkdir -p $@
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
"$(COMPILERBIN)"/cc.exe $(CXXFLAGS) -c -o $@ $< $(CC_INCLUDE_PATH)
$(OBJ_DIR)/%.o: $(TSM_SRC_DIR)/%.cpp
"$(COMPILERBIN)"/cc.exe $(CXXFLAGS) -c -o $@ $< $(CC_INCLUDE_PATH)
$(OBJ_DIR)/%.o: $(SL_SRC_DIR)/%.cpp
"$(COMPILERBIN)"/cc.exe $(CXXFLAGS) -c -o $@ $< $(CC_INCLUDE_PATH)
-include $(OBJ_FILES:.o=.d)
假设我们的源文件是 $(SRC_DIR)/longpath/source/foo.cpp
,我们要建立对象文件 $(OBJ_DIR)/foo.o
. 我们可能希望有这样的规则,但是我们在写makefile的时候不知道路径,所以我们必须在构建的时候让Make来计算。
$(OBJ_DIR)/foo.o: $(SRC_DIR)/longpath/source/foo.cpp
... $< -o $@
但是我们在写makefile的时候并不知道路径,所以我们必须让Make在编译的时候把它弄清楚。
有不止一种方法可以做到这一点。最简单的方法是使用 的 vpath
指令.
如果我们提前知道路径,就可以写成这样。
vpath %.cpp $(SRC_DIR)/longpath/source
$(OBJ_DIR)/foo.o: foo.cpp
... $< -o $@
让我们使用 vpath
来搜索源文件,并使用其完整路径作为前提条件(因此也就有了 $<
).
该 vpath
指令可以接受多个目录,虽然我们事先不知道路径,但我们知道如何计算它们。
vpath %.cpp $(dir $(SRC_FILES))
$(OBJ_DIR)/foo.o: foo.cpp
... $< -o $@
一旦我们确认这样做是可行的, 我们就可以切换到一个模式规则。
$(OBJ_DIR)/%.o: %.cpp
... $< -o $@
然后改变 OBJ_FILES
据此。
OBJ_FILES += $(patsubst %.cpp,$(OBJ_DIR)/%.o,$(notdir $(SRC_FILES)))
all: $(OBJ_FILES)
... $^