简体   繁体   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's cross compiling autotools is supposed to be flexible, but I've isolated a bug that's been breaking cross compiler builds that ought to work. GCC的交叉编译自动工具本来应该很灵活,但是我隔离了一个错误,该错误正在破坏应该起作用的交叉编译器版本。

Note: Some systems will "poison" default compiler tool names to prevent using wrong tools by default. 注意:某些系统会“毒化”默认的编译器工具名称,以防止默认情况下使用错误的工具。 On my system, x86_64-pc-gnu-linux-ar will execute but "ar" is not found. 在我的系统上,将执行x86_64-pc-gnu-linux-ar,但未找到“ ar”。

I need to build cross compiler toolchains with custom names. 我需要使用自定义名称构建交叉编译器工具链。 gcc's configure script supports this with --program-prefix or --program-transform-name. gcc的configure脚本通过--program-prefix或--program-transform-name支持此功能。 However, when using a custom name, all compile time tools have to be explicitly named on the configure line. 但是,使用自定义名称时,必须在配置行上显式命名所有编译时工具。 gcc configure is not intelligent enough to find tools it has just built with a name change. gcc configure不够智能,无法找到它刚用名称更改构建的工具。 (too stupid). (太傻)。

The GCC manual states how to explicitly name tools: GCC手册说明了如何明确命名工具:

configure AR=x86_foo_b_ar AR_FOR_TARGET=ARMv6m_foo_b_ar ... 

However, it doesn't work right. 但是,它不能正常工作。 Autoools sometimes ignores the supplied names and the build fails. Autoools有时会忽略提供的名称,并且构建失败。 In particular, it ignores 'AR' and 'OBJDUMP' variables. 特别是,它将忽略“ AR”和“ OBJDUMP”变量。

Apparently the toplevel gcc configure was created at a later date than lower level configures. 显然,顶层gcc配置创建的日期比底层配置的创建日期晚。

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

Makefile.am does not exist in some subdirectories, but it does exist in newer subdirectories. Makefile.am在某些子目录中不存在,但在较新的子目录中确实存在。

This causes inconsistencies in variable passing from the top-level makefile. 这会导致从顶层makefile传递的变量不一致。

Internally, the top level "configure" script has variables AR_FOR_HOST (alias for AR), AR_FOR_BUILD, and AR_FOR_TARGET. 在内部,顶级“配置”脚本具有变量AR_FOR_HOST(AR的别名),AR_FOR_BUILD和AR_FOR_TARGET。 These variables are used to re-define "AR" when entering sub-directories to force a generic make script to compile for a particular target. 这些变量用于在输入子目录时重新定义“ AR”,以强制通用make脚本针对特定目标进行编译。

I've even gone so far as to define the internal variables correctly as well as "AR" and "OBJDUMP" on the configure command line. 我什至可以在configure命令行上正确定义内部变量以及“ AR”和“ OBJDUMP”。 ( Shouldn't be needed ). (不需要)。

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

I'm wanting gcc to both make and use tools that start with the prefix: armv6m-softfloat-eabi-newlib- (Arm cortex m0 chipset is what I am using) 我想要gcc制作和使用以前缀开头的工具:armv6m-softfloat-eabi-newlib-(我正在使用Arm cortex m0芯片组)

But "make" still fails when attempting to execute "ar" in the .../libcpp directory. 但是,当尝试在... / libcpp目录中执行“ ar”时,“ make”仍然失败。 The reason is that .../libcpp/Makefile.in is not updated by automake. 原因是... / libcpp / Makefile.in不会由automake更新。 It's a hand crafted file. 这是一个手工制作的文件。 On line 28 of the old .../libcpp/Makefile.in it says "AR = ar" 在旧的... / libcpp / Makefile.in的第28行上,它说“ AR = ar”

So, the AR variable is hardcoded to "ar" But, "ar" doesn't exist on my system. 因此,AR变量被硬编码为“ ar”,但是,“ ar”在我的系统上不存在。 I've tried editing .../libcpp/Makefile.in with "AR = dummyname" , and the build crashes with "can't fine dummyname" instead of can't find "ar". 我试过使用“ AR = dummyname”编辑... / libcpp / Makefile.in,并且构建崩溃时显示为“ ca n't fine dummyname”而不是找不到“ ar”。 So, the bug is on line 28. 因此,该错误位于第28行。

