首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无视CFLAGS?

无视CFLAGS?
EN

Stack Overflow用户
提问于 2020-01-30 00:24:33
回答 2查看 405关注 0票数 1

我正在构建一个使用GNU的包(副3.4)。运行./configure失败的消息如下:

代码语言:javascript
复制
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时,由于以下错误,这似乎是失败的:

代码语言:javascript
复制
/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环境变量来解决这个问题:

代码语言:javascript
复制
CFLAGS=-fPIC ./configure

但是,虽然这显然是在./configure的其他阶段使用.

代码语言:javascript
复制
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相关的特性测试

代码语言:javascript
复制
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,上面的代码是从以下代码生成的:

代码语言:javascript
复制
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来解决这个问题:

代码语言:javascript
复制
CC="gcc -fPIC" ./configure

这是可行的,但它很难看(如果想要调用没有gcc-fPIC怎么办?)AC_CHECK_SIZEOF忽视CFLAGS有什么原因吗

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-30 01:12:02

看来我在评论中表达的怀疑已经得到证实。副程序在执行某些检查时有意配置用于用户指定的,包括与time_t相关的检查。因此,这不是Autoconf忽略您的旗帜的问题,而是做坏事的问题。

我重申,我认为这是一个更重要的问题,配置一开始就不适合你。我建议将此作为反对该项目的一个问题。虽然我不喜欢这个恶习太轻率地忽略用户的CFLAGS,但这是另一回事,而且我怀疑devs不会有多大的吸引力。

票数 3
EN

Stack Overflow用户

发布于 2020-01-30 17:06:09

John正确地指出了问题所在,基于这些信息,我做了一些调查,我已经弄清楚了到底是怎么回事。

我是在rpm的控制下构建它的,它调用了这样的配置:

代码语言:javascript
复制
%configure --enable-native-gtk3ui $COMMON_FLAGS

%configure扩展为如下所示的shell代码块:

代码语言:javascript
复制
  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。失败的配置测试是:

代码语言:javascript
复制
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行指向gcc规范文件,该文件如下所示:

代码语言:javascript
复制
*self_spec:
+ %{!static:%{!shared:%{!r:-pie}}}

这有效地将-pie选项添加到命令行。我们可以使用一个简单的hello.c程序来再现失败:

代码语言:javascript
复制
#include <stdio.h>
#include <unistd.h>

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

如下所示:

代码语言:javascript
复制
$ 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

但问题是:

成功的gcc调用如下所示:

代码语言:javascript
复制
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,如下所示:

代码语言:javascript
复制
*cc1_options:
+ %{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:-fPIE}}}}}}

这将负责将-fPIE添加到命令行,这将导致编译成功:

代码语言:javascript
复制
$ gcc -o hello -pie -fPIE hello.c
$

我们遇到这个失败是因为configure脚本在测试期间替换了CFLAGS,但是保留了LDFLAGS。这将导致错误的命令行。

出于我自己的目的,我只是修补configure脚本,以便在与time_t相关的测试中不替换CFLAGS。这看起来既权宜之计(如果我只是注释掉适当的行,这是一个单一字符的差异)和有效(它导致一个成功的构建)。

我可能会向上游报告这是个错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59977486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档