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