源代码定制编译:构建理想的库 以curl为例

server/2024/12/2 3:35:19/

文章目录

  • 源代码
  • 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++)、链接器、库等,专门针对目标架构。常见的工具链有:

  • ARM 架构:arm-none-eabi-gcc、aarch64-linux-gnu-gcc 等。
  • MIPS 架构:mipsel-linux-gnu-gcc。

在 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 来编译代码。编译出的二进制文件会适用于目标平台。


http://www.ppmy.cn/server/146608.html

相关文章

Oracle 19c RAC单节点停机维护硬件

背景 RAC 环境下一台主机硬件光纤卡不定时重启,造成链路会间断几秒,期间数据库会话响应时间随之变长,该光纤卡在硬件厂商的建议下,决定停机更换备件,为保证生产影响最小,决定停掉该节点,另外节…

CSS定位

定位 其中,绝对定位和固定定位会脱离文档流 设置定位之后:可以使用四个方向值进行调整位置:left、top、right、bottom 相对定位 温馨提示 设置定位之后,相对定位和绝对定位他是相对于具有定位的父级元素进行位置调整&#xff0c…

设置Mysql5.6允许外网访问

设置mysql用户支持外网访问步骤: 需要使用root权限登录mysql,更新mysql.user表,设置指定用户的Host字段为%,默认一般为127.0.0.1或者localhost。 1.登录数据库 1 mysql -u root -p 输入密码 1 mysql> use mysql; 2.查询hos…

python股票数据分析(Pandas)练习

需求: 使用pandas读取一个CSV文件,文件内容包括股票名称、价格和交易量。完成以下任务: 找出价格最高的股票; 计算总交易量; 绘制价格折线图。 代码实现: import pandas as pd import matplotlib.pyplot …

docker从入门到入土

卸载旧版本 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ …

mind+自定义库编写注意事项

在mind图形化命令编写中,main.ts 文件是通过图形化编程工具生成 C 代码,然后将生成的 C 代码上传到 Arduino Uno 上执行。 这些由main.ts定义的图形化代码通过生成的代码,需要包含调用arduinoc/libraries文件夹的*.h和*.cpp文件&#…

STM32 使用ARM Compiler V6 编译裸机 LWIP协议栈报错的解决方法

在lwip 的cc.h 中使用以下宏定义,来兼容 V5 和 V6编译器 #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION > 6010050) /* ARM Compiler V6 */ #define __CC_ARM /* when use v6 compiler define this */ #endifV6编译的速度确实比V5块了好多倍。 …

unity工程转为安卓使用的aar文件

1.unity导出时选择安卓平台,导出的最终工程如下: 2.将该工程导入AndroidStudio里,File->new->import project, 选择上一步导出的文件夹。导入完成如下: 3.导入进来之后,手动在下方文件夹添加string文件&#xff…