정적 링크 util-linux - 크로스 컴파일(대신 동적으로 링크된 파일 생성)

정적 링크 util-linux - 크로스 컴파일(대신 동적으로 링크된 파일 생성)

나는 arm용 util-linux를 크로스 컴파일하려고 시도했지만 계속 동적으로 링크된 실행 파일로 끝나는데 왜 그런지 모르겠습니다. 내 목표는 정적입니다. 나는 비슷한 단계를 사용하여 다른 도구를 사용하여 크로스 컴파일을 해왔고 항상 작동했기 때문에 이번에는 내가 뭘 잘못하고 있는지 알 수 없습니다. 우분투 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로 바꾸세요. 이미 작동 중인 크로스 컴파일 설정이 있었기 때문에 그냥 사용했습니다.)gnueabiarmhf

답변3

업데이트 - 아래의 다른 답변을 참조하세요

좋아, util-linux의 구성 스크립트로 생성된 Makefile 파일과 정적으로 링크된 파일로 끝나는 다른 유틸리티로 생성된 또 다른 Makefile 파일을 분석한 후(말 그대로) 몇 시간 동안 전달된 매개변수를 성공적으로 검색했습니다.arm-리눅스-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

그리고 짜잔! :) mywhere가 생성되었습니다.

그래서 나는 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목록에 추가해도 작동하지 않습니다(다른 사람들은 합니다). 해당 목록 외부의 다른 정적 버전을 얻을 수 있는 방법이 있습니까?

관련 정보