文章目录
- 源代码
- curl
- 开发环境
- 下载地址
- 制定理想的库
- 初级
- 进阶
- 如何知道选项名称
- 交叉编译
- 交叉编译工具链
- 配置编译环境
- 设置目标架构库和头文件路径
- 编译代码
源代码
我们在日常中会接触到比较多第三方库,比如
- 网络库相关:
libevent、mongoose、curl - 图形界面:
lvgl、png - 日志库:
log4cpp
每个成熟的第三方库,无论是从github上拉下来的,还是其他途径获取到的,都会带有readme和doc,建议大家学习使用他们的时候,尽量从自带的文档中学习。如果还有不明白的,可以找AI询问,但不要太相信,有些AI还没来得及更新到最新的第三方库,比如在lvgl的时候,就踩过很多坑
根据项目的情况,我们会选择将其编译成一个静态库或者一个动态库,这个库我们有时候可能会放到另一种系统种使用,那么就需要进行交叉编译。
curl
我们以curl8.8.0为例去进行讲解
libcurl 是一个免费的、易用的客户端 URL 传输库,支持多种协议,包括 HTTP、HTTPS、FTP、FTPS、SFTP、SCP、DICT、TELNET、TFTP、LDAP、LDAPS、FILE、IMAP、IMAPS、POP3、POP3S、SMTP、SMTPS、RTSP 等。
开发环境
本机系统: windows 11
开发环境:vscode + wsl + ubuntu22.04
如何在windows 上搭建 wsl+ubuntu,请移步wsl的介绍和搭建
下载地址
https://github.com/curl/curl
制定理想的库
从拉下的代码中,我们能看到curl提供了CMakeLists.txt 和 configure 脚本两种构建和配置软件项目的自动化工具,由于接下来我们还需要进行交叉编译,因此我们选择使用CMakeLists.txt去构建和配置。
curl 库依赖于ssl库,故需要提前编译好对应的ssl库,可手动编译,而后把对应位置添加上,也可直接sudo apt install openssl,这里就不详细介绍了
初级
在cmakeLists.txt 同级目录中做以下操作
mkdir build
cd build
cmake ..
make
make install
大功告成,直接就在build下生成了包含curl支持的所有协议的动态库。还有所要用到的头文件。基本上开源的代码打包成库都能这么操作。
至于为什么是动态库,因为curl默认编译的就是动态库,要改为静态库也很简单,打开CMakeLists,看到如下选项没有,BUILD_STATIC_LIBS 即表示静态库,把他的OFF改为ON即可。BUILD_SHARED_LIBS是动态库,不需要的时候改为OFF就行
好了,这是最简单的方式,适合用于啥需求都没有,只需要一个动态库和静态库的。但在项目开发中,我们是不建议这种操作的
进阶
我们需要一个curl的共享库,但是项目目前不需要用到IMAP、MQTT、POP3、FILF这些协议,那应该怎么处理。按照上面的方式,在CmakeLists上直接修改? 这样会不利于后期的维护。
- 在CMakeLists.txt中建立两个文件 x64.cmake 和 x64_build.sh
- x64.cmake
set(CMAKE_SYSTEM_NAME Linux)set(BUILD_SHARED_LIBS OFF)
set(BUILD_STATIC_LIBS ON)
set(BUILD_CURL_EXE OFF)
set(CURL_ENABLE_EXPORT_TARGET OFF)# 将不需要的用到的协议 disable 打开
set(CURL_DISABLE_IMAP ON)
set(CURL_DISABLE_FILE ON)
set(CURL_DISABLE_MQTT ON)
set(CURL_DISABLE_POP3 ON)# 如果是自己编译的ssl库,则需要将库和头文件的名称添加
set(OPENSSL_CRYPTO_LIBRARY /mnt/f/***/libcrypto.a)
set(OPENSSL_SSL_LIBRARY /mnt/f/***/libssl.a)
set(OPENSSL_INCLUDE_DIR /mnt/f/***/inc/)set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
- x64_build.sh
#!/usr/bin/env bash
if [ -d ./build ]; then rm -rf ./build/; fi
mkdir -p "./build"
cd "./build"
cmake -DCMAKE_TOOLCHAIN_FILE=../x64.cmake -DCMAKE_INSTALL_PREFIX=../bin/x64 ..
make
make install
DCMAKE_INSTALL_PREFIX 指定了install的路径
这样在编译的时候直接执行./x64_build.sh,就可以得到想要的库和头文件了
如何知道选项名称
以上,像我们使用的BUILD_SHARED_LIBS ,CURL_DISABLE_MQTT ,我们怎么知道是通过这些去配置呢
一般有如下两种方式:
- 使用命令行查看,可能不全
mkdir build && cd build
cmake .. -LH
- 直接在Cmakelists.txt上查看
- 欢迎大家指教,也许有更好的方式我没发现
交叉编译
交叉编译:用于在一种架构的平台上生成用于另一种架构的可执行文件。以下是通用的交叉编译步骤。
交叉编译工具链
首先需要安装交叉编译工具链,或厂商提供对应的编译工具链。工具链包含编译器(如 gcc 或 g++)、链接器、库等,专门针对目标架构。常见的工具链有:
在 Ubuntu 上可以用以下命令安装 ARM 工具链:
sudo apt update
sudo apt install gcc-arm-linux-gnueabi
配置编译环境
使用CMake 创建一个工具链文件(toolchain.cmake) 来定义目标平台
# toolchain.cmake
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR arm)SET(CMAKE_C_COMPILER arm-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++)# 其他配置选项
然后在编译时指定工具链文件:
cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake ..
make
设置目标架构库和头文件路径
在编译过程中,链接器需要知道目标架构的库路径。可以通过以下方式设置:
export SYSROOT=/path/to/target/rootfs
export CFLAGS="--sysroot=$SYSROOT"
export LDFLAGS="--sysroot=$SYSROOT"
或者在 CMake 中指定库文件路径和头文件路径。
编译代码
在完成环境配置后,直接使用 cmake 来编译代码。编译出的二进制文件会适用于目标平台。