我们有一个模块结构如下的项目:
- Project
- mod1
- mod1.cpp
- mod1.h
- main.cpp
- mod2
- mod2.cpp
- mod2.h
- main.cpp
- more modules
每个模块中的 main.cpp 文件实例化并测试该模块。一个模块可以包含和使用另一个模块。因此,例如,模块 1 可以包括模块 2 并最终包括其他模块。
我们想要创建一个编译文件并包含正确的模块和 main.cpp 文件。因此,如果我编写“make module2”,makefile 将编译 mod2.cpp、main.cpp(在模块 2 中)并包含 mod2.h。如果我编写“make module1”,makefile 将编译 mod2.cpp、mod1.cpp main.cpp(在模块 1 中)并包含 mod1.h 和 mod2.h。
我对 makefile 的经验并不丰富,我已经使用了几天但没有成功。使其通用化会更好,这样添加新模块就不需要对 makefile 进行重大更改。
我得到的最接近的解决方案是:
.PHONY: clean
FLAGS=-std=c++11 -g -I"$(SYSTEMC_PATH)/include" -I"$(SYSTEMC_PATH)" -L"$(SYSTEMC_PATH)/lib-linux64" -lsystemc $(addprefix -I, $(wildcard src/*))
SRCS_WITHOUT_MAIN= $(filter-out %main.cpp, $(shell find src -name '*.cpp'))
TARGET_OBJS=$(subst src, .build/obj, $(subst .cpp,.o,$(SRCS_WITHOUT_MAIN)))
all: $(filter-out unit_test, $(subst src/, ,$(wildcard src/*)))
.SECONDARY:
.build/obj/%.o: src/%.cpp
@mkdir -p $(shell dirname $@)
g++ $(FLAGS) $^ -c -o $@
clean:
@rm -r .build
%: $(TARGET_OBJS) .build/obj/%/main.o
@mkdir -p $(shell dirname .build/bin/$@)
g++ $(FLAGS) $^ -o .build/bin/$@
SRCS_WITHOUT_MAIN 保存所有模块的所有 cpp 文件,除了主文件。TARGET_OBJS 是相应的目标文件列表。% 目标匹配,例如“mod1”,它编译所有 cpp 文件和 mod1 的 main.cpp。
问题是,有时我们在编译后运行时会出现段错误,我们需要执行“make clean && make”才能让它再次工作。有一天,我花了 4 个小时调试我的代码,只是为了发现 makefile 出现了某种损坏。现在项目中的每个人都一直在使用“make clean && make”,因为害怕遇到和我一样的情况……
有谁知道一个聪明的方法来做到这一点?顺便说一句:这是一个 SystemC 项目。