假设您有一个makefile
,其中包含两个目标,如下所示:
# targetA
X86CPPTARGET += targetA
targetA,SRCS = FILEA.cpp FILEB.cpp commonFile.cpp
targetA.so,DEPSOL = libUsedByCommon1.cpp
targetA,CPPFLAGS += -Ifakeinclude -std=c++11
# tartargetBgetA
X86CPPTARGET += targetB
targetB,SRCS = FILEC.cpp FILED.cpp commonFile.cpp
targetA.so,DEPSOL = libUsedByCommon2.cpp
targetB,CPPFLAGS += -std=c++11
targetA
和targetB
共享一个文件,即commonFile.cpp
,其中包含多个#include
d头。
commonFile.o
仅由GNU make创建一次,并且在targetB
的编译过程中可以重复使用。
targetA
中包含的CPPFLAGS使编译器使用一个include,该include包含更多符号,而默认include目录中的符号更多。 libUsedByCommon2
不会导出fakeinclude
目录的标头中包含的所有其他符号,并且在链接时会导致undefined reference
。
我目前使用的解决方法是创建一个指向commonFile.cpp
的符号链接,并在我的makefile
中仅在一个目标中使用它。
# targetA
X86CPPTARGET += targetA
targetA,SRCS = FILEA.cpp FILEB.cpp commonFile.cpp
targetA.so,DEPSOL = libUsedByCommon1.cpp
targetA,CPPFLAGS += -Ifakeinclude -std=c++11
# tartargetBgetA
X86CPPTARGET += targetB
targetB,SRCS = FILEC.cpp FILED.cpp **commonFile_symbolic_link.cpp**
targetA.so,DEPSOL = libUsedByCommon2.cpp
targetB,CPPFLAGS += -std=c++11
是否有解决此问题的更清洁的方法?
使用不同的包含路径时,是否有一种方法可以强制GNU make重新编译commonFile.cpp
?
答案 0 :(得分:3)
您可以使用不同的构建命令来创建两个依赖于同一C文件的新目标,例如以下示例...
commonFileA.o: commonFile.cpp
$(CC) -o $@ $^ -FlagsA
commonFileB.o: commonFile.cpp
$(CC) -o $@ $^ -FlagsB
然后您可以使用“ commonFileA.o”作为依赖项,以在版本中链接这些特殊标志等。
答案 1 :(得分:2)
您可能应该尝试编译相同的源文件,但使用两个不同的输出对象文件:
a0.o: MYFLAGS := foo bar
a0.o: a.c
a1.o: MYFLAGS := baz cux
a1.o: a.c
然后,对于相关目标,使用a0.o
或a1.o
作为先决条件。
答案 2 :(得分:2)
我执行此操作的一种方法是设置一个变量,然后以特定目标递归调用make
。这种方法的优点之一是您只能指定一次目标。
这是不完整摘录,显示了该技术:
all: debug release
debug:
@echo -e "\n====== BUILDING DEBUG PROGRAM ======\n"
@FLAGS="$(CXXFLAGS_DBG)" SUFFIX="-debug" $(MAKE) general
release:
@echo -e "\n====== BUILDING RELEASE PROGRAM ======\n"
@FLAGS="$(CXXFLAGS_REL)" $(MAKE) general
general: $(PROGRAM)$(SUFFIX)
$(PROGRAM)$(SUFFIX): $(SRC)/program.cpp
$(CXX) $(FLAGS) -o $@ $^