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

发布于 2024-10-16 08:12:12 字数 760 浏览 10 评论 0原文

我正在开发一些在 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 类型,但似乎有点矫枉过正。专为便携式构建而设计的自动工具与裸机嵌入式系统(其中主机元组等内容由目标微控制器决定)之间似乎也存在固有的阻抗不匹配。

I'm working on some bare-metal embedded code that runs on ARM, and thus has to deal with the whole ARM vs. THUMB mode distinction. The current build system uses static pattern rules to determine whether to compile files in ARM or THUMB mode.

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

Where ACOBJS is a list of output objects that should be in ARM mode and the same for TCOBJS and Thumb mode. These lists are created from the list of sources in the usual manner of

ACOBJS   = $(ACSRC:.c=.o)
TCOBJS   = $(TCSRC:.c=.o)

Currently this results in the object files from the build being strewn about the source tree, which I don't particularly desire. I've been trying to set this up for out of tree builds but haven't been able to get this to work. I don't necessarily need to get full out of tree builds working, but I would like to at least be able to use an output directory under which all the intermediate files end up going. What is the best strategy to achieve this under these constraints?

One option I'm considering is using either automake or the whole autotools toolchain to build a makefile. This would seem to support creating the type of makefile I want, but seems like overkill. It also seems like there would be an inherent impedance mismatch between autotools, which is designed for portable builds, and bare-metal embedded systems, where things like host tuple are dictated by the target micro.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泪眸﹌ 2024-10-23 08:12:12

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

下面是一个 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) 
lt; -o $@

然后进行某种源构建:

mkdir build
cd build
make -f ../Makefile

This is a bit old but I was just trying to do the same thing this was the first google hit. I thought it was worth sharing another approach since neither answer is convenient if you're not using autotools and want to be able to build in any directory with a single command and later just blow away that directory.

Here's an example of a Makefile that refers to files relative to the directory containing the 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) 
lt; -o $@

Then to do an sort of source build:

mkdir build
cd build
make -f ../Makefile
衣神在巴黎 2024-10-23 08:12:12

考虑/假设您不关心可移植性并且正在使用 GNU make,您可以使用 VPATH 功能

  • 创建要在其中进行构建的目录。
  • 在该目录中创建一个“Makefile”(大约)包含以下内容:

    <前><代码>源路径 = ..
    VPATH = $(源路径)
    include $(path_to_source)/Makefile

  • 更改 path_to_source 变量以指向源代码树的根。

此外,您可能需要调整原始 Makefile 以确保它支持源代码外构建。例如,您不能引用构建规则中的先决条件,而必须使用 $^ 和 $<。 (请参阅 GNU make - 使用目录搜索编写菜谱)您可能还需要修改vpath-makefile。例如:添加 CFLAGS+=-I$(path_to_source) 可能有用。

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

Considering/assuming you don't care about portability and are using GNU make, you can use the VPATH feature:

  • Create the directory where you want to do your build.
  • Create a 'Makefile' in that directory with (approximately) the following contents:

    path_to_source = ..
    VPATH = $(path_to_source)
    include $(path_to_source)/Makefile
  • Change the path_to_source variable to point to the root of your source tree.

Additionally you probably need to tweak your original Makefile to make sure that it supports the out of source build. For example, you can't reference to prerequisites from your build rules and instead must use $^ and $<. (See GNU make - Writing Recipes with Directory Search) You might also need to modify the vpath-makefile. For example: adding CFLAGS+=-I$(path_to_source) might be useful.

Also note that if a file is in both your source and build directory, make will use the file in your build directory.

夜光 2024-10-23 08:12:12

关于automake

如果您使用automake,您几乎就在使用整个自动工具。如果没有 autoconfautomake 就无法工作。

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

使用 GNU make

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

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

使用类似 这个答案以确保arm/和< code>thumb/ 目录(以及任何子目录)存在。

On automake

If you use automake, you're pretty much using the entire autotools. automake cannot work without autoconf.

The Makefiles generated by automake support out-of-source builds and cross-compilation, so you should be able to create subdirectories arm/ and thumb/ and run ../configure --host=arm-host-prefix in arm/ and run ../configure --host=thumb-host-prefix in thumb/. (I don't know the actual host tuples that you'd use for each compiler.)

Using GNU make

Since you're using GNUMake, you could do something like this:

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

Use something like this answer to ensure that the arm/ and thumb/ directories (and any subdirectories) exist.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文