NMT Data Mining & Big Data

CMake学习笔记2

2025-03-31
NMt

记录学习CMake管理C++工程的过程(使用.cmake文件)。

@@@@

CMake的更多命令详解

  1. cmake_minimum_required //指定 cmake 的最小版本
     cmake_minimum_required(VERSION 3.4.1) 
    

    注: 这行命令是可选的,我们可以不写这句话,但在有些情况下,如果 CMakeLists.txt 文件中使用了一些高版本 cmake 特有的一些命令的时候,就需要加上这样一行,提醒用户升级到该版本之后再执cmake。

  2. project //指定项目信息

     project(
         Demo 
         LANGAGES CXX C
         DESCRIPTION "My own game code"
         VERSION 0.1.0)
    

    注: 这个命令不是强制性的,但最好都加上。 第一个参数是必须的,其他可选。 当你定义了项目名称之后,CMake 会自动生成以下两个变量:

    • demo_BINARY_DIR
    • demo_SOURCE_DIR

    这两个变量分别表示项目的二进制输出目录和源代码目录。 此外,CMake 还会定义两个通用变量:

    • PROJECT_BINARY_DIR
    • PROJECT_SOURCE_DIR
      这两个变量与 demo_BINARY_DIR 和 demo_SOURCE_DIR 等价,区别在于它们是更通用的写法,不依赖于项目名称。
  3. add_executable //用于在项目中添加一个可执行文件的目标

     add_executable(<name> <options>... <sources>...)
     # for example: 
     add_executable(demo demo.cpp) # 生成可执行文件
    
    • <name>:指定可执行文件的名称。这个名称将用作生成的可执行文件的名称,并且也将用于在 CMake 中引用该目标。
    • <options>:可选参数,用于指定特定的选项或属性。例如,可以使用 -D 选项定义预处理宏,或者使用 -I 选项指定额外的包含目录等。
    • <sources>:指定源文件的列表,用于构建可执行文件。这可以是一个或多个源文件,可以包括 C、C++、汇编等类型的源文件。

    生成静态库示例:

     add_library(<静态库目标名> STATIC <源文件列表>)
     add_library(mylib_static STATIC src/mylib.cpp)    
    

    生成动态库示例:

     add_library(<动态库目标名> SHARED <源文件列表>)
     add_library(mylib_shared SHARED src/mylib.cpp)
    
  4. set //用于设置变量的值

     set(<variable> <value>... [PARENT_SCOPE])    
     # for example:  
     set(far "Hello, CMake!")
     set(CMAKE_CXX_STANDARD 11) // 设置使用 C++ 11 标准 
    
  5. message //用于在 cmake 中打印相应的信息

     message([<mode>] "message text" [arg1 [arg2 ...]])
     # for example: 
     message(STATUS "hello cmake")
    
    • mode 用于指定输出消息的模式,常用的模式如下:
      • STATUS:以普通信息的形式输出。
      • WARNING:以警告信息的形式输出。
      • AUTHOR_WARNING:以作者警告信息的形式输出。
      • SEND_ERROR:以错误信息的形式输出,并停止构建过程。
      • FATAL_ERROR:以致命错误信息的形式输出,并立即终止构建过程。
  6. get_filename_component //用于对文件路径进行解析,从而提取出文件名、目录、扩展名等相关信息

     get_filename_component(<VAR> <FileName> <COMPONENT> [CACHE])
     # for example: 
     # CMAKE_CURRENT_LIST_DIR 表示当前正在处理的cmake变量 
     get_filename_component(CURRENT_DIR_PATH "${CMAKE_CURRENT_LIST_DIR}" ABSOLUTE) 
     # 从完整路径中提取目录名称
     get_filename_component(CURRENT_DIR_NAME "${CURRENT_DIR_PATH}" NAME) 
     project(${CURRENT_DIR_NAME})
    
    • <VAR>:这是一个变量名,用于存储解析后的结果。
    • <FileName>:要进行解析的文件路径,可以是绝对路径,也可以是相对路径。
    • <COMPONENT>:指定要提取的文件路径信息的组件,常见的取值有以下几种:
      • PATH:提取文件路径中的目录部分。
      • NAME:提取文件的完整名称,包含扩展名。
      • NAME_WE:提取文件的名称,但不包含扩展名。
      • EXT:提取文件的扩展名。
      • ABSOLUTE:将相对路径转换为绝对路径。
    • [CACHE]:这是一个可选参数,若指定了该参数,解析结果会被存储到 CMake 缓存中。# 获取当前子CMake文件所在目录的完整路径
     # 获取当前子CMake文件所在目录的完整路径 
     # CMAKE_CURRENT_LIST_DIR 表示当前正在处理的cmake变量 
     get_filename_component(CURRENT_DIR_PATH "${CMAKE_CURRENT_LIST_DIR}" ABSOLUTE) 
    
     # 从完整路径中提取目录名称
     get_filename_component(CURRENT_DIR_NAME "${CURRENT_DIR_PATH}" NAME) 
     project(${CURRENT_DIR_NAME})
    
  7. aux_source_directory //发现目录中所有的文件

     # 用法示例
     aux_source_directory(<dir> <variable>)
    
     # for example
     cmake_minimum_required(VERSION 3.28)
    
     project(firstproject)
    
     aux_source_directory(. SRCS) # 当前目录中的文件路径 都存储到 SRCS 
    
     message(STATUS ${SRCS})
    
     #add_executable(firstproject main.cpp calc.h calc.cpp)
     add_executable(firstproject ${SRCS})
    
  8. target_include_directories // 指定要包含的头文件目录,头文件目录包含了用于编译源代码的头文件 。
    针对目标添加头文件,对于保持项目的组织结构清晰、解决头文件依赖问题非常有用

     include_directories(<target> 
                         [SYSTEM] 
                         [AFTER|BEFORE] 
                         <INTERFACE|PUBLIC|PRIVATE> 
                         dir1 [dir2 ...])
    
     target:目标的名称,必须是通过 add_executable()add_library() 等命令
             先创建出来的可执行文件或库。
     SYSTEM:可选参数,指定被包含的目录是系统目录,这会告诉编译器将这些目录视为系统的标准头文件目录,
             避免编译器产生警告
     AFTER 或 BEFORE:可选关键字,BEFORE 指定包含目录应该在默认目录之前被添加到编译器的搜索路径;
                               AFTER 则是默认情况,将包含目录添加到已有的包含目录之后
     <INTERFACE|PUBLIC|PRIVATE>:指定包含目录的范围和传播方式
         PRIVATE:目录仅对该目标可见,不会影响依赖该目标的其他目标,即只对当前目标的源文件使用。
         INTERFACE:目录不会添加到该目标的编译选项中,但会添加到链接该目标的其他目标中,即目标对应的头文件使用。
         PUBLIC:目录既会添加到该目标的编译选项中,也会添加到链接该目标的其他目标中,即目标对应的头文件、源文件都使用
         dir1,ir2:要添加为包含目录的路径列表,可以是目录名、绝对路径或相对路径 
    
     # for example
     set(HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../Person)
     target_include_directories(${PROJECT_NAME} PRIVATE ${HEADER_DIR})
    

