如何在VScode中使用CMake链接库,主要是静态库,动态库在Windows中直接放在exe同目录。
说明
Cmake工具包使用VS Studio Community 2022 - amd64。- 这篇博客会以两个库作为例子,一个是自己写的
add.h及add.cpp另一个则链接openCV4.8.0。 - 这篇博客不记录
CMake、C++等工具相关配置。
关于add.h
编译链接静态库
- 以下是文件结构,未标识后缀的应视为文件夹,除
.vscode属一个文件夹(主要是C++相关配置文件)。 - 此项目名称为
cmake-study。
D:/cmake-study/├─.vscode├─build├─lesson2-1│ ├─add│ ├─add.cpp│ └─CMakelists.txt│ ├─lib│ ├─add_static.lib│ └─add.h│ ├─CMakelists.txt│ └─main.cpp├─CMakeLists.txtC++中我们自己写的库可以与main一起放在同一目录下,#include"add.h"然后进行调试或运行。对于我们自己写的库,为避免过多的代码复写,直接编译成动态库或静态库要更加省力。所以我们的目标是将add.cpp编译成静态库,然后通过CMake指定需要链接的库,然后直接在main.cpp中调用即可。
编写lesson2-1/add中的CMakelists
我们的目标是通过该CMakelists.txt指定将add.cpp编译为一个静态库,Windows系统一般以.lib作后缀。所以该CMakelists.txt应编写如下。
add_library(add_static add.cpp)add_library指定我们需要编译一个‘库’,而内部的add_static指定编译后库的名字,也即编译后,我们的静态库应该叫add_static.lib,而add.cpp则是需要编译的文件,需要注意的是,这里使用的是相对路径,也可以写成./add.cpp。
编写lesson2-1中的CMakelists
该CMakelists的目标是将./add中的CMakelists加入进来,同时指定需要包括的静态库文件的位置、需要链接的静态库文件以及需要编译的文件。在本文件结构下,把所有静态库以及相关头文件全部放在同目录的lib文件夹下。则可以编写CMakelists.txt如下。
add_subdirectory(add)include_directories(./lib)add_executable(lesson2-1 main.cpp)target_link_libraries(lesson2-1 D:/cmake-study/lesson2-1/lib/add_static.lib)add_subdirectory将同目录下add文件夹加入进来,同时include_directories指定包括头文件位置,add_executable指定需要一同编译的文件,同时指定生成一个lesson2-1的项目文件,该文件可以在./cmake-study/build中找到。最后target_link_libraries指定需要链接的文件以及被链接的项目文件。但此处仿佛必须写绝对路径,否则依然会出现 LNK ERROR,故也可以参考下列编写方法。
add_subdirectory(add)include_directories(./lib)link_directories(./lib) # 指定链接库的路径add_executable(lesson2-1 main.cpp)target_link_libraries(lesson2-1 add_static.lib) # 在指定的 link_directories 中选择链接的库编写cmake-study中的CMakelists
该CMakelists.txt主要作为所有项目的管理,所以主要是设定一些基本设置。比如我们还有lesson2-2文件夹,该文件中还可以有其他C++项目,或是即将要讲到的lesson2-opencv文件夹。我们指定C++ 14以及最低CMake版本为 3.15。同时指定整个项目文件名为cmake-study。
cmake_minimum_required(VERSION 3.15)project(camke_study)
set(CMAKE_CXX_STANDARD 14)add_subdirectory(lesson2-1)add_subdirectory(lesson2-2)add_subdirectory(lesson2-opencv)关于链接openCV
我们首先给出一个示例程序,main.cpp,注意cv::imread中的图像路径需要自己指定,如果不指定的话也可以看终端是否成功输出”无法读取输入图像”。
#include <opencv2/opencv.hpp>#include <iostream>int main(int argc, char **argv){ cv::Mat inputImage = cv::imread("path/to/image.jpg", cv::IMREAD_COLOR); if (inputImage.empty()) { std::cout << "无法读取输入图像" << std::endl; return -1; } cv::Mat outputImage; inputImage.copyTo(outputImage); cv::imshow("原始图像", inputImage); cv::imshow("复制后的图像", outputImage); cv::waitKey(0); return 0;}链接opencv2/opencv.hpp
注意此处cmake-study/CMakelists.txt文件与示例add.h一致,主要是用于所有项目的管理。所以重要的是cmake-study/lesson2-opencv文件夹下的CMakelists.txt。
D:/cmake-study/├─.vscode├─build├─lesson2-opencv│ ├─CMakelists.txt│ └─main.cpp├─CMakeLists.txt编写lesson2-opencv中的CMakelists
通过第一个例子我们已经知道,要链接opencv2/opencv.hpp文件,我们需要该文件的位置,以及相关静态库/动态库的位置。官网下载openCV4.8.0并指定路径进行安装后,打开该opencv文件,我们主要需要/opencv/build/include(该文件夹内包括了opencv2以及各种头文件)和/opencv/build/x64/vc16中的bin(动态库)以及lib(静态库)。注意以上opencv文件路径省略了前面的部分,需要使用绝对路径。所以我们可以编写CMakelists.txt如下
include_directories(D:/opencv/build/include)add_executable(lesson2-opencv main.cpp)target_link_libraries(lesson2-opencv D:/opencv/build/x64/vc16/lib/opencv_world480d.lib) # debug版本选择opencv_world480d.lib当然,我们也可以将opencv/build/include中的include文件夹直接复制到main.cpp相同目录中,同时新建一个文件夹lib将静态库复制在里面,此时CMakelists编写如下。
include_directories(include)link_directories(./lib)add_executable(lesson2-opencv main.cpp)target_link_libraries(lesson2-opencv opencv_world480d.lib) # debug版本选择opencv_world480d.lib