目录
1、简单demo
(1)最简单的demo工程如下:
#include <iostream>
#include <string>
int main(int argc,char** argv)
{
std::cout << "hello world" << std::endl;
return 0;
}
文件结构如下,其中include可用来自定义接口功能类。
(2)CMakeLists.txt文件
demo的CMakeLists.txt文件如下:
cmake_minimum_required(VERSION 3.0)
project(MAIN)
set(CMAKE_CXX_STANDARD 11)
add_definitions(-O0 -g3 -ggdb)
include_directories(
./include
)
file(GLOB_RECURSE SRC_CPP ./src/*.cpp)
#${PROJECT_NAME}是工程名MAIN,也可以直接写MAIN
add_executable(${PROJECT_NAME} ${SRC_CPP})
#对于多线程函数需要下面一行代码
#target_link_libraries(${PROJECT_NAME} pthread)
生成可执行文件:创建build文件,产物都放在build里面,便于管理,步骤如下:
test$ mkdir build
test$ cd build
test/build$ cmake .. //生成Makefile
test/build$ make -j //编译Makefile
test/build$. /MAIN //执行可执行文件
2、包含三方库demo
(1)find_package用法
在工程代码中使用安装第三方软件包/库时,需要导入其头文件和对应的静态库或动态库。使用find_package就可完成对该库的查找和路径的使用。语法如下:
find_package(<package> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[NO_POLICY_SCOPE])
常用参数:
package:必填参数。查找包名,注意包的名字。
REQUIRED:可选参数。表示要查找到该包名,找不到则停止CMake的执行。若不填REQUIRED字段,即使找不到,CMake继续执行。
COMPONENTS:可选参数。该参数后面填写必须要找到的组件components,若有一个找不到就算失败,CMake就会停止执行。
(2)opecv环境demo用法
(1)查看包的.cmake文件
(2)确定包名和库文件相关的变量
接着打开上面的OpenCVConfig.cmake文件,如下:
opencv的包名:OpenCV
.h文件地址变量:OpenCV_INCLUDE_DIRS
链接库名称变量:OpenCV_LIBS
完成demo如下:
#include <opencv2/opencv.hpp>
using namespace cv;
int main() {
Mat img;
// 读取图像
img = imread("/home/han/Pictures/1.PNG",1); // 1-RGB、0-gray
// 创建一个名为 "beautiful"窗口
namedWindow("beautiful",WINDOW_AUTOSIZE);
// 在窗口中显示“beautiful”窗口
imshow("beautiful", img);
// 等待6000 ms后窗口自动关闭
waitKey(6000);
// destroyAllWindows();
// destroyWindow("beautiful");
return 0;
}
CMakeLists.txt文件如下:
PROJECT(MAIN)
cmake_minimum_required(VERSION 3.5)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# find required opencv
find_package(OpenCV REQUIRED)
# directory of opencv headers
include_directories(${OpenCV_INCLUDE_DIRS})
# name of executable file and path of source file
add_executable(MAIN main.cpp)
# directory of opencv library
#link_directories(${OpenCV_LIBRARY_DIRS})
message("OpenCV_LIBRARY_DIRS is ${OpenCV_LIBRARY_DIRS}")
# opencv libraries
target_link_libraries(MAIN ${OpenCV_LIBS})
关于find_package的用法可参考:“轻松搞定CMake”系列之find_package用法详解_https://blog.csdn.net/zhanghm1995/article/details/-CSDN博客
3、多个CMake工程编译
(1)文件结构如如下
(2)各级CMake内容
a> 最外层CMake
cmake_minimum_required(VERSION 3.16.3)
project(test2)
add_subdirectory(src)
#add_subdirectory下多个目录和输出目录关系
b> src下CMake
cmake_minimum_required(VERSION 3.16.3)
# 计数器变量
set(DIR_COUNT 0)
# 获取当前目录下的文件和目录列表
file(GLOB DIR_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ./*)
# 遍历列表
foreach(DIR_NAME ${DIR_LIST})
# 判断是否为目录
set(curTMP ${CMAKE_CURRENT_SOURCE_DIR}/${DIR_NAME})
message("curTMP0 is ${curTMP}")
if(IS_DIRECTORY ${curTMP})
# 增加计数
math(EXPR DIR_COUNT "${DIR_COUNT}+1")
add_subdirectory(${curTMP})
endif()
endforeach()
# 输出目录数量
message("当前目录下共有 ${DIR_COUNT} 个目录")
c> project1下面CMake
cmake_minimum_required(VERSION 3.16.3)
project(project1)
include_directories(./include)
add_definitions(-O0 -g3 -ggdb)
aux_source_directory(./ SRC_LIST) #查找源文件(.c/.cpp文件),不能递归到下一个目录
#file(GLOB SRC_LIST src/*.cpp) #不能递归到下一个目录
#file(GLOB_RECURSE SRC_LIST src/*.cpp) #不能递归到下一个目录
message("SRC_LIST var is ${SRC_LIST}")
add_executable(${PROJECT_NAME} ${SRC_LIST} main.cpp)
d> project2下面的CMake
cmake_minimum_required(VERSION 3.16.3)
project(project2)
include_directories(./include)
add_definitions(-O0 -g3 -ggdb)
aux_source_directory(./ SRC_LIST) #查找源文件(.c/.cpp文件),不能递归到下一个目录
#file(GLOB SRC_LIST src/*.cpp) #不能递归到下一个目录
#file(GLOB_RECURSE SRC_LIST src/*.cpp) #不能递归到下一个目录
message("SRC_LIST var is ${SRC_LIST}")
add_executable(${PROJECT_NAME} ${SRC_LIST} main.cpp)
(3)生成的产物路径如下
在项目最外层目录,创建build目录,执行如下命令:
$ cmake ..
$ make -j
生成的目标产物目录结构如下:
从上面的产物结构可以看出,产物的路径跟项目路径结构是相似的。
4、一个工程依赖另一个工程生成的动态库
(1)项目目录如下
(2)CMake预定义变量
CMAKE_SOURCE_DIR:多个工程最顶层的CMakeLists.txt所在的路径。
CMAKE_CURRENT_SOURCE_DIR:当前正在目录的CMakeLists.txt的路径。
PROJECT_SOURCE_DIR:当前处理工程的CMakeLists.txt所在的路径。
CMAKE_LIBRARY_OUTPUT_DIRECTORY:放置生成动态库文件的路径
CMAKE_ARCHIVE_OUTPUT_DIECTORY:放在生成静态库文件的路径
(3)最外层工程下CMake
cmake_minimum_required(VERSION 3.16.3)
project(test)
add_subdirectory(src)
(4)src下的CMake
cmake_minimum_required(VERSION 3.16.3)
file(GLOB DIR_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ./*)
message("DIR_LIST is ${DIR_LIST}")
set(FILE_CNT 0)
foreach(DIR_NAME ${DIR_LIST})
set(curTemp ${CMAKE_CURRENT_SOURCE_DIR}/${DIR_NAME})
if(IS_DIRECTORY ${curTemp})
add_subdirectory(${curTemp})
math(EXPR FILE_CNT "${FILE_CNT}+1")
endif()
endforeach()
message("FILE_CNT IS ${FILE_CNT}")
(5)project1下的CMake
cmake_minimum_required(VERSION 3.16.3)
project(F1Dev)
set(CMAKE_VERBOSE_MAKEFILE ON)#打开编译过程中信息
include_directories(include)
file(GLOB_RECURSE SRC_CPP src/*.cpp)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
add_library(dev SHARED ${SRC_CPP})
string(TIMESTAMP COMPILE_TIME %Y%m%d_%H%M%S)
message("F1Dev Time is ${COMPILE_TIME}")
(6)project2下的CMake
cmake_minimum_required(VERSION 3.16.3)
project(operator)
set(CMAKE_VERBOSE_MAKEFILE ON)#打开编译过程中信息
include_directories(thirdParty include)
file(GLOB_RECURSE SRC_CPP src/*.cpp)
message("PROJECT_SOURCE_DIR IS ${PROJECT_SOURCE_DIR}")
message("CMAKE_SOURCE_DIR IS ${CMAKE_SOURCE_DIR}")
link_directories(${CMAKE_SOURCE_DIR}/bin)
add_executable(operator main.cpp ${SRC_CPP})
target_link_libraries(operator dev)
string(TIMESTAMP COMPILE_TIME %Y%m%d_%H%M%S)
message("operator Time is ${COMPILE_TIME}")
(7)main.cpp文件如下
#include "controllDev.h"
int main(int argc,char** argv)
{
AIFactroy::Operator obj1;
obj1.InitDev(1);
obj1.RunDev(1);
obj1.RunDev(2);
return 0;
}
运行结果如下
完整的工程demo见链接:CMake中一个工程依赖另一个工程生成的动态库demo资源-CSDN文库
附加:
CMake编译工程/第一个CMakeLists.txt(最详细案例演示)_芯辰大海的博客-CSDN博客
【CMake】CMakeLists.txt的超傻瓜手把手教程(附实例源码)_Yngz_Miao的博客-CSDN博客_cmakelists教程