实例2引入

CMake 构建方法2:调用子目录中的cmake脚本方法 include方法可以引入子目录中的cmake后缀的配置文件 将配置加入add_executable中

工程目录

KCircle
	|-----KCircle.cpp
	|-----KCircle.h
	|-----KCircle.cmake
KCircleMain
	|-----CMakeLists.txt
	|-----main.cpp

CMakeLists.txt 编写

cmake_minimum_required(VERSION 3.10)

Project(KCircle)

#设置默认的编译模式为 Debug
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Debug)
endif()

include(../KCircle/KCircle.cmake)

# 添加可执行文件
add_executable(${PROJECT_NAME} main.cpp ${SOURCES_FILE})

# 生成${PROJECT_NAME}.exe

# add_subdirectory(KCircle)
#add_executable(${PROJECT_NAME} main.cpp ${SOURCES_FILE})

# 向工程添加多个特定头文件的搜索路径  -I
target_include_directories(${PROJECT_NAME} PRIVATE ${HEADER_DIR})

# 显式添加源文件,使其在IDE中可
target_sources(${PROJECT_NAME} PRIVATE ${HEADERS_FILE})

.cmake 文件的编写

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 定义源文件和头文件列表,CMAKE_CURRENT_SOURCE_DIR表的CMakeLists.txt的路径
set(SOURCES_FILE
    ${CMAKE_CURRENT_SOURCE_DIR}/../KCircle/KCircle.cpp
)

set(HEADERS_FILE
    ${CMAKE_CURRENT_SOURCE_DIR}/../KCircle/KCircle.h
)

set(HEADER_DIR
    ${CMAKE_CURRENT_SOURCE_DIR}/../KCircle
)

生成工程文件以及编译文件

在项目的文件夹下输入构建命令:

call "F:\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsamd64_x86.bat"  # 这里的路径是在Visual Studio的安装路径中找的
mkdir Debug
cd Debug
# 把代码构建xx.sln文件
cmake  -G "Visual Studio 16 2019"  -A x64 -DCMAKE_BUILD_TYPE=Debug  ../KCircleMain
# 编译xx.sln 生成xx.exe
msbuild /m KCircleMain.sln /p:Platform=x64 /p:Configuration=Debug

编译成功之后,可以进入Debug目录下的Debug目录,运行exe文件,就可以执行工程:

转载请注明:南梦婷的博客 » 点击阅读原文


Similar Posts

上一篇 CMake学习笔记1

Comments