cmakelist find_package_cmake中文手册

(1) 2024-08-21 09:23

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
cmakelist find_package_cmake中文手册,希望能够帮助你!!!。

本文主要内容如下:
1. cmake find_package的基本原理
2. 如何编写自己的 cmake module模块
3. 使用cmake find_package 使用不同版本的opencv lib问题(opencv 安装在指定的目录,不是系统的目录)

1. cmake find_package的基本原理

当编译一个需要使用第三方库的软件时,我们需要知道:

去哪儿找头文件 .h 对比GCC的 -I 参数
去哪儿找库文件 (.so/.dll/.lib/.dylib/…) 对比GCC的 -L 参数
需要链接的库文件的名字 对比GCC的 -l 参数

比如说,我们需要一个第三方库 curl,那么我们的 CMakeLists.txt 需要指定头文件目录,和库文件,类似:

include_directiories(/usr/include/curl) target_link_libraries(myprogram path/curl.so)

如果借助于cmake提供的finder会怎么样呢?使用cmake的Modules目录下的FindCURL.cmake,相应的CMakeList.txt 文件:

find_package(CURL REQUIRED) include_directories(${CURL_INCLUDE_DIR}) target_link_libraries(curltest ${CURL_LIBRARY})

那么cmake是如何查找的呢?

find_package()命令首先会在模块路径中寻找Find.cmake,这是查找库的一个典型方式。具体查找路径依次为CMake:变量${CMAKE_MODULE_PATH}中的所有目录。如果没有,然后再查看它自己的模块目录/share/cmake-x.y/Modules/$CMAKE_ROOT的具体值可以通过CMake中message命令输出)。这称为模块模式。

为了能支持各种常见的库和包,CMake自带了很多模块。可以通过命令 cmake –help-module-list (输入cmake –help,然后双击Tab会有命令提示)得到你的CMake支持的模块的列表: 直接查看模块路径。比如Ubuntu linux上,模块的路径是 ls /usr/share/cmake/Modules/:

ll -th /usr/share/cmake-3.5/Modules/ ...... -rw-r--r-- 1 root root 76K Sep 27 2016 FindBoost.cmake -rw-r--r-- 1 root root 2.7K Mar 24 2016 FindCoin3D.cmake -rw-r--r-- 1 root root 77K Mar 24 2016 FindCUDA.cmake -rw-r--r-- 1 root root 3.1K Mar 24 2016 FindCups.cmake -rw-r--r-- 1 root root 2.4K Mar 24 2016 FindCURL.cmake ........

让我们以bzip2库为例。CMake中有个 FindBZip2.cmake 模块。只要使用 find_package(BZip2) 调用这个模块,cmake会自动给一些变量赋值,然后就可以在CMake脚本中使用它们了。变量的列表可以查看cmake模块文件,或者使用命令:

root@xy:~/cmake_practice/cmake_build/build_demo10# cmake --help-module FindBZip2 FindBZip2 --------- Try to find BZip2 Once done this will define :: BZIP2_FOUND - system has BZip2 BZIP2_INCLUDE_DIR - the BZip2 include directory BZIP2_LIBRARIES - Link these to use BZip2 BZIP2_NEED_PREFIX - this is set if the functions are prefixed with BZ2_ BZIP2_VERSION_STRING - the version of BZip2 found (since CMake 2.8.8)

cmake 会将路径赋值给对应的变量,我们以curl的cmake为例,其部分内容如下:

 find_path(CURL_INCLUDE_DIR NAMES curl/curl.h) mark_as_advanced(CURL_INCLUDE_DIR) # Look for the library (sorted from most current/relevant entry to least). find_library(CURL_LIBRARY NAMES curl # Windows MSVC prebuilts: curllib libcurl_imp curllib_static # Windows older "Win32 - MSVC" prebuilts (libcurl.lib, e.g. libcurl-7.15.5-win32-msvc.zip): libcurl ) 

比如一个使用bzip2的简单程序,编译器需要知道 bzlib.h 的位置,链接器需要找到bzip2库(动态链接的话,Unix上是 libbz2.so 类似的文件,Windows上是 libbz2.dll )

project(helloworld) add_executable(helloworld hello.c) find_package (BZip2) if (BZIP2_FOUND) include_directories(${BZIP_INCLUDE_DIRS}) target_link_libraries (helloworld ${BZIP2_LIBRARIES}) endif (BZIP2_FOUND)

2. 如何编写自己的 cmake module模块

下面以工程demo9为示例, 项目目录结构如下:

├── cmake │ └── FindDEMO9LIB.cmake ├── CMakeLists.txt ├── demo9.cpp ├── demo9.h └── demo9_main.cpp

其中demo9.h和demo9.cpp生成lib, demo9_main.cpp link对应的lib生成可执行文件

文件内容如下:

//=========================demo9.h=================== #ifndef PROJECT_DEMO9_H #define PROJECT_DEMO9_H namespace demo9{ 
    void print_demo9(); } #endif //PROJECT_DEMO3_H_H //======================demo9.cpp================== #include "demo9.h" #include <iostream> namespace demo9{ 
    void print_demo9(){ std::cout<<"this is demo9"<<std::endl; } } //======================demo9_main.cpp================== #include "demo9.h" int main(){ demo9::print_demo9(); return 0; } 

首先我们使用demo9.h and demo9.cpp 生成静态lib,并安装:

-- Installing: /usr/local/demo9/lib/libdemo9_lib.a -- Installing: /usr/local/demo9/include/demo9.h

FindDEMO9LIB.cmake的内容如下(精简版本):