All other variables in the .../libcpp/Makefile.in are of the form: ... / libcpp / Makefile.in中的所有其他变量的格式为:

CC = @CC@
INSTALL = @INSTALL@

etc.. On a positive note: The compiler used by .../libcpp IS the fully qulaified name I gave to gcc-7.3.0/configure. 积极一点:... / libcpp使用的编译器是我为gcc-7.3.0 / configure赋予的完整名称。 That success made me think I could fix the bug by editing the makefile to read: 这种成功使我认为我可以通过将makefile编辑为以下内容来修复该错误:

AR = @AR@

But the build fails with "Can't find AR@" 但是构建失败并显示“找不到AR @”

I'm not familiar enough with autotools to hand edit the Makefile.in and fix the bug. 我对自动工具不太熟悉,无法手动编辑Makefile.in并修复错误。 What's the @variable@ name format do? @ variable @名称格式是什么?

Does the configure.ac in the subdirectory have to define "AR" in some way for @AR@ to be linked to the value in the toplevel directory? 子目录中的configure.ac是否必须以某种方式定义“ AR”才能将@ AR @链接到顶级目录中的值?

I've tried a few other tests while building different gcc versions. 在构建不同的gcc版本时,我还尝试了其他一些测试。 Re-running autoconfig, automake, is hell because GCC uses AC_PREREQ() macro. 重新运行autoconfig automake很麻烦,因为GCC使用AC_PREREQ()宏。

For example, I have autotools 2.69 installed ... but gcc 7.3.0 fails and complains that I must use autotools 2.64, ONLY. 例如,我安装了2.69自动工具...但是gcc 7.3.0失败,并抱怨我只能使用自动工具2.64。 eg: AC_PREREQ(2.64) 例如:AC_PREREQ(2.64)

So, fixing the bug via autotools doesn't seem practical. 因此,通过自动工具修复该错误似乎不切实际。 I'm hoping to simply patch the .../libcpp/Makefile.in, since that file is exactly the same in so many versions of gcc. 我希望简单地修补... / libcpp / Makefile.in,因为在许多版本的gcc中该文件是完全相同的。

Questions: Why is "ar" hard-coded ? 问题:为什么“ ar”是硬编码的? Is this a serious legacy issue? 这是一个严重的遗留问题吗? and what is a minimal patch that won't interfere with other configurations of GCC? 什么是不会干扰GCC其他配置的最小补丁?

Is it better to modify the shell or the Makefile; 修改shell或Makefile更好吗? eg: like the top level configure shell script could define a bash function that would be inherited by make as "if" it were a program. 例如:像顶层configure shell脚本一样,可以定义bash函数,该bash函数将由make继承为“ if”,它是一个程序。

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

Edit: A quick-fix patch for gcc-7.3.0 This is not a "correct" fix, but just a work-around. 编辑:gcc-7.3.0的快速修复补丁这不是一个“正确”的修复程序,而只是一种解决方法。

I've found three places where the sub-directories ignore variables passed in from the toplevel configure. 我发现了三个地方,子目录会忽略从顶层配置传入的变量。 .../libcpp/Makefile.in on line 29 .../gcc/configure just before line 29531 .../libcc1/configure just before 14574 ... / libcpp / Makefile.in在第29行... / gcc / configure在第29531行之前... / libcc1 / configure在14574之前

The second and third errors are from a defective macro in configure.ac. 第二个和第三个错误来自configure.ac中的有缺陷的宏。 I haven't traced it back because I can't run autoconfig anyway. 我没有追溯它,因为无论如何我都无法运行自动配置。

I added a line to the configure(s), to see if passing the default OBJDUMP override variable would allow gcc to compile. 我在configure(s)中添加了一行,以查看是否传递默认的OBJDUMP覆盖变量是否将允许gcc进行编译。 It does. 是的 I'm not sure I've chosen the right override variable for all cases of gcc compile switches, but at least it proves where the bug is. 我不确定是否为gcc编译开关的所有情况都选择了正确的替代变量,但至少它可以证明错误所在。

Patch file follows: 补丁文件如下:

--- 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 : there are a lot of things you could try, but the very first would be to specify AR on the command line when you run make : TL; DR :您可以尝试很多方法,但是首先要在运行make时在命令行上指定AR

