makefile 变量可以分配从源文件读取的值吗?

发布于 2024-09-10 17:44:54 字数 293 浏览 4 评论 0原文

假设有一个 C 程序,它将其版本存储在 main.c 中的全局 char* 中。构建系统(gnu make)是否可以在构建时以某种方式提取此变量的值,以便构建的可执行文件可以具有与程序中显示的确切版本名称?

我想要实现的是给定源:

char g_version[] = "Superprogram 1.32 build 1142";

构建系统将生成一个名为 Superprogram 1.32 build 1142.exe 的可执行文件

Suppose there is a C program, which stores its version in a global char* in main.c. Can the buildsystem (gnu make) somehow extract the value of this variable on build time, so that the executable built could have the exact version name as it appears in the program?

What I'd like to achieve is that given the source:

char g_version[] = "Superprogram 1.32 build 1142";

the buildsystem would generate an executable named Superprogram 1.32 build 1142.exe

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

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

发布评论

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

评论(4

梅倚清风 2024-09-17 17:44:54

shell 函数允许您调用外部应用程序,例如 sed,可用于解析源代码以获取所需的详细信息。

The shell function allows you to call external applications such as sed that can be used to parse the source for the details required.

骄傲 2024-09-17 17:44:54

从宏定义版本变量:

char g_version[] = VERSION;

然后使 makefile 在编译时在命令行上放置 -D 参数

gcc hack.c -DVERSION=\"Superprogram\ 1.99\"

当然,您应该在示例中使用 sed/grep/awk 等来生成版本字符串。

Define your version variable from a Macro:

char g_version[] = VERSION;

then make your makefile put a -D argument on the command line when compiling

gcc hack.c -DVERSION=\"Superprogram\ 1.99\"

And of course you should in your example use sed/grep/awk etc to generate your version string.

你丑哭了我 2024-09-17 17:44:54

您可以在 Makefile 中使用 unix 文本工具(grep、sed、awk、perl、tail 等)的任意组合,以便从源文件中提取该信息。

You can use any combination of unix text tools (grep, sed, awk, perl, tail, ...) in your Makefile in order to extract that information from source file.

岁月无声 2024-09-17 17:44:54

通常版本被定义为多个#define值的组合(如arv 库 例如)。

因此,让我们看一个简单且有效的示例:

// myversion.h
#define  __MY_MAJOR__ 1
#define  __MY_MINOR__ 8

然后在您的 Makefile 中:

# Makefile
source_file := myversion.h
MAJOR_Identifier := __MY_MAJOR__
MINOR_Identifier := __MY_MINOR__

MAJOR := `cat $(source_file) | tr -s ' ' | grep "\#define $(MAJOR_Identifier)" | cut -d" " -f 3`
MINOR := `cat $(source_file) | tr -s ' ' | grep '\#define $(MINOR_Identifier)' | cut -d" " -f 3`

all:
  @echo "From the Makefile we extract: MAJOR=$(MAJOR) MINOR=$(MINOR)"

解释

这里我使用了几个工具,因此它更加健壮:

  • tr -s ' ': 删除元素之间的额外空格,
  • grep:选择符合我们目的的唯一行,
  • cut -d" " -f 3:提取所选行的第三个元素,即目标值!

请注意,定义值可以是任何值(不仅仅是数字)。

请注意使用 := (而不是 =),请参阅:https://stackoverflow .com/a/10081105/4716013

Usually the version is defined as a composition of several #define values (like in the arv library for example).

So let's go for a simple and working example:

// myversion.h
#define  __MY_MAJOR__ 1
#define  __MY_MINOR__ 8

Then in your Makefile:

# Makefile
source_file := myversion.h
MAJOR_Identifier := __MY_MAJOR__
MINOR_Identifier := __MY_MINOR__

MAJOR := `cat $(source_file) | tr -s ' ' | grep "\#define $(MAJOR_Identifier)" | cut -d" " -f 3`
MINOR := `cat $(source_file) | tr -s ' ' | grep '\#define $(MINOR_Identifier)' | cut -d" " -f 3`

all:
  @echo "From the Makefile we extract: MAJOR=$(MAJOR) MINOR=$(MINOR)"

Explanation

Here I have used several tools so it is more robust:

  • tr -s ' ': to remove extra space between elements,
  • grep: to select the unique line matching our purpose,
  • cut -d" " -f 3: to extract the third element of the selected line which is the target value!

Note that the define values can be anything (not only numeric).

Beware to use := (not =) see: https://stackoverflow.com/a/10081105/4716013

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