Autotools:GCC的Makefile.in有一个bug(7.3.0及更早版本)。如何重新编程automake以找到' ar'和' objdump'

时间:2018-06-14 05:38:53

标签: gcc cross-compiling autotools

GCC的交叉编译autotools应该是灵活的,但我已经隔离了一个错误,它已经破坏了应该工作的交叉编译器构建。

注意:有些系统会“毒害”#34;默认编译器工具名称,以防止使用错误的工具。在我的系统上,x86_64-pc-gnu-linux-ar将执行,但是" ar"找不到。

我需要使用自定义名称构建交叉编译器工具链。 gcc的configure脚本支持--program-prefix或--program-transform-name。但是,使用自定义名称时,必须在配置行上显式命名所有编译时工具。 gcc configure不够智能,无法找到刚刚使用名称更改构建的工具。 (太愚蠢了)。

GCC手册说明了如何明确命名工具:

configure AR=x86_foo_b_ar AR_FOR_TARGET=ARMv6m_foo_b_ar ... 

但是,它不能正常工作。 Autoools有时会忽略提供的名称,并且构建失败。特别是,它忽略了AR' AR'和' OBJDUMP'变量

显然,顶级gcc配置是在较低级别配置之后创建的。

Makefile.in without Makefile.am in GCC?

Makefile.am在某些子目录中不存在,但 存在于较新的子目录中。

这会导致从顶级makefile传递的变量不一致。

在内部,顶级"配置"脚本具有变量AR_FOR_HOST(AR的别名),AR_FOR_BUILD和AR_FOR_TARGET。这些变量用于重新定义" AR"进入子目录时强制通用make脚本为特定目标编译。

我甚至已经正确地定义了内部变量以及" AR"和" OBJDUMP"在configure命令行上。 (不应该需要)。

gcc-7.3.0/configure --host=x86_64-pc-linux-gnu --program-prefix=armv6m-softfloat-eabi-newlib- AR_FOR_BUILD=/usr/bin/x86_64-pc-linux-gnu-ar AR=/usr/bin/x86_64-pc-linux-gnu-ar AR_FOR_HOST=/usr/bin/x86_64-pc-linux-gnu-ar AR_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/ar AS_FOR_BUILD=/usr/bin/x86_64-pc-linux-gnu-as AS=/usr/bin/x86_64-pc-linux-gnu-as AS_FOR_HOST=/usr/bin/x86_64-pc-linux-gnu-as AS_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/as DLLTOOL_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/dlltool LD_FOR_BUILD=/usr/bin/x86_64-pc-linux-gnu-ld LD=/usr/bin/x86_64-pc-linux-gnu-ld LD_FOR_HOST=/usr/bin/x86_64-pc-linux-gnu-ld LD_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/ld LIPO_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/lipo NM_FOR_BUILD=/usr/bin/x86_64-pc-linux-gnu-nm NM=/usr/bin/x86_64-pc-linux-gnu-nm NM_FOR_HOST=/usr/bin/x86_64-pc-linux-gnu-nm NM_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/nm OBJCOPY_FOR_BUILD=/usr/bin/x86_64-pc-linux-gnu-objcopy OBJCOPY=/usr/bin/x86_64-pc-linux-gnu-objcopy OBJCOPY_FOR_HOST=/usr/bin/x86_64-pc-linux-gnu-objcopy OBJCOPY_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/objcopy OBJDUMP_FOR_BUILD=/usr/bin/x86_64-pc-linux-gnu-objdump OBJDUMP=/usr/bin/x86_64-pc-linux-gnu-objdump OBJDUMP_FOR_HOST=/usr/bin/x86_64-pc-linux-gnu-objdump OBJDUMP_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/objdump RANLIB_FOR_BUILD=/usr/bin/x86_64-pc-linux-gnu-ranlib RANLIB=/usr/bin/x86_64-pc-linux-gnu-ranlib RANLIB_FOR_HOST=/usr/bin/x86_64-pc-linux-gnu-ranlib RANLIB_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/ranlib READELF_FOR_BUILD=/usr/bin/x86_64-pc-linux-gnu-readelf READELF=/usr/bin/x86_64-pc-linux-gnu-readelf READELF_FOR_HOST=/usr/bin/x86_64-pc-linux-gnu-readelf READELF_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/readelf STRIP_FOR_BUILD=/usr/bin/x86_64-pc-linux-gnu-strip STRIP=/usr/bin/x86_64-pc-linux-gnu-strip STRIP_FOR_HOST=/usr/bin/x86_64-pc-linux-gnu-strip STRIP_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/strip CC_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/cc CXX_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/cxx WINDRES_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/windres WINDMC_FOR_TARGET=/usr/libexec/gcc/armv6m-softfloat-eabi-newlib/windmc --target=armv6m-softfloat-eabi --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/armv6m-softfloat-eabi-newlib/gcc-bin/7.3.0 --includedir=/usr/lib/gcc/armv6m-softfloat-eabi-newlib/7.3.0/include --datadir=/usr/share/gcc-data/armv6m-softfloat-eabi-newlib/7.3.0 --mandir=/usr/share/gcc-data/armv6m-softfloat-eabi-newlib/7.3.0/man --infodir=/usr/share/gcc-data/armv6m-softfloat-eabi-newlib/7.3.0/info --with-gxx-include-dir=/usr/lib/gcc/armv6m-softfloat-eabi-newlib/7.3.0/include/g++-v7 --with-python-dir=/share/gcc-data/armv6m-softfloat-eabi-newlib/7.3.0/python --enable-languages=c --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion=Gentoo 7.3.0-r3 p1.4 --disable-esp --enable-poison-system-directories --disable-bootstrap --with-newlib --enable-multilib --disable-altivec --disable-fixed-point --with-float=soft --disable-libgcj --disable-libgomp --disable-libmudflap --disable-libssp --disable-libcilkrts --disable-libmpx --disable-vtable-verify --disable-libvtv --disable-libquadmath --enable-lto --without-isl --disable-libsanitizer --enable-default-pie --enable-default-ssp

