C++工程的CMakeLists.txt文件编写

目录

1、简单demo

(1)最简单的demo工程如下:

 (2)CMakeLists.txt文件

2、包含三方库demo

(1)find_package用法

(2)opecv环境demo用法

3、多个CMake工程编译

(1)文件结构如如下

(2)各级CMake内容

a> 最外层CMake

b> src下CMake

c> project1下面CMake

 d> project2下面的CMake

(3)生成的产物路径如下

4、一个工程依赖另一个工程生成的动态库

(1)项目目录如下

(2)CMake预定义变量

(3)最外层工程下CMake

(4)src下的CMake

(5)project1下的CMake

(6)project2下的CMake

(7)main.cpp文件如下


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教程

【C++】Cmake使用教程(看这一篇就够了)_隐居的遮天恶鬼的博客-CSDN博客

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CMakeLists.txt文件是用于管理C代码编译的工具。通过使用cmake命令,可以将CMakeLists.txt文件中的定义转换成编译所需的makefile文件,再使用make命令编译可生成可执行文件。这样可以方便地管理C代码的编译过程。 在使用CMakeLists.txt文件进行C程序的编译时,可以按照以下几种方式进行编译: 1. 单独编译main.cpp文件:这种方式适用于只有一个源文件的情况,可以直接在CMakeLists.txt文件中指定编译的源文件和生成的可执行文件的名称。 2. 编译一组cpp和h文件:如果有多个cpp和h文件需要编译,可以在CMakeLists.txt文件中使用add_executable命令指定编译的源文件,然后使用target_link_libraries命令链接需要的库文件。这样可以将多个源文件编译成一个可执行文件。 3. 编译多组cpp和h文件:如果有多组cpp和h文件需要编译,可以在CMakeLists.txt文件中使用add_subdirectory命令指定需要编译的子目录,并在子目录中的CMakeLists.txt文件中进行具体的编译设置。这样可以将多组源文件编译成多个可执行文件。 通过使用CMakeLists.txt文件进行编译,可以更加灵活地管理C代码的编译过程,使代码结构更清晰,便于维护和管理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [CMake编译工程/第一个CMakeLists.txt(最详细案例演示)](https://blog.csdn.net/weixin_42322256/article/details/124191696)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [编写CMakeLists.txt文件进行C++程序的cmake编译](https://blog.csdn.net/qq_39400324/article/details/124356401)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [C++版本使用CMakeLists.txt编译(同目录多个源文件)可执行文件](https://download.csdn.net/download/Zhangyanfeng1/12603209)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值