如何强制GNU make重新编译在具有不同FLAGS的两个目标中使用的同一目标文件

时间:2018-12-10 16:35:43

标签: c++ c makefile clearcase ld

假设您有一个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

targetAtargetB共享一个文件,即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

3 个答案:

答案 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.oa1.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 $@ $^