Статическая компоновка util-linux - кросс-компиляция (вместо этого создает динамически связанные файлы)

Статическая компоновка util-linux - кросс-компиляция (вместо этого создает динамически связанные файлы)

Я пытался сделать кросс-компиляцию util-linux для arm, но я все время получаю динамически связанные исполняемые файлы, и я не знаю, почему это так. Моя цель — статика. Я делал кросс-компиляцию до этого разными инструментами, используя похожие шаги, и это всегда работало, так что я не знаю, что я делаю не так в этот раз. Я использую 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

Как видите, я указал static везде, где только мог, даже повторяя что-то «просто чтобы убедиться, что он меня понимает», и после запуска скрипта конфигурации вот что получилось:

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будучи только что созданным файлом и:

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="--static". После того, как я это сделал, все связалось статически!

Повторяю, я запустил:

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на gnueabiв вашей настройке, я просто использовал это, потому что у меня уже была рабочая armhfнастройка кросс-компиляции).

решение3

Обновление — см. мой другой ответ ниже

Итак, после нескольких часов (буквально) и часов анализа файла Makefile, созданного скриптом конфигурации util-linux, и другого файла 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статически слинковать, и это не работает, даже если я добавляю это в список (другие добавляют). Есть ли способ получить другие статические версии вне этого списка?

Связанный контент