cmake 学习使用笔记(二)库的生成与使用

2023-05-16

        学习使用cmake 生成及使用库,使用cmake 生成 .lib 静态库 及动态库(.dll)。及linux 下使用的静态库 .a 和 动态库(.so, 也称为共享库)

目录

使用工具

生成库(导入库)

 add_library()

生成静态库(Windows)

使用 vs 2019 生成静态库

 使用Clion 生成静态库(windows .lib)

使用静态库(Windows) 

方式一:使用  link_libraries()

 使用 target_link_libraries()

使用全路径

使用  link_directories + target_link_libraries

 引入头文件(include_directories)不与不引入头文件

error LNK2019:

静态库(.a) 的使用

仅不同是使用 link_directories + target_link_libraries

动态链接库 

使用mingw与cmake 生成 .dll

生成共享库

共享库的使用

aux_source_directory 的使用

aux_source_directory  引用文件

aux_source_directory 生成库


使用工具

        开发工具:clion、cmake

        平台: win

生成库(导入库)

add_library 除了生成导入库,还可生成对象库,接口库等

使用 cmake  CMakeList.txt

项目结构:

声明库函数 .h

#pragma once

double mySqrt(double x);

定义库函数 .cpp 

#include "myMathSquare.h"


double mySqrt(double x)
{
	return (x * x);
}

 CMakeLists.txt

# CMakeList.txt: MyLibraryTest 的 CMake 项目,在此处包括源代码并定义
# 项目特定的逻辑。
#
#注意:cmake的语法支持大小、小写和大小写混合上边的代码中我们使用的cmake语法是小写的.
cmake_minimum_required (VERSION 3.8)
project ("MyLibraryTest")
# 设置系统自带变量
set(cmake_cxx_standard 11)

set(myHeadPath "${CMAKE_CURRENT_SOURCE_DIR}/header") 
include_directories(${myHeadPath})

add_library(MyMathFunctions STATIC ./source/myMathSquare.cpp)

# TODO: 如有需要,请添加测试并安装目标。

 add_library()

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [source1] [source2] [...])
添加名为<name>的库,库的源文件可指定,也可用target_sources()后续指定

<name>属性必须全局唯一
生成的library名会根据STATICSHARED及 生成平台 成为name.a/name.lib 或 name.so/.dll

windows下,如果dll没有export任何信息,则不能使用SHARED,要标识为MODULE

MODULE:  在使用 dyId 的系统有效,如果不支持dyid, 则被当做shared对待

EXCLUDE_FROM_ALL: 这个库不会被默认构建,除非有其他的组件或者手工构建


生成静态库(Windows)

使用 vs 2019 生成静态库

        开始尝试使用 vs 2019 建立的 cmake 项目生成 静态库。一直未找到生成入口。(生成windows 静态库仅仅只是想尝试使用 cmake生成 .lib 静态库, 更简单的方式是 vs .sln 解决方案中直接设置,或直接新建 生成静态库解决方案)。

        偶然终于找到怎么生成 使用 cmake 生成解决方案。然运行解决方案生成 库。

项目右键 打开终端

 使用 cmake 生成解决方案

j命令:  cmake .

 结果:

 

 打开解决方案:

 生成:

如果用此种方式生成动态库 貌似 只生成dll,不生成调用 dll 所需的静态库

修改:add_library(MyMathFunctions SHARED ./source/myMathSquare.cpp) 

其他步骤一致

 使用Clion 生成静态库(windows .lib)

打开项目文件夹

 设置 Clion 中的 visual studio  环境

打开设置:

 新增工具链

 

 改为 64 位

 新增cmake 环境

 选择debug 或者 release

 查看文件夹下 是否出现 visual studio 相应的文件夹

 如果没有  打开 cmake   reset 或 刷新

 选择相应环境 构建

 

 生成结果

使用静态库(Windows) 

新建一个调用文件 xxx.cpp 

#include <iostream>

using namespace std;
extern double mySqrt(double x);
extern void hello();
void customLibTest() {
	double x = 8;
	double res = mySqrt(x);
	cout << "输入x: " << x << "的平方是" << res << endl;
}
int main()
{
#ifdef MyDebug
    cout << "获取版本:" << cPlusPlusTest_version_major << endl;
#else
    cout << "获取版本: " << cPlusPlusTest_version_minor << endl;
#endif // DEBUG
    customLibTest();
    hello();
    return 0;
}

方式一:使用  link_libraries()