make AR=x86_foo_b_ar

That shouldn't be necessary when you've already specified the same to configure , but if it doesn't work then that suggests a problem one or more levels up from the Makefile.in you're looking at. 不应该是必要的,当你已经指定到相同的configure ,但如果它不那么这表明一个问题,从一个或多个级别后续工作Makefile.in你看。 Variable definitions specified on the make command line override definitions in makefiles. make命令行上指定的变量定义将覆盖makefile中的定义。


"make" still fails when attempting to execute "ar" from the .../libcpp directory. 尝试从... / libcpp目录执行“ ar”时,“ make”仍然失败。 The reason is that .../libcpp/Makefile.in is not updated by automake. 原因是... / libcpp / Makefile.in不会由automake更新。 It's a hand crafted file. 这是一个手工制作的文件。

To be clear, since understanding the system you are trying to use is immensely helpful in troubleshooting it, automake does not run at configuration or build time. 需要明确的是,由于了解您要使用的系统在排除系统故障方面非常有用,因此automake不会在配置或构建时运行。 It is used by the package maintainer to build one or more Makefile.in files to be included in source distributions, such as the one you obtained. 软件包维护者使用它来构建一个或多个Makefile.in文件,这些文件将包含在源分发中,例如您获得的文件。 Of course, this is not the only way to create Makefile.in files, and the configure script does not care how you create them (or other input files). 当然,这不是在文件中创建Makefile.in的唯一方法,并且configure脚本并不关心如何创建它们(或其他输入文件)。

I'm not familiar enough with autotools to hand edit the Makefile.in and fix the bug. 我对自动工具不太熟悉,无法手动编辑Makefile.in并修复错误。 What's the @variable@ name format do? @ variable @名称格式是什么?

Does the configure.ac in the subdirectory have to define "AR" in some way for @AR@ to be linked to the value in the toplevel directory? 子目录中的configure.ac是否必须以某种方式定义“ AR”才能将@ AR @链接到顶级目录中的值?

The @variable@ construction is used for values that are expected to be substituted by the configure script when it builds a corresponding output file. @variable@构造用于在configure相应的输出文件时预期由configure脚本替换的值。 For that to take place, there needs to be at least a corresponding AC_SUBST([variable]) or its equivalent in the configure.ac (sometimes named configure.in , instead). 对于要发生,需要有至少一个相应的AC_SUBST([variable])或其等价物在configure.ac (有时称为configure.in ,代替)。 Normally, that's preceded somewhere in configure.ac by code assigning an appropriate value to shell variable variable . 通常,在configure.ac中的某处之前,先通过代码将适当的值分配给shell变量variable

If you modify configure.ac then you need to rebuild the configure script, and in that case it's probably safest to rebuild the whole build system, as a package maintainer would do. 如果修改configure.ac则需要重建configure脚本,在这种情况下,重建整个构建系统可能是最安全的,就像软件包维护者所做的那样。 There may be a script provided for that purpose in the package ( autogen.sh is a common name for such scripts), but the default mechanism is to run the Autotools program autoreconf in the top-level directory of the project source tree. 软件包中可能为此目的提供了一个脚本( autogen.sh是此类脚本的通用名称),但是默认机制是在项目源代码树的顶级目录中运行Autotools程序autoreconf

I've tried a few other tests while building different gcc versions. 在构建不同的gcc版本时,我还尝试了其他一些测试。 Re-running autoconfig, automake, is hell because GCC uses AC_PREREQ() macro. 重新运行autoconfig automake很AC_PREREQ() ,因为GCC使用AC_PREREQ()宏。

For example, I have autotools 2.69 installed ... but gcc 7.3.0 fails and complains that I must use autotools 2.64, ONLY. 例如,我安装了2.69自动工具...但是gcc 7.3.0失败,并抱怨我只能使用自动工具2.64。 eg: AC_PREREQ(2.64) 例如: AC_PREREQ(2.64)

That description is not consistent with the documentation of AC_PREREQ , nor with my experience with that macro. 该描述与AC_PREREQ的文档AC_PREREQ ,也不符合我对该宏的经验。 AC_PREREQ tests for the specified Autoconf version or newer . AC_PREREQ测试指定的Autoconf版本或更高版本 It does not demand an exact Autoconf version. 它不需要确切的Autoconf版本。 There may be something else in the build system that does so, but it's not AC_PREREQ . 生成系统中可能还有其他功能,但不是AC_PREREQ