我希望gcc同时制作和使用以前缀开头的工具:armv6m-softfloat-eabi-newlib- (Arm cortex m0芯片组是我正在使用的)

但" make"在尝试执行" ar"时仍然失败在... / libcpp目录中。原因是... / libcpp / Makefile.in没有被automake更新。它是手工制作的文件。在旧的... / libcpp / Makefile.in的第28行,它说" AR = ar"

因此,AR变量被硬编码为" ar"但是," ar"在我的系统上不存在。我已尝试使用" AR = dummyname"编辑... / libcpp / Makefile.in和#34的构建崩溃不能使用dummyname"而不是找不到" ar"。所以,这个错误就在第28行。

... / libcpp / Makefile.in中的所有其他变量的格式为:

CC = @CC@
INSTALL = @INSTALL@

等。 从积极的方面来说:... / libcpp使用的编译器是我给gcc-7.3.0 / configure的完全规范的名称。这个成功让我觉得我可以通过编辑makefile来解决这个问题:

AR = @AR@

但是构建失败了"无法找到AR @"

我对autotools不熟悉,不能手动编辑Makefile.in并修复bug。 @ variable @ name格式的作用是什么?

子目录中的configure.ac是否必须定义" AR"以某种方式将@ AR @链接到顶层目录中的值?

我在构建不同的gcc版本时尝试了一些其他测试。重新运行autoconfig,automake,是因为GCC使用AC_PREREQ()宏。

例如,我安装了自动工具2.69 ...但gcc 7.3.0失败并抱怨我必须使用autotools 2.64,仅限。例如:AC_PREREQ(2.64)

因此,通过autotools修复bug似乎并不实用。 我希望简单地修补... / libcpp / Makefile.in,因为在很多版本的gcc中该文件完全相同。

问题: 为什么" ar"硬编码?这是一个严重的遗留问题吗?什么是不会干扰GCC其他配置的最小补丁?

修改shell或Makefile是否更好;例如:像顶级配置shell脚本可以定义一个bash函数,该函数将由make作为"如果"这是一个程序。

