使用不同的预处理器宏在同一源树上构建多个目标

goj*_*oji 3 c++ makefile build cmake scons

我对makeautotools(我还没有用于这个项目)的知识充其量是最基本的,尽管在很长一段时间内进行了大量的谷歌搜索和实验.我有一个像下面这样的源层次结构,我正试图找到尽可能无缝的构建方式.

该应用程序由一个主应用程序组成,其中包含app/src下各种子文件夹中的源代码.这些是使用该文件夹的根目录中的相应Makefile构建的.

然后我有多个其他实用程序驻留在app/tools下的不同文件夹,每个文件夹都有自己的Makefile.

app/src/module1/file1.cpp
app/src/module1/file1.hpp
app/src/module2/file2.cpp
app/src/module2/file2.hpp
app/src/module3/file3.cpp
app/src/module3/file3.hpp
app/src/main.cpp
app/src/main.hpp
app/src/Makefile
app/tools/util1/file1.cpp
app/tools/util1/file1.hpp
app/tools/util1/Makefile
app/tools/util2/file2.cpp
app/tools/util2/file2.hpp
app/tools/util2/Makefile
Run Code Online (Sandbox Code Playgroud)

对我来说问题是,其中一些工具依赖于app/src源文件夹中的源文件,但启用了预处理宏EXTERNAL_TOOL.因此,编译主应用程序和varous实用程序生成的目标文件不兼容.

目前要构建项目的每个部分,我必须清理它们之间的源树.这很痛苦,当然不是我想要的.解决这个问题的最佳方法是什么?我所拥有的那些我无法付诸实践的想法是:

  1. 为项目的每个部分分离构建目录
  2. 在构建外部工具时,以某种方式在主应用程序源代码树中标记它们的目标文件(util.file1.o?)

我不太确定我有时间和耐心需要掌握make/autotools.可能其他一个构建工具(scons?cmake?)使这种任务更容易实现?如果是这样的话?

更新:这就是我现在所拥有的

SOURCES := util1.cpp util2.cpp util3.cpp \
    ../../src/module1/file1.cpp \
    ../../src/module1/file2.cpp \
    ../../src/module1/file3.cpp \
    ../../src/module2/file4.cpp \
    ../../src/module3/file5.cpp \
    ../../src/module3/file6.cpp \
    ../../src/module4/file7.cpp \
    ../../src/module4/file8.cpp \
    ../../src/module3/file9.cpp \
    ../../src/module4/file10.cpp \
    ../../src/module5/file11.cpp \
    ../../src/module3/file12.cpp \
    ../../src/module1/file13.cpp \
    ../../src/module3/file14.cpp \
    ../../src/module3/file15.cpp

OBJECTS = $(join $(addsuffix .util/, $(dir $(SOURCES))), $(notdir $(SOURCES:.cpp=.o)))

.PHONY: all mkdir
all: util
util: $(OBJECTS)
    $(CXX) $(CXXFLAGS) $(OBJECTS) $(LIBS) -o util

$(OBJECTS): | mkdir
    $(CXX) -c $(CXXFLAGS) -o $@ $(patsubst %.o,%.cpp,$(subst .util/,,$@))

mkdir:
    @mkdir -p $(sort $(dir $(OBJECTS)))

clean:
    -@rm -f $(OBJECTS) util
    -@rmdir $(sort $(dir $(OBJECTS))) 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

经过广泛的谷歌搜索浏览后,我发现了这一点.这似乎有效,但这部分看起来并不特别好(感觉有点像黑客):

$(OBJECTS): | mkdir
    $(CXX) -c $(CXXFLAGS) -o $@ $(patsubst %.o,%.cpp,$(subst .util/,,$@))
Run Code Online (Sandbox Code Playgroud)

特别是我不太热衷于我之前从源创建对象列表并添加后缀,只是在这里做反向.我似乎无法让它以任何其他方式工作.

han*_*ank 5

CMake的有add_definitionsremove_definitions命令.您可以使用它们为项目的不同部分定义宏:

# building tools #
add_definitions(-DEXTERNAL_TOOL)
add_subdirectory($TOOL1$ $BUILD_DIR$)
add_subdirectory($TOOL2$ $BUILD_DIR$)
...

# building main app #
remove_definitions(-DEXTERNAL_TOOL)
add_executable(...)
Run Code Online (Sandbox Code Playgroud)