【发布时间】:2014-03-04 07:32:11
【问题描述】:
我最近花了 5 个小时来弄清楚如何编写我需要的 makefile。我不是信息学家或程序员,所以我想要一些关于我设法做的事情的 cmet。我已经在不同的网站上看了很多,但仍然......
我需要一个可以创建不同可执行文件的 makefile:prog1、prog2...
要创建.o 文件,因为我有许多具有许多依赖项的文件,我不想全部指定它们。所以我想/需要使用带有模式规则的自动变量。为了加快编译速度,我还注意只重新编译修改后的文件。我通过使用-MD 标志实现了这一点,该标志创建了一个保存在$(BUILD) 目录中的.d 文件。
我仍然无法自动检测.o 文件prog1 需要哪些。所以现在我必须自动指定它们......如果你知道如何自动指定它们......
我也想将.o 文件保存在$(BUILD) 目录中,但我无法成功。
欢迎任何建议! 谢谢
CXX = g++
ERRORS = -Wall -Wextra -pedantic
LAPACK = -llapack -lblas
OPTION = -O3 -fopenmp
CXXFLAGS = $(LAPACK) $(ERRORS) $(OPTION)
LDFLAGS = $(LAPACK) $(ERRORS) $(OPTION)
BUILD=build
SRCS=(wildcard *.cpp)
all:prog1 prog2 ...
prog1:prog1.o dep_only_for_prog_1.o dep_for_all_progs.o dep_for_some_progs.o
$(CXX) -o $@ $^ $(LDFLAGS) $(NOASSERT)
prog2:prog2.o dep_only_for_prog_2.o dep_for_all_progs.o dep_for_some_progs.o
$(CXX) -o $@ $^ $(LDFLAGS) $(NOASSERT)
...
%.o:%.cpp
$(CXX) -MD -c $(CXXFLAGS) $(NOASSERT) $< -o $@
mv $(<:.cpp=.d) $(BUILD)
-include $(addprefix $(BUILD)/$(SRCS:.cpp=.d))
clean:
rm -f *.o $(BUILD)/*
【问题讨论】:
-
Makefile 应该如何知道哪些文件用于 prog1,哪些用于 prog2?如果你把这个任务交给一个人,你会告诉他/她什么规则,以便他/她知道哪些文件属于哪个程序?
-
@Cornstalks:让链接器解决它。它理解内容;没有。 (这就是为什么你首先需要像
.d文件这样的黑客) -
@Cornstalks:我会对人类说,看看主文件中的包含,如果有'dep1.hpp',看看是否有'dep1.o',如果有,包括'dep1.o'。重复此操作,直到检查了所有递归包含的文件...但也许我做错了...
-
@MSalters:链接器如何对其进行排序?
-
没有规定每个
dep1.hpp都必须有一个源文件。一些头文件(尤其是在 C++ 中)没有任何源文件。有时源文件没有头文件。有时源文件的前缀与标头不同。这些都是完全合法的。 MSalters:链接器无法对其进行排序。假设您链接两个不同的目标文件,它们都包含符号main。链接器将如何选择正确的?简而言之,对不起 PinkFloyd 但你不走运。你必须在你的 makefile 中明确写出哪些源属于哪些程序。