blob: c4dae25241b2ca042b15b13b614a9b39df192df1 [file] [log] [blame]
Alexandre Lision51140e12013-12-02 10:54:09 -05001# - 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#
68MACRO (_set_src_dist_scope_vars)
69STRING(REPLACE "${CMAKE_SOURCE_DIR}" "" _src_dist_subdir "${CMAKE_CURRENT_SOURCE_DIR}")
70if (NOT _src_dist_subdir)
71 set(_src_dist_fulldir ${SRC_DIST_DIR})
72else()
73 set(_src_dist_fulldir ${SRC_DIST_DIR}${_src_dist_subdir})
74endif()
75set(_src_dist_cmd_file_path ${CMAKE_CURRENT_BINARY_DIR}/${_SRC_DIST_CMD_FILE_NAME})
76ENDMACRO()
77
78#
79# Check for the NOT_INCLUDE_DEFAULT option.
80#
81MACRO(_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
98ENDMACRO()
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#
106MACRO (_src_dist_internal_init)
107# internal variable for distribution cmake file
108set(_SRC_DIST_CMD_FILE_NAME "cmake_src_dist.cmake")
109
110if (${_src_dist_dirlist_length} EQUAL 0)
111 set(_src_dist_tardir ${PROJECT_NAME}-${VERSION})
112else()
113 list(GET _src_dist_dirlist 0 _src_dist_tardir)
114endif()
115set(SRC_DIST_DIR ${CMAKE_BINARY_DIR}/${_src_dist_tardir})
116
117message(STATUS "Source distribution direcrory set to: ${SRC_DIST_DIR}")
118
119_set_src_dist_scope_vars()
120file(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#
126file(APPEND ${_src_dist_cmd_file_path} "
127# clear contents of an existing distribution directory
128file(REMOVE_RECURSE ${SRC_DIST_DIR})
129")
130
131add_custom_target(src_dist
132 COMMAND ${CMAKE_COMMAND} -P ${_src_dist_cmd_file_path}
133 COMMAND ${CMAKE_COMMAND} -E tar cfj ${SRC_DIST_DIR}.tar.bz2 ${_src_dist_tardir}
134 COMMAND ${CMAKE_COMMAND} -E remove_directory ${SRC_DIST_DIR}
135 )
136
137ENDMACRO()
138
139################# User visible macros ###################
140#
141MACRO(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
146if (NOT DEFINED _SRC_DIST_INIT)
147 _src_dist_internal_init()
148 set(_SRC_DIST_INIT TRUE)
149else()
150 _set_src_dist_scope_vars()
151 file(REMOVE ${_src_dist_cmd_file_path})
152endif()
153
154if(_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} "
172FILE(INSTALL DESTINATION \"${_src_dist_fulldir}\" TYPE FILE FILES
173\"${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt\")
174")
175 endif()
176endif()
177
178ENDMACRO()
179
180# Add a subdirectory to the src distribution
181#
182MACRO(add_src_dist_dirs)
183
184foreach(_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} "
192include(\"${CMAKE_CURRENT_BINARY_DIR}/${_dir}/${_SRC_DIST_CMD_FILE_NAME}\")
193")
194endforeach()
195ENDMACRO()
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#
202MACRO(add_src_dist_files)
203
204foreach(_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} "
213FILE(INSTALL DESTINATION \"${_src_dist_tmp_path}\" TYPE FILE FILES
214 \"${CMAKE_CURRENT_SOURCE_DIR}/${_file}\") ")
215
216endforeach()
217
218ENDMACRO()