Why CMake
一个c++程序,编译过程中最关键的就是编译和链接,链接需要的是各种静态.a和动态.so .dll的库文件(里面存放着真正运行的逻辑)。 同时也需要include头文件(头文件用于定义函数,不包含实现。这么拆分之后,就可以让用户只看到api,无法看到实现源码了)。 那么cmake就能够很好地解决程序应该去哪里去寻找到这些链接库文件的问题
更多可关注
有能力的同学可以直接参考cmake官方
FindPython — CMake 3.23.0-rc5 Documentation
一些常用语法
一个标准,添加了opencv的的cmake看起来是这样的
cmake_minimum_required (VERSION 3.8)
project ("CMakeProject1")
set(INC_DIR D:/opencv/opencv/build/include/) # 找到自己的路径
set(LINK_DIR D:/opencv/opencv/build/x64/vc15/lib) # 找到自己的路径
include_directories(${INC_DIR})
link_directories(${LINK_DIR})
link_libraries(opencv_world)
add_executable (CMakeProject1 "CMakeProject1.cpp" "CMakeProject1.h")
如果去掉include_directories(${INC_DIR}),则程序无法找到引用的头文件,也就找不到函数的api
无法找到文件,打开包括文件 <opencv/core/core.hpp> no such file or directory
如果去掉link_directories(${LINK_DIR}),则程序无法找到.lib文件,
fatal error LNK1104: 无法打开文件 opencv_world.lib
如果去掉 link_libraries(opencv_world) ,会导致程序无法正常找到编译后的dll动态链接库的位置,也就找不到实现
D:\work\cmake\CMakeProject1\out\build\x64-Debug\CMakeProject1\CMakeProject1.cpp.obj : error LNK2019: 无法解析的外部符号 "void __cdecl cv::circle(class cv::debug_build_guard::_InputOutputArray const &,class cv::Point_<int>,int,class cv::Scalar_<double> const &,int,int,int)" (?circle@cv@@YAXAEBV_InputOutputArray@debug_build_guard@1@V?$Point_@H@1@HAEBV?$Scalar_@N@1@HHH@Z),函数 main 中引用了该符号
D:\work\cmake\CMakeProject1\out\build\x64-Debug\CMakeProject1\CMakeProject1\CMakeProject1.exe : fatal error LNK1120: 7 个无法解析的外部命令
TARGET_LINK_LIBRARIES
由于官方推荐,因此重点介绍TARGET_LINK_LIBRARIES (设置要链接的库文件的名称)
语法:TARGET_LINK_LIBRARIES(targetlibrary1 <debug | optimized> library2 ..)
TARGET_LINK_LIBRARIES(myProject hello),连接libhello.so库
TARGET_LINK_LIBRARIES(myProject libhello.a)
TARGET_LINK_LIBRARIES(myProject libhello.so)
官网不推荐使用link_directoris这里就不介绍了,而是推荐使用find_package和find_library寻找共享库的绝对路径,再传给target_link_libraries使用。同样如果我们使用find,那么以上的cmake就会变成
cmake_minimum_required (VERSION 3.8)
set(INC_DIR D:/opencv/opencv/build/include/) # 找到自己的路径
include_directories(${INC_DIR})
find_package(OpenCV REQUIRED) #
add_executable (CMakeProject1 "CMakeProject1.cpp" "CMakeProject1.h")
target_link_libraries(CMakeProject1 ${OpenCV_LIBRARIES}) # OpenCV python.lib 库