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


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

    使用工具

            开发工具:clion、cmake

            平台: win

    生成库(导入库)

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

    使用 cmake  CMakeList.txt

    项目结构:

    声明库函数 .h

    1. #pragma once
    2. double mySqrt(double x);

    定义库函数 .cpp 

    1. #include "myMathSquare.h"
    2. double mySqrt(double x)
    3. {
    4. return (x * x);
    5. }

     CMakeLists.txt

    1. # CMakeList.txt: MyLibraryTest 的 CMake 项目,在此处包括源代码并定义
    2. # 项目特定的逻辑。
    3. #
    4. #注意:cmake的语法支持大小、小写和大小写混合上边的代码中我们使用的cmake语法是小写的.
    5. cmake_minimum_required (VERSION 3.8)
    6. project ("MyLibraryTest")
    7. # 设置系统自带变量
    8. set(cmake_cxx_standard 11)
    9. set(myHeadPath "${CMAKE_CURRENT_SOURCE_DIR}/header")
    10. include_directories(${myHeadPath})
    11. add_library(MyMathFunctions STATIC ./source/myMathSquare.cpp)
    12. # TODO: 如有需要,请添加测试并安装目标。

     add_library()

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

    属性必须全局唯一
    生成的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 

    1. #include
    2. using namespace std;
    3. extern double mySqrt(double x);
    4. extern void hello();
    5. void customLibTest() {
    6. double x = 8;
    7. double res = mySqrt(x);
    8. cout << "输入x: " << x << "的平方是" << res << endl;
    9. }
    10. int main()
    11. {
    12. #ifdef MyDebug
    13. cout << "获取版本:" << cPlusPlusTest_version_major << endl;
    14. #else
    15. cout << "获取版本: " << cPlusPlusTest_version_minor << endl;
    16. #endif // DEBUG
    17. customLibTest();
    18. hello();
    19. return 0;
    20. }

    方式一:使用  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:指定目标编译选项
    1. target_link_libraries(
    2. <PRIVATE|PUBLIC|INTERFACE> ...
    3. [<PRIVATE|PUBLIC|INTERFACE> ...]...)

     可以链接多个库: 例如:

    target_link_libraries(cPlusPlusTestProject ${PROJECT_SOURCE_DIR}/3dPart/lib/MyMathFunctions.lib ${PROJECT_SOURCE_DIR}/3dPart/lib/LibTest.lib)
    1. target_link_libraries(target target1 target2)
    2. 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

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

    结果:

     

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

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

    引入头文件:

    1. #include
    2. #include "myMathSquare.h"
    3. using namespace std;
    4. extern void hello();
    5. void customLibTest() {
    6. double x = 8;
    7. double res = mySqrt(x);
    8. cout << "输入x: " << x << "的平方是" << res << endl;
    9. }
    10. int main()
    11. {
    12. #ifdef MyDebug
    13. cout << "获取版本:" << cPlusPlusTest_version_major << endl;
    14. #else
    15. cout << "获取版本: " << cPlusPlusTest_version_minor << endl;
    16. #endif // DEBUG
    17. customLibTest();
    18. hello();
    19. return 0;
    20. }

     例如:

    error LNK2019:

    无法解析的外部符号 "double __cdecl mySqrt(double)" 

    遇到的坑,把 .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

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

    共享库的使用

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

     sharedLibTest.h

    1. //
    2. // Created by ly on 2022/7/21.
    3. //
    4. #ifndef SHAREDLIBTEST_SHAREDLIBTEST_H
    5. #define SHAREDLIBTEST_SHAREDLIBTEST_H
    6. void test();
    7. #endif //SHAREDLIBTEST_SHAREDLIBTEST_H

    sharedLibTest.cpp

    1. //
    2. // Created by ly on 2022/7/21.
    3. //
    4. #include
    5. #include "sharedLibTest.h"
    6. #include "myMathSquare.h"
    7. void test(){
    8. double x = 8;
    9. double d = mySqrt(x);
    10. std::cout << "x 的平方是: " << d << std::endl;
    11. }

     main.cpp

    1. #include
    2. #include "sharedLibTest.h"
    3. int main() {
    4. std::cout << "Hello, World!" << std::endl;
    5. test();
    6. return 0;
    7. }

    CMakeLists.txt

    1. cmake_minimum_required(VERSION 3.17)
    2. project(sharedLibTest)
    3. set(CMAKE_CXX_STANDARD 11)
    4. include_directories(${PROJECT_SOURCE_DIR}/3dPart/include)
    5. include_directories(${PROJECT_SOURCE_DIR}/header)
    6. #link_directories(3dPart/lib)
    7. link_directories(${PROJECT_SOURCE_DIR}/3dPart/lib)
    8. add_executable(sharedLibTest
    9. header/sharedLibTest.h
    10. source/sharedLibTest.cpp
    11. main.cpp)
    12. target_link_libraries(sharedLibTest libMyMathFunctions.so)

     运行结果:

     

     

     

  • 相关阅读:
    深挖全媒体多模态数据价值,蜜度亮相2022世界人工智能大会
    【C语言小例程26/100】
    品牌被侵权 有效治理下架的方法
    so-vits-svc:AI翻唱,语音克隆
    联盟认证 | 聚铭网络正式成为中国反网络病毒联盟成员
    Web自动化测试理解
    时间复杂度计算超全整理!!(数据结构和算法的第一步
    Golang:gin模板渲染base64图片出现#ZgotmplZ
    代码随想录笔记_哈希_219存在重复元素II
    数据结构学习笔记——图的基本知识
  • 原文地址:https://blog.csdn.net/qq_41722795/article/details/125638209