[笔记]Modern CMake 3:基本介绍

文章目录

    • 组织项目结构
    • 运行其他程序
      • 在configure阶段运行命令
      • 在build阶段运行命令
      • 一个完整的例子

Modern CMake 3:基本介绍

组织项目结构

CMake没有统一的项目结构,一些常用原则可以帮助我们组织更好的项目结构:

  • 项目内部能够十分方便的读取其他工程;
  • 避免项目结构冲突;
  • 并行构建.

一个典型的例子(仅做参考),假设你的项目叫做project,你的库名为lib,可执行程序名为app

- project
  - .gitignore
  - README.md
  - LICENCE.md
  - CMakeLists.txt
  - cmake
    - FindSomeLib.cmake
  - include
    - project
      - lib.hpp
  - src
    - CMakeLists.txt
    - project
      - CMakeLists.txt
      - lib.cpp
  - apps
    - CMakeLists.txt
    - app.cpp
  - tests
    - testlib.cpp
  - docs
    - Doxyfile.in
  - extern
    - googletest
  - scripts
    - helper.py
  1. 源文件中都应包含CMakeLists.txt文件。可以使用add_subdirectory添加包含CMakeLists.txt文件的子目录到工程。
  2. 大多时候,我们需要cmake文件夹,所有Find*.cmake文件都应在此文件夹中找到。把cmake文件夹添加到CMake path的方法:
set(CMAKE_MOUDLE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKEMOUDLE_PATH})

如果你想使Build目录在source目录之外,添加以下代码在你的CMakeLists.txt文件的顶部:

### Require out-of-source builds
file(TO_CMAKE_PATH "$PROJECT_BINARY_DIR/CMakeLists.txt" LOC_PATH)
if(EXISTS ${LOC_PATH})
	message(FATAL_ERROR "You cannot build in a source directory (or any directory with a CMakeLists.txt file). Please make a build subdirectory. Feel free to remove CMakeCache.txt and CMakeFiles.")
endif()

运行其他程序

在configure阶段运行命令

CMake在configure阶段运行命令相当的容易。使用execute_process运行进程并能得到结果。还可以使用${CMAKE_COMMAND},find_packaage(Git,或者find_program运行命令。使用RESULT_VARIABLE检测返回值,OUTPUT_VARIABLE可以得到输出结果。

举一个更新git子模块的例子:

find_package(Git QUIET)

if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
	execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
		WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
		RESULT_VARIABLE GIT_SUBMOD_RESULT)
	if(NOT GIT_SUBMOD_RESULT EQUAL "0")
		message(FATAL_ERROR "git submodule update --init failed with ${GIT_SUBMODE_RESULT}, please checkout submoudles")
	endif()
endif()

在build阶段运行命令

在build阶段运行命令需要一些技巧。我们需要考虑什么时候需要运行命令?以及命令的输出是否为另外target的输入?以下是一个调研Python脚本生成头文件的例子:

find_package(PythonInterp REQUIRED)
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/Generated.hpp"
	COMMAND "${PYTHON_EXECUTABLE" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/GenerateHeader.py" --argument
	DEPENDS some_target)

add_custom_target(generate_header ALL
	DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/include/Generated.hpp")

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/GENERATED.hpp DESTINATION include)

一个完整的例子

# 所有的CMake files都是由此开始的。在新版本CMake中,给定最低版本号建议使用rang方式。
cmake_minimun_required(VERSION 3.1...3.14)

# 项目声明。你应该表明项目使用的语言和版本,这都是非常有价值的信息
project(ModernCMakeExample VERSION 1.0 LANGUAGES CXX)

# 设置变量(尤其是c++语言,本例没有变量声明)

# Find packages 

add_library(MyLibExample simple_lib.cpp simple_lib.h)

# 应用程序,输出名称和target保持一致
add_executable(MyExample simple_example.cpp)

# 链接target
target_link_library(MyExample PRIVATE MyLibExample)

你可能感兴趣的:(CMake)