Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/unity_build/cmake/tools/TargetUtilities.cmake @ 8649

Last change on this file since 8649 was 8649, checked in by rgrieder, 13 years ago

Added EXCLUDE_FROM_BUILD_UNITS to the ADD_TARGET commands and implemented it's effects.

  • Property svn:eol-style set to native
File size: 16.8 KB
Line 
1 #
2 #             ORXONOX - the hottest 3D action shooter ever to exist
3 #                             > www.orxonox.net <
4 #
5 #        This program is free software; you can redistribute it and/or
6 #         modify it under the terms of the GNU General Public License
7 #        as published by the Free Software Foundation; either version 2
8 #            of the License, or (at your option) any later version.
9 #
10 #       This program is distributed in the hope that it will be useful,
11 #        but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #                 GNU General Public License for more details.
14 #
15 #   You should have received a copy of the GNU General Public License along
16 #      with this program; if not, write to the Free Software Foundation,
17 #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 #
19 #
20 #  Author:
21 #    Reto Grieder
22 #  Description:
23 #    Adds a library or an executable like ADD_LIBRARY/ADD_EXECUTABLE, but
24 #    accepts a lot more input information. Simply supply the keywords
25 #    described below in any order you wish.
26 #    The output is then stored in "_arg_ARGNAME" where ARGNAME is the the
27 #    name of the switch or list.
28 #
29 #    Switches: (when given --> TRUE, FALSE otherwise)
30 #      FIND_HEADER_FILES: Searches the current directory for all header files
31 #                         and adds them to the target.
32 #      EXCLUDE_FROM_ALL:  Inherited from ADD_LIBRARY/ADD_EXECUTABLE
33 #      ORXONOX_EXTERNAL:  Specify this for third party libraries
34 #      NO_DLL_INTERFACE:  Link statically with MSVC
35 #      NO_SOURCE_GROUPS:  Don't create msvc source groups
36 #      MODULE:            For dynamic module libraries (libraries only)
37 #      WIN32:             Inherited from ADD_EXECUTABLE (executables only)
38 #      PCH_NO_DEFAULT:    Do not make precompiled header files default if
39 #                         specified with PCH_FILE
40 #      NO_INSTALL:        Do not install the target at all
41 #      NO_VERSION:        Prevents adding any version to a target
42 #
43 #    Lists:
44 #      LINK_LIBRARIES:    Redirects to TARGET_LINK_LIBRARIES
45 #      LINK_LIBS_LINUX:   Redirects to TARGET_LINK_LIBRARIES only on Linux
46 #      LINK_LIBS_WIN32:   Redirects to TARGET_LINK_LIBRARIES only on Windows
47 #      LINK_LIBS_APPLE:   Redirects to TARGET_LINK_LIBRARIES only on Apple
48 #      LINK_LIBS_UNIX:    Redirects to TARGET_LINK_LIBRARIES only on UNIX
49 #      VERSION:           Set version to the binary
50 #      SOURCE_FILES:      Source files for the target
51 #      DEFINE_SYMBOL:     Sets the DEFINE_SYMBOL target property
52 #      TOLUA_FILES:       Files with tolua interface
53 #      PCH_FILE:          Precompiled header file
54 #      PCH_EXCLUDE:       Source files to be excluded from PCH support
55 #      OUTPUT_NAME:       If you want a different name than the target name
56 #      EXCLUDE_FROM_BUILD_UNITS: Specifies files that are not put into
57 #                         automatic (full) build units. They can still
58 #                         explicitely be included in a BUILD_UNIT (partial)
59 #  Note:
60 #    This function also installs the target!
61 #  Prerequisistes:
62 #    ORXONOX_DEFAULT_LINK
63 #  Parameters:
64 #    _target_name, ARGN for the macro arguments
65 #
66
67INCLUDE(BuildUnits)
68INCLUDE(CMakeDependentOption)
69INCLUDE(CapitaliseName)
70INCLUDE(GenerateToluaBindings)
71INCLUDE(ParseMacroArguments)
72INCLUDE(SourceFileUtilities)
73IF(PCH_COMPILER_SUPPORT)
74  INCLUDE(PrecompiledHeaderFiles)
75ENDIF()
76
77MACRO(ORXONOX_ADD_LIBRARY _target_name)
78  TU_ADD_TARGET(${_target_name} LIBRARY "MODULE" ${ARGN})
79ENDMACRO(ORXONOX_ADD_LIBRARY)
80
81MACRO(ORXONOX_ADD_EXECUTABLE _target_name)
82  TU_ADD_TARGET(${_target_name} EXECUTABLE "WIN32" ${ARGN})
83ENDMACRO(ORXONOX_ADD_EXECUTABLE)
84
85
86MACRO(TU_ADD_TARGET _target_name _target_type _additional_switches)
87  CAPITALISE_NAME(${_target_name} _target_name_capitalised)
88  STRING(TOUPPER "${_target_name}" _target_name_upper)
89
90  # Specify all possible options (either switch or with add. arguments)
91  SET(_switches   FIND_HEADER_FILES  EXCLUDE_FROM_ALL  ORXONOX_EXTERNAL
92                  NO_DLL_INTERFACE   NO_SOURCE_GROUPS  PCH_NO_DEFAULT 
93                  NO_INSTALL         NO_VERSION        ${_additional_switches})
94  SET(_list_names LINK_LIBRARIES     VERSION           SOURCE_FILES
95                  DEFINE_SYMBOL      TOLUA_FILES       PCH_FILE
96                  PCH_EXCLUDE        OUTPUT_NAME       LINK_LIBS_LINUX
97                  LINK_LIBS_WIN32    LINK_LIBS_APPLE   LINK_LIBS_UNIX
98                  EXCLUDE_FROM_BUILD_UNITS)
99
100  PARSE_MACRO_ARGUMENTS("${_switches}" "${_list_names}" ${ARGN})
101
102  # Process source files with support for build units
103  # Note: All file paths are relative to the root source directory, even the
104  #       name of the build unit.
105  SET(_${_target_name}_source_files)
106  SET(_get_build_unit_file FALSE)
107  SET(_add_to_build_unit FALSE)
108  FOREACH(_file ${_arg_SOURCE_FILES})
109    IF(_file STREQUAL "BUILD_UNIT")
110      # Next file is the name of the build unit
111      SET(_get_build_unit_file TRUE)
112    ELSEIF(_file STREQUAL "END_BUILD_UNIT")
113      IF(NOT _build_unit_file)
114        MESSAGE(FATAL_ERROR "No name provided for build unit")
115      ENDIF()
116      IF(ENABLE_BUILD_UNITS)
117        IF(NOT _build_unit_include_string)
118          MESSAGE(STATUS "Warning: Empty build unit!")
119        ENDIF()
120        IF(EXISTS ${_build_unit_file})
121          FILE(READ ${_build_unit_file} _include_string_file)
122        ENDIF()
123        IF(NOT _build_unit_include_string STREQUAL "${_include_string_file}")
124          FILE(WRITE ${_build_unit_file} "${_build_unit_include_string}")
125        ENDIF()
126        LIST(APPEND _${_target_name}_source_files ${_build_unit_file})
127        LIST(APPEND _${_target_name}_build_units ${_build_unit_file})
128        # Store the number of files included. May be used for full build units.
129        SET_SOURCE_FILES_PROPERTIES(${_build_unit_file}
130          PROPERTIES BUILD_UNIT_SIZE "${_build_unit_count}")
131      ENDIF()
132      SET(_add_to_build_unit FALSE)
133    ELSEIF(_get_build_unit_file)
134      # Note: ${_file} is relative to the binary directory
135      SET(_build_unit_file ${CMAKE_BINARY_DIR}/${_file})
136      SET(_get_build_unit_file FALSE)
137      SET(_add_to_build_unit TRUE)
138      SET(_build_unit_include_string)
139      SET(_build_unit_count "0")
140    ELSE()
141      # Default, add source file
142
143      # Prepare relative paths
144      IF(NOT _file MATCHES "^(.\\:|\\/)")
145        # Path can be relative to the current source directory if the file was
146        # not added with the source file macros. Otherwise there is a "./" at
147        # the beginning of each file and the filename is relative
148        # to the CMAKE_SOURCE_DIR
149        STRING(REGEX REPLACE "^\\.\\/(.+)$" "\\1" _temp ${_file})
150        IF(NOT ${_temp} STREQUAL ${_file})
151          SET(_file ${CMAKE_SOURCE_DIR}/${_temp})
152        ELSE()
153          SET(_file ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
154        ENDIF()
155      ENDIF()
156
157      LIST(APPEND _${_target_name}_source_files ${_file})
158
159      # Handle build units
160      IF(_add_to_build_unit AND ENABLE_BUILD_UNITS)
161        IF(_file MATCHES "\\.(c|cc|cpp|cxx)$")
162          SET(_build_unit_include_string "${_build_unit_include_string}#include \"${_file}\"\n")
163          MATH(EXPR _build_unit_count "1 + ${_build_unit_count}")
164        ENDIF()
165        # Don't compile these files, even if they are source files
166        SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
167      ENDIF()
168    ENDIF()
169  ENDFOREACH(_file)
170
171  # Assemble all header files of the library
172  IF(_arg_FIND_HEADER_FILES)
173    GET_ALL_HEADER_FILES(_${_target_name}_header_files)
174  ENDIF()
175
176  # Combine source and header files
177  SET(_${_target_name}_files
178    ${_${_target_name}_header_files}
179    ${_${_target_name}_source_files}
180  )
181  # Remove potential duplicates
182  LIST(REMOVE_DUPLICATES _${_target_name}_files)
183
184  # Mark files to be excluded from build units
185  IF(_arg_EXCLUDE_FROM_BUILD_UNITS)
186    SET_SOURCE_FILES_PROPERTIES(${_arg_EXCLUDE_FROM_BUILD_UNITS}
187      PROPERTIES EXCLUDE_FROM_BUILD_UNITS TRUE)
188  ENDIF()
189
190  # Full build units
191  IF(NOT _arg_ORXONOX_EXTERNAL AND ENABLE_BUILD_UNITS MATCHES "full")
192    GENERATE_BUILD_UNITS(${_target_name} _${_target_name}_files)
193  ENDIF()
194
195  # TOLUA_FILES
196  IF(_arg_TOLUA_FILES)
197    GENERATE_TOLUA_BINDINGS(${_target_name_capitalised} _${_target_name}_files
198                            INPUTFILES ${_arg_TOLUA_FILES})
199    # Workaround for XCode: The folder where the bind files are written to has
200    # to be present beforehand.
201    IF(CMAKE_CONFIGURATION_TYPES)
202      FOREACH(_dir ${CMAKE_CONFIGURATION_TYPES})
203        FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_dir})
204      ENDFOREACH(_dir)
205    ENDIF()
206  ENDIF()
207
208  # First part (pre target) of precompiled header files
209  IF(PCH_COMPILER_SUPPORT AND _arg_PCH_FILE)
210    # Provide convenient option to control PCH
211    IF(_arg_PCH_NO_DEFAULT)
212      SET(PCH_DEFAULT FALSE)
213    ELSE()
214      SET(PCH_DEFAULT TRUE)
215    ENDIF()
216    CMAKE_DEPENDENT_OPTION(PCH_ENABLE_${_target_name_upper}
217      "Enable using precompiled header files for library ${_target_name}." ${PCH_DEFAULT} PCH_ENABLE OFF)
218    # Almost never used individually, but produces a lot of options --> hide
219    MARK_AS_ADVANCED(PCH_ENABLE_${_target_name_upper})
220
221    IF(PCH_ENABLE_${_target_name_upper} AND NOT PCH_DISABLE_${_target_name})
222      PRECOMPILED_HEADER_FILES_PRE_TARGET(${_target_name} ${_arg_PCH_FILE} _${_target_name}_files EXCLUDE ${_arg_PCH_EXCLUDE})
223    ENDIF()
224  ENDIF()
225
226  # Generate the source groups
227  IF(MSVC AND NOT _arg_NO_SOURCE_GROUPS)
228    GENERATE_SOURCE_GROUPS(${_${_target_name}_files})
229
230    IF(NOT _arg_ORXONOX_EXTERNAL)
231      # Move the ...Prereqs.h and the PCH files to the 'Config' section
232      IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_target_name_capitalised}Prereqs.h)
233        SOURCE_GROUP("Config" FILES ${_target_name_capitalised}Prereqs.h)
234      ENDIF()
235      IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_arg_PCH_FILE})
236        SOURCE_GROUP("Config" FILES ${CMAKE_CURRENT_SOURCE_DIR}/${_arg_PCH_FILE})
237      ENDIF()
238    ENDIF()
239  ENDIF()
240
241  # Set link mode (SHARED/STATIC)
242  IF(MSVC AND _arg_NO_DLL_INTERFACE)
243    # Certain libraries don't have dllexport/dllimport and can't be linked shared with MSVC
244    SET(_link_mode STATIC)
245  ELSEIF(_arg_ORXONOX_EXTERNAL)
246    # Externals can be linked shared or statically
247    SET(_link_mode ${ORXONOX_EXTERNAL_LINK_MODE})
248  ELSE()
249    # All our own libraries are linked dynamically because of static symbols
250    SET(_link_mode SHARED)
251  ENDIF()
252
253  # No warnings needed from third party libraries
254  IF(_arg_ORXONOX_EXTERNAL)
255    REMOVE_COMPILER_FLAGS("-W3 -W4" MSVC)
256    ADD_COMPILER_FLAGS("-w" NOT MSVC)
257    ADD_COMPILER_FLAGS("-W0" MSVC)
258  ENDIF()
259
260  # Don't compile header files
261  FOREACH(_file ${_${_target_name}_files})
262    IF(NOT _file MATCHES "\\.(c|cc|cpp|cxx|mm)$")
263      SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
264    ENDIF()
265  ENDFOREACH(_file)
266
267
268
269  # Add the library/executable
270  IF("${_target_type}" STREQUAL "LIBRARY")
271    ADD_LIBRARY(${_target_name} ${_link_mode}
272                ${_arg_EXCLUDE_FROM_ALL} ${_${_target_name}_files})
273  ELSE()
274    ADD_EXECUTABLE(${_target_name} ${_arg_WIN32} ${_arg_EXCLUDE_FROM_ALL}
275                   ${_${_target_name}_files})
276  ENDIF()
277
278
279
280  # Change library prefix to "lib"
281  IF(MSVC AND ${_target_type} STREQUAL "LIBRARY")
282    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
283      PREFIX "lib"
284    )
285  ENDIF()
286
287  # MSVC hack to exclude external library sources from the intellisense database
288  # (IntelliSense stops working when adding "-Zm1000" as compile flag. "/Zm1000"
289  # would not work because of the slash)
290  IF(_arg_ORXONOX_EXTERNAL AND MSVC)
291    GET_TARGET_PROPERTY(_compile_flags ${_target_name} COMPILE_FLAGS)
292    IF(NOT _compile_flags)
293      SET(_compile_flags)
294    ENDIF()
295    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES COMPILE_FLAGS "${_compile_flags} -Zm1000")
296  ENDIF()
297
298  # Configure modules
299  IF (_arg_MODULE)
300    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
301      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Windows
302      LIBRARY_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Unix
303    )
304    ADD_MODULE(${_target_name})
305    # Ensure that the main program depends on the module
306    SET(ORXONOX_MODULES ${ORXONOX_MODULES} ${_target_name} CACHE INTERNAL "")
307  ENDIF()
308
309  # Static library flags are not globally available
310  IF(ORXONOX_STATIC_LINKER_FLAGS)
311    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES STATIC_LIBRARY_FLAGS ${ORXONOX_STATIC_LINKER_FLAGS})
312  ENDIF()
313
314  # LINK_LIBRARIES
315  IF(_arg_LINK_LIBRARIES)
316    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBRARIES})
317  ENDIF()
318  IF(_arg_LINK_LIBS_LINUX AND LINUX)
319    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBS_LINUX})
320  ENDIF()
321  IF(_arg_LINK_LIBS_WIN32 AND WIN32)
322    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBS_WIN32})
323  ENDIF()
324  IF(_arg_LINK_LIBS_APPLE AND APPLE)
325    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBS_APPLE})
326  ENDIF()
327  IF(_arg_LINK_LIBS_UNIX AND UNIX)
328    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBS_UNIX})
329  ENDIF()
330
331  # Visual Leak Detector specific stuff (avoids the include)
332  IF(VISUAL_LEAK_DETECTOR_ENABLE)
333    TARGET_LINK_LIBRARIES(${_target_name} debug ${VLD_LIBRARY})
334  ENDIF()
335
336  # RPATH settings for the installation
337  IF("${_target_type}" STREQUAL "LIBRARY")
338    IF(_arg_MODULE)
339      SET(_rpath "${MODULE_RPATH}")
340    ELSE()
341      SET(_rpath "${LIBRARY_RPATH}")
342    ENDIF()
343  ELSE()
344    SET(_rpath "${RUNTIME_RPATH}")
345  ENDIF()
346  SET_TARGET_PROPERTIES(${_target_name} PROPERTIES INSTALL_RPATH "${_rpath}")
347
348  # DEFINE_SYMBOL
349  IF(_arg_DEFINE_SYMBOL)
350    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES DEFINE_SYMBOL ${_arg_DEFINE_SYMBOL})
351  ELSEIF(NOT _arg_ORXONOX_EXTERNAL)
352    # Automatically add the macro definitions for our own libraries
353    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES DEFINE_SYMBOL "${_target_name_upper}_SHARED_BUILD")
354  ENDIF()
355
356  # VERSION
357  IF(_arg_VERSION)
358    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${_arg_VERSION})
359  ELSEIF(NOT _arg_ORXONOX_EXTERNAL AND NOT _arg_NO_VERSION AND NOT ${_target_type} STREQUAL "EXECUTABLE")
360    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${ORXONOX_VERSION})
361  ENDIF()
362
363  # OUTPUT_NAME
364  IF(_arg_OUTPUT_NAME)
365    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES OUTPUT_NAME  ${_arg_OUTPUT_NAME})
366  ENDIF()
367
368  # Second part of precompiled header files
369  IF(PCH_COMPILER_SUPPORT AND PCH_ENABLE_${_target_name_upper} AND _arg_PCH_FILE AND NOT PCH_DISABLE_${_target_name})
370    PRECOMPILED_HEADER_FILES_POST_TARGET(${_target_name} ${_arg_PCH_FILE})
371  ENDIF()
372
373  # Install all targets except for static ones (executables also have SHARED in _link_mode)
374  IF(${_link_mode} STREQUAL "SHARED" AND NOT _arg_NO_INSTALL)
375    IF(_arg_MODULE)
376      INSTALL(TARGETS ${_target_name}
377        RUNTIME DESTINATION ${MODULE_INSTALL_DIRECTORY}
378        LIBRARY DESTINATION ${MODULE_INSTALL_DIRECTORY}
379      )
380    ELSE()
381      INSTALL(TARGETS ${_target_name}
382        RUNTIME DESTINATION ${RUNTIME_INSTALL_DIRECTORY}
383        LIBRARY DESTINATION ${LIBRARY_INSTALL_DIRECTORY}
384      )
385    ENDIF()
386    IF(INSTALL_PDB_FILES) # MSVC specific: install debug symbols files
387      FOREACH(_config RelForDevs RelWithDebInfo)
388        GET_TARGET_PROPERTY(_location ${_target_name} LOCATION_${_config})
389        # Get absolute location without dll/exe extension
390        STRING(REGEX REPLACE "^(.+)\\.(dll|exe)$" "\\1" _location_we ${_location})
391        IF(_arg_MODULE)
392          INSTALL(FILES ${_location_we}.pdb
393            DESTINATION ${MODULE_INSTALL_DIRECTORY}
394            CONFIGURATIONS ${_config}
395          )
396        ELSE()
397          INSTALL(FILES ${_location_we}.pdb
398            DESTINATION ${RUNTIME_INSTALL_DIRECTORY}
399            CONFIGURATIONS ${_config}
400          )
401        ENDIF()
402      ENDFOREACH(_config)
403    ENDIF()
404  ENDIF()
405
406ENDMACRO(TU_ADD_TARGET)
407
408
409# Creates a helper file with name <name_of_the_library>${ORXONOX_MODULE_EXTENSION}
410# This helps finding dynamically loadable modules at runtime
411
412FUNCTION(ADD_MODULE _target)
413  # We use the properties to get the name because the librarys name may differ from
414  # the target name (for example orxonox <-> liborxonox)
415
416  GET_TARGET_PROPERTY(_target_loc ${_target} LOCATION)
417  GET_FILENAME_COMPONENT(_target_name ${_target_loc} NAME_WE)
418
419  IF(CMAKE_CONFIGURATION_TYPES)
420    FOREACH(_config ${CMAKE_CONFIGURATION_TYPES})
421      SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_config}/${_target_name}${ORXONOX_MODULE_EXTENSION})
422
423      FILE(WRITE ${_module_filename})
424
425      INSTALL(
426        FILES ${_module_filename}
427        DESTINATION ${MODULE_INSTALL_DIRECTORY}
428        CONFIGURATIONS ${_config}
429      )
430    ENDFOREACH()
431  ELSE()
432    SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_target_name}${ORXONOX_MODULE_EXTENSION})
433
434    FILE(WRITE ${_module_filename})
435
436    INSTALL(
437      FILES ${_module_filename}
438      DESTINATION ${MODULE_INSTALL_DIRECTORY}
439    )
440  ENDIF()
441ENDFUNCTION(ADD_MODULE)
Note: See TracBrowser for help on using the repository browser.