Linux 커널을 빌드할 때 대상 "scripts/extract-cert"를 생성하는 규칙이 없습니다 - Centos 7, devtoolset-9

Linux 커널을 빌드할 때 대상 "scripts/extract-cert"를 생성하는 규칙이 없습니다 - Centos 7, devtoolset-9

일부 패치 세트를 사용하여 Linux 커널을 컴파일하기 위해 빌드 환경을 디버깅하려고 합니다.

5.15.86 Linux 커널 브랜치에 대한 최소 gcc 버전 요구 사항을 충족하기 위해 CentOS 7 환경에 devtoolset-9를 설치했습니다. simple을 사용하여 커널을 컴파일할 때 make bzImage다음 오류가 발생합니다.

make[2]: *** No rule to make target `scripts/extract-cert', needed by `certs/x509_certificate_list'.  Stop.

그런 다음 스크립트에 CD를 넣고 실행하여 extract-cert를 만들려고 했지만 make extract-cert다음 오류가 발생했습니다.

    cc     extract-cert.c   -o extract-cert
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: /tmp/ccx32b6d.o: in function `display_openssl_errors':
extract-cert.c:(.text+0x3e): undefined reference to `ERR_peek_error'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x7f): undefined reference to `ERR_error_string'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0xc2): undefined reference to `ERR_get_error_line'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: /tmp/ccx32b6d.o: in function `drain_openssl_errors':
extract-cert.c:(.text+0xdd): undefined reference to `ERR_peek_error'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0xf6): undefined reference to `ERR_get_error_line'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: /tmp/ccx32b6d.o: in function `write_cert':
extract-cert.c:(.text+0x132): undefined reference to `BIO_new_file'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x186): undefined reference to `X509_get_subject_name'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x1a0): undefined reference to `X509_NAME_oneline'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x1b9): undefined reference to `i2d_X509_bio'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: /tmp/ccx32b6d.o: in function `main':
extract-cert.c:(.text+0x230): undefined reference to `OPENSSL_add_all_algorithms_noconf'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x235): undefined reference to `ERR_load_crypto_strings'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x23a): undefined reference to `ERR_clear_error'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x338): undefined reference to `ENGINE_load_builtin_engines'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x347): undefined reference to `ENGINE_by_id'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x386): undefined reference to `ENGINE_init'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x3e2): undefined reference to `ENGINE_ctrl_cmd_string'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x437): undefined reference to `ENGINE_ctrl_cmd'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x48a): undefined reference to `BIO_new_file'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x4df): undefined reference to `PEM_read_bio_X509'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x4fb): undefined reference to `ERR_peek_last_error'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x522): undefined reference to `ERR_clear_error'
/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: extract-cert.c:(.text+0x57a): undefined reference to `BIO_free'
collect2: error: ld returned 1 exit status
make: *** [extract-cert] Error 1

OpenSSL 소스 코드에서 검색했습니다.깃허브링커가 불평하는 기호를 찾으십시오. 따라서 이것은 OpenSSL 버그인 것 같습니다. OpenSSL을 설치했지만 devtoolset-9에서 어떻게 작동하는지 잘 모르겠습니다. OpenSSL 라이브러리를 찾기 위해 devtoolset-9에서 링커를 어떻게 얻나요? pkgconfig 파일은 올바른 것으로 보이며 라이브러리는 /usr/lib64/에 있습니다.

$>gcc --version
gcc (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2) Copyright (C) 2019 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.
openssl version
OpenSSL 1.0.2k-fips  26 Jan 2017

$>yum list installed | grep ssl
openssl.x86_64                          1:1.0.2k-26.el7_9        @updates
openssl-devel.x86_64                    1:1.0.2k-26.el7_9        @updates
openssl-libs.x86_64                     1:1.0.2k-26.el7_9        @updates

$>find . -name 'libssl*'
./usr/lib64/pkgconfig/libssl.pc
./usr/lib64/libssl.so.1.0.2k
./usr/lib64/libssl.so.10
./usr/lib64/libssl3.so
./usr/lib64/libssl.so

$>cat ./usr/lib64/pkgconfig/libssl.pc
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib64
includedir=${prefix}/include

Name: OpenSSL-libssl
Description: Secure Sockets Layer and cryptography libraries
Version: 1.0.2k
Requires: libcrypto
Libs: -L${libdir} -lssl
Libs.private: -ldl -lz -lgssapi_krb5 -lkrb5 -lcom_err -lk5crypto
Cflags: -I${includedir} -I/usr/include

$>cat ./usr/lib64/pkgconfig/libcrypto.pc
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib64
includedir=${prefix}/include
enginesdir=/usr/lib64/openssl/engines

Name: OpenSSL-libcrypto
Description: OpenSSL cryptography library
Version: 1.0.2k
Requires:
Libs: -L${libdir} -lcrypto
Libs.private: -ldl -lz
Cflags: -I${includedir}

@Ginnungagap:결과 echo | gcc -xc -E -v -는 다음과 같습니다.

$> echo | gcc -xc -E -v -
Using built-in specs.
COLLECT_GCC=gcc
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-9/root/usr --mandir=/opt/rh/devtoolset-9/root/usr/share/man --infodir=/opt/rh/devtoolset-9/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --with-default-libstdcxx-abi=gcc4-compatible --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-9.3.1-20200408/obj-x86_64-redhat-linux/isl-install --disable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=x86-64'
 /opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/cc1 -E -quiet -v - -mtune=generic -march=x86-64
ignoring nonexistent directory "/opt/rh/devtoolset-9/root/usr/lib/gcc/x86_64-redhat-linux/9/include-fixed"
ignoring nonexistent directory "/opt/rh/devtoolset-9/root/usr/lib/gcc/x86_64-redhat-linux/9/../../../../x86_64-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /opt/rh/devtoolset-9/root/usr/lib/gcc/x86_64-redhat-linux/9/include
 /usr/local/include
 /opt/rh/devtoolset-9/root/usr/include
 /usr/include
End of search list.
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "<stdin>"
COMPILER_PATH=/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/:/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/:/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/:/opt/rh/devtoolset-9/root/usr/lib/gcc/x86_64-redhat-linux/9/:/opt/rh/devtoolset-9/root/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/opt/rh/devtoolset-9/root/usr/lib/gcc/x86_64-redhat-linux/9/:/opt/rh/devtoolset-9/root/usr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/opt/rh/devtoolset-9/root/usr/lib/gcc/x86_64-redhat-linux/9/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=x86-64'

답변1

이 문제는 script/Makefile의 손상된 Makefile로 인해 발생합니다. 나는 이전 커널 버전에서 사용자 정의 패치를 선택했고 어느 시점에서 새로운 kbuild는 hostprogs를 축약했습니다.언제나-y가 도입되었습니다. 이전 패치를 선택하면 다시 hostprogs-y로 변경되었습니다. 이로 인해 script/*의 도우미가 kbuild에 의해 빌드되지 않습니다.

extract-cert에 대한 Makefile 항목의 예:

hostprogs-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING)   += extract-cert

종합해서 얻은 정보는여기.

Masahiro Yamada의 패치를 인용하면 다음과 같습니다.

호스트 프로그램을 빌드하려면 필요한 빌드 규칙을 사용하기 위해 "hostprogs"에 프로그램 이름을 추가해야 하지만 종속성이 없기 때문에 이것만으로는 빌드하기에 충분하지 않습니다.

호스트 프로그램에는 두 가지 유형이 있습니다. 서로에 대한 전제 조건으로 빌드되거나(예: lib/Makefile의 gen_crc32table) Kbuild가 Makefile에 액세스할 때 항상 빌드됩니다(예: script/genksyms/Makefile의 genksyms).

후자는 일반적으로 커널 빌드 중에 전역적으로 사용되는 호스트 프로그램을 포함하는 scripts/ 아래의 Makefile에 나타납니다. 이를 빌드하려면 "hostprogs" 및 "always-y"에 추가해야 합니다.

이 커밋은 단축형으로 hostprogs-always-y를 추가합니다.

답변2

커널 5.17에서는 extract-certs가 script/에서 certs/로 이동되었습니다.범죄

내 생각에는 make 타겟을 업데이트해야 한다고 생각합니다.

관련 정보