# 辅助输出信息 message("now using FindDEMO9LIB.cmake find demo9 lib") # 将demo9.h文件路径赋值给DEMO9LIB_INCLUDE_DIR FIND_PATH(DEMO9LIB_INCLUDE_DIR demo9.h /usr/include/demo9/ /usr/local/demo9/include/) message("./h dir ${DEMO9LIB_INCLUDE_DIR}") # 将libdemo9_lib.a文件路径赋值给DEMO9LIB_LIBRARY FIND_LIBRARY(DEMO9LIB_LIBRARY libdemo9_lib.a /usr/local/demo9/lib/) message("lib dir: ${DEMO9LIB_LIBRARY}") if(DEMO9LIB_INCLUDE_DIR AND DEMO9LIB_LIBRARY) # 设置变量结果 set(DEMO9LIB_FOUND TRUE) endif(DEMO9LIB_INCLUDE_DIR AND DEMO9LIB_LIBRARY)

主CMakeLists.txt内容如下:

cmake_minimum_required(VERSION 3.5) project(demo9) # create libdemo9_lib.a set(SRC_LIB demo9.cpp) add_library(demo9_lib STATIC ${SRC_LIB}) # install it install(TARGETS demo9_lib DESTINATION demo9/lib) install(FILES demo9.h DESTINATION demo9/include) # create demo9_main exectuable set(SRC_EXE demo9_main.cpp) # set demo9_lib cmake module path set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) message("cmake_module_path: ${CMAKE_MODULE_PATH}") find_package(DEMO9LIB) if(DEMO9LIB_FOUND) add_executable(demo9_main ${SRC_EXE}) message("found demo9 ${DEMO9LIB_INCLUDE_DIR} ${DEMO9LIB_LIBRARY}") include_directories(${DEMO9LIB_INCLUDE_DIR}) target_link_libraries(demo9_main ${DEMO9LIB_LIBRARY}) else() message("not found DEMO9LIB_FOUND") endif(DEMO9LIB_FOUND)

编译输出信息如下:

root@xy:~/cmake_practice/cmake_build/build_demo9# cmake ../../cmake_tuorial/demo9/ cmake_module_path: /home/xy/cmake_practice/cmake_tuorial/demo9/cmake now using FindDEMO9LIB.cmake find demo9 lib ./h dir /usr/local/demo9/include lib dir: /usr/local/demo9/lib/libdemo9_lib.a found demo9 /usr/local/demo9/include /usr/local/demo9/lib/libdemo9_lib.a

make

root@xy:~/cmake_practice/cmake_build/build_demo9# make -j10 cmake_module_path: /home/xy/cmake_practice/cmake_tuorial/demo9/cmake now using FindDEMO9LIB.cmake find demo9 lib ./h dir /usr/local/demo9/include lib dir: /usr/local/demo9/lib/libdemo9_lib.a found demo9 /usr/local/demo9/include /usr/local/demo9/lib/libdemo9_lib.a -- Configuring done .......................................

运行:

root@xy:~/cmake_practice/cmake_build/build_demo9# ./demo9_main  this is demo9

3. 使用cmake find_package 使用不同版本的opencv lib问题(opencv 安装在指定的目录,不是系统的目录)

下面在给出一个opencv的示例,opencv3.1安装在/home/xy/opencv3.1_install/lib/目录下(可以参考这篇英文blog安装)。

最终安装完成会有对应的cmake文件,查看如下:

xy@xy:~/opencv_demo/demo1$ ll -th ~/opencv3.1_install/lib/share/OpenCV/ total 60K drwxrwxr-x 5 xy xy 4.0K May 28 19:00 ./ ...... -rw-r--r-- 1 xy xy 16K May 28 18:56 OpenCVConfig.cmake -rw-r--r-- 1 xy xy 418 May 28 18:56 OpenCVConfig-version.cmake -rw-r--r-- 1 xy xy 4.5K May 28 18:56 OpenCVModules.cmake -rw-r--r-- 1 xy xy 11K May 28 18:56 OpenCVModules-release.cmake

测试代码如下:

#include <stdio.h> #include "opencv2/opencv.hpp" #include<iostream> using namespace std; using namespace cv; int main(int argc, char** argv ) { cout << "OpenCV version : " << CV_VERSION << endl; cout << "Major version : " << CV_MAJOR_VERSION << endl; cout << "Minor version : " << CV_MINOR_VERSION << endl; if ( argc != 2 ) { printf("usage: DisplayImage.out <Image_Path>\n"); return -1; } Mat image; image = imread( argv[1], 1 ); if ( !image.data ) { printf("No image data \n"); return -1; } cout<<image.size()<<endl; cout<<image.size().width<<endl; cout<<image.size().height<<endl; namedWindow("Display Image", WINDOW_AUTOSIZE ); imshow("Display Image", image); waitKey(0); return 0; }

对应的cmake 如下:

cmake_minimum_required(VERSION 3.5.0) project(demo1) //set cmake module path set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "~/opencv3.1_install/lib/share/OpenCV/" ) find_package( OpenCV 3.1.0 REQUIRED ) include_directories( ${OpenCV_INCLUDE_DIRS} ) message("OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}") message("OpenCV_LIBS: ${OpenCV_LIBS}") add_executable( demo1 demo.cpp ) target_link_libraries( demo1 ${OpenCV_LIBS} )

cmake build输出如下:

xy@xy:~/opencv_demo/demo1$ cmake . OpenCV_INCLUDE_DIRS: /home/xy/opencv3.1_install/lib/include/opencv;/home/xy/opencv3.1_install/lib/include OpenCV_LIBS: opencv_videostab;opencv_videoio;.....

程序运行如下:

cmakelist find_package_cmake中文手册_https://bianchenghao6.com/blog__第1张

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

上一篇

已是最后文章

下一篇

已是最新文章

发表回复