Alexandre Lision | ddd731e | 2014-01-31 11:50:08 -0500 | [diff] [blame] | 1 | # - a CMake module that helps to create a source distribution
|
| 2 | #
|
| 3 | # This module provide some macros that setup a source distribution.
|
| 4 | # In contrast to standard CPack processing this is a very lightweight
|
| 5 | # module that works very fast. The source distribution module enables
|
| 6 | # the Cmake user to add indivdiual files and directories and thus
|
| 7 | # provides a more fine grained control than CPack.
|
| 8 | #
|
| 9 | # The module works similar to the standard CMake INSTALL command: the
|
| 10 | # macros of this module prepare CMake files (cmake_src_dist.cmake) that
|
| 11 | # contain all necessary commands to create the distribution directoy.
|
| 12 | # The make target 'src_dist' executes the commands and builds the
|
| 13 | # compressed tar file of the source distribution.
|
| 14 | #
|
| 15 | # Usage:
|
| 16 | # src_distribution_init([NOT_INCLUDE_DEFAULT] [<distribtuion name>])
|
| 17 | # Initializes the source distribution functions. Each CMakeList.txt
|
| 18 | # that distributes sources must call this macro before it can use
|
| 19 | # other source distrbution macros.
|
| 20 | # Only the first call from the top level CMakeLists.txt uses the
|
| 21 | # distribution name argument. All subsequent call silently ignore it.
|
| 22 | # The macro sets the distribution name to ${PROJECT_NAME}-{VERSION}
|
| 23 | # if no distribution name is provided.
|
| 24 | # The macro automatically includes some default files and directories
|
| 25 | # into the distribution: CMakeLists.txt and the cmake directory.
|
| 26 | # Set NOT_INCLUDE_DEFAULT to disable this function.
|
| 27 | # The macro creates a make target 'src_dist'. This target executes
|
| 28 | # all operations to create the distribution directory structure and
|
| 29 | # to create the compressed tar file <distrbution name>.tar.gz. The
|
| 30 | # source distribution directory can be deleted afterwards.
|
| 31 | #
|
| 32 | # add_src_dist_dirs(<DIRECTORY> [<DIRECTORY>]*)
|
| 33 | # Works imilar to the normal add_subdirectory command of CMake.
|
| 34 | # This call adds a subdirectory that contains sources or other
|
| 35 | # files that go into a source distribution. The subdirecty must
|
| 36 | # contain a CMakeLists.txt file that also uses the source distrbution
|
| 37 | # macros.
|
| 38 | #
|
| 39 | # add_src_dist_files(<FILENAME> [<FILENAME>]*)
|
| 40 | # Adds one or more files to the source distrbution.
|
| 41 | #
|
| 42 | # Eaxample:
|
| 43 | #
|
| 44 | # include(SourceDistrbution)
|
| 45 | #
|
| 46 | # The following call initializes the module and sets the distrbution's
|
| 47 | # name to 'mySourceDist'. The macro creates a directory with this name
|
| 48 | # in the current build directory and include the standard CMakeLists.txt
|
| 49 | # file and the 'cmake' directory (it it exists) into the distribution.
|
| 50 | #
|
| 51 | # src_distribution_init(mySourceDist)
|
| 52 | #
|
| 53 | # Now add some files (assumes ${src_files} was set previously):
|
| 54 | # add_src_dist_files(README LICENSE ${src_files})
|
| 55 | #
|
| 56 | # Now add a subdirectoy, in this case an include directory:
|
| 57 | # add_src_dist_dirs(include)
|
| 58 | #
|
| 59 | #
|
| 60 | # ---- internal macros ----
|
| 61 | #
|
| 62 | # This macro gets the current directory relative to CMAKE_SOURCE_DIR
|
| 63 | # and sets an internal variable to the current distribution directory.
|
| 64 | # Another variable holds the current path to the CMake command file.
|
| 65 | # Other macros use these variable to construct commands
|
| 66 | # to build the distribution structure.
|
| 67 | #
|
| 68 | MACRO (_set_src_dist_scope_vars)
|
| 69 | STRING(REPLACE "${CMAKE_SOURCE_DIR}" "" _src_dist_subdir "${CMAKE_CURRENT_SOURCE_DIR}")
|
| 70 | if (NOT _src_dist_subdir)
|
| 71 | set(_src_dist_fulldir ${SRC_DIST_DIR})
|
| 72 | else()
|
| 73 | set(_src_dist_fulldir ${SRC_DIST_DIR}${_src_dist_subdir})
|
| 74 | endif()
|
| 75 | set(_src_dist_cmd_file_path ${CMAKE_CURRENT_BINARY_DIR}/${_SRC_DIST_CMD_FILE_NAME})
|
| 76 | ENDMACRO()
|
| 77 |
|
| 78 | #
|
| 79 | # Check for the NOT_INCLUDE_DEFAULT option.
|
| 80 | #
|
| 81 | MACRO(_src_dist_parse_options _result _default _length)
|
| 82 | set(${_default} TRUE)
|
| 83 |
|
| 84 | foreach(_arg ${ARGN})
|
| 85 | if (_arg STREQUAL "NOT_INCLUDE_DEFAULT")
|
| 86 | set(${_default} FALSE)
|
| 87 | endif()
|
| 88 | endforeach()
|
| 89 |
|
| 90 | set(${_result} ${ARGN})
|
| 91 | list(LENGTH ${_result} ${_length})
|
| 92 | if (${_length} GREATER 0)
|
| 93 | list(REMOVE_ITEM ${_result} "NOT_INCLUDE_DEFAULT")
|
| 94 | endif()
|
| 95 | # recompute length of list
|
| 96 | list(LENGTH ${_result} ${_length})
|
| 97 |
|
| 98 | ENDMACRO()
|
| 99 |
|
| 100 |
|
| 101 | #
|
| 102 | # This macro initializes the source distribution package.
|
| 103 | # Only the top-level initialization macro init_src_distribution()
|
| 104 | # calls this internal macro.
|
| 105 | #
|
| 106 | MACRO (_src_dist_internal_init)
|
| 107 | # internal variable for distribution cmake file
|
| 108 | set(_SRC_DIST_CMD_FILE_NAME "cmake_src_dist.cmake")
|
| 109 |
|
| 110 | if (${_src_dist_dirlist_length} EQUAL 0)
|
| 111 | set(_src_dist_tardir ${PROJECT_NAME}-${VERSION})
|
| 112 | else()
|
| 113 | list(GET _src_dist_dirlist 0 _src_dist_tardir)
|
| 114 | endif()
|
| 115 | set(SRC_DIST_DIR ${CMAKE_BINARY_DIR}/${_src_dist_tardir})
|
| 116 |
|
| 117 | message(STATUS "Source distribution direcrory set to: ${SRC_DIST_DIR}")
|
| 118 |
|
| 119 | _set_src_dist_scope_vars()
|
| 120 | file(REMOVE ${_src_dist_cmd_file_path})
|
| 121 |
|
| 122 | # fill in first commands into the distribution cmake file. Calling
|
| 123 | # 'make src_dist' executes the stored commands and prepares the source
|
| 124 | # distrubtion.
|
| 125 | #
|
| 126 | file(APPEND ${_src_dist_cmd_file_path} "
|
| 127 | # clear contents of an existing distribution directory
|
| 128 | file(REMOVE_RECURSE ${SRC_DIST_DIR})
|
| 129 | ")
|
| 130 |
|
| 131 | add_custom_target(src_dist
|
| 132 | COMMAND ${CMAKE_COMMAND} -P ${_src_dist_cmd_file_path}
|
| 133 | COMMAND ${CMAKE_COMMAND} -E tar cfz ${SRC_DIST_DIR}.tar.gz ${_src_dist_tardir}
|
| 134 | COMMAND ${CMAKE_COMMAND} -E remove_directory ${SRC_DIST_DIR}
|
| 135 | )
|
| 136 |
|
| 137 | ENDMACRO()
|
| 138 |
|
| 139 | ################# User visible macros ###################
|
| 140 | #
|
| 141 | MACRO(src_distribution_init)
|
| 142 |
|
| 143 | # clear old src distribution cmake command file
|
| 144 | _src_dist_parse_options(_src_dist_dirlist _src_dist_default _src_dist_dirlist_length ${ARGN})
|
| 145 |
|
| 146 | if (NOT DEFINED _SRC_DIST_INIT)
|
| 147 | _src_dist_internal_init()
|
| 148 | set(_SRC_DIST_INIT TRUE)
|
| 149 | else()
|
| 150 | _set_src_dist_scope_vars()
|
| 151 | file(REMOVE ${_src_dist_cmd_file_path})
|
| 152 | endif()
|
| 153 |
|
| 154 | if(_src_dist_default)
|
| 155 | if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
| 156 | set(_src_dist_list_tmp)
|
| 157 | # Get all files names in cmake subdir
|
| 158 | # Unfortunately CMake also globs all directories and files that start
|
| 159 | # with . - that is not the same as shell behaviour
|
| 160 | file(GLOB_RECURSE _src_dist_names_tmp RELATIVE
|
| 161 | ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/*)
|
| 162 | #
|
| 163 | # Remove all file names that contain a name that start with .
|
| 164 | foreach(_nm ${_src_dist_names_tmp})
|
| 165 | string(REGEX REPLACE .*/\\..* "" _nm ${_nm})
|
| 166 | set(_src_dist_list_tmp ${_src_dist_list_tmp} ${_nm})
|
| 167 | endforeach()
|
| 168 | add_src_dist_files(${_src_dist_list_tmp})
|
| 169 | endif()
|
| 170 | if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt")
|
| 171 | file(APPEND ${_src_dist_cmd_file_path} "
|
| 172 | FILE(INSTALL DESTINATION \"${_src_dist_fulldir}\" TYPE FILE FILES
|
| 173 | \"${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt\")
|
| 174 | ")
|
| 175 | endif()
|
| 176 | endif()
|
| 177 |
|
| 178 | ENDMACRO()
|
| 179 |
|
| 180 | # Add a subdirectory to the src distribution
|
| 181 | #
|
| 182 | MACRO(add_src_dist_dirs)
|
| 183 |
|
| 184 | foreach(_dir ${ARGN})
|
| 185 | if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_dir}/CMakeLists.txt)
|
| 186 | message(FATAL_ERROR
|
| 187 | "Soure distribution subdirectory \"${CMAKE_CURRENT_SOURCE_DIR}/${_dir}\" does not contain a CMakeLists.txt")
|
| 188 | endif()
|
| 189 |
|
| 190 | # include subdirectory's distribution cmake command file
|
| 191 | file(APPEND ${_src_dist_cmd_file_path} "
|
| 192 | include(\"${CMAKE_CURRENT_BINARY_DIR}/${_dir}/${_SRC_DIST_CMD_FILE_NAME}\")
|
| 193 | ")
|
| 194 | endforeach()
|
| 195 | ENDMACRO()
|
| 196 |
|
| 197 | #
|
| 198 | # Add files to the src distribution. The handles and install files
|
| 199 | # that are in the same directory as the current source as well as files
|
| 200 | # in sub directories of the current source (with relative path).
|
| 201 | #
|
| 202 | MACRO(add_src_dist_files)
|
| 203 |
|
| 204 | foreach(_file ${ARGN})
|
| 205 | get_filename_component(_src_dist_tmp_path ${_file} PATH)
|
| 206 | # string(REPLACE "${CMAKE_SOURCE_DIR}" "" _src_dist_tmp_path "${_src_dist_tmp_path}")
|
| 207 | if(_src_dist_tmp_path)
|
| 208 | set(_src_dist_tmp_path ${_src_dist_fulldir}/${_src_dist_tmp_path})
|
| 209 | else ()
|
| 210 | set(_src_dist_tmp_path ${_src_dist_fulldir})
|
| 211 | endif()
|
| 212 | file(APPEND ${_src_dist_cmd_file_path} "
|
| 213 | FILE(INSTALL DESTINATION \"${_src_dist_tmp_path}\" TYPE FILE FILES
|
| 214 | \"${CMAKE_CURRENT_SOURCE_DIR}/${_file}\") ")
|
| 215 |
|
| 216 | endforeach()
|
| 217 |
|
| 218 | ENDMACRO()
|