cmake-动态库和静态库及使用OpenCV第三方库

文章目录

  • 静态库
    • 准备的文件
    • CMakeLists文件
    • 使用静态库
  • 动态库
    • 准备的文件
    • CMakeLists文件
    • 使用动态库
  • 使用OpenCV库

?项目中会有单个源文件构建的多个可执行文件的可能。项目中有多个源文件,通常分布在不同子目录中。这种实践有助于项目的源代码结构,而且支持模块化、代码重用和关注点分离。同时,这种分离可以简化并加速项目的重新编译。

静态库

准备的文件

add.h

int add(int a,int b);

add.cpp

int add(int a,int b)
{
    return a+b;    
}

main.cpp

#include "add.h"
#include <iostream>
int main()
{
    int a = 3,b = 4;
    std::cout<<add(3,4)<<std::endl;
    return 0;    
}

CMakeLists文件

在这里插入图片描述
?首先这是我们的目录结构。我们需要先编译静态库,所以我们会在外层的CMakeLists.txt文件中先编译add文件夹中的静态库。
所以外层CMakeLists.txt文件的内容为:

add_subdirectory(add)

add文件夹中的CMakeLists.txt文件

add_library(add_static add.cpp)

?add_library(add_static STATIC add.cpp):生成必要的构建指令,将指定的源码编译到库中。add_library的第一个参数是目标名。整个CMakeLists.txt中,可使用相同的名称来引用库。生成的库的实际名称将由CMake通过在前面添加前缀lib和适当的扩展名作为后缀来形成。生成库是根据第二个参数(STATIC或SHARED)和操作系统确定的。

使用静态库

?接下来我们需要在外层main.cpp文件中使用该静态库。

add_subdirectory(add)

include_directories(./lib)
add_executable(lesson2_1 main.cpp)
target_link_libraries(lesson2_1 ${CMAKE_CURRENT_SOURCE_DIR}/lib/add_static.lib)

?target_link_libraries(lesson2_1 ${CMAKE_CURRENT_SOURCE_DIR}/lib/add_static.lib): 将库链接到可执行文件。此命令还确保可执行文件可以正确地依赖于静态库。因此,在静态链接到可执行文件之前,需要完成静态库的构建。
?我们先把编译好的静态库和头文件放到lib文件夹下。
在这里插入图片描述
最后的编译结果。
在这里插入图片描述

动态库

准备的文件

add.cpp

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

CMAKE_STUDY_API int add(int a,int b)
{
    return a+b;    
}

add.h

#include "export.h"
CMAKE_STUDY_API int add(int a,int b);

export.h

#pragma once

#ifdef EXPORT
#define CMAKE_STUDY_API __declspec(dllexport)
#else
#define CMAKE_STUDY_API __declspec(dllimport)
#endif

main.cpp

#include "add.h"
#include <iostream>
int main()
{
    int a = 3,b = 4;
    std::cout<<add(3,4)<<std::endl;
    return 0;    
}

CMakeLists文件

在这里插入图片描述
以上为目录结构
?与静态库一样,我们都需要先编译动态库,然后再编译可执行文件。
所以我们外部的CMakeLists.txt文件为:

add_subdirectory(add)

add文件夹下的CMakeLists.txt文件为:

add_library(add_shared SHARED add.cpp)
target_compile_definitions(add_shared PRIVATE EXPORT)

由于在windows下的动态库需要有宏定义来指定动态库是导出还是导入。
在这里插入图片描述
target_compile_definitions(add_shared PRIVATE EXPORT)主要是用来定义该动态库有个自定义的宏EXPORT。

使用动态库

?与静态库不同,在windows下我们生成的动态库会有一个lib文件和一个dll文件,lib文件是动态库函数的导出符号文件。
外部的CMakeLists.txt文件:

add_subdirectory(add)

include_directories(./lib)
add_executable(lesson2_2 main.cpp)
target_link_libraries(lesson2_2 ${CMAKE_CURRENT_SOURCE_DIR}/lib/add_shared.lib)

在这里插入图片描述
我们先把头文件和lib文件都拷贝到lib文件夹下。
然后再把生成的dll文件拷贝到生成的可执行文件的目录下。否则会出现缺失dll文件的错误。
在这里插入图片描述
在这里插入图片描述
最后的执行结果。

使用OpenCV库

?我们先从官网上下载OpenCV的库。
在这里插入图片描述
main.cpp

#include<iostream>

#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

int main(int argc, char** argv)    
{                                  
	Mat image;
	image = imread("C:/cmake_study/lesson2_opencv/1.jpeg");
	if (image.data == nullptr)
	{
		//cout <<"图片不存在" << endl;
	}
	else
	{
		imshow("meinv", image);
		waitKey(0);
	}

	//cout << "图像宽为:" << image.cols << "	高度为:" << image.rows << "	通道数为:" << image.channels() << endl

	system("pause");
	return 0;
}

CMakeLists.txt文件

include_directories(C:/3rd/opencv/build/include)
add_executable(lesson2_opencv main.cpp)
target_link_libraries(lesson2_opencv "C:/3rd/opencv/build/x64/vc16/lib/opencv_world480d.lib")

我们只需要指定OpenCV的lib文件的路径和头文件即可,最后将dll文件拷贝到可执行文件的目录下。
在这里插入图片描述