尽管在很长一段时间内进行了大量的谷歌搜索和实验,但我对make和autotools的了解(我还没有用于这个项目)充其量只是初级知识。我有一个像下面这样的源层次结构,我试图找到尽可能无缝地构建的方法。
该应用程序由一个主应用程序组成,其源代码位于 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
对我来说,问题是其中一些工具依赖于 app/src 源文件夹中的源文件,但启用了预处理宏 EXTERNAL_TOOL。所以编译主应用程序生成的目标文件和各种实用程序不兼容。
目前要构建项目的每个部分,我必须清理其间的源代码树。这很痛苦,而且肯定不是我最终想要的。解决这个问题的最佳方法是什么?我曾经有但无法付诸实践的想法是:
- 项目每个部分的单独构建目录
- 在构建外部工具时,以某种方式在主应用程序源树中标记它们的目标文件(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
我是在广泛搜索 SO 浏览后发现的。这似乎可行,但这部分看起来并不是特别好(感觉有点像黑客):
$(OBJECTS): | mkdir
$(CXX) -c $(CXXFLAGS) -o $@ $(patsubst %.o,%.cpp,$(subst .util/,,$@))
特别是我不太热衷于我之前从源创建对象列表并添加后缀的事实,只是在这里做相反的事情。我似乎无法让它以任何其他方式工作。