从 C 源文件中将一组变量读入 Makefile?

Reading a set of variables into a Makefile from a C source file?

我有一个可以使用标准 makefile 构建的 AVR8 GCC 应用程序。因为一些想要构建应用程序的人不想设置 make 之类的(或者这样做有困难),我也想出了如何设置项目以便可以从 Arduino IDE 还有。

一切正常。

但是,我通常在 makefile 中设置一些项目,例如版本号等,但是在 makefile 中创建 VERSION 字符串并将其作为定义传递到每个源文件编译中.但是,当来自 Arduino IDE 的 运行 时,该步骤显然没有发生。所以,我必须在 Arduino 草图存根中创建第二个 #define 来重新创建定义。

这意味着当我更新版本时,我需要在 2 个地方这样做,在 makefile 和源文件中。

简单的选择是将 VERSION 创建的内容简单地移动到源文件中,两者都可以使用它。而且,我可以这样做,但是

makefile 实际上需要版本信息,以创建正确的文件名(想想 app_v1.2.3.4.bin)和将版本号嵌入到 bin 文件中,因为引导加载程序使用它(如果需要)以确保引导加载程序闪存的版本比闪存中已有的版本更新。因此,如果我将 VERSIONRELEASEMODIFICATION 等定义移动到 C 代码中,我需要找到一种方法将它们拉回到 makefile 中。

我尝试使用 makefile 中的文件读取操作,但他们似乎忽略了:

#define VERSION 0

带有前缀“#”字符。

我看到 运行 sed/awk/etc 在 bash 中有一些选项,但我不想对环境做太多假设,makefile 目前 运行 在 Windows 和 Unix/Linux 上没有任何区别。

我尝试了几个堆栈溢出示例,但似乎没有任何文件(.h 或其他文件)产生这 4 个数字。

我可以创建 version.h,只需:

#define VERSION      0
#define RELEASE      1
#define MODIFICATION 2
#define FIX          4

如果我可以将其读入 makefile 并创建我需要的变量。

吉姆

我认为在这种情况下,您可以使用 makefile 的“文件”功能。 它允许您写入(使用 > 说明符)或读取(使用 < 说明符)to/from 文件。然后您可以 trim (过滤掉)您的 makefile 中的变量。 资料来源:https://www.gnu.org/software/make/manual/html_node/File-Function.html#File-Function

您可以使用 GNU make 的 $(shell ...) 函数来提取宏扩展。假设 VERSIONsrc.c 中定义并且标记由空格(而不是制表符)分隔:

VERSION := $(shell sed -n -e "s/^\#define VERSION  *\(.*\)//p" src.c)

.PHONY: all
all:
    @echo VERSION=$(VERSION)

您可以看看 gmtt,它是根据您的用例设计的。在 gmtt 中,以下内容应读取并分析您的头文件:

include gmtt.mk

# create a 3-column table from the header file. The first column is just the "#define"
VNR_TABLE := 3 $(file < version.h)

# Extract the values from the table: select column 3 from VNR_TABLE where column 2 equals a string constant. 
# Be careful not to introduce spaces in the compare!
VER := $(call select,3,$(VNR_TABLE),$$(call str-eq,$,VERSION))
REL := $(call select,3,$(VNR_TABLE),$$(call str-eq,$,RELEASE))
MODF := $(call select,3,$(VNR_TABLE),$$(call str-eq,$,MODIFICATION))
FIX := $(call select,3,$(VNR_TABLE),$$(call str-eq,$,FIX))

我无法测试它,但我想你明白了。

PS:使用 GNUmake 库意味着将 included 文件放在 makefile.

旁边