繁体   English   中英

自动工具:GCC的Makefile.in有一个错误(7.3.0及更早版本)。 如何重新编程自动制作以查找“ ar”和“ objdump”

[英]Autotools: GCC's Makefile.in has a bug (7.3.0 and earlier). How to re-program automake to find 'ar' and 'objdump'

GCC的交叉编译自动工具本来应该很灵活,但是我隔离了一个错误,该错误正在破坏应该起作用的交叉编译器版本。

注意:某些系统会“毒化”默认的编译器工具名称,以防止默认情况下使用错误的工具。 在我的系统上,将执行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”和“ OBJDUMP”变量。

显然,顶层gcc配置创建的日期比底层配置的创建日期晚。

在GCC中没有Makefile.am的Makefile.in吗?

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

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

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

我什至可以在configure命令行上正确定义内部变量以及“ AR”和“ OBJDUMP”。 (不需要)。

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芯片组)

但是,当尝试在... / libcpp目录中执行“ ar”时,“ make”仍然失败。 原因是... / libcpp / Makefile.in不会由automake更新。 这是一个手工制作的文件。 在旧的... / libcpp / Makefile.in的第28行上,它说“ AR = ar”

因此,AR变量被硬编码为“ ar”,但是,“ ar”在我的系统上不存在。 我试过使用“ AR = dummyname”编辑... / libcpp / Makefile.in,并且构建崩溃时显示为“ ca n't fine dummyname”而不是找不到“ ar”。 因此,该错误位于第28行。

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

CC = @CC@
INSTALL = @INSTALL@

积极一点:... / libcpp使用的编译器是我为gcc-7.3.0 / configure赋予的完整名称。 这种成功使我认为我可以通过将makefile编辑为以下内容来修复该错误:

AR = @AR@

但是构建失败并显示“找不到AR @”

我对自动工具不太熟悉,无法手动编辑Makefile.in并修复错误。 @ variable @名称格式是什么?

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

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

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

因此,通过自动工具修复该错误似乎不切实际。 我希望简单地修补... / libcpp / Makefile.in,因为在许多版本的gcc中该文件是完全相同的。

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

修改shell或Makefile更好吗? 例如:像顶层configure shell脚本一样,可以定义bash函数,该bash函数将由make继承为“ if”,它是一个程序。

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

编辑:gcc-7.3.0的快速修复补丁这不是一个“正确”的修复程序,而只是一种解决方法。

我发现了三个地方,子目录会忽略从顶层配置传入的变量。 ... / libcpp / Makefile.in在第29行... / gcc / configure在第29531行之前... / libcc1 / configure在14574之前

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

我在configure(s)中添加了一行,以查看是否传递默认的OBJDUMP覆盖变量是否将允许gcc进行编译。 是的 我不确定是否为gcc编译开关的所有情况都选择了正确的替代变量,但至少它可以证明错误所在。

补丁文件如下:

--- 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

TL; DR :您可以尝试很多方法,但是首先要在运行make时在命令行上指定AR

make AR=x86_foo_b_ar

不应该是必要的,当你已经指定到相同的configure ,但如果它不那么这表明一个问题,从一个或多个级别后续工作Makefile.in你看。 make命令行上指定的变量定义将覆盖makefile中的定义。


尝试从... / libcpp目录执行“ ar”时,“ make”仍然失败。 原因是... / libcpp / Makefile.in不会由automake更新。 这是一个手工制作的文件。

需要明确的是,由于了解您要使用的系统在排除系统故障方面非常有用,因此automake不会在配置或构建时运行。 软件包维护者使用它来构建一个或多个Makefile.in文件,这些文件将包含在源分发中,例如您获得的文件。 当然,这不是在文件中创建Makefile.in的唯一方法,并且configure脚本并不关心如何创建它们(或其他输入文件)。

我对自动工具不太熟悉,无法手动编辑Makefile.in并修复错误。 @ variable @名称格式是什么?

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

@variable@构造用于在configure相应的输出文件时预期由configure脚本替换的值。 对于要发生,需要有至少一个相应的AC_SUBST([variable])或其等价物在configure.ac (有时称为configure.in ,代替)。 通常,在configure.ac中的某处之前,先通过代码将适当的值分配给shell变量variable

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

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

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

该描述与AC_PREREQ的文档AC_PREREQ ,也不符合我对该宏的经验。 AC_PREREQ测试指定的Autoconf版本或更高版本 它不需要确切的Autoconf版本。 生成系统中可能还有其他功能,但不是AC_PREREQ

无论如何,一种替代方法是获取并安装Autoconf 2.64。 您甚至可以将其与现有版本一起安装。 某些系统甚至为此目的提供了预先构建的软件包。

因此,通过自动工具修复该错误似乎不切实际。 我希望简单地修补... / libcpp / Makefile.in,因为在许多版本的gcc中该文件是完全相同的。

修补Makefile.in不需要事后重新运行自动工具,因此至少可以想象这样会起作用。 甚至对于由Makemake生成的Makefile.in文件。 您可以考虑看看在项目中某些由Automake生成的Makefile.in文件中AR是如何定义的(假设有的话),以了解其外观。

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

我只能推测。 作为一个门槛问题,我倾向于假设在该Makefile ,构建系统的存档器是所需要的(而不是预期的主机系统的存档器,也不是主机目标的跨档案文件)。 在这种情况下,将AR = ar作为默认值提供是合理的,因为可以通过在命令行上声明该变量来覆盖它。

实际上,您没有得到您指定的configure AR似乎对我来说是一个错误-可能是在更新构建系统的某些更高级别的某个点时引入的回归。 我毫不费力地想到了这样的问题,因为像您这样的系统配置非常少见,在该配置中,系统自己的存档器仅以非标准名称使用。

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

首先尝试在顶级make命令行上传递AR定义:

make AR=x86_foo_b_ar

这样的定义将传递给递归调用的子make ,并且命令行上的定义(默认情况下不是来自环境)将覆盖Makefile中的定义。

修改shell或Makefile更好吗? 例如:像顶层configure shell脚本一样,可以定义bash函数,该bash函数将由make继承为“ if”,它是一个程序。

可以修改顶层configure脚本,以定义Shell函数并将其导出到子进程,但不能导出到其父级或同级。 这是没有具体configure ; 外壳无法正常工作。 进行任何更改(如果有),最好在运行configure之前在Makefile.in文件中进行,或者在之后生成的Makefile

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM