【问题标题】:Triggering C source #define from`make` command line从`make`命令行触发C源#define
【发布时间】:2018-06-19 09:13:20
【问题描述】:

我想将 C 源代码 #define“链接”到 makefile 变量 - 以便能够通过 make 定义或取消定义。

例如,

// my C source file
#ifdef SOMETHING
   // do something
#else
   // do something else
#endif 

然后SOMETHING 将从make 命令行触发:

make something=true

这适用于我的makefile

ifeq ($(something),true)
    COMPILER_FLAGS += -DSOMETHING   
endif

我在徘徊,这是正确的方法吗?
有没有更简单或更好的解决方案?

【问题讨论】:

  • 是的,对于这类事情,这是一个很常见的成语。您是否面临任何特殊问题?
  • 谢谢。没有任何问题。只是想确保这是正确的方式,因为在 #define 之后,我似乎必须再添加一些...
  • 这很常见,但有一个令人不快的警告:如果您正在调试(或生成自动报告,例如为软件进程检查点生成报告),那么您需要以某种方式从临时命令行传输定义的宏到某种稳定的存储形式,这意味着在构建过程中将控制台输出记录到某个文件中,该文件成为发布的一部分。由于它不是源代码的一部分,即使是智能调试器也经常无法弄清楚定义。您必须确定简单的节拍在您的情况下是否稳定。
  • 请注意,现在所有酷孩子似乎都在使用更高级别的构建系统,例如 CMake - 我想这可能会使管理构建变体比直接在 makefile 上运行的临时解决方案容易得多。跨度>

标签: makefile


【解决方案1】:

以下不是临时解决方案,但它需要您使用 make 库:gmtt 是 GNUmake 表工具包,设计时或多或少考虑了这样的用例。您可以指定使用关系数据库中已知的select 语句的(适度)形式访问的表。这样你就可以避开复杂的ifeq 层次结构,并且可以很容易地引入构建参数。当然有人可以争辩说,在我的示例中,三个非常简单的ifeq 段落也可以完成,而无需引入 make 库,但以下解决方案的优点是表格迫使您分离关注点,而您不需要除了生成 #define 之外,担心有人在 ifeq 之一中偷偷添加了附加功能。

include gmtt/gmtt.mk

#define a 3-column table; there must be no empty cells (put in a comment)!
define project-defs =
3
type-1   APPLES   15
type-1   ORANGES  0
type-1   PEARS   /*empty*/

type-2   APPLES   0
type-2   ORANGES  15
type-2   PEARS   /*empty*/

type-3   APPLES   15
type-3   ORANGES  15
endef

#select column 2 and 3 of the above table and create a C-source line with '#define' from them
define project-defines :=
$(call map-select,2 3,$(project-defs),$$(call str-eq,$$1,$(project-type)),\#define $$1 $$2$$(newline))
endef

$(info Building with the following defines: $(project-defines))

$(file > project_def.h,$(project-defines))

有了这个makefile,你现在可以调用make project-type=type-1等等,makefile将为你生成project_def.h,它将作为一个普通的头文件,而不是在命令行中不可见的定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-09
    • 2013-03-20
    • 2012-02-21
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    相关资源
    最近更新 更多