ModernCMake-Chinese
  • Introduction
  • Modern CMake 简介
    • 安装 CMake
    • 运行 CMake
    • Do's and Don'ts
    • CMake 中的新变化
  • 基础知识简介
    • 变量和 Cache
    • 在CMake 中编程
    • 与你的代码交互
    • 如何结构化你的工程
    • 运行其他程序
  • Adding Features
    • C++11 and Beyond
    • Small but common needs
    • Utilities
    • Useful modules
    • IDEs
    • Debugging
  • Including Projects
    • Submodule
    • DownloadProject
    • Fetch (CMake 3.11)
  • Testing
    • GoogleTest
    • Catch
  • Exporting and Installing
    • Installing
    • Exporting
    • Packaging
  • Looking for libraries
    • CUDA
    • OpenMP
    • Boost
    • MPI
    • ROOT
      • UseFile Example
      • Simple Example
      • Simple Example CMake 3.11+
      • Dictionary Example
    • Minuit2
Powered by GitBook
On this page
  • Configure File
  • Version.h.in
  • CMake lines:
  • Reading files

Was this helpful?

  1. 基础知识简介

与你的代码交互

Configure File

CMake allows you to access CMake variables from your code using configure_file. This command copies a file (traditionally ending in .in from one place to another, substituting all CMake variables it finds. If you want to avoid replacing existing ${} syntax in your input file, use the @ONLY keyword. There's also a COPY_ONLY keyword if you are just using this as a replacement for file(COPY.

This functionality is used quite frequently; for example, on Version.h.in:

Version.h.in

#pragma once

#define MY_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define MY_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define MY_VERSION_PATCH @PROJECT_VERSION_PATCH@
#define MY_VERSION_TWEAK @PROJECT_VERSION_TWEAK@
#define MY_VERSION "@PROJECT_VERSION@"

CMake lines:

configure_file (
    "${PROJECT_SOURCE_DIR}/include/My/Version.h.in"
    "${PROJECT_BINARY_DIR}/include/My/Version.h"
)

You should include the binary include directory as well when building your project. If you want to put any true/false variables in a header, CMake has C specific #cmakedefine and #cmakedefine01 replacements to make appropriate define lines.

You can also (and often do) use this to produce .cmake files, such as the configure files (see the section on configuring).

Reading files

The other direction can be done too; you can read in something (like a version) from your source files. If you have a header only library that you'd like to make available with or without CMake, for example, then this would be the best way to handle a version. This would look something like this:

# Assuming the canonical version is listed in a single line
# This would be in several parts if picking up from MAJOR, MINOR, etc.
set(VERSION_REGEX "#define MY_VERSION[ \t]+\"(.+)\"")

# Read in the line containing the version
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/My/Version.hpp"
    VERSION_STRING REGEX ${VERSION_REGEX})

# Pick out just the version
string(REGEX REPLACE ${VERSION_REGEX} "\\1" VERSION_STRING "${VERSION_STRING}")

# Automatically getting PROJECT_VERSION_MAJOR, My_VERSION_MAJOR, etc.
project(My LANGUAGES CXX VERSION ${VERSION_STRING})

Above, file(STRINGS file_name variable_name REGEX regex) picks lines that match a regex; and the same regex is used to then pick out the parentheses capture group with the version part. Replace is used with back substitution to output only that one group.

Previous在CMake 中编程Next如何结构化你的工程

Last updated 6 years ago

Was this helpful?