从 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 文件中,因为引导加载程序使用它(如果需要)以确保引导加载程序闪存的版本比闪存中已有的版本更新。因此,如果我将 VERSION
、RELEASE
、MODIFICATION
等定义移动到 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 ...)
函数来提取宏扩展。假设 VERSION
在 src.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 库意味着将 include
d 文件放在 makefile
.
旁边
我有一个可以使用标准 makefile
构建的 AVR8 GCC 应用程序。因为一些想要构建应用程序的人不想设置 make 之类的(或者这样做有困难),我也想出了如何设置项目以便可以从 Arduino IDE 还有。
一切正常。
但是,我通常在 makefile
中设置一些项目,例如版本号等,但是在 makefile
中创建 VERSION 字符串并将其作为定义传递到每个源文件编译中.但是,当来自 Arduino IDE 的 运行 时,该步骤显然没有发生。所以,我必须在 Arduino 草图存根中创建第二个 #define
来重新创建定义。
这意味着当我更新版本时,我需要在 2 个地方这样做,在 makefile
和源文件中。
简单的选择是将 VERSION
创建的内容简单地移动到源文件中,两者都可以使用它。而且,我可以这样做,但是
makefile
实际上需要版本信息,以创建正确的文件名(想想 app_v1.2.3.4.bin)和将版本号嵌入到 bin 文件中,因为引导加载程序使用它(如果需要)以确保引导加载程序闪存的版本比闪存中已有的版本更新。因此,如果我将 VERSION
、RELEASE
、MODIFICATION
等定义移动到 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 ...)
函数来提取宏扩展。假设 VERSION
在 src.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 库意味着将 include
d 文件放在 makefile
.