靜態連結 util-linux - 交叉編譯(產生動態連結檔)

靜態連結 util-linux - 交叉編譯(產生動態連結檔)

我一直在嘗試為arm交叉編譯util-linux,但我總是得到動態連結的可執行文件,我不知道為什麼會這樣。我的目標是靜態的。我一直在使用類似步驟的不同工具之前進行交叉編譯,而且它一直有效,所以我不知道這次我做錯了什麼。我使用的是 Ubuntu 16.04。以下是我正在運行的命令:

export CC=arm-linux-gnueabi-gcc
export ac_cs_linux_vers=4
export CFLAGS=-static
export CPPFLAGS=-static
export LDFLAGS=-static

./configure --host=arm-linux LDFLAGS=-static --disable-shared --without-tinfo --without-ncurses --disable-ipv6 --disable-pylibmount --enable-static-programs=fdisk,sfdisk,whereis --prefix=/opt/util-linux/arm --bindir=/opt/util-linux/arm/bin --sbindir=/opt/util-linux/arm/sbin

正如您所看到的,我在我能想到的每個地方都指定了靜態,甚至重複了一些東西“只是為了確保它理解我”,並且在運行配置腳本後,以下是輸出:

util-linux  2.28.2

prefix:            /opt/util-linux/arm
exec prefix:       ${prefix}

localstatedir:     ${prefix}/var
bindir:            /opt/util-linux/arm/bin
sbindir:           /opt/util-linux/arm/sbin
libdir:            ${exec_prefix}/lib
includedir:        ${prefix}/include
usrbin_execdir:    ${exec_prefix}/bin
usrsbin_execdir:   ${exec_prefix}/sbin
usrlib_execdir:    ${exec_prefix}/lib

compiler:          arm-linux-gnueabi-gcc
cflags:            -static
suid cflags:       
ldflags:           -static
suid ldflags:      

Python:            /usr/bin/python
Python version:    2.7
Python libs:       ${exec_prefix}/lib/python2.7/site-packages

Bash completions:  /usr/share/bash-completion/completions
Systemd support:   no
Btrfs support:     yes

warnings:

然後我這樣做:

make fdisk

或者

make whereis

編譯完成後,我會:

file fdisk

軟碟是剛剛建立的文件並且:

fdisk: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=369363ef8f8173a3a1c2edc178eb77255a2dc415, not stripped

正如您所看到的,它說“動態連結”。我一直在互聯網上搜索,但未能找到答案。我也這樣做:

./configure --host=arm-linux LDFLAGS=-static --disable-shared --without-tinfo --without-ncurses --disable-ipv6 --disable-pylibmount --prefix=/opt/util-linux/arm --bindir=/opt/util-linux/arm/bin --sbindir=/opt/util-linux/arm/sbin

這與先前的設定指令完全相同,除了缺少「--enable-static-programs」參數,該參數預設「應該」將所有內容編譯為靜態,但事實並非如此。

我做錯了什麼還是這是一個 Makefile 錯誤?

答案1

我剛剛弄清楚為什麼我的問題中發布的原始命令沒有生成靜態文件!我必須跑使 LDFLAGS="--靜態」。在我這樣做之後,一切都靜態連結了!

再說一遍,我跑了:

export CC=arm-linux-gnueabi-gcc
export ac_cs_linux_vers=4
export CFLAGS=-static
export SUID_CFLAGS=-static
export SUID_LDFLAGS=-static
export CPPFLAGS=-static
export LDFLAGS=-static

然後

./configure --host=arm-linux-gnueabi --disable-shared --without-tinfo --without-ncurses --disable-ipv6 --disable-pylibmount --prefix=/opt/util-linux/arm --bindir=/opt/util-linux/arm/bin --sbindir=/opt/util-linux/arm/sbin

進而

make LDFLAGS="--static"

一切都是靜態連結的!正如我之前的回答所示,不再需要物件文件收集,但是,這也可以用作替代方案。

另外,為了供您參考,這是我的版本信息,你們中的一些人可能會關心:

$ arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ arm-linux-androideabi-ld --version
GNU gold (GNU Binutils 2.25.90.20151125) 1.11
Copyright (C) 2015 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

答案2

靜態二進位檔案是使用.static擴充功能建構的;構建後,我得到

$ file fdisk.static
fdisk.static: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=b51ec4b17f772b881d2a1eaefd368cfb96d0db12, not stripped

我只得到了這個

./configure --host=arm-linux-gnueabihf --enable-static-programs=fdisk

(您不應該需要任何FLAGS變數;在您的設定中替換gnueabihf為,我只是使用它,因為我已經有了有效的交叉編譯設定)。gnueabiarmhf

