C++ Cmake的构建静态库和动态库详解

C++ Cmake的构建静态库和动态库详解

什么是静态库和动态库

在C++编程中,常常需要使用一些共用的代码库,这些代码库可以被其他的程序或者模块共享使用。为了方便管理这些代码库,我们通常会将它们打包成静态库或者动态库。静态库是在编译时被链接到程序中,而动态库则是在运行时被链接到程序中。两者的主要区别在于,静态库会被完全复制到编译后的可执行文件中,而动态库则只会在程序启动时加载并链接。

Cmake构建静态库

在Cmake中,我们可以使用add_library命令来构建静态库。该命令的语法如下:

add_library(libname STATIC source1 source2 ...)

其中,libname是库的名称,source1source2等则是源文件的列表。下面是一个简单的示例:

├── CMakeLists.txt
└── srcs
    ├── func1.cpp
    ├── func2.cpp
    └── func3.cpp
# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

project(mylib)

add_library(mylib STATIC srcs/func1.cpp srcs/func2.cpp srcs/func3.cpp)

在编译时,我们可以使用以下指令:

mkdir build
cd build
cmake ..
make

编译完成后,会在build目录下生成一个名为libmylib.a的静态库。

Cmake构建动态库

与构建静态库类似,在Cmake中,我们可以使用add_library命令来构建动态库。不过要将STATIC关键字改为SHARED。下面是一个简单的示例:

├── CMakeLists.txt
└── srcs
    ├── func1.cpp
    ├── func2.cpp
    └── func3.cpp
# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

project(mylib)

add_library(mylib SHARED srcs/func1.cpp srcs/func2.cpp srcs/func3.cpp)

在编译时,我们可以使用以下指令:

mkdir build
cd build
cmake ..
make

编译完成后,会在build目录下生成一个名为libmylib.so的动态库。

示例1:静态库和动态库交叉编译

在开发中,有时我们需要将代码库在不同平台之间进行移植。这时候就需要进行交叉编译。下面是一个简单的示例。

假设我们需要将上述示例在arm64平台上进行编译。首先,我们需要安装aarch64-linux-gnu-g++编译器。我们可以使用以下指令进行安装:

sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu

然后,我们需要修改CMakeLists.txt文件,以支持交叉编译:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

project(mylib)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)

add_library(mylib STATIC srcs/func1.cpp srcs/func2.cpp srcs/func3.cpp)

接下来,我们需要创建一个编译目录,然后运行cmake命令来配置项目:

mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake ..

其中,toolchain.cmake是一个交叉编译的工具链文件,其内容如下:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)

最后,我们可以使用以下指令进行编译:

make

编译完成后,会在build目录下生成一个名为libmylib.a的静态库(或者名为libmylib.so的动态库,根据项目配置而定)。

示例2:为动态库定制名称和版本号

在实际开发中,我们常常需要为动态库定制名称和版本号。这可以通过SET_TARGET_PROPERTIES命令来实现。下面是一个简单的示例。

# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

project(mylib)

add_library(mylib SHARED srcs/func1.cpp srcs/func2.cpp srcs/func3.cpp)

# 指定库的名称和版本号
set_target_properties(mylib PROPERTIES
    VERSION 1.0.0
    SOVERSION 1
    OUTPUT_NAME "mylib-custom-name")

其中,VERSION用于指定库的版本号,SOVERSION用于指定API的版本号,OUTPUT_NAME用于指定库文件的名称。

在编译时,我们可以使用以下指令:

mkdir build
cd build
cmake ..
make

编译完成后,会在build目录下生成一个名为mylib-custom-name.so的动态库。

总结

