使用makefile和静态模式规则进行树构建

时间:2011-02-04 03:15:25

标签: build-process makefile gnu-make

我正在开发一些在ARM上运行的裸机嵌入式代码,因此必须处理整个ARM与THUMB模式的区别。当前构建系统使用静态模式规则来确定是以ARM还是THUMB模式编译文件。

$(ACOBJS) : %.o : %.c
    @echo
    $(CC) -c $(CFLAGS) $(AOPT) -I . $(IINCDIR) $< -o $@
$(TCOBJS) : %.o : %.c
    @echo
    $(CC) -c $(CFLAGS) $(TOPT) -I . $(IINCDIR) $< -o $@

其中ACOBJS是应该处于ARM模式的输出对象列表,对于TCOBJS和Thumb模式是相同的。这些列表是以通常的

方式从源列表中创建的
ACOBJS   = $(ACSRC:.c=.o)
TCOBJS   = $(TCSRC:.c=.o)

目前,这导致构建中的目标文件散布在源树上,我并不特别希望这样。我一直试图在树构建中设置它,但是无法使其工作。我不一定需要充分利用树构建工作,但我希望至少能够使用输出目录,在该目录下所有中间文件最终都会运行。在这些限制条件下实现这一目标的最佳策略是什么?

我正在考虑的一个选项是使用automake或整个autotools工具链来构建一个makefile。这似乎支持创建我想要的makefile类型,但看起来有点矫枉过正。设计用于便携式构建的自动工具和裸机嵌入式系统之间似乎存在固有的阻抗不匹配,其中主机元组之类的东西由目标微观元素决定。

3 个答案:

答案 0 :(得分:3)

考虑/假设您不关心可移植性并使用GNU make,您可以使用VPATH feature

  • 创建您要进行构建的目录。
  • 使用(近似)以下内容在该目录中创建“Makefile”:

    path_to_source = ..
    VPATH = $(path_to_source)
    include $(path_to_source)/Makefile
  • 将path_to_source变量更改为指向源树的根目录。

此外,您可能需要调整原始Makefile以确保它支持源代码构建。例如,您无法从构建规则引用先决条件,而必须使用$ ^和$&lt;。 (请参阅GNU make - Writing Recipes with Directory Search)您可能还需要修改vpath-makefile。例如:添加CFLAGS+=-I$(path_to_source)可能很有用。

另请注意,如果文件同时位于源目录和构建目录中,make将使用构建目录中的文件。

答案 1 :(得分:3)

这有点旧,但我只是想做同样的事情,这是第一次谷歌热播。我认为值得分享另一种方法,因为如果您不使用自动工具并希望能够使用单个命令构建任何目录并且之后只是吹走该目录,那么回答都不方便。

这是一个Makefile的示例,它引用相对于包含Makefile的目录的文件。

MAKEFILE_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
MFD := $(MAKEFILE_DIR)

CXX=g++
CXXFLAGS=-std=c++14 -Wall -Wextra -pedantic -c

test: test.o adjacency_pointers_graph.o
    $(CXX) $^ -o $@

%.o: $(MFD)/%.cpp $(MFD)/adjacency_pointers_graph.h
    $(CXX) $(CXXFLAGS) $< -o $@

然后做一种源代码构建:

mkdir build
cd build
make -f ../Makefile

答案 2 :(得分:1)

automake

如果您使用automake,那么您几乎可以使用整个自动工具。如果没有automakeautoconf就无法运作。

Makefile生成的automake支持源外构建和交叉编译,因此您应该能够创建子目录arm/thumb/并运行../configure --host=arm-host-prefix中的arm/并在../configure --host=thumb-host-prefix中运行thumb/。 (我不知道你为每个编译器使用的实际主机元组。)

使用GNU make

由于您使用的是GNUMake,您可以执行以下操作:

ACOBJS := $(addprefix arm/,$(ACSRC:.c=.o))
TCOBJS := $(addprefix thumb/,$(TCSRC:.c=.o))

使用this answer之类的内容确保arm/thumb/目录(以及任何子目录)存在。