Linux gcc compile/link issuses.

本文介绍如何通过向链接器传递特定选项来创建一个没有未解析符号的共享库。主要讨论了使用-Wl,-z,defs选项的方法。

Create a shared library without any unresolved symbol

You can pass options to the linker like this: -Wl,options. So what we can do here is -Wl,-z,defs.

你遇到的链接错误如下: ```bash /opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/10.3.1/../../../../aarch64-none-linux-gnu/bin/ld: cannot find -lssl /opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/10.3.1/../../../../aarch64-none-linux-gnu/bin/ld: skipping incompatible /home/thn/at606_v1r3_server/verify_area_key/lib/libcrypto.a when searching for -lcrypto /opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/10.3.1/../../../../aarch64-none-linux-gnu/bin/ld: cannot find -lcrypto collect2: error: ld returned 1 exit status make: *** [Makefile:35: app] Error 1 ``` --- ## ✅ 错误分析与解决方案 ### ❌ 错误 1:`cannot find -lssl` > **原因**:系统找不到 `libssl.so` 或 `libssl.a`(OpenSSL 的 SSL 库) ⚠️ 注意:你只提供了 `-L/home/thn/.../lib` 给 `libcrypto.a`,但没有为 `libssl` 指定路径。 即使你在本地有 `libcrypto.a`,你也需要对应的 **`libssl.a`**(或 `.so`)文件,并且它必须是 **aarch64 架构编译的版本**。 --- ### ❌ 错误 2:`skipping incompatible ... libcrypto.a` > 🔴 关键信息:**incompatible** 这说明: - 你的 `libcrypto.a` 是用 **x86_64 主机编译的**(PC 上 GCC 编译) - 而你现在使用的是 **交叉编译器 aarch64-none-linux-gnu-gcc** - 所以这个静态库是 x86_64 架构的,不能用于 aarch64 目标平台! 👉 即使文件名一样,架构不匹配也无法链接。 --- ## ✅ 解决方案 ### ✅ 步骤 1:确认你需要什么类型的 OpenSSL 库 你要构建一个运行在 **ARM64 (aarch64)** 设备上的程序 → 必须使用 **aarch64 版本的 libssl.a 和 libcrypto.a** 所以你不能使用 PC 上通过 `apt install libssl-dev` 安装的库(那是 x86_64 的)! --- ### ✅ 步骤 2:获取 aarch64 兼容的 OpenSSL 静态库 #### 方式一:自己交叉编译 OpenSSL(推荐) 从源码编译适用于 aarch64 的 OpenSSL: ```bash # 下载 OpenSSL 源码(例如 1.1.1w) wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz tar -xzf openssl-1.1.1w.tar.gz cd openssl-1.1.1w ``` 配置并交叉编译: ```bash ./Configure linux-aarch64 \ --prefix=/home/thn/openssl-aarch64 \ --openssldir=/home/thn/openssl-aarch64 \ shared \ no-async \ -fPIC \ -m64 # 设置交叉编译工具链 export CROSS_COMPILE=aarch64-none-linux-gnu- export CC=${CROSS_COMPILE}gcc export AR=${CROSS_COMPILE}ar export RANLIB=${CROSS_COMPILE}ranlib # 清除默认检测的主机参数 make clean ./Configure linux-aarch64 \ --prefix=/home/thn/openssl-aarch64 \ --cross-compile-prefix=${CROSS_COMPILE} \ --openssldir=/home/thn/openssl-aarch64 \ no-shared \ no-async \ -fPIC ``` 编译并安装: ```bash make -j$(nproc) make install ``` 输出目录 `/home/thn/openssl-aarch64/lib/` 中会有: - `libssl.a` - `libcrypto.a` ✅ 这两个才是你可以使用的 aarch64 静态库! --- ### ✅ 步骤 3:修改 Makefile,正确指向 aarch64 库路径 假设你把编译好的 aarch64 OpenSSL 放在: ``` /home/thn/openssl-aarch64/lib/ ``` 那么修改你的 Makefile: ```makefile # 添加 OpenSSL 库搜索路径 LDFLAGS += -L/home/thn/openssl-aarch64/lib LDFLAGS += -Wl,--whole-archive LDFLAGS += -lssl -lcrypto LDFLAGS += -Wl,--no-whole-archive LDFLAGS += -lpthread -lm -lrt ``` 或者完整命令行改为: ```makefile $(CC) $(OBJECTS) \ -o app \ -L/home/thn/openssl-aarch64/lib \ -lssl -lcrypto \ -ljansson -lpthread -lm -lrt \ -Wl,--whole-archive \ -Wl,--no-whole-archive ``` --- ### ✅ 步骤 4:验证静态库是否为 aarch64 架构 使用 `file` 和 `aarch64-none-linux-gnu-readelf` 检查: ```bash file /home/thn/openssl-aarch64/lib/libcrypto.a # 输出应包含: ARM aarch64 aarch64-none-linux-gnu-readelf -h /home/thn/openssl-aarch64/lib/libcrypto.a | grep Class # 应输出: Class: ELF64 # Machine: AArch64 ``` 如果你对原来的 `libcrypto.a` 运行: ```bash file /home/thn/at606_v1r3_server/verify_area_key/lib/libcrypto.a ``` 你会看到它是 `x86-64` 架构 → ❌ 不兼容! --- ### ✅ 步骤 5:(可选)静态链接所有内容(避免动态依赖) 为了确保完全静态链接(推荐嵌入式开发): ```makefile LDFLAGS = -static -L/home/thn/openssl-aarch64/lib -lssl -lcrypto ... ``` 注意: - 如果 `libssl.a` 依赖其他库(如 zlib),也需要提供 aarch64 版本。 - 可加 `-lz` 并提供 `libz.a`。 --- ## ✅ 总结:你现在要做的事 | 步骤 | 操作 | |------|------| | 1 | 删除错误的 x86_64 `libcrypto.a` | | 2 | 下载 OpenSSL 源码(1.1.1 或 3.0.x) | | 3 | 使用 `aarch64-none-linux-gnu-gcc` 交叉编译 OpenSSL 静态库 | | 4 | 将生成的 `libssl.a` 和 `libcrypto.a` 放入指定目录 | | 5 | 修改 Makefile 中的 `-L` 路径指向新库目录 | | 6 | 确保头文件路径也正确:`-I/home/thn/openssl-aarch64/include` | --- ## ✅ 推荐 Makefile 片段 ```makefile # 工具链 CC = aarch64-none-linux-gnu-gcc AR = aarch64-none-linux-gnu-ar # OpenSSL 路径(你自己编译输出的位置) OPENSSL_DIR = /home/thn/openssl-aarch64 CFLAGS += -I$(OPENSSL_DIR)/include LDFLAGS += -L$(OPENSSL_DIR)/lib # 对象文件 OBJECTS = cJSON_Parse.o cJSON.o link.o main.o mongoose.o ... # 链接目标 app: $(OBJECTS) $(CC) $^ $(LDFLAGS) -lssl -lcrypto -ljansson -lpthread -lm -lrt -o $@ ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值