Как изменить имя VAR без получения необъявленной ошибки после 'make install'?

Мой 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 становится yo, но оно не объявлено. Моя цель напечатать йо, но как решить это дело?

1 ответ

Решение

Я предполагаю, что вы хотите, чтобы программа доставила вывод

yo

Правильное цитирование в configure.in

Вы также, вероятно, заметили, что вам не хватает кавычек, чтобы сделать замену текста определения VAR строковый литерал. Сложность состоит в том, что вы передаете это значение через два экземпляра оболочки, которая будет отбрасывать кавычки: тот, который выполняет configure и тот, который вызывается make запустить компилятор. Таким образом, вам нужно три уровня цитирования с соответствующим экранированием:

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

(Вы можете попробовать использовать одинарные кавычки, чтобы уменьшить количество \, но это, вероятно, станет еще более безобразным.)

Правильное цитирование в Makefile.am

Вы также можете сделать цитату в Makefile.am, Это особенно полезно, если вам нужно значение VAR в Makefile тоже для других целей. Вам нужны два уровня qoutes: один для того, чтобы сделать значение строковым литералом, а другой - для оболочки:

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

Это работает, даже если VAR содержит (одиночные) пробелы или другие забавные символы, единственные проблемные символы ', ", а также \,

Stringification

В качестве альтернативы вы можете позволить препроцессору добавлять кавычки, используя оператор 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"])

в configure.in и удалить hello_CFLAGS =-DVAR=@VAR@ от Makefile.am, В качестве альтернативы, если вам нужно вычислить значение VAR в configureиспользовать

VAR=yo
AC_DEFINE_UNQUOTED([VAR], ["$VAR"])

который будет интерпретировать замены оболочки в значении.

В обоих случаях у вас нет доступа к VAR в Makefile.

Другие вопросы по тегам