1# - When enabled, stamp the current version on C/C++ sources 2# 3# To set up your source code for proper stamping, start your file 4# with a Doxygen-style comment block, starting with /* and ending with */ 5# On a line by itself, with unimportant whitespace, add the standard Doxygen 6# "version" command: 7# @version xxx 8# or 9# \version xxx 10# 11# To make sure it works, please do actually put xxx as the current version: 12# when you save, add one of the command below to your cmake build, and run 13# cmake, it should replace xxx with the current version. (It replaces anything 14# between the end of the whitespace after \version and the end of the line 15# with the version that you pass in your build script, so put nothing else 16# on that line!) 17# 18# For <version>, I recommend passing the value of a CMake variable like 19# ${CPACK_PACKAGE_VERSION} 20# Remember, reduced duplication of information means reduced errors! 21# 22# WARNING! 23# This does edit your source directory, but will only execute if the 24# (hidden/advanced, default OFF) variable ENABLE_VERSION_STAMPING is on. 25# 26# Additionally, it tries to be very careful: 27# - It will not edit files that are outside your source tree 28# - It will only attempt a substitution within the first C-style comment block 29# of your code (that is, the first /* */), but only if // is not found first 30# 31# stamp_target_with_version(<version> <target_name> [HEADERS_ONLY | <source>...]) - 32# If no source file is specified, all will be processed. 33# 34# stamp_sources_with_version(<version> <source> [<source> ...]) - 35# Use for files not directly associated with a target. 36# 37# Original Author: 38# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> 39# http://academic.cleardefinition.com 40# Iowa State University HCI Graduate Program/VRAC 41# 42# Copyright Iowa State University 2009-2010. 43# Distributed under the Boost Software License, Version 1.0. 44# (See accompanying file LICENSE_1_0.txt or copy at 45# http://www.boost.org/LICENSE_1_0.txt) 46 47if(__stamp_sources_with_version) 48 return() 49endif() 50set(__stamp_sources_with_version YES) 51 52if(NOT APPLE) 53 option(ENABLE_VERSION_STAMPING 54 "Modify source files to update the version in the comment header. Maintainers only!" 55 OFF) 56 mark_as_advanced(ENABLE_VERSION_STAMPING) 57endif() 58 59# Stash where our data is, at include() time 60get_filename_component(_sswv_mod_dir ${CMAKE_CURRENT_LIST_FILE} PATH) 61 62 63# Internal utility function - not for outside use 64function(_stamp_file_with_version version filename) 65 if(NOT SED_EXECUTABLE) 66 find_program(SED_EXECUTABLE sed) 67 mark_as_advanced(SED_EXECUTABLE) 68 endif() 69 # TODO: fix the sed script on Mac 70 if(SED_EXECUTABLE AND ENABLE_VERSION_STAMPING AND NOT APPLE) 71 get_source_file_property(_abs "${filename}" LOCATION) 72 if(NOT _abs) 73 get_filename_component(_abs "${filename}" ABSOLUTE) 74 endif() 75 file(RELATIVE_PATH _rel "${CMAKE_SOURCE_DIR}" "${_abs}") 76 if(NOT "${_rel}" MATCHES "[.][.]") 77 # Only if this file is in the source tree 78 get_filename_component(_name "${filename}" NAME) 79 set(_in_source_dir YES) 80 # Create the sed script 81 configure_file("${_sswv_mod_dir}/StampSourcesWithVersion.sed.in" 82 "${CMAKE_CURRENT_BINARY_DIR}/stamp-${_name}.sed" 83 @ONLY) 84 85 if(APPLE) 86 set(extendedre_arg -E) 87 else() 88 set(extendedre_arg -r) 89 endif() 90 91 set(sedargs 92 ${extendedre_arg} 93 -f 94 "${CMAKE_CURRENT_BINARY_DIR}/stamp-${_name}.sed" 95 ${filename}) 96 97 # Run the sed script 98 execute_process(COMMAND 99 ${SED_EXECUTABLE} 100 ${sedargs} 101 OUTPUT_FILE 102 "${CMAKE_CURRENT_BINARY_DIR}/stampedoutput-${_name}.out" 103 WORKING_DIRECTORY 104 "${CMAKE_CURRENT_SOURCE_DIR}") 105 106 # Check to see if changes were made 107 execute_process(COMMAND 108 ${CMAKE_COMMAND} 109 -E 110 compare_files 111 "${CMAKE_CURRENT_BINARY_DIR}/stampedoutput-${_name}.out" 112 ${filename} 113 WORKING_DIRECTORY 114 "${CMAKE_CURRENT_SOURCE_DIR}" 115 RESULT_VARIABLE 116 files_different 117 OUTPUT_QUIET 118 ERROR_QUIET) 119 120 # if so, run it again, but in-place this time 121 if(files_different) 122 message(STATUS "Stamping file ${_rel} with version ${version}") 123 execute_process(COMMAND 124 ${SED_EXECUTABLE} 125 -i 126 ${sedargs} 127 OUTPUT_FILE 128 "${CMAKE_CURRENT_BINARY_DIR}/stampedoutput-${_name}.out" 129 WORKING_DIRECTORY 130 "${CMAKE_CURRENT_SOURCE_DIR}") 131 else() 132 message(STATUS "Version stamp up-to-date on file ${_rel}") 133 endif() 134 endif() 135 endif() 136endfunction() 137 138function(stamp_sources_with_version version) 139 foreach(_file ${ARGN}) 140 _stamp_file_with_version("${version}" "${_file}") 141 endforeach() 142endfunction() 143 144function(stamp_target_with_version version target_name) 145 146 set(_target_stampables) 147 148 get_target_property(_target_sources ${target_name} SOURCES) 149 foreach(_source ${_target_sources}) 150 get_source_file_property(_lang "${_source}" LANGUAGE) 151 get_source_file_property(_loc "${_source}" LOCATION) 152 if("${_lang}" MATCHES "CXX" OR "${_lang}" MATCHES "C") 153 list(APPEND _target_stampables "${_loc}") 154 endif() 155 endforeach() 156 157 set(_src_to_stamp) 158 if("${ARGN}" STREQUAL "HEADERS_ONLY") 159 # We were passed HEADERS_ONLY 160 foreach(_file ${_target_stampables}) 161 get_filename_component(_ext "${_file}" EXT) 162 if("${_ext}" MATCHES "[.]([hH]|hpp|HPP|hxx|HXX)$" OR NOT _ext) 163 list(APPEND _src_to_stamp "${_file}") 164 endif() 165 endforeach() 166 167 elseif(ARGN) 168 # We were passed a list of files 169 set(_src_to_stamp ${ARGN}) 170 171 else() 172 # We were passed only a target - process all source in the source tree. 173 set(_src_to_stamp ${_target_stampables}) 174 endif() 175 176 stamp_sources_with_version(${version} ${_src_to_stamp}) 177endfunction() 178 179 180 181