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

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

目录

使用工具

生成库(导入库)

 add_library()

生成静态库(Windows)

使用 vs 2019 生成静态库

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

使用静态库(Windows) 

使用全路径

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

error LNK2019:

静态库(.a) 的使用

动态链接库 

使用mingw与cmake 生成 .dll

生成共享库

共享库的使用

aux_source_directory 的使用

aux_source_directory  引用文件

aux_source_directory 生成库


使用工具

        开发工具:clion、cmake

        平台: win

生成库(导入库)

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

使用 cmake  CMakeList.txt

项目结构:

cmake 学习使用笔记(二)库的生成与使用_第1张图片

声明库函数 .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( [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 学习使用笔记(二)库的生成与使用_第2张图片

 使用 cmake 生成解决方案

j命令:  cmake .

cmake 学习使用笔记(二)库的生成与使用_第3张图片

 结果:

 cmake 学习使用笔记(二)库的生成与使用_第4张图片

 打开解决方案:

cmake 学习使用笔记(二)库的生成与使用_第5张图片

 生成:

cmake 学习使用笔记(二)库的生成与使用_第6张图片

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

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

其他步骤一致

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

打开项目文件夹

cmake 学习使用笔记(二)库的生成与使用_第7张图片

 设置 Clion 中的 visual studio  环境

打开设置:

cmake 学习使用笔记(二)库的生成与使用_第8张图片

 新增工具链

 cmake 学习使用笔记(二)库的生成与使用_第9张图片

 改为 64 位

cmake 学习使用笔记(二)库的生成与使用_第10张图片

 新增cmake 环境

cmake 学习使用笔记(二)库的生成与使用_第11张图片

 选择debug 或者 release

cmake 学习使用笔记(二)库的生成与使用_第12张图片

 查看文件夹下 是否出现 visual studio 相应的文件夹cmake 学习使用笔记(二)库的生成与使用_第13张图片

 如果没有  打开 cmake   reset 或 刷新

cmake 学习使用笔记(二)库的生成与使用_第14张图片

 选择相应环境 构建

 cmake 学习使用笔记(二)库的生成与使用_第15张图片

 生成结果cmake 学习使用笔记(二)库的生成与使用_第16张图片

使用静态库(Windows) 

新建一个调用文件 xxx.cpp 

#include 

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(${PROJECT_SOURCE_DIR}/3dPart/lib/MyMathFunctions.lib) 
#使用link_libraries链接MyMathFunctions.lib

cmake 学习使用笔记(二)库的生成与使用_第17张图片

 运行结果:

cmake 学习使用笔记(二)库的生成与使用_第18张图片

 target_link_libraries:指定目标链接的库

target_link_directories: 指定目标包含的头文件路径
target_compile_options:指定目标编译选项
target_link_libraries( 
                       ... 
                      [ ...]...)

 可以链接多个库: 例如:

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(../3dPart/lib)
target_link_libraries(cPlusPlusTestProject MyMathFunctions)#直接写库的名称

结果:

 cmake 学习使用笔记(二)库的生成与使用_第19张图片

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

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

引入头文件:

#include 
#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;
}

 例如:

cmake 学习使用笔记(二)库的生成与使用_第20张图片

error LNK2019:

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

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

静态库(.a) 的使用

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

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

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

需要注意的是,生成的.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 环境

cmake 学习使用笔记(二)库的生成与使用_第21张图片

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

生成共享库

cmake 学习使用笔记(二)库的生成与使用_第22张图片

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

共享库的使用

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

cmake 学习使用笔记(二)库的生成与使用_第23张图片

 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 
#include "sharedLibTest.h"
#include "myMathSquare.h"

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

}

 main.cpp

#include 
#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)# 共享库可以调用全名,也可以调用项目名称

 运行结果:

cmake 学习使用笔记(二)库的生成与使用_第24张图片

aux_source_directory 的使用

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

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

aux_source_directory  引用文件

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

aux_source_directory(. DIR_SR)
add_executable(testAuxSource ${DIR_SR})

文件目录

 cmake 学习使用笔记(二)库的生成与使用_第25张图片

cmake 学习使用笔记(二)库的生成与使用_第26张图片

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

文件目录:

cmake 学习使用笔记(二)库的生成与使用_第27张图片

 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)

 cmake 学习使用笔记(二)库的生成与使用_第28张图片

运行结果:

cmake 学习使用笔记(二)库的生成与使用_第29张图片

aux_source_directory 生成库

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

aux_source_directory(. DIR_LIB_SRC)

add_library(MyMathFunctions SHARED ${DIR_LIB_SRC})

 生成库的其它步骤不变

你可能感兴趣的:(C++,学习,c++,cmake,CMakelist.txt使用)