Vinculação estática util-linux - compilação cruzada (em vez disso, produz arquivos vinculados dinamicamente)

Vinculação estática util-linux - compilação cruzada (em vez disso, produz arquivos vinculados dinamicamente)

Tenho tentado fazer a compilação cruzada do util-linux para arm, mas continuo acabando com arquivos executáveis ​​vinculados dinamicamente e não sei por que isso acontece. Meu objetivo é estático. Tenho feito compilação cruzada antes de diferentes ferramentas usando etapas semelhantes e sempre funcionou, então não sei o que estou fazendo de errado desta vez. Estou usando o Ubuntu 16.04. Aqui estão os comandos que estou executando:

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

Como você pode ver, especifiquei static em todos os lugares em que consegui pensar em repetir coisas "só para ter certeza de que me entenderam" e depois de executar o script de configuração, aqui está a saída:

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:

Então eu faço:

make fdisk

ou

make whereis

e assim que a compilação estiver concluída, eu faço:

file fdisk

fdisksendo o arquivo que acabou de ser criado e:

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

Como você pode ver, diz "vinculado dinamicamente". Estive pesquisando por toda a Internet, mas não consegui encontrar uma resposta. Eu também faço:

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

Que é exatamente o mesmo comando de configuração anterior, exceto pelo parâmetro "--enable-static-programs" ausente, que "deveria" por padrão compilar tudo como estático, exceto que não o faz.

Estou fazendo algo errado ou isso é um erro do Makefile?

Responder1

Acabei de descobrir por que os comandos originais postados na minha pergunta não estavam produzindo arquivos estáticos! eu tive que corrermake LDFLAGS="--estático". Depois que fiz isso, tudo ficou vinculado estaticamente!

Para repetir, corri:

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

então

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

e então

make LDFLAGS="--static"

e tudo vinculado estaticamente! Não há mais necessidade de coleta de arquivos de objetos, conforme demonstrado na minha resposta anterior, mas sim, isso também pode ser usado como alternativa.

Também para sua informação, aqui estão as informações da minha versão, pois alguns de vocês provavelmente se importarão:

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

Responder2

Os binários estáticos são construídos com uma .staticextensão; depois da construção, eu recebo

$ 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

Eu consegui isso apenas com

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

(você não deve precisar de nenhuma FLAGSvariável; substitua gnueabihfpor gnueabina sua configuração, só usei isso porque já tinha uma armhfconfiguração de compilação cruzada funcional).

Responder3

Atualização - Veja minha outra resposta abaixo

Ok, depois de horas (literalmente) e horas analisando o arquivo Makefile criado pelo script configure do util-linux e outro arquivo Makefile criado por outro utilitário que acaba com arquivos vinculados estaticamente, recuperei com sucesso os parâmetros passados ​​​​paraarm-linux-gnueabi-gccque produzem arquivos vinculados estaticamente. Então acabei com isso:

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>

Então, depois de compilarOnde é:

make whereis

Em seguida, fiz uma pesquisa por todos os arquivos-objeto produzidos:

find . -name "*.o"

Acabei com:

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

Então consolidei todos esses arquivos objeto em uma linha e executei outro comando:

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

E pronto! :) mywhereis foi gerado.

Então fiz as honras executando o comando 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

Que alívio!! Ok, a solução não é idealmasele faz o trabalho e pode ser simplificado!

Passei cerca de 8 horas no total trabalhando nisso e experimentando e percebi que pode não haver "uma solução para todos", mas isso realmente funciona! Testei o arquivo no meu celular Android e funciona!!

Além disso, esta solução parece ser uma "solução única para todos", pois apenas vincula os arquivos de objeto para criar um arquivo vinculado estaticamente. Testei isso com outro utilitário de um pacote fonte completamente diferente e também funcionou.

Responder4

Passei horas tentando vincular estaticamente todo o conjunto de programas, mas apenas alguns podem ser produzidos dessa maneira:

De configure.h:

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

Preciso lsblkestar vinculado estaticamente e não funciona mesmo se eu adicioná-lo à lista (outros fazem). Existe uma maneira de obter outras versões estáticas fora dessa lista?

informação relacionada