如何将宏定义从“make”命令行参数(-D)传递给 C 源代码?

Posted

技术标签:

【中文标题】如何将宏定义从“make”命令行参数(-D)传递给 C 源代码?【英文标题】:How to pass macro definition from "make" command line arguments (-D) to C source code? 【发布时间】:2012-02-21 14:14:07 【问题描述】:

我通常使用以下选项将宏定义从“make command line”传递到“makefile”: -Dname=值。该定义可在 makefile 中访问。

我还使用类似的编译器选项将宏定义从“makefile”传递到“源代码”: -Dname=value(许多编译器都支持)。此定义可在源代码中访问。

我现在需要的是让我的 makefile 的用户能够立即将任意宏定义从“make.exe 命令行”传递到“源代码”,而无需更改 makefile 中的任何内容。

所以用户可以输入: make -f mymakefile.mk -SOMEOPTION var=5

那么直接main.c代码就可以看到var:

int main()

  int i = var;

【问题讨论】:

为什么投反对票?对我来说,这似乎是一个完全合理的问题。 【参考方案1】:

这样调用make命令:

make CFLAGS=-Dvar=42

并确保在 Makefile 的编译命令中使用$(CFLAGS)。正如@jørgensen 所提到的,将变量赋值放在make 命令之后将覆盖已定义Makefile 的CFLAGS 值。

或者,您可以将-Dvar=42 设置在CFLAGS 之外的另一个变量中,然后在CFLAGS 中重用该变量以避免完全覆盖CFLAGS

【讨论】:

你不能使用 "CFLAGS = $(CFLAGS) -Wall";这将是一个递归定义,而 make 不允许这样做。您可以使用“CFLAGS := $(CFLAGS) -Wall”或“CFLAGS += -Wall”,但它们也不起作用,因为命令行上的分配具有更高的优先级。您可以使用“覆盖 CFLAGS += -Wall”,但通常我们建议您只在内部选择不同的变量。 GNU 编码标准要求 CFLAGS 等留给用户,makefile 选择另一个变量,例如“local_CFLAGS = $(CFLAGS) -Wall”。 只是为了添加到@MadScientist 注释中,GNU Coding Standards also state 应该放在最后,这样用户指定的任何选项都将覆盖 Makefile 内部设置的任何内容。这意味着使用例如local_CFLAGS = -Wall $(CFLAGS)。相反,如果您确实想优先考虑某些事情,请将其放在$(CFLAGS) 之后,就像@MadScientist 评论中一样。 如何设置多个宏? @WoodyHuang 例如CFLAGS="-Dvar1=42 -Dvar2=314" CPPFLAGS 可能比CFLAGSCXXFLAGS 更适合:***.com/a/53527858/2278206【参考方案2】:

只需为此使用特定的变量。

$ cat Makefile 
all:
    echo foo | gcc $(USER_DEFINES) -E -xc - 

$ make USER_DEFINES="-Dfoo=one"
echo foo | gcc -Dfoo=one -E -xc - 
...
one

$ make USER_DEFINES="-Dfoo=bar"
echo foo | gcc -Dfoo=bar -E -xc - 
...
bar

$ make 
echo foo | gcc  -E -xc - 
...
foo

【讨论】:

【参考方案3】: $猫x.mak 全部: 回声$(选项) $ make -f x.mak 'OPTION=-DPASSTOC=42' 回声-DPASSTOC=42 -DPASSTOC=42

【讨论】:

【参考方案4】:

调用make this方式

make CFLAGS=-Dvar=42

因为您确实想覆盖 Makefile 的 CFLAGS,而不仅仅是环境(它在 Makefile 变量方面的优先级较低)。

【讨论】:

【参考方案5】:

在下面找到满足您要求的 C 文件和 Makefile 实现

foo.c

 main ()
    
        int a = MAKE_DEFINE;
        printf ("MAKE_DEFINE value:%d\n", a);
    

生成文件

all:
    gcc -DMAKE_DEFINE=11 foo.c

【讨论】:

问题是将任意定义从 make 命令行直接传递到 C 源代码“而不更改 makefile”。所以我想更改我的 makefile 一次,以允许进行这些任意定义。 不适用于 make。也就是说 make -DMAKE_DEFINE=11 表示无效选项。【参考方案6】:

由于声誉低下,我无法评论已接受的答案。

我想提一下预定义变量CPPFLAGS。 它可能比CFLAGSCXXFLAGS 更合适,因为GNU Make 手册将其描述为:

提供给 C 预处理器和使用它的程序的额外标志 (C 和 Fortran 编译器)。

使用CPPFLAGS 的内置隐式规则示例

n.on.c 自动生成,配方如下: $(CC) $(CPPFLAGS) $(CFLAGS) -c n.on.ccn.cppn.C 自动生成,配方如下: $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c

可以使用命令make CPPFLAGS=-Dvar=123 来定义所需的宏。

更多信息

Variables Used by Implicit Rules Catalogue of Built-In Rules

【讨论】:

以上是关于如何将宏定义从“make”命令行参数(-D)传递给 C 源代码?的主要内容,如果未能解决你的问题,请参考以下文章

如何将命令行参数从pytest传递给代码

如何将参数从 bat 文件或命令行传递给 plpgsql 函数?

如何将任意命令行参数从 MinGW shell 传递给本机 Windows 程序?

递归nmake目标

将命令行参数从 VB 传递到 C# WPF 应用程序

如何在linux环境下使用make命令时加入宏定义