为什么选择CLion
在Windows平台下,个人认为最能体现CMake的也就是CLion了。
- vscode : 配置那几个文件,而且你要调试是必须要配置task.json。task.json中的args[]又是在使用编译器的命令行参数,个人觉得比较麻烦,而且你大部分精力都在那个玩意的配置上,对CMakeLists的不会太在意
- VS:那个东西虽说可以支持cmake生成,但我没用那个功能。
所以,以下的案例全部是基于CLion的,同时我也提前说一下 “Windows的路径真的和狗屎一样”
案例1:OpenCV
首先 OpenCV是有库文件的,这一点要知道。
-
从官网上下载好源代码
-
使用cmake-gui去编译 (Configure → Generate)
- 我使用的是mingw编译器
- 提前创建好build方便存放编译好的文件
-
编译结束后,进入你事先创建好的build,然后用管理员打开powershell,cd到这个目录,分别执行:
- mingw32-make -j 4
- minge32-make install
-
install结束后,应该在事先创建好的build中出现了install文件夹,把这个install里面的bin加到环境变量中
- 其中 include 是存放头文件的地方;x64是存放库文件的地方
- install的过程实际上是将库文件拷贝到系统指定路径的过程,install之后find_package()就可以找到它了
-
CMakeLists:
-
set(OpenCV_DIR C:/opencv-4.x/opencv_build/install) 设置OpenCV_DIR 为路径,因为我直接安装到build里面(我默认install就是在原来的build),所以不指定的话系统找不到。
[ 注 ] 这里是 为什么安装到原来的build文件夹中呢? 因为cmake_install.cmake中其实指定了安装路径:
if(NOT DEFINED CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX "C:/Users/75742/Desktop/opencv-4.x/opencv_build/install") endif()
opencv默认给我 把CMAKE_INSTALL_PREFIX 修改了
-
find_package(OpenCV REQUIRED) 系统既然已经可以找到了,那就直接find_package即可。需要注意OpenCV这个名字不是乱起的,你要在build文件夹内,找到OpenCVConfig.cmake这个文件,这里面就告诉你 应该怎么弄(看注释):
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS}) # Not needed for CMake >= 2.8.11
target_link_libraries(MY_TARGET_NAME ${OpenCV_LIBS})
这就是 分别对应了这里的b c d三步。同时它还告诉你CMake的版本至少应该2.8.11以上
以下就是抄就完事
-
include_directories(${OpenCV_INCLUDE_DIRS}) 这里是为了让你能include到这个文件,这个.h文件也是库文件的索引。
-
target_link_libraries(CLionProject PUBLIC ${OpenCV_LIBS}) 最后一步就切实的把库文件按链接进来,这样你之前的.h中的函数声明才能找到实现。
这样你OpenCV就安装完了,你可以写测试代码来测试它
-
案例2:Eigen
与OpenCV不同,Eigen是header only library,也就是这里想表达的案例是一个没有库文件只有头文件的第三方模块。
因为Eigen相对比较小,所以将.h和.cpp写到一个文件中。从而没有库文件,这种库也是非常常见的。
-
依旧是从官网下载源码
-
用cmake-gui编译 → build →install 和OpenCV是一样的
在Eigen的Eigen3Config.cmake中并没有像OpenCV一样,默认修改了CMAKE_INSTALL_PREFIX ,所以这个install安装到了系统指定的路径,之前也说过Windows的默认路径是:C:/Program Files/。按道理它是应该安装到这个默认路径,但实际上在安装过程中提示我安装到了(){PROJECT_NAME}中。
[ 注 ] 这里的install文件夹不一定叫这个名字,因为你默认是${PROJECT_NAME}对PROJECT_NAME解引用获取名字,所以名字还叫eigen3
-
因为是只有头文件,所以target_link_libraries 就没意义了,因为没有库文件
-
将install复制到你项目文件夹里面
-
find_package(Eigen3 REQUIRED) 找到包
-
include_directories(./Eigen3/include/eigen3/Eigen) 包括头文件 既可。
[ 注1 ] 在 Eigen3Config.cmake里如此设置:
set (EIGEN3_INCLUDE_DIRS "${PACKAGE_PREFIX_DIR}/include/eigen3")所以你最后的install文件夹应该是还有两层/include /eigen3
[ 注2 ] : 因为我 include_directories(./Eigen3/include/eigen3/Eigen) 所以我测试的#include ”./Dense” 就能找到模块。如果你是include_directories(./Eigen3/include/eigen3) 则需要额外#include “./Eigen/Dense”
-
如果出现怎么也找不到路径的情况,就是一切都设置好了,但就是找不到路径。这时试一下把项目目录下的build删了,没准就能解决问题。如果删build都没有解决问题,那就是你的问题了。