答案3

更新 - 請參閱下面我的其他答案

好的,經過幾個小時(字面意思)分析由util-linux 的配​​置腳本創建的Makefile 文件和另一個實用程式創建的另一個Makefile 文件(最終會生成靜態鏈接文件),我成功檢索了傳遞給的參數ARM-Linux-gnueabi-gcc產生靜態連結檔。所以我最終得到了這個:

arm-linux-gnueabi-gcc -ffloat-store -static -DHAVE_CONFIG_H -static  -D_U_="__attribute__((unused))" -o <name_of_your_file> <object files produced by the compiler separated by space>

所以編譯後哪裡:

make whereis

然後我搜尋了生成的所有目標檔案:

find . -name "*.o"

我最終得到:

./misc-utils/whereis.o
./lib/libcommon_la-blkdev.o
./lib/libcommon_la-sysfs.o
./lib/libcommon_la-idcache.o
./lib/libcommon_la-procutils.o
./lib/libcommon_la-mbsalign.o
./lib/libcommon_la-linux_version.o
./lib/libcommon_la-env.o
./lib/libcommon_la-pager.o
./lib/libcommon_la-strutils.o
./lib/libcommon_la-mangle.o
./lib/libcommon_la-timeutils.o
./lib/libcommon_la-fileutils.o
./lib/libcommon_la-exec_shell.o
./lib/libcommon_la-match.o
./lib/libcommon_la-crc32.o
./lib/libcommon_la-md5.o
./lib/libcommon_la-randutils.o
./lib/libcommon_la-ttyutils.o
./lib/libcommon_la-cpuset.o
./lib/libcommon_la-color-names.o
./lib/libcommon_la-ismounted.o
./lib/libcommon_la-path.o
./lib/libcommon_la-canonicalize.o
./lib/libcommon_la-loopdev.o
./lib/libcommon_la-setproctitle.o
./lib/libcommon_la-strv.o

然後我將所有這些物件檔案合併到一行中,然後執行另一個命令:

arm-linux-gnueabi-gcc -ffloat-store -static -DHAVE_CONFIG_H -static  -D_U_="__attribute__((unused))" -o mywhereis ./misc-utils/whereis.o ./lib/libcommon_la-blkdev.o ./lib/libcommon_la-sysfs.o ./lib/libcommon_la-idcache.o ./lib/libcommon_la-procutils.o ./lib/libcommon_la-mbsalign.o ./lib/libcommon_la-linux_version.o ./lib/libcommon_la-env.o ./lib/libcommon_la-pager.o ./lib/libcommon_la-strutils.o ./lib/libcommon_la-mangle.o ./lib/libcommon_la-timeutils.o ./lib/libcommon_la-fileutils.o ./lib/libcommon_la-exec_shell.o ./lib/libcommon_la-match.o ./lib/libcommon_la-crc32.o ./lib/libcommon_la-md5.o ./lib/libcommon_la-randutils.o ./lib/libcommon_la-ttyutils.o ./lib/libcommon_la-cpuset.o ./lib/libcommon_la-color-names.o ./lib/libcommon_la-ismounted.o ./lib/libcommon_la-path.o ./lib/libcommon_la-canonicalize.o ./lib/libcommon_la-loopdev.o ./lib/libcommon_la-setproctitle.o ./lib/libcommon_la-strv.o

瞧! :) mywhereis 已產生。

因此,我透過執行 file 命令來獲得榮譽:

mywhereis: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=a5b7c4ad147dc26ed211a7aa643f744a29e477f3, not stripped

多麼輕鬆啊!好吧,這個解決方案並不理想它完成了工作並且可以簡化!

我總共花了大約 8 個小時來研究這個問題並進行實驗,我意識到可能沒有“一勞永逸的解決方案”,但這確實可以完成這項工作!我在我的 Android 手機上測試了該文件,它有效!

此外,該解決方案似乎是“一勞永逸”,因為它只是連結目標檔案以建立靜態連結檔案。我使用完全不同的來源包中的另一個實用程式對此進行了測試,並且也有效。

答案4

我花了幾個小時試圖讓整套程式靜態鏈接,結果只有少數可以透過這種方式產生:

configure.h

  --enable-static-programs=LIST
                          link static the programs in LIST (comma-separated,
                          supported for losetup, mount, umount, fdisk, sfdisk,
                          blkid, nsenter, unshare)

我需要lsblk靜態鏈接,即使我將其添加到列表中也不起作用(其他人這樣做)。有沒有辦法取得該清單之外的其他靜態版本?

相關內容