link_libraries(${PROJECT_SOURCE_DIR}/3dPart/lib/MyMathFunctions.lib) 
#使用link_libraries链接MyMathFunctions.lib  

 运行结果:

 使用 target_link_libraries()

 target_link_libraries:指定目标链接的库


target_link_directories: 指定目标包含的头文件路径  

target_compile_options:指定目标编译选项  
target_link_libraries(<target> 
                      <PRIVATE|PUBLIC|INTERFACE> <item>... 
                      [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)

 可以链接多个库: 例如:


target_link_libraries(cPlusPlusTestProject ${PROJECT_SOURCE_DIR}/3dPart/lib/MyMathFunctions.lib ${PROJECT_SOURCE_DIR}/3dPart/lib/LibTest.lib)  
target_link_libraries(target target1 target2)
target_link_libraries(target3 target target4)

 PUBLI:表示target能够使用target1&target2库中的内容,target3 能够使用target1 & target2中定义的内容;默认状态为PUBLIC;
PRIVATE:表示target能够使用target1&target2库中的内容,target3不能使用target1&target2中定义的内容,只能使用target中定义的内容;
INTERFACE:表示target无法使用target1&target2的内容,但是target3 能够使用target1 & target2;

使用全路径


target_link_libraries(cPlusPlusTestProject ${PROJECT_SOURCE_DIR}/3dPart/lib/MyMathFunctions.lib)  

使用  link_directories + target_link_libraries

link_directories(../3dPart/lib)
target_link_libraries(cPlusPlusTestProject MyMathFunctions)#直接写库的名称

结果:

 

 引入头文件(include_directories)不与不引入头文件

使用 extern 上述代码不引入头文件  使用 extern 声明

引入头文件:

#include <iostream>
#include "myMathSquare.h"
using namespace std;

extern void hello();
void customLibTest() {
	double x = 8;
	double res = mySqrt(x);
	cout << "输入x: " << x << "的平方是" << res << endl;
}
int main()
{
#ifdef MyDebug
    cout << "获取版本:" << cPlusPlusTest_version_major << endl;
#else
    cout << "获取版本: " << cPlusPlusTest_version_minor << endl;
#endif // DEBUG
    customLibTest();
    hello();
    return 0;
}

 例如:

error LNK2019:

无法解析的外部符号 &quot;double __cdecl mySqrt(double)&quot; 

遇到的坑,把 .a 当成 .lib 用了 

静态库(.a) 的使用

.a 库的使用与 .lib 相差无几。

使用全路径是与 lib 相同(使用库的全名):例如:


target_link_libraries(cPlusPlusTestProject ${PROJECT_SOURCE_DIR}/3dPart/lib/libMyMathFunctions.a)  

仅不同是使用 link_directories + target_link_libraries

需要注意的是,生成的.a  有前缀 lib. 例如: libxxxx.a, 去掉前缀使用 例如:


link_directories(${PROJECT_SOURCE_DIR}/3dPart/lib)  

target_link_libraries(cPlusPlusTestProject MyMathFunctions)  

动态链接库 

使用mingw与cmake 生成 .dll

      使用 mingw 与 cmake 生成的是 xxx.dll 与 xxx.dll.a

       修改生成库类型:


add_library(MyMathFunctions SHARED ./source/myMathSquare.cpp)  

选择配置好的 winGW 环境

 生成  动态库 .dll 及静态库  .dll.a

生成共享库

 Linux 动态链接库,共享库只生成 .so

共享库的使用

将共享库复制第第三方库中,同时复制头文件:如

 sharedLibTest.h

//
// Created by ly on 2022/7/21.
//

#ifndef SHAREDLIBTEST_SHAREDLIBTEST_H
#define SHAREDLIBTEST_SHAREDLIBTEST_H
void test();
#endif //SHAREDLIBTEST_SHAREDLIBTEST_H

sharedLibTest.cpp

//
// Created by ly on 2022/7/21.
//
#include <iostream>
#include "sharedLibTest.h"
#include "myMathSquare.h"

void test(){
    double x = 8;
    double d = mySqrt(x);
    std::cout << "x 的平方是: " << d << std::endl;

}

 main.cpp

#include <iostream>
#include "sharedLibTest.h"

int main() {
    std::cout << "Hello, World!" << std::endl;
    test();
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.17)
project(sharedLibTest)

set(CMAKE_CXX_STANDARD 11)

include_directories(${PROJECT_SOURCE_DIR}/3dPart/include)
include_directories(${PROJECT_SOURCE_DIR}/header)
#link_directories(3dPart/lib)
link_directories(${PROJECT_SOURCE_DIR}/3dPart/lib)

add_executable(sharedLibTest
        header/sharedLibTest.h
        source/sharedLibTest.cpp
        main.cpp)
target_link_libraries(sharedLibTest libMyMathFunctions.so)

 方式1:target_link_libraries(testAuxSource MyMathFunctions) 


方式2:target_link_libraries(testAuxSource libMyMathFunctions.so)  

#target_link_libraries(testAuxSource MyMathFunctions)# 共享库可以调用全名,也可以调用项目名称  

 运行结果:

aux_source_directory 的使用

在目录中查找所有源文件。

收集指定目录中所有源文件的名称,并将列表存储在提供的变量中。即将某目录下的所有的源码文件设定一个变量名称,便于后期使用变量名代替所有的源码文件,比如与add_library生成静态库一并使用,以便指定子构建系统的构建的库类型和名称

aux_source_directory  引用文件

例如:一个文件夹包含所有头文件,源文件。


aux_source_directory(. DIR_SR)  

add_executable(testAuxSource ${DIR_SR})  

文件目录

 

当头文件和源文件不在同一个目录时:

文件目录:

 cmakelist.txt 文件内容:


cmake_minimum_required(VERSION 3.17)
project(sharedLibTest)

set(CMAKE_CXX_STANDARD 11)

include_directories(${PROJECT_SOURCE_DIR}/3dPart/include)
include_directories(${PROJECT_SOURCE_DIR}/header)
#link_directories(3dPart/lib)
link_directories(${PROJECT_SOURCE_DIR}/3dPart/lib)

aux_source_directory(${PROJECT_SOURCE_DIR}/header/ DIR_SR)
aux_source_directory(${PROJECT_SOURCE_DIR}/source/ DIR_SRS)
aux_source_directory(. DIR_SRS_MAIN)
#add_executable(sharedLibTest
#        header/sharedLibTest.h
#        source/sharedLibTest.cpp
#        main.cpp)

SET (MyCode ${DIR_SR} ${DIR_SRS} ${DIR_SRS_MAIN})
#add_executable(sharedLibTest ${DIR_SR} ${DIR_SRS} ${DIR_SRS_MAIN})
add_executable(sharedLibTest ${MyCode})
target_link_libraries(sharedLibTest libMyMathFunctions.so)  

 

运行结果:

aux_source_directory 生成库

思考: 是否可以将头文件一起生存到库中?

aux_source_directory(. DIR_LIB_SRC)

add_library(MyMathFunctions SHARED ${DIR_LIB_SRC})

 生成库的其它步骤不变

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cmake 学习使用笔记(二)库的生成与使用 的相关文章

随机推荐

  • FPGA基于XDMA实现PCIE X8的HDMI视频采集 提供工程源码和QT上位机程序和技术支持

    目录 1 前言2 我已有的PCIE方案3 PCIE理论4 总体设计思路和方案5 vivado工程详解6 驱动安装7 QT上位机软件8 上板调试验证9 福利 xff1a 工程代码的获取 1 前言 PCIE xff08 PCI Express
  • Zynq实现SDI视频解码PCIE传输 提供工程源码和QT上位机源码加技术支持

    目录 1 前言2 我已有的SDI编解码方案3 我已有的PCIE方案4 基于zynq架构的PCIE5 总体设计思路和方案SDI摄像头Gv8601a单端转差GTX解串SDI解码VGA时序恢复YUV转RGB图像缓存PCIE发送通路SDI同步输出通
  • FPGA实现MPEG2视频压缩PCIe传输 提供软硬件工程源码和技术支持

    目录 1 前言2 MPEG2视频压缩实现3 我已有的FPGA图像视频编解码方案4 我已有的PCIE方案5 MPEG2视频压缩PCIE传输设计方案FPGA硬件设计软件设计 6 Vivado工程详解7 Linux下的XDMA驱动安装8 上板调试
  • FPGA基于GS2971/GS2972实现SDI视频收发 提供工程源码和技术支持

    目录 1 前言2 我目前已有的SDI编解码方案3 GS2971 GS2972芯片解读GS2971解读GS2972解读 4 详细设计方案5 vivado工程1解读硬件逻辑工程软件SDK工程 6 vivado工程2解读硬件逻辑工程软件SDK工程
  • STM32 CubeMX生成DAC+DMA+TIM生成正弦波

    1 首先配置好系统时钟 2 打开DAC 3 配置DMA xff0c 在DAC中的 34 DMA Setting 34 选项卡中添加DMA DMA模式选择循环模式 4 配置定时器 在第二步中选择的是TIM6 在第一步中设置的定时器频率是36M
  • allegro 使用汇总

    1 如何在allegro中取消花焊盘 十字焊盘 set up gt design parameter gt shape gt edit global dynamic shape parameters gt Thermal relief co
  • 操作系统的分页和分段式管理

    计算存储的层次结构 xff1a 当前技术没有能够提供这样的存储器 xff0c 因此大部分的计算机都有一个存储器层次结构 xff0c 即少量的非常快速 昂贵 易变的高速缓存 cache xff1b 若干兆字节的中等速度 中等价格 易变的主存储
  • 三极管什么时候工作在饱和区

    http www dzsc com dzbbs 20070115 200765213434343495 html 三极管什么时候工作在饱和区 xff1f 以前我以为Ib大的时候就在饱和区 现在看了书 xff0c 看来应该是两个PN结都正偏的
  • shell脚本基础

    摘自 xff1a 一篇教会你写90 的shell脚本 1 注释 xff1a 单行注释 xff1a 多行注释 xff1a 注意第一种注释方法的 34 后面有一个空格 xff09 39 多行注释内容 39 lt lt block 多行注释内容
  • RT-thread 中CAN总线的应用

    准备 xff1a RT thread Studio 2 2 5 CubeMX 6 6 1 rt thread驱动包 4 0 3 1 新建项目 2 打开CubeMX Settings xff0c 设置CAN 找到CAN1 xff0c 并勾选激
  • Rt-thread的CAN应用2

    1 rtt中使能CAN1 2 CubeMX生成部分代码 xff0c 完成下面操作然后生成MDK ARM项目文件 3 将CubeMX生成的 HAL CAN MspInit 函数 粘贴到drv can c中 并在rt hw can init 函
  • STM32的IIC接口输入输出定义

    IO方向设置 PC11 端口 define SDA IN GPIOC gt CRH amp 61 0XFFFF0FFF GPIOC gt CRH 61 8 lt lt 12 define SDA OUT GPIOC gt CRH amp 6
  • 从头开始用树莓派做一个NAS【最新超详细教程】

    一 概述 众所周知在办公的时候两台电脑之间经常倒数据资料非常麻烦 xff0c 而NAS可以很好的解决这个问题 树莓派搭建NAS方法有很多 xff0c 我们之前也拍过直接用Samba FTP这些来实现NAS功能 xff0c 但是这些需要你会在
  • 串口发送通信---UART发送---STM32F4实现

    串口发送程序配置过程 xff08 HAL库 xff09 初始化串口相关参数 xff0c 使能串口 HAL StatusTypeDef span class token function HAL UART Init span span cla
  • 基于UDP的文件传输VS编程

    要求 xff1a 实现基于UDP的文件传输 xff0c 客户端发送文件 xff0c 服务端接受文件 服务端实现 xff1a include 34 stdafx h 34 include 34 iostream 34 include 34 a
  • 成功解决VSCODE运行C++的报错问题g++

    成功解决VSCODE运行C 43 43 的报错问题g 43 43 解决方案调试 很久写C 43 43 了 xff0c 直接打开C 43 43 写代码测试一下 xff0c 报错 xff0c 真一脸懵逼 捯饬很久 xff0c 解决了问题 解决方
  • linux下的环境变量

    环境变量 环境变量 xff0c 是指在操作系统中用来指定操作系统运行环境的一些参数 通常具备以下特征 xff1a 字符串 本质 有统一的格式 xff1a 名 61 值 值 值用来描述进程环境信息 存储形式 xff1a 与命令行参数类似 ch
  • 【004 关键字】extern “C“的作用是什么?

    一 extern 34 C 34 的作用 extern 34 C 34 关键字常用于C 43 43 和C混合编程中 xff0c 用于指定函数或变量采用C语言的命名和调用约定 加上extern 34 C 34 后 xff0c 会指示编译器这部
  • C++模板编程--学习C++类库的编程基础

    目录 一 函数模板二 类模板三 实现C 43 43 STL向量容器vector代码四 理解容器空间配置器allocator的重要性 一 函数模板 1 模板的意义 xff1a 对类型也可以进行参数化了 2 函数模板 lt 61 是不进行编译的
  • cmake 学习使用笔记(二)库的生成与使用

    学习使用cmake 生成及使用库 xff0c 使用cmake 生成 lib 静态库 及动态库 xff08 dll xff09 及linux 下使用的静态库 a 和 动态库 xff08 so 也称为共享库 xff09 目录 使用工具 生成库