cmake-10-codeGeneration

Method

configure time + configure_file

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

project(recipe-01 LANGUAGES Fortran C)

# Get username
execute_process(
  COMMAND
    whoami
  TIMEOUT
    1
  OUTPUT_VARIABLE
    _user_name
  OUTPUT_STRIP_TRAILING_WHITESPACE
  )

# host name information
cmake_host_system_information(RESULT _host_name QUERY HOSTNAME)
cmake_host_system_information(RESULT _fqdn QUERY FQDN)

# processor information
cmake_host_system_information(RESULT _processor_name QUERY PROCESSOR_NAME)
cmake_host_system_information(RESULT _processor_description QUERY PROCESSOR_DESCRIPTION)

# os information
cmake_host_system_information(RESULT _os_name QUERY OS_NAME)
cmake_host_system_information(RESULT _os_release QUERY OS_RELEASE)
cmake_host_system_information(RESULT _os_version QUERY OS_VERSION)
cmake_host_system_information(RESULT _os_platform QUERY OS_PLATFORM)

string(TIMESTAMP _configuration_time "%Y-%m-%d %H:%M:%S [UTC]" UTC)

configure_file(print_info.c.in print_info.c @ONLY)

add_executable(example "")

target_sources(example
  PRIVATE
    example.f90
    ${CMAKE_CURRENT_BINARY_DIR}/print_info.c
  )

# print_info.c.in

#include <stdio.h>
#include <unistd.h>

void print_info(void) {
  printf("\n");
  printf("Configuration and build information\n");
  printf("-----------------------------------\n");
  printf("\n");
  printf("Who compiled                | %s\n", "@_user_name@");
  printf("Compilation hostname        | %s\n", "@_host_name@");
  printf("Fully qualified domain name | %s\n", "@_fqdn@");
  printf("Operating system            | %s\n",
         "@_os_name@, @_os_release@, @_os_version@");
  printf("Platform                    | %s\n", "@_os_platform@");
  printf("Processor info              | %s\n",
         "@_processor_name@, @_processor_description@");
  printf("CMake version               | %s\n", "@CMAKE_VERSION@");
  printf("CMake generator             | %s\n", "@CMAKE_GENERATOR@");
  printf("Configuration time          | %s\n", "@_configuration_time@");
  printf("Fortran compiler            | %s\n", "@CMAKE_Fortran_COMPILER@");
  printf("C compiler                  | %s\n", "@CMAKE_C_COMPILER@");
  printf("\n");

  fflush(stdout);
}

$ cmake . && make && ./example
	Configuration and build information
	-----------------------------------
	
	Who compiled                | jianleya
	Compilation hostname        | jianleya-VirtualBox
	Fully qualified domain name | jianleya-VirtualBox
	Operating system            | Linux, 5.8.0-49-generic, #55~20.04.1-Ubuntu SMP Fri Mar 26 01:01:07 UTC 2021
	Platform                    | x86_64
	Processor info              | Unknown P6 family, 2 core Intel(R) Core(TM) i5-7300U CPU @ 2.60GHz
	CMake version               | 3.16.3
	CMake generator             | Unix Makefiles
	Configuration time          | 2021-05-13 07:10:20 [UTC]
	Fortran compiler            | /usr/bin/f95
	C compiler                  | /usr/bin/cc

configure time by python tool

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

project(recipe-02 LANGUAGES Fortran C)

# Get username
execute_process(
  COMMAND
    whoami
  TIMEOUT
    1
  OUTPUT_VARIABLE
    _user_name
  OUTPUT_STRIP_TRAILING_WHITESPACE
  )

# host name information
cmake_host_system_information(RESULT _host_name QUERY HOSTNAME)
cmake_host_system_information(RESULT _fqdn QUERY FQDN)

# processor information
cmake_host_system_information(RESULT _processor_name QUERY PROCESSOR_NAME)
cmake_host_system_information(RESULT _processor_description QUERY PROCESSOR_DESCRIPTION)

# os information
cmake_host_system_information(RESULT _os_name QUERY OS_NAME)
cmake_host_system_information(RESULT _os_release QUERY OS_RELEASE)
cmake_host_system_information(RESULT _os_version QUERY OS_VERSION)
cmake_host_system_information(RESULT _os_platform QUERY OS_PLATFORM)

string(TIMESTAMP _configuration_time "%Y-%m-%d %H:%M:%S [UTC]" UTC)