In any case, one alternative would be to obtain and install Autoconf 2.64. 无论如何,一种替代方法是获取并安装Autoconf 2.64。 You may even be able to install it alongside your existing version. 您甚至可以将其与现有版本一起安装。 Some systems even provide pre-built packages for exactly that purpose. 某些系统甚至为此目的提供了预先构建的软件包。

So, fixing the bug via autotools doesn't seem practical. 因此,通过自动工具修复该错误似乎不切实际。 I'm hoping to simply patch the .../libcpp/Makefile.in, since that file is exactly the same in so many versions of gcc. 我希望简单地修补... / libcpp / Makefile.in,因为在许多版本的gcc中该文件是完全相同的。

Patching a Makefile.in does not require afterward re-running the autotools, so it's at least conceivable that that would work. 修补Makefile.in不需要事后重新运行自动工具,因此至少可以想象这样会起作用。 Even for Makefile.in files that were generated by Automake. 甚至对于由Makemake生成的Makefile.in文件。 You could consider having a look at how AR is defined in some of the Automake-generated Makefile.in files in the project (supposing there are any) for an idea of how it should look. 您可以考虑看看在项目中某些由Automake生成的Makefile.in文件中AR是如何定义的(假设有的话),以了解其外观。

Why is "ar" hard-coded ? 为什么“ ar”是硬编码的? Is this a serious legacy issue? 这是一个严重的遗留问题吗?

I can only speculate. 我只能推测。 As a threshold matter, I'm inclined to suppose that in that Makefile , the archiver of the build system is the one wanted (not that of the intended host system, nor a cross-ar for host-target). 作为一个门槛问题,我倾向于假设在该Makefile ,构建系统的存档器是所需要的(而不是预期的主机系统的存档器,也不是主机目标的跨档案文件)。 It is reasonable in that case for AR = ar to be provided as a default, because that can be overridden via a declaration of that variable on the command-line. 在这种情况下,将AR = ar作为默认值提供是合理的,因为可以通过在命令行上声明该变量来覆盖它。

That you are in fact not getting the AR you specify to configure looks like a bug to me -- probably a regression introduced at some point when some of the higher-level bits of the build system were updated. 实际上,您没有得到您指定的configure AR似乎对我来说是一个错误-可能是在更新构建系统的某些更高级别的某个点时引入的回归。 I have no trouble imagining such an issue slipping by, as a system configuration such as yours, in which the system's own archiver goes only by a non-standard name, is very uncommon. 我毫不费力地想到了这样的问题,因为像您这样的系统配置非常少见,在该配置中,系统自己的存档器仅以非标准名称使用。

and what is a minimal patch that won't interfere with other configurations of GCC? 什么是不会干扰GCC其他配置的最小补丁?

The first thing to try is to pass the AR definition on the top-level make command line: 首先尝试在顶级make命令行上传递AR定义:

make AR=x86_foo_b_ar

Such definitions will be passed on to recursively-invoked sub- make s, and definitions on the command line (but not, by default, from the environment) override definitions in Makefiles. 这样的定义将传递给递归调用的子make ,并且命令行上的定义(默认情况下不是来自环境)将覆盖Makefile中的定义。

Is it better to modify the shell or the Makefile; 修改shell或Makefile更好吗? eg: like the top level configure shell script could define a bash function that would be inherited by make as "if" it were a program. 例如:像顶层configure shell脚本一样,可以定义bash函数,该bash函数将由make继承为“ if”,它是一个程序。

The top-level configure script could be modified to define a shell function and export it to child processes, but not to its parent or siblings. 可以修改顶层configure脚本,以定义Shell函数并将其导出到子进程,但不能导出到其父级或同级。 This is nothing specific to configure ; 这是没有具体configure ; the shell just doesn't work that way. 外壳无法正常工作。 Whatever changes you make, if any, would be best made in Makefile.in files before running configure , or in the generated Makefile s afterward. 进行任何更改(如果有),最好在运行configure之前在Makefile.in文件中进行,或者在之后生成的Makefile

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

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