1. 项目概述
在嵌入式开发和跨平台移植工作中,交叉编译是开发者必须掌握的核心技能。本文将详细介绍如何在Ubuntu系统下,使用龙芯(loongarch64)工具链完整编译libnetconf2静态库的全过程。libnetconf2是一个用于实现NETCONF协议的开源库,广泛应用于网络设备管理领域。
作为一名长期从事嵌入式开发的工程师,我深知交叉编译过程中依赖管理的复杂性。libnetconf2的编译尤其具有代表性,它需要处理多达7个相互依赖的第三方库,包括libyang、libssh、OpenSSL等。本文将不仅提供标准编译步骤,还会分享我在实际项目中积累的宝贵经验,帮助读者避开那些官方文档中不会提及的"坑"。
2. 环境准备与工具链配置
2.1 系统与工具要求
编译环境建议使用Ubuntu 20.04 LTS或更新版本,确保系统已安装以下基础工具:
- make (建议4.2.1及以上)
- cmake (建议3.16及以上)
- 龙芯交叉编译工具链(loongarch64-unknown-linux-gnu)
提示:可以通过
sudo apt install build-essential cmake一键安装基础编译工具。对于嵌入式开发,建议使用干净的Ubuntu环境,避免已有库文件造成干扰。
2.2 工具链路径设置
龙芯工具链通常安装在/opt目录下。为方便后续操作,我们先设置环境变量:
bash复制export TOOLCHAIN_BIN=/opt/loongson-gnu-toolchain-13.2/bin/loongarch64-unknown-linux-gnu
export DEPS_BASE=/root/workspace/lib_libary/dep_libs
建议将这些变量写入~/.bashrc文件,避免每次打开终端都需要重新设置。
2.3 源码下载与解压
libnetconf2及其依赖库的下载地址如下:
| 库名称 | 下载地址 | 示例版本 |
|---|---|---|
| OpenSSL | https://openssl-library.org/source/ | openssl-3.6.0 |
| zlib | https://zlib.net/fossils/ | zlib-1.3 |
| libssh | https://www.libssh.org/files/ | libssh-0.11.3 |
| pcre2 | https://github.com/PCRE2Project/pcre2 | pcre2-10.47 |
| libyang | https://github.com/CESNET/libyang | libyang-4.2.2 |
| curl | https://github.com/curl/curl | curl-8.18.0 |
| libnetconf2 | https://github.com/CESNET/libnetconf2 | libnetconf2-4.1.2 |
下载后使用以下命令解压:
bash复制tar -zxvf curl-8.18.0.tar.gz
tar -zxvf libnetconf2-4.1.2.tar.gz
tar -xvf libssh-0.11.3.tar.xz
tar -zxvf libyang-4.2.2.tar.gz
tar -zxvf openssl-3.6.0.tar.gz
tar -zxvf pcre2-10.47.tar.gz
tar -zxvf zlib-1.3.tar.gz
3. 依赖库编译详解
3.1 OpenSSL编译
OpenSSL是加密通信的基础库,编译时需要特别注意配置参数:
bash复制cd openssl-3.6.0
./Configure linux64-loongarch64 \
--cross-compile-prefix=${TOOLCHAIN_BIN}- \
--prefix=${DEPS_BASE}/openssl \
no-shared no-dso
make && make install
关键参数解析:
linux64-loongarch64:指定目标平台架构no-shared:只编译静态库no-dso:禁用动态加载模块
经验:OpenSSL 3.x版本对交叉编译支持更好,如果遇到问题可以尝试降级到1.1.1版本。
3.2 zlib编译
zlib是压缩库,使用cmake编译:
bash复制cd zlib-1.3
mkdir -p build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=${DEPS_BASE}/zlib \
-DCMAKE_C_COMPILER=${TOOLCHAIN_BIN}-gcc \
-DCMAKE_AR=${TOOLCHAIN_BIN}-ar \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_PROCESSOR=loongarch64
make && make install
3.3 libssh编译
libssh依赖OpenSSL和zlib,编译时需要正确指定路径:
bash复制cd libssh-0.11.3
mkdir -p build && cd build
cmake .. \
-DCMAKE_C_COMPILER=${TOOLCHAIN_BIN}-gcc \
-DCMAKE_INSTALL_PREFIX=${DEPS_BASE}/libssh \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DWITH_SERVER=ON \
-DOPENSSL_ROOT_DIR=${DEPS_BASE}/openssl \
-DZLIB_ROOT=${DEPS_BASE}/zlib
make && make install
3.4 pcre2编译
pcre2是正则表达式库,使用configure编译:
bash复制cd pcre2-10.47
./configure \
--host=loongarch64-unknown-linux-gnu \
--prefix=${DEPS_BASE}/pcre2 \
CC=${TOOLCHAIN_BIN}-gcc \
--disable-shared
make && make install
3.5 libyang编译
libyang是YANG数据建模语言库,依赖pcre2:
bash复制cd libyang-4.2.2
mkdir -p build && cd build
cmake .. \
-DCMAKE_C_COMPILER=${TOOLCHAIN_BIN}-gcc \
-DCMAKE_INSTALL_PREFIX=${DEPS_BASE}/libyang \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DPCRE2_INCLUDE_DIR=${DEPS_BASE}/pcre2/include \
-DPCRE2_LIBRARY=${DEPS_BASE}/pcre2/lib/libpcre2-8.a
make && make install
3.6 curl编译
curl是网络传输库,依赖OpenSSL和zlib:
bash复制cd curl-8.18.0
CPPFLAGS="-I${DEPS_BASE}/openssl/include -I${DEPS_BASE}/zlib/include" \
LDFLAGS="-L${DEPS_BASE}/openssl/lib -L${DEPS_BASE}/zlib/lib" \
CC=${TOOLCHAIN_BIN}-gcc \
./configure \
--host=loongarch64-unknown-linux-gnu \
--prefix=${DEPS_BASE}/curl \
--with-openssl \
--with-zlib \
--disable-shared
make && make install
4. libnetconf2编译与问题解决
4.1 基础编译
bash复制cd libnetconf2-4.1.2
mkdir -p build && cd build
cmake .. \
-DCMAKE_C_COMPILER=${TOOLCHAIN_BIN}-gcc \
-DCMAKE_INSTALL_PREFIX=${DEPS_BASE}/libnetconf2 \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_FIND_ROOT_PATH=${DEPS_BASE} \
-DCMAKE_C_FLAGS="-I${DEPS_BASE}/pcre2/include -I${DEPS_BASE}/zlib/include -I${DEPS_BASE}/openssl/include -I${DEPS_BASE}/libssh/include -I${DEPS_BASE}/curl/include -I${DEPS_BASE}/libyang/include" \
-DCMAKE_EXE_LINKER_FLAGS="-L${DEPS_BASE}/pcre2/lib -L${DEPS_BASE}/zlib/lib -L${DEPS_BASE}/openssl/lib -L${DEPS_BASE}/libssh/lib -L${DEPS_BASE}/curl/lib -L${DEPS_BASE}/libyang/lib -Wl,--start-group -lssh -lcurl -lssl -lcrypto -lyang -lpcre2-8 -lz -Wl,--end-group -ldl -lpthread -lm"
make && make install
4.2 常见问题解决
问题1:示例程序链接错误
解决方法:修改examples/CMakeLists.txt,显式指定链接库:
cmake复制add_executable(${app_name} ${app_name}.c)
target_link_libraries(${app_name} netconf2
${CURL_LIBRARY}
${LIBSSH_LIBRARY}
${OPENSSL_SSL_LIBRARY}
${OPENSSL_CRYPTO_LIBRARY}
${ZLIB_LIBRARY}
${LIBYANG_LIBRARY}
${PCRE2_LIBRARY}
dl pthread m)
问题2:CMake报错"REMOVE_ITEM requires two or more arguments"
解决方法:修改CMakeModules/UseCompat.cmake,增加空值判断:
cmake复制if(CMAKE_THREAD_LIBS_INIT AND CMAKE_REQUIRED_LIBRARIES)
list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
endif()
5. 验证与部署
编译完成后,关键文件位置:
- 静态库:
${DEPS_BASE}/libnetconf2/lib/libnetconf2.a - 示例程序:
./build/examples/下的client和server
可以使用file命令验证二进制文件架构:
bash复制file examples/client
# 应显示:ELF 64-bit LSB executable, LoongArch...
在实际项目中,我建议将编译好的库文件打包成tar.gz,方便在不同开发环境间迁移:
bash复制cd ${DEPS_BASE}
tar -czvf libnetconf2-loongarch64-static.tar.gz *
6. 经验总结
-
依赖顺序很重要:必须严格按照openssl→zlib→libssh→pcre2→libyang→curl→libnetconf2的顺序编译,因为后边的库依赖前边的库。
-
静态链接技巧:使用
-Wl,--start-group和-Wl,--end-group解决循环依赖问题,这是静态链接时的常见技巧。 -
版本兼容性:不同版本库之间可能存在兼容性问题,建议使用文中指定的版本组合,这是我经过多次测试验证的稳定组合。
-
调试建议:如果编译失败,先检查config.log或CMakeCache.txt文件,这些文件通常包含详细的错误信息。
-
交叉编译通用技巧:对于其他架构的交叉编译,只需替换工具链前缀和目标平台参数,整体流程是类似的。
