编译内核时提示<openssl/bio.h>
缺失,原因是编译的机器上没有安装libssl库。
网上查了一下基本都需要用apt之类的安装libssl,但是我是在公用的机器上编译的,并不太方便直接安装。
于是下载编译了openssl源码,然后尝试在编译内核时把头文件和编译好的库添加进去,但是依然会报错。
实际上,用到openssl的是scripts下的extract-cert.c, 这个文件是用本地的GCC编译的,并不是内核的一部分, 所以make时直接传递的CFLAGS等参数是不会作用到这个文件的编译的。
研究了一下暂时没找到怎么在编译内核时给这个文件指定CFLAGS。 所以直接修改了scripts下的Makefile。
1# SPDX-License-Identifier: GPL-2.0
2###
3# scripts contains sources for various helper programs used throughout
4# the kernel for the build process.
5
6# 修改的部分
7OPENSSL_INSTALL=<.....>/openssl-build/ # 编译好的openssl
8OPENSSL_LDFLAG=-L$(OPENSSL_INSTALL)lib # openssl的库文件
9OPENSSL_CFLAG=-I$(OPENSSL_INSTALL)include # openssl的头文件
10
11CRYPTO_LIBS = $(shell pkg-config --libs libcrypto 2> /dev/null || echo $(OPENSSL_LDFLAG) -lcrypto) # 把编译好的openssl库加进来
12CRYPTO_CFLAGS = $(OPENSSL_CFLAG) $(shell pkg-config --cflags libcrypto 2> /dev/null) # 添加openssl的头文件
13
14
15hostprogs-always-$(CONFIG_BUILD_BIN2C) += bin2c
16hostprogs-always-$(CONFIG_KALLSYMS) += kallsyms
17hostprogs-always-$(BUILD_C_RECORDMCOUNT) += recordmcount
18hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable
19hostprogs-always-$(CONFIG_ASN1) += asn1_compiler
20hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file
21hostprogs-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert
22hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
23hostprogs-always-$(CONFIG_SYSTEM_REVOCATION_LIST) += extract-cert
24
25HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include
26HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
27HOSTCFLAGS_sign-file.o = $(CRYPTO_CFLAGS)
28HOSTLDLIBS_sign-file = $(CRYPTO_LIBS)
29HOSTCFLAGS_extract-cert.o = $(CRYPTO_CFLAGS)
30HOSTLDLIBS_extract-cert = $(CRYPTO_LIBS)
31
32ifdef CONFIG_UNWINDER_ORC
33ifeq ($(ARCH),x86_64)
34ARCH := x86
35endif
36HOSTCFLAGS_sorttable.o += -I$(srctree)/tools/arch/x86/include
37HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED
38HOSTLDLIBS_sorttable = -lpthread
39endif
40
41# The following programs are only built on demand
42hostprogs += unifdef
43
44# The module linker script is preprocessed on demand
45targets += module.lds
46
47subdir-$(CONFIG_GCC_PLUGINS) += gcc-plugins
48subdir-$(CONFIG_MODVERSIONS) += genksyms
49subdir-$(CONFIG_SECURITY_SELINUX) += selinux
50
51# Let clean descend into subdirs
52subdir- += basic dtc gdb kconfig mod
之后正常执行内核编译步骤即可。
附openssl编译步骤:
1# 下载openssl源码
2
3./config --prefix=<.....>/openssl-build/ # 指定安装位置
4make CC=x86_64-conda-linux-gnu-gcc -j # 编译,公用的机器gcc版本太低,所以使用的是conda安装的gcc
5make install # 编译安装
补充
以上编译的是5.9的内核。其他版本的Makefile会有区别,不过方法是一样的。
如果是新的内核,还需要涉及到其他地方。原来的scripts/Makefile里仍然需要修改,只是要编译的文件变成了sign-file
。
1HOSTCFLAGS_sign-file.o = $(OPENSSL_CFLAG) # $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null)
2HOSTLDLIBS_sign-file = $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo $(OPENSSL_LDFLAG) -lcrypto)
而extract-cert.c在/certs里,这个目录里的Makefile也需要修改。
1HOSTCFLAGS_extract-cert.o := $(OPENSSL_CFLAG) # $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null)
2HOSTLDLIBS_extract-cert := -L$(OPENSSL_INSTALL)lib -lcrypto # $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo $(OPENSSL_LDFLAG) -lcrypto)
但是make时还会报错,
1certs/extract-cert: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory
因为是用非系统库目录下的.so库文件编译的,所以编译好的extract-cert运行时还是会找不到动态链接库libcrypto.so。找到certs/Makefile
里的cmd_extract_certs
,
用环境变量LD_LIBRARY_PATH
来给它添加运行时的用到的动态链接库。
1EXPORT_LD_LIBRARY_PATH=env "LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):$(OPENSSL_INSTALL)lib"
2
3quiet_cmd_extract_certs = CERT $@
4 cmd_extract_certs =$(EXPORT_LD_LIBRARY_PATH) $(obj)/extract-cert "$(extract-cert-in)" $@
5extract-cert-in = $(filter-out $(obj)/extract-cert, $(real-prereqs))
这样应该能正常编译整个内核了。
总结
主要是问题来自内核编译之前需要先编译scripts/
里的一些工具,它们和内核本身是没有关系的。本来编译它们时额外指定头文件和库很简单,只是在Linux本来就很复杂的Makefile工程里解决起来比较麻烦。