GNU Make 在编译前自动将必要的文件带到工作区

问题描述 投票:0回答:1

前言:我的团队正在开发一些硬件的驱动程序,另一个团队正在开发硬件内部微控制器的固件。不同的工作空间,不同的 Git,除了我们依赖他们的 FW。

编译他们的工作区时,输出之一是文件

fw.h
。它是自动生成的,不是我的 Git 的一部分。

假设我有文件

driver.cpp
,其中包含文件
fw.h
.

我希望我的 Make 会自动检测我的工作区中是否缺少

fw.h
,从 Git 中引入 FW 工作区,编译它,将
fw.h
复制到正确的位置,然后编译我的驱动程序。

虽然我知道如何完成这些步骤中的大部分,但我不知道如何依赖

fw.h
.

我目前的解决方案是这样的:

get_fw:
    rm -rf $(fw_ws)
    git clone https://mygit/fw $(fw_ws)
    cd $(fw_ws) && $(MAKE) "all kind of flags specific for FW"
    cp $(fw_ws)/output/fw.h $(driver_inc)

driver.o: get_fw

问题是现在这个

get_fw
每次编译我的驱动程序时都会运行,即使
fw.h
已经存在。这需要相当多的时间。 我试过像这样天真的方法:

driver.o: fw.h

fw.h: get_fw

但它的效果为零,

get_fw
只是不运行并且
driver.cpp
的编译因缺少包含而失败。

makefile gnu-make
1个回答
0
投票

您的

get_fw
规则不会生成名为
get_fw
的文件,因此
get_fw
总是过时的。
driver.o
get_fw
作为先决条件,因此不仅它本身总是过时的,而且
get_fw
的配方必须在
driver.o
的配方之前运行。

make
的角度来看,最一致的做法可能是将
get_fw
规则转换为创建真正的 driver.o 先决条件的适当规则。像这样的东西,也许:

driver.o: $(driver_inc)/fw.h

$(driver_inc)/fw.h:
        rm -rf $(fw_ws)
        git clone https://mygit/fw $(fw_ws)
        cd $(fw_ws) && $(MAKE) "all kind of flags specific for FW"
        cp $(fw_ws)/output/$(@F) $(@D)

$(@D)
$(@F)
是自动变量,分别扩展到规则目标的目录和基本名称部分。在这种情况下,
$(@F)
扩展为
fw.h
,而
$(@D)
扩展为
$(driver_inc)
扩展到的任何内容。

请注意,因为标题规则本身没有先决条件,所以如果标题存在,它将始终被认为是最新的。要重建标头,您需要将其删除。

如果你想拥有按需重建标头的能力,那么你有多种选择。一种方法是创建标头配方所依赖的外部脚本,您也可以直接运行该脚本。另一种方法是为其创建一个单独的

make
规则,您可以通过递归
make
:

从标头配方访问该规则
driver.o: $(driver_inc)/fw.h

$(driver_inc)/fw.h:
        $(MAKE) create_fw_header

.PHONY: create_fw_header
create_fw_header:
        rm -rf $(fw_ws)
        git clone https://mygit/fw $(fw_ws)
        cd $(fw_ws) && $(MAKE) "all kind of flags specific for FW"
        cp $(fw_ws)/output/fw.h $(driver_inc)

还有其他替代品,包括但不限于这两者之间的各种中间体。

© www.soinside.com 2019 - 2024. All rights reserved.