if [ -z ${AR##*-*} ] ; then
    ar() { $AR } 
fi

编辑:gcc-7.3.0的快速修补补丁 这不是一个正确的"修复,但只是解决方法。

我找到了三个子目录忽略从toplevel配置传入的变量的地方。 第29行的... / libcpp / Makefile.in ... / gcc /在第29531行之前配置 ... / libcc1 /在14574之前配置

第二个和第三个错误来自configure.ac中的有缺陷的宏。我还没有追溯到它,因为无论如何我都无法运行自动配置。

我在configure中添加了一行,以查看是否传递默认的OBJDUMP覆盖变量将允许gcc进行编译。确实如此。我不确定我是否为gcc编译开关的所有情况选择了正确的覆盖变量,但至少它证明了bug的位置。

补丁文件如下:

--- gcc-old/libcpp/Makefile.in                                                  
+++ gcc-new/libcpp/Makefile.in                                                  
@@ -28,3 +28,3 @@                                                               
 INSTALL = @INSTALL@                                                            
-AR = ar                                                                        
+AR ?= ar                                                                       
 ARFLAGS = cru                                                                  
--- gcc-old/gcc/configure                                                       
+++ gcc-new/gcc/configure                                                       
@@ -29531,4 +29531,6 @@                                                         
      ;;                                                                        
    esac                                                                        

+   if [ -n $OBJDUMP ]; then export_sym_check="$OBJDUMP -T"; fi                 
+                                                                               
    if test x"$enable_plugin" = x"yes"; then                                    
--- gcc-old/libcc1/configure                                                    
+++ gcc-new/libcc1/configure                                                    
@@ -14574,4 +14574,6 @@                                                         
      ;;                                                                        
    esac                                                                        

+   if [ -n $OBJDUMP ]; then export_sym_check="$OBJDUMP -T"; fi                 
+                                                                               
    if test x"$enable_plugin" = x"yes"; then

1 个答案:

答案 0 :(得分:2)

TL; DR :您可以尝试很多事情,但第一个是在运行AR时在命令行上指定make

make AR=x86_foo_b_ar

当你已经为configure指定了相同的时,

或者您正在查看的Makefile.in更高级别。 make命令行上指定的变量定义会覆盖makefile中的定义。

  

"使"在尝试执行" ar"时仍然失败来自... / libcpp目录。原因是... / libcpp / Makefile.in没有被automake更新。它是手工制作的文件。

要清楚,因为了解您尝试使用的系统对排除故障非常有帮助,automake不会在配置或构建时运行。包维护者使用它来构建要包含在源分发中的一个或多个Makefile.in文件,例如您获得的文件。当然,这不是创建Makefile.in文件的唯一方法,而configure脚本并不关心如何创建它们(或其他输入文件)。

  

我对autotools不熟悉,不能手动编辑Makefile.in并修复bug。 @ variable @ name格式的作用是什么?

     

子目录中的configure.ac是否必须定义" AR"以某种方式将@ AR @链接到顶层目录中的值?

@variable@构造用于构建相应输出文件时预期由configure脚本替换的值。要实现这一点,需要在AC_SUBST([variable])(有时命名为configure.ac)中至少有相应的configure.in或其等价物。通常情况下,代码会在configure.ac中的某个位置通过代码为shell变量variable指定适当的值。

如果修改configure.ac,则需要重建configure脚本,在这种情况下,重建整个构建系统可能是最安全的,就像软件包维护者一样。包中可能有为此目的提供的脚本(autogen.sh是此类脚本的通用名称),但默认机制是在顶级目录中运行Autotools程序autoreconf。项目源树。

  

我在构建不同的gcc版本时尝试了一些其他测试。   重新运行autoconfig,automake,是因为GCC使用AC_PREREQ()   宏。

     

例如,我安装了自动工具2.69 ...但是gcc 7.3.0失败了   并抱怨我必须使用autotools 2.64,仅限。例如:   AC_PREREQ(2.64)

该描述与AC_PREREQ的文档不一致,也与我对该宏的经验不一致。 AC_PREREQ测试指定的Autoconf版本或更新。它不需要精确的Autoconf版本。构建系统中可能还有其他内容可以执行此操作,但它不是AC_PREREQ

在任何情况下,一种替代方案是获取并安装Autoconf 2.64。您甚至可以将其与现有版本一起安装。有些系统甚至可以提供预先构建的软件包。

  

因此,通过autotools修复bug似乎并不实用。我希望   只需修补... / libcpp / Makefile.in,因为该文件完全正确   在许多版本的gcc中也一样。

修补Makefile.in后不需要重新运行autotools,所以至少可以想象它会起作用。即使是由Automake生成的Makefile.in文件也是如此。你可以考虑一下如何在项目中的一些Automake生成的AR文件中定义Makefile.in(假设有任何文件),以了解它应该如何看待。

  

为什么" ar"硬编码?这是一个严重的遗留问题吗?

我只能推测。作为一个门槛问题,我倾向于认为在那个Makefile中,构建系统的归档器是想要的(不是预期的主机系统的归档,也不是主机 - 目标的交叉)。 )。在这种情况下,AR = ar作为默认值提供是合理的,因为可以通过在命令行上声明该变量来覆盖

你实际上没有得到你指定给AR的{​​{1}}看起来像是一个错误 - 可能是在构建的某些高级位时某些时候引入的回归系统更新了。我可以毫不费力地想象这样一个问题,因为像你这样的系统配置,系统自己的归档器只能以非标准名称发送,这种情况非常罕见。

  

什么是   最小的补丁不会干扰GCC的其他配置?

首先要尝试的是在顶级configure命令行上传递AR定义:

make

此类定义将传递给递归调用的子make AR=x86_foo_b_ar ,并且命令行上的定义(但默认情况下,不会从环境中定义)覆盖Makefile中的定义。

  

修改shell或Makefile是否更好;例如:像顶部一样   level configure shell脚本可以定义一个bash函数   如果"继承为make as"这是一个程序。

可以修改顶级make脚本以定义shell函数并将其导出到子进程,但到其父进程或兄弟进程。这与configure无关; shell只是不这样做。无论您做出哪些更改(如果有),最好在configure文件中进行更改,然后再运行Makefile.in,或者之后生成的configure