autoconf игнорирует CFLAGS? - PullRequest
       82

autoconf игнорирует CFLAGS?

1 голос
/ 30 января 2020

Я создаю пакет ( Vice 3.4 ), который использует GNU autoconf. Выполнение ./configure завершается неудачно со следующим сообщением:

checking size of time_t... 0
configure: error: can not figure type of time_t
error: Bad exit status from /var/tmp/rpm-tmp.wIgnPw (%build)

При проверке config.log возникает ошибка из-за следующей ошибки:

/usr/bin/ld: /tmp/ccMTSdtB.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: nonrepresentable section on output
collect2: error: ld returned 1 exit status

Я попытался решить эту проблему, добавив -fPIC в переменную окружения CFLAGS:

CFLAGS=-fPIC ./configure

Но хотя это явно используется на других этапах ./configure ...

configure:3657: checking whether the C compiler works
configure:3679: gcc -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE=1 -fPIC  -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld conftest.c  >&5

Это не похоже, что он используется в функциональных тестах, связанных с time_t:

configure:9684: checking for time_t in time.h
configure:9700: gcc -c -g -O3 -Wall -Wformat -Wformat-signedness -Wshadow -Wpointer-arith -Wstrict-prototypes -Wuninitialized -Wunreachable-code -Wno-unused-parameter -Werror=implicit-function-declaration -Wfatal-errors  conftest.c >&5
[...]
configure:9753: checking size of time_t
configure:9758: gcc -o conftest -g -O3 -Wall -Wformat -Wformat-signedness -Wshadow -Wpointer-arith -Wstrict-prototypes -Wuninitialized -Wunreachable-code -Wno-unused-parameter -Werror=implicit-function-declaration -Wfatal-errors  -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld conftest.c  >&5

Глядя на configure.ac, приведенный выше код генерируется из:

if test $bu_cv_decl_time_t_time_h = yes; then
  AC_CHECK_SIZEOF([time_t],[],[#include <time.h>])
else
  AC_CHECK_SIZEOF([time_t],[],[#include <sys/types.h>])
fi

Я смог чтобы обойти проблему, переопределив CC вместо этого:

CC="gcc -fPIC" ./configure

Это работает, но уродливо (что если кто-то захочет позвонить gcc без -fPIC?). Есть ли причина, по которой AC_CHECK_SIZEOF игнорирует CFLAGS?

Ответы [ 2 ]

2 голосов
/ 30 января 2020

Похоже, подозрение, которое я высказал в комментариях, подтвердилось. Программа конфигурирования VICE преднамеренно заменяет свой собственный выбор CFLAGS на указанные пользователем , когда она выполняет некоторые проверки, в том числе связанные с time_t. Таким образом, это не вопрос Autoconf игнорирования ваших флагов, а скорее VICE .

Я повторяю, что я думаю, что это более важная проблема, что конфигурация не работает из коробки для вас в первую очередь. Я предлагаю поднять это как проблему против проекта. Хотя мне не нравится, что VICE так ловко игнорирует CFLAGS пользователя, но это отдельный вопрос, и я подозреваю, что он не получит большой поддержки от разработчиков.

0 голосов
/ 30 января 2020

Джон правильно определил проблему, и на основе этой информации я немного покопался и выяснил, что происходит.

Я строю это под контролем rpm, который вызывает настройте так:

%configure --enable-native-gtk3ui $COMMON_FLAGS

То, что %configure расширяется в кусок кода оболочки, который выглядит следующим образом:



  CFLAGS="${CFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection}" ; export CFLAGS ; 
  CXXFLAGS="${CXXFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection}" ; export CXXFLAGS ; 
  FFLAGS="${FFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules}" ; export FFLAGS ; 
  FCFLAGS="${FCFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules}" ; export FCFLAGS ; 
  LDFLAGS="${LDFLAGS:--Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld}" ; export LDFLAGS; 
  [ "1" = 1 ] && for i in $(find $(dirname ./configure) -name config.guess -o -name config.sub) ; do 
      [ -f /usr/lib/rpm/redhat/$(basename $i) ] && /usr/bin/rm -f $i && /usr/bin/cp -fv /usr/lib/rpm/redhat/$(basename $i) $i ; 
  done ; 
  [ "1" = 1 ] && [ x != "x-Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld" ] && 
      for i in $(find . -name ltmain.sh) ; do 
        /usr/bin/sed -i.backup -e 's~compiler_flags=$~compiler_flags="-Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld"~' $i 
      done ; 
  ./configure --build=x86_64-redhat-linux-gnu --host=x86_64-redhat-linux-gnu \
    --program-prefix= \
    --disable-dependency-tracking \
     \
    --prefix=/usr \
    --exec-prefix=/usr \
    --bindir=/usr/bin \
    --sbindir=/usr/sbin \
    --sysconfdir=/etc \
    --datadir=/usr/share \
    --includedir=/usr/include \
    --libdir=/usr/lib64 \
    --libexecdir=/usr/libexec \
    --localstatedir=/var \
    --sharedstatedir=/var/lib \
    --mandir=/usr/share/man \
    --infodir=/usr/share/info

Особый интерес вызывает тот факт, что это настройка LDFLAGS. Неудачный тест конфигурации:

gcc -o conftest -g -O3 -Wall -Wformat -Wformat-signedness -Wshadow \
  -Wpointer-arith -Wstrict-prototypes -Wuninitialized -Wunreachable-code \
  -Wno-unused-parameter -Werror=implicit-function-declaration \
  -Wfatal-errors  -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now \
  -specs=/usr/lib/rpm/redhat/redhat-hardened-ld conftest.c

Эта строка -specs указывает на файл ag cc spe c, который выглядит следующим образом:

*self_spec:
+ %{!static:%{!shared:%{!r:-pie}}}

Это эффективно добавляет -pie опция для командной строки. Мы можем воспроизвести ошибку с помощью простой hello.c программы:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv) {
    printf("hello world\n");
    return(0);
}

Примерно так:

$ gcc -o hello -pie hello.c
/usr/bin/ld: /tmp/ccXRAu6r.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: nonrepresentable section on output
collect2: error: ld returned 1 exit status

Но вот в чем дело:

A успешно gcc вызов выглядит следующим образом:

gcc -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 \
  -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong \
  -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 \
  -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic \
  -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection \
  -D_GNU_SOURCE=1 -fPIC  -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now \
  -specs=/usr/lib/rpm/redhat/redhat-hardened-ld conftest.c 

Обратите внимание, что там есть второй параметр -specs, который указывает на /usr/lib/rpm/redhat/redhat-hardened-cc1, который выглядит следующим образом:

*cc1_options:
+ %{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:-fPIE}}}}}}

Это обеспечивает добавление -fPIE в командную строку, что приводит к успешной компиляции:

$ gcc -o hello -pie -fPIE hello.c
$

Мы сталкиваемся с этой ошибкой, поскольку сценарий configure заменяет 1045 * * CFLAGS во время испытаний, но с сохранением LDFLAGS. Это приводит к некорректной командной строке.

Для моих собственных целей я просто исправляю скрипт configure, чтобы он не заменял CFLAGS во время связанных с time_t тестов. Это кажется целесообразным (это односимвольная разность, если я просто закомментирую соответствующую строку) и эффективным (это приводит к успешной сборке).

Я, вероятно, сообщу об этом в исходной версии как об ошибке.

...