如何在'make install'之后更改VAR名称而不会出现未声明的错误?

时间:2015-08-13 18:49:04

标签: c autotools autoconf automake cflags

我的configure.in文件有:

VAR=yo
AC_SUBST(VAR)

Makefile.am有:

bin_PROGRAMS = hello
hello_SOURCES = hello.c 
hello_CFLAGS =-DVAR=@VAR@

C文件是:

#include <stdio.h>
int main()
{
    printf("%s\n",VAR);
    return 0;
}

当我'make install'时出现错误

Making install in src
make[1]: Entering directory `/home/albertpod/hello/src'
if gcc -DPACKAGE_NAME=\"hello\" -DPACKAGE_TARNAME=\"hello\" -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"hello\ 1.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"hello\" -DVERSION=\"1.0\" -I. -I.    -DVAR=yo -g -O2 -MT hello-hello.o -MD -MP -MF ".deps/hello-hello.Tpo" -c -o hello-hello.o `test -f 'hello.c' || echo './'`hello.c; \
    then mv -f ".deps/hello-hello.Tpo" ".deps/hello-hello.Po"; else rm -f ".deps/hello-hello.Tpo"; exit 1; fi
hello.c: In function ‘main’:
hello.c:8:13: error: ‘yo’ undeclared (first use in this function)
hello.c:8:13: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [hello-hello.o] Error 1
make[1]: Leaving directory `/home/albertpod/hello/src'
make: *** [install-recursive] Error 1

所以VAR的名字变得哟,但它是未宣布的。我的目标是打印你,但如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

我假设您希望程序提供输出

yo

configure.in

中的正确引用

您也可能注意到您缺少引号,以使定义VAR的替换文本成为字符串文字。困难在于您将通过shell的两个实例传递此值,该实例将删除引号:执行configure的实例和make调用以运行编译器的实例。因此,您需要三个级别的引用,并进行适当的转义:

VAR="\"\\\"yo\\\"\""
AC_SUBST(VAR)

(你可以尝试在那里使用单引号来减少\的数量,但它可能会变得更加难看。)

Makefile.am

中的正确引用

您也可以在Makefile.am中进行引用。如果您还需要Makefile中的VAR值以用于其他目的,这将非常有用。你需要两个级别的qoutes,一个用于使值成为字符串文字,另一个用于被shell吃掉:

hello_CFLAGS =-DVAR='"@VAR@"'

即使VAR包含(单个)空格或其他有趣的字符,这也是有效的,唯一有问题的字符是'"\

字串化

或者,您可以让预处理器使用stringify运算符#添加引号:

#include <stdio.h>

#define STR2(arg) #arg
#define STR(arg) STR2(arg)

int main()
{
    printf("%s\n",STR(VAR));
    return 0;
}

由于#运算符的工作原理,因此宏中的间接是必要的。如果您只使用一个级别的宏,则输出将为VAR

当然,只有当值不包含任何有趣的字符(如空格)时,这才有效。

使用AC_DEFINE

使用AC_DEFINE,将VAR定义为由引号括起的值会稍微容易一些。使用

AC_DEFINE([VAR], ["yo"])
<{1>}中的

并从configure.in移除hello_CFLAGS =-DVAR=@VAR@。或者,如果您需要在Makefile.am中计算VAR的值,请使用

configure

将解释值中的shell替换。

在这两种情况下,您都无法访问Makefile中的VAR=yo AC_DEFINE_UNQUOTED([VAR], ["$VAR"])