My configure.in
file has:
VAR=yo
AC_SUBST(VAR)
Makefile.am
has:
bin_PROGRAMS = hello
hello_SOURCES = hello.c
hello_CFLAGS =-DVAR=@VAR@
C file is:
#include <stdio.h>
int main()
{
printf("%s\n",VAR);
return 0;
}
When I do 'make install' there is error
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
So name of VAR becomes yo, but it is undeclared. My goal is to print yo, but how to solve this case?
I'm assuming you want the program to deliver the output
yo
configure.in
You also probably noticed that you are missing quotes, to make the replacement text of the define VAR
a string literal. The difficulty is that you are passing this value through two instances of the shell that will strip quotes: the one that executes configure
and the one that is invoked by make
to run the compiler. So you need three levels of quoting, with appropriate escaping:
VAR="\"\\\"yo\\\"\""
AC_SUBST(VAR)
(You can try using single quotes in there to reduce the number of \
, but it will probably become even more ugly.)
Makefile.am
You can also do the quoting in Makefile.am
. This is especially useful if you need the value of VAR
in the Makefile for other purposes too. You need two levels of qoutes, one to make the value a string literal and one that gets eaten by the shell:
hello_CFLAGS =-DVAR='"@VAR@"'
This works even if VAR contains (single) spaces or other funny characters, the only problematic characters are '
, "
, and \
.
Alternatively you can let the preprocessor add the quotes using the stringify operator #
:
#include <stdio.h>
#define STR2(arg) #arg
#define STR(arg) STR2(arg)
int main()
{
printf("%s\n",STR(VAR));
return 0;
}
The indirection in the macros is necessary due to a quirk how the #
operator works. If you would only use one level of macros, the output would be VAR
.
Of course, this only works as long as the value does not contain any funny characters, like spaces.
AC_DEFINE
With AC_DEFINE
it is slightly easier to define VAR to a value surrounded by quotes. Use
AC_DEFINE([VAR], ["yo"])
in configure.in
and remove hello_CFLAGS =-DVAR=@VAR@
from Makefile.am
. Alternatively, if you need to compute the value of VAR
in configure
, use
VAR=yo
AC_DEFINE_UNQUOTED([VAR], ["$VAR"])
which will interpret shell substitutions in the value.
In both cases, you don't have access to VAR
in the Makefile.