set(_config_script
"
from pathlib import Path
source_dir = Path('${CMAKE_CURRENT_SOURCE_DIR}')
binary_dir = Path('${CMAKE_CURRENT_BINARY_DIR}')
input_file = source_dir / 'print_info.c.in'
output_file = binary_dir / 'print_info.c'

import sys
sys.path.insert(0, str(source_dir))

from configurator import configure_file
vars_dict = {
    '_user_name':             '${_user_name}',
    '_host_name':             '${_host_name}',
    '_fqdn':                  '${_fqdn}',
    '_processor_name':        '${_processor_name}',
    '_processor_description': '${_processor_description}',
    '_os_name':               '${_os_name}',
    '_os_release':            '${_os_release}',
    '_os_version':            '${_os_version}',
    '_os_platform':           '${_os_platform}',
    '_configuration_time':    '${_configuration_time}',
    'CMAKE_VERSION':          '${CMAKE_VERSION}',
    'CMAKE_GENERATOR':        '${CMAKE_GENERATOR}',
    'CMAKE_Fortran_COMPILER': '${CMAKE_Fortran_COMPILER}',
    'CMAKE_C_COMPILER':       '${CMAKE_C_COMPILER}',
}
configure_file(input_file, output_file, vars_dict)
")

find_package(PythonInterp QUIET REQUIRED)

execute_process(
  COMMAND
    ${PYTHON_EXECUTABLE} "-c" ${_config_script}
  )

add_executable(example "")

target_sources(example
  PRIVATE
    example.f90
    ${CMAKE_CURRENT_BINARY_DIR}/print_info.c
  )

$ ./example
	Configuration and build information
	-----------------------------------
	
	Who compiled                | jianleya
	Compilation hostname        | jianleya-VirtualBox
	Fully qualified domain name | jianleya-VirtualBox
	Operating system            | Linux, 5.8.0-49-generic, #55~20.04.1-Ubuntu SMP Fri Mar 26 01:01:07 UTC 2021
	Platform                    | x86_64
	Processor info              | Unknown P6 family, 2 core Intel(R) Core(TM) i5-7300U CPU @ 2.60GHz
	CMake version               | 3.16.3
	CMake generator             | Unix Makefiles
	Configuration time          | 2021-05-13 07:14:32 [UTC]
	Fortran compiler            | /usr/bin/f95
	C compiler                  | /usr/bin/cc

build time by python tool

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(recipe-03 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# we require Python for this recipe to work
find_package(PythonInterp QUIET REQUIRED)

# generate directory where we place the generated code
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated)

# upper bound
set(MAX_NUMBER "100" CACHE STRING "Upper bound for primes")

# generate code
add_custom_command(
  OUTPUT
    ${CMAKE_CURRENT_BINARY_DIR}/generated/primes.hpp
  COMMAND
    ${PYTHON_EXECUTABLE} generate.py ${MAX_NUMBER} ${CMAKE_CURRENT_BINARY_DIR}/generated/primes.hpp
  WORKING_DIRECTORY
    ${CMAKE_CURRENT_SOURCE_DIR}
  DEPENDS
    generate.py
  )

add_executable(example "")

target_sources(example
  PRIVATE
    example.cpp
    ${CMAKE_CURRENT_BINARY_DIR}/generated/primes.hpp
  )

target_include_directories(example
  PRIVATE
    ${CMAKE_CURRENT_BINARY_DIR}/generated
  )

$ make
	[ 33%] Generating generated/primes.hpp
	Scanning dependencies of target example
	[ 33%] Generating generated/primes.hpp
	[ 66%] Building CXX object CMakeFiles/example.dir/example.cpp.o
	[100%] Linking CXX executable example
	[100%] Built target example


Product Code

use project version

# set minimum cmake version
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

# project name and language
project(recipe-04 VERSION 2.0.1 LANGUAGES C)

# generate file version.h based on version.h.in
configure_file(
  version.h.in
  generated/version.h
  @ONLY
  )

# example code
add_executable(example example.c)

# needs to find the generated header file
target_include_directories(example
  PRIVATE
    ${CMAKE_CURRENT_BINARY_DIR}/generated
  )
# version.h.in
	#pragma once
	
	#define PROJECT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
	#define PROJECT_VERSION_MINOR @PROJECT_VERSION_MINOR@
	#define PROJECT_VERSION_PATCH @PROJECT_VERSION_PATCH@
	
	#define PROJECT_VERSION "v@PROJECT_VERSION@"

# example.c
// provides PROJECT_VERSION, PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR
#include "version.h"

#include <stdio.h>

int main() {
  printf("This is output from code %s\n", PROJECT_VERSION);
  printf("Major version number: %i\n", PROJECT_VERSION_MAJOR);
  printf("Minor version number: %i\n", PROJECT_VERSION_MINOR);

  printf("Hello CMake world!\n");
}
	
# log
$ ./example
This is output from code v2.0.1
Major version number: 2
Minor version number: 0
Hello CMake world!

use version file

# set minimum cmake version
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(recipe-05 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# read PROGRAM_VERSION from file
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION")
  file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" PROGRAM_VERSION)
  string(STRIP "${PROGRAM_VERSION}" PROGRAM_VERSION)
else()
  message(FATAL_ERROR "File ${CMAKE_CURRENT_SOURCE_DIR}/VERSION not found")
endif()

# generate file version.hpp based on version.hpp.in
configure_file(
  version.hpp.in
  generated/version.hpp
  @ONLY
  )

# example code
add_executable(example example.cpp)

# needs to find the generated header file
target_include_directories(example
  PRIVATE
    ${CMAKE_CURRENT_BINARY_DIR}/generated
  )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值