

Introduction:
The purpose of this content is similar to the previous article, but the starting point is different. Our plan is to read version information from a file instead of setting it in CMakeLists.txt. The goal of storing the version in a separate file is to allow other build frameworks or development tools to use information independent of CMake, without needing to duplicate the information across multiple files.

✦
Project Structure
✦
.
├── CMakeLists.txt
├── example.cpp
├── version.hpp.in
└── VERSION.txt
https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter6/03
✦
Related Source Code
✦
VERSION.txt
2.0.1-rc-2
version.hpp.in
#pragma once
#include <string>
const std::string PROGRAM_VERSION = "@PROGRAM_VERSION@";
example.cpp
#include "version.hpp"
#include <iostream>
int main() {
std::cout << "This is output from code v" << PROGRAM_VERSION << std::endl;
std::cout << "Hello CMake world!" << std::endl;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(example LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION.txt")
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION.txt" PROGRAM_VERSION)
string(STRIP "${PROGRAM_VERSION}" PROGRAM_VERSION)
else()
message(FATAL_ERROR "File ${CMAKE_CURRENT_SOURCE_DIR}/VERSION.txt not found")
endif()
configure_file(
version.hpp.in
generated/version.hpp
@ONLY
)
add_executable(example example.cpp)
target_include_directories(example
PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/generated
)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION.txt")
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION.txt" PROGRAM_VERSION)
string(STRIP "${PROGRAM_VERSION}" PROGRAM_VERSION)
else()
message(FATAL_ERROR "File ${CMAKE_CURRENT_SOURCE_DIR}/VERSION.txt not found")
endif()
First, check if the VERSION.txt file exists; if it does not, an error message is issued. If it exists, the content is read into the PROGRAM_VERSION variable, which strips trailing whitespace.
Once the PROGRAM_VERSION variable is set, it can be used to configure version.hpp.in to generate generated/version.hpp:
configure_file(
version.hpp.in
generated/version.hpp
@ONLY
)
✦
Result Display
✦
$ mkdir -p build
$ cd build
$ cmake ..
$ cmake --build .
$ ./example
This is output from code v2.0.1-rc-2
Hello CMake world!
version.hpp
#pragma once
#include <string>
const std::string PROGRAM_VERSION = "2.0.1-rc-2";
Finally, I wish everyone to become stronger!!!

