使用与源不同的构建结构自动生成具有Gnu Make实用程序的文件

时间:2011-07-28 23:26:11

标签: makefile compilation makefile-project

我已经看到以下技术用于自动编译特定目录中的所有C(或C ++,或者我想你想要的扩展名)文件。

SOURCE_DIRS = .
SOURCES := $(subst ./,,$(wildcard $(SOURCE_DIRS:=/*.cpp)))
HEADERS := $(subst ./,,$(wildcard $(SOURCE_DIRS:=/*.h)))
OBJECTS := $(addprefix build/,$(SOURCES:.cpp=.o))
CXX = g++
CXXFLAGS = -Wall -pedantic -g
#LDFLAGS = 

all: build/exe_name

build/exe_name: $(OBJECTS)
        $(CXX) -o $@ $(OBJECTS) $(LDFLAGS)

build/%.o: %.cpp $(HEADERS) Makefile
        mkdir -p $(dir $@)
        $(CXX) -o $@ $(CXXFLAGS) -c $<

唯一的问题是它构建了与源目录中相同结构的所有文件。因此,如果您有一个包含代码的子文件夹,那么构建将具有匹配的子文件夹。

那么,我如何修改它(或者可以做什么),将所有输出的目标直接放在build /目录中,而不是放在与源目录匹配的层次结构中?

我已经考虑过在目标中使用时尝试去除'%'中可能出现的任何目录,但我找不到任何好的命令来执行此操作。此外,尝试在创建时更改OBJECTS路径似乎有点问题,因为我不知道'%'变量如何读取它,除了它神奇地编译OBJECTS列表中的所有内容。

感谢您提供任何帮助。

2 个答案:

答案 0 :(得分:3)

按顺序,

  1. 我看不出它是如何工作的。您的通配符方法不会递归到源文件夹的子文件夹中,并且除了“SOURCE_DIRS =。”之外,您的%.o规则将不起作用。
  2. 您的%.o规则有点松散。如果您更改一个标头,Make将重建所有目标文件。
  3. 每个可以找到的源合并到您的可执行文件中可能并不明智。在此方案中,使用共享代码很难拥有多个可执行文件。
  4. 为了克服1)的问题并编写一个我可以测试的makefile,我不得不搞乱“查找”,我讨厌,所以以下是未经测试的。
  5. 我认为这样做(在GNUMake中):
SOURCES := whatever...
vpath %.cpp $(dir $(SOURCES))
SOURCES := $(notdir $(SOURCES))

答案 1 :(得分:0)

最简单(尽管不是严格限制)的方式是使用automake而不设置subdir-options选项。