Makefile和C代码之间的变量冲突

时间:2019-05-25 20:16:37

标签: c makefile

在我的C Makefile中,有以下几行:

ifeq ($(VERBOSE_PRINT), TRUE)
  CFLAGS += -D TRUE
else
  CFLAGS += -D FALSE
endif

正如您所知道的,该标志指示我是否应该打印调试语句。

在我的C代码的其他地方,我用

定义TRUE和FALSE。
#define FALSE 0
#define TRUE !FALSE

然后,当我尝试编译代码时,出现以下错误:

types.h:6:0: error: "FALSE" redefined [-Werror]
#define FALSE 0
<command-line>:0:0: note: this is the location of the previous definition

如果我从C代码中删除TRUE和FALSE的定义,我的程序就会发疯。

这是怎么回事,如何解决此冲突?

谢谢。

2 个答案:

答案 0 :(得分:4)

对于两个不兼容的事物,您不能使用相同的名称,因此您需要更改其中之一。因为您没有任何意义,所以很可能您想更改Makefile。像这样:

ifeq ($(VERBOSE_PRINT), TRUE)
  CFLAGS += -DDEBUG=1
else
  CFLAGS += -DDEBUG=0
endif

然后在您的C代码中可以拥有

#if DEBUG
    printf( ... debugging messages ... )
#endif

答案 1 :(得分:2)

在编译器命令行上,-DXYZ等效于-DXYZ=1(POSIX c99)。这意味着在命令行上使用-DFALSE时,您同时拥有#define FALSE 1#define FALSE 0,这是非良性的重定义。可以按良性方式重新定义宏(这意味着替换令牌的顺序在当前定义和新定义中都是相同的,请参见C11 §6.10.3 Macro replacement ¶1-2。)

您需要在代码中使用其他变量来决定是否进行打印:

#ifdef VERBOSE_PRINT
    printf("Debugging!\n");
#endif

然后可以在命令行上使用-DVERBOSE_PRINT启用打印,而将其保留以禁用打印。或者,您可以使用:

#if VERBOSE_PRINT
    printf("Debugging!\n");
#endif

然后您的makefile可以包含:

ifeq ($(VERBOSE_PRINT), TRUE)
  CFLAGS += -DVERBOSE_PRINT=TRUE
else
  CFLAGS += -DVERBOSE_PRINT=FALSE
endif

这种技术不太常见。如果您没有在编译器命令行上指定值(C11 §6.10.1 Conditional inclusion ¶4),它将像您有#define VERBOSE_PRINT 0一样工作。

相关问题