本文介绍了如何使用Cmake构建静态库和动态库,并提供了两个示例。静态库适用于需要在编译时被链接到程序中的场景,动态库适用于需要在运行时被动态加载和链接的场景。在实际开发中,我们可以通过交叉编译和定制名称和版本号来实现库的移植和管理。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ Cmake的构建静态库和动态库详解 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 详解C++ 临时量与临时对象及程序的相关优化

    详解C++ 临时量与临时对象及程序的相关优化 什么是临时量和临时对象 在C++中,我们可以通过语句创建临时变量,这些临时变量被称为临时量(temporary),也称为临时表达式(temporary expression)。例如: int i = 2; int j = i + 3; 在第二个语句中,i + 3是一个临时量,它在完成表达式的计算后就会被销毁。 临…

    C 2023年5月22日
    00
  • 希望所有计算机学生能看到这篇c语言教程

    大部分程序员走入编程世界第一个学习的语言就是C语言。 作为一门古老的编程语言,c语言拥有48年的发展历程。 为什么要学习 C语言? C语言是学习计算机程序设计语言的入门语言。最全面的编程面试网站 C语言是一门偏底层的语言,学好它,可以让你更好的了解计算机。 学会了C语言,你就能学习现在任何的高级编程语言。因为所有的高级语言都是以C语言为基础的。 怎么学习c语…

    C 2023年4月30日
    00
  • C语言 strcspn()函数

    下面是关于C语言中strcspn()函数的完整使用攻略。 strcspn()函数介绍 strcspn()函数是一个C语言标准库函数,用于查找字符串中第一个不在另一个字符串中出现的字符的位置,并返回该位置。 函数原型如下: size_t strcspn(const char *str1, const char *str2); 它的第一个参数为要查找的字符串,第…

    C 2023年5月9日
    00
  • C Primer Plus (7.12) 編程練習

    /*C Primer Plus (7.11) 3*/ 1 #include<stdio.h> 2 int main() 3 { 4 double weight,height; 5 printf(“Please enter your weight and height.\n”); 6 printf(“Weight (pound):”); 7 sca…

    C语言 2023年4月18日
    00
  • 激战2 国服9月12日客户端官方更新文档

    激战2 国服9月12日客户端官方更新文档攻略 更新内容 新增“幻像术”职业技能,可使玩家在战斗中召唤幻像进行攻击或掩护。 强化“元素使”职业技能,增加多种元素精灵形态,提高技能伤害输出。 调整“狂战士”职业技能,降低技能冷却时间,增加爆发输出和生存能力。 优化游戏画面,支持更高分辨率和更流畅的帧率,提高游戏体验。 新增游戏活动“龙族秘宝”,可在游戏中搜寻龙族…

    C 2023年5月22日
    00
  • 解读C语言非void函数却没有return会怎么样

    解读C语言非void函数却没有return会怎么样: 当一个C语言函数声明为非void类型时,我们期望它返回一个值,但如果没有在函数内部使用return关键字,则可能会导致以下问题: 函数返回值不确定 在非void函数没有return语句时,函数返回值不确定,编译器会尝试返回一个随机值或者未初始化的值,这可能会导致程序运行时无法预期的行为。例如,在以下代码中…

    C 2023年5月23日
    00
  • c++ 实现文件逐行读取与字符匹配

    首先,需要明确我们要实现的功能是文件逐行读取,并且在每一行中与指定字符进行匹配。实现这个功能的一种主流方法是使用C++语言中的文件输入输出流以及字符串处理函数。 以下是C++进行文件逐行读取并匹配字符的代码示例: #include <iostream> #include <fstream> #include <string&gt…

    C 2023年5月22日
    00
  • Objective-C和Swift的转换速查手册(推荐)

    作为网站作者,我们提供了一份Objective-C和Swift的转换速查手册,可以帮助开发者快速了解两种语言之间的相互转换规则。以下是手册的完整攻略: 什么是Objective-C和Swift的转换速查手册? Objective-C和Swift是苹果公司官方推出的两种主要开发语言,然而两者之间的语法和语义存在一定的差异,导致不同版本之间的代码转换比较困难。为…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部