Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Renamed the infamous 'Compilation' to 'BuildUnit' which definitely suits better and avoids much of the general confusion.
There are no actual changes, just the renaming.

  • Property svn:eol-style set to native
File size: 15.6 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 #  Note:
57 #    This function also installs the target!
58 #  Prerequisistes:
59 #    ORXONOX_DEFAULT_LINK
60 #  Parameters:
61 #    _target_name, ARGN for the macro arguments
62 #
63
64INCLUDE(CMakeDependentOption)
65INCLUDE(CapitaliseName)
66INCLUDE(GenerateToluaBindings)
67INCLUDE(ParseMacroArguments)
68INCLUDE(SourceFileUtilities)
69IF(PCH_COMPILER_SUPPORT)
70  INCLUDE(PrecompiledHeaderFiles)
71ENDIF()
72
73MACRO(ORXONOX_ADD_LIBRARY _target_name)
74  TU_ADD_TARGET(${_target_name} LIBRARY "MODULE" ${ARGN})
75ENDMACRO(ORXONOX_ADD_LIBRARY)
76
77MACRO(ORXONOX_ADD_EXECUTABLE _target_name)
78  TU_ADD_TARGET(${_target_name} EXECUTABLE "WIN32" ${ARGN})
79ENDMACRO(ORXONOX_ADD_EXECUTABLE)
80
81
82MACRO(TU_ADD_TARGET _target_name _target_type _additional_switches)
83  CAPITALISE_NAME(${_target_name} _target_name_capitalised)
84  STRING(TOUPPER "${_target_name}" _target_name_upper)
85
86  # Specify all possible options (either switch or with add. arguments)
87  SET(_switches   FIND_HEADER_FILES  EXCLUDE_FROM_ALL  ORXONOX_EXTERNAL
88                  NO_DLL_INTERFACE   NO_SOURCE_GROUPS  PCH_NO_DEFAULT 
89                  NO_INSTALL         NO_VERSION        ${_additional_switches})
90  SET(_list_names LINK_LIBRARIES     VERSION           SOURCE_FILES
91                  DEFINE_SYMBOL      TOLUA_FILES       PCH_FILE
92                  PCH_EXCLUDE        OUTPUT_NAME       LINK_LIBS_LINUX
93                  LINK_LIBS_WIN32    LINK_LIBS_APPLE   LINK_LIBS_UNIX)
94
95  PARSE_MACRO_ARGUMENTS("${_switches}" "${_list_names}" ${ARGN})
96
97  # Process source files with support for build units
98  # Note: All file paths are relative to the root source directory, even the
99  #       name of the build unit.
100  SET(_${_target_name}_source_files)
101  SET(_get_build_unit_file FALSE)
102  SET(_add_to_build_unit FALSE)
103  FOREACH(_file ${_arg_SOURCE_FILES})
104    IF(_file STREQUAL "BUILD_UNIT")
105      # Next file is the name of the build unit
106      SET(_get_build_unit_file TRUE)
107    ELSEIF(_file STREQUAL "END_BUILD_UNIT")
108      IF(NOT _build_unit_file)
109        MESSAGE(FATAL_ERROR "No name provided for build unit")
110      ENDIF()
111      IF(NOT DISABLE_BUILD_UNITS)
112        IF(NOT _build_unit_include_string)
113          MESSAGE(STATUS "Warning: Empty build unit!")
114        ENDIF()
115        IF(EXISTS ${_build_unit_file})
116          FILE(READ ${_build_unit_file} _include_string_file)
117        ENDIF()
118        IF(NOT _build_unit_include_string STREQUAL "${_include_string_file}")
119          FILE(WRITE ${_build_unit_file} "${_build_unit_include_string}")
120        ENDIF()
121        LIST(APPEND _${_target_name}_source_files ${_build_unit_file})
122      ENDIF()
123      SET(_add_to_build_unit FALSE)
124    ELSEIF(_get_build_unit_file)
125      SET(_build_unit_file ${CMAKE_BINARY_DIR}/${_file})
126      SET(_get_build_unit_file FALSE)
127      SET(_add_to_build_unit TRUE)
128      SET(_build_unit_include_string)
129    ELSE()
130      # Default, add source file
131
132      # Prepare relative paths
133      IF(NOT _file MATCHES "^(.\\:|\\/)")
134        # Path can be relative to the current source directory if the file was
135        # not added with the source file macros. Otherwise there is a "./" at
136        # the beginning of each file and the filename is relative
137        # to the CMAKE_SOURCE_DIR
138        STRING(REGEX REPLACE "^\\.\\/(.+)$" "\\1" _temp ${_file})
139        IF(NOT ${_temp} STREQUAL ${_file})
140          SET(_file ${CMAKE_SOURCE_DIR}/${_temp})
141        ELSE()
142          SET(_file ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
143        ENDIF()
144      ENDIF()
145
146      LIST(APPEND _${_target_name}_source_files ${_file})
147
148      # Handle build units
149      IF(_add_to_build_unit AND NOT DISABLE_BUILD_UNITS)
150        IF(_file MATCHES "\\.(c|cc|cpp|cxx)$")
151          SET(_build_unit_include_string "${_build_unit_include_string}#include \"${_file}\"\n")
152        ENDIF()
153        # Don't compile these files, even if they are source files
154        SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
155      ENDIF()
156    ENDIF()
157  ENDFOREACH(_file)
158
159  # Assemble all header files of the library
160  IF(_arg_FIND_HEADER_FILES)
161    GET_ALL_HEADER_FILES(_${_target_name}_header_files)
162  ENDIF()
163
164  # Combine source and header files
165  SET(_${_target_name}_files
166    ${_${_target_name}_header_files}
167    ${_${_target_name}_source_files}
168  )
169  # Remove potential duplicates
170  LIST(REMOVE_DUPLICATES _${_target_name}_files)
171
172  # TOLUA_FILES
173  IF(_arg_TOLUA_FILES)
174    GENERATE_TOLUA_BINDINGS(${_target_name_capitalised} _${_target_name}_files
175                            INPUTFILES ${_arg_TOLUA_FILES})
176    # Workaround for XCode: The folder where the bind files are written to has
177    # to be present beforehand.
178    IF(CMAKE_CONFIGURATION_TYPES)
179      FOREACH(_dir ${CMAKE_CONFIGURATION_TYPES})
180        FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_dir})
181      ENDFOREACH(_dir)
182    ENDIF()
183  ENDIF()
184
185  # First part (pre target) of precompiled header files
186  IF(PCH_COMPILER_SUPPORT AND _arg_PCH_FILE)
187    # Provide convenient option to control PCH
188    IF(_arg_PCH_NO_DEFAULT)
189      SET(PCH_DEFAULT FALSE)
190    ELSE()
191      SET(PCH_DEFAULT TRUE)
192    ENDIF()
193    CMAKE_DEPENDENT_OPTION(PCH_ENABLE_${_target_name_upper}
194      "Enable using precompiled header files for library ${_target_name}." ${PCH_DEFAULT} PCH_ENABLE OFF)
195    # Almost never used individually, but produces a lot of options --> hide
196    MARK_AS_ADVANCED(PCH_ENABLE_${_target_name_upper})
197
198    IF(PCH_ENABLE_${_target_name_upper})
199      PRECOMPILED_HEADER_FILES_PRE_TARGET(${_target_name} ${_arg_PCH_FILE} _${_target_name}_files EXCLUDE ${_arg_PCH_EXCLUDE})
200    ENDIF()
201  ENDIF()
202
203  # Generate the source groups
204  IF(MSVC AND NOT _arg_NO_SOURCE_GROUPS)
205    GENERATE_SOURCE_GROUPS(${_${_target_name}_files})
206
207    IF(NOT _arg_ORXONOX_EXTERNAL)
208      # Move the ...Prereqs.h and the PCH files to the 'Config' section
209      IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_target_name_capitalised}Prereqs.h)
210        SOURCE_GROUP("Config" FILES ${_target_name_capitalised}Prereqs.h)
211      ENDIF()
212      IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_arg_PCH_FILE})
213        SOURCE_GROUP("Config" FILES ${CMAKE_CURRENT_SOURCE_DIR}/${_arg_PCH_FILE})
214      ENDIF()
215    ENDIF()
216  ENDIF()
217
218  # Set link mode (SHARED/STATIC)
219  IF(MSVC AND _arg_NO_DLL_INTERFACE)
220    # Certain libraries don't have dllexport/dllimport and can't be linked shared with MSVC
221    SET(_link_mode STATIC)
222  ELSEIF(_arg_ORXONOX_EXTERNAL)
223    # Externals can be linked shared or statically
224    SET(_link_mode ${ORXONOX_EXTERNAL_LINK_MODE})
225  ELSE()
226    # All our own libraries are linked dynamically because of static symbols
227    SET(_link_mode SHARED)
228  ENDIF()
229
230  # No warnings needed from third party libraries
231  IF(_arg_ORXONOX_EXTERNAL)
232    REMOVE_COMPILER_FLAGS("-W3 -W4" MSVC)
233    ADD_COMPILER_FLAGS("-w" NOT MSVC)
234    ADD_COMPILER_FLAGS("-W0" MSVC)
235  ENDIF()
236
237  # Don't compile header files
238  FOREACH(_file ${_${_target_name}_files})
239    IF(NOT _file MATCHES "\\.(c|cc|cpp|cxx|mm)$")
240      SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
241    ENDIF()
242  ENDFOREACH(_file)
243
244
245
246  # Add the library/executable
247  IF("${_target_type}" STREQUAL "LIBRARY")
248    ADD_LIBRARY(${_target_name} ${_link_mode}
249                ${_arg_EXCLUDE_FROM_ALL} ${_${_target_name}_files})
250  ELSE()
251    ADD_EXECUTABLE(${_target_name} ${_arg_WIN32} ${_arg_EXCLUDE_FROM_ALL}
252                   ${_${_target_name}_files})
253  ENDIF()
254
255
256
257  # Change library prefix to "lib"
258  IF(MSVC AND ${_target_type} STREQUAL "LIBRARY")
259    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
260      PREFIX "lib"
261    )
262  ENDIF()
263
264  # MSVC hack to exclude external library sources from the intellisense database
265  # (IntelliSense stops working when adding "-Zm1000" as compile flag. "/Zm1000"
266  # would not work because of the slash)
267  IF(_arg_ORXONOX_EXTERNAL AND MSVC)
268    GET_TARGET_PROPERTY(_compile_flags ${_target_name} COMPILE_FLAGS)
269    IF(NOT _compile_flags)
270      SET(_compile_flags)
271    ENDIF()
272    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES COMPILE_FLAGS "${_compile_flags} -Zm1000")
273  ENDIF()
274
275  # Configure modules
276  IF (_arg_MODULE)
277    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
278      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Windows
279      LIBRARY_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Unix
280    )
281    ADD_MODULE(${_target_name})
282    # Ensure that the main program depends on the module
283    SET(ORXONOX_MODULES ${ORXONOX_MODULES} ${_target_name} CACHE INTERNAL "")
284  ENDIF()
285
286  # Static library flags are not globally available
287  IF(ORXONOX_STATIC_LINKER_FLAGS)
288    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES STATIC_LIBRARY_FLAGS ${ORXONOX_STATIC_LINKER_FLAGS})
289  ENDIF()
290
291  # LINK_LIBRARIES
292  IF(_arg_LINK_LIBRARIES)
293    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBRARIES})
294  ENDIF()
295  IF(_arg_LINK_LIBS_LINUX AND LINUX)
296    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBS_LINUX})
297  ENDIF()
298  IF(_arg_LINK_LIBS_WIN32 AND WIN32)
299    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBS_WIN32})
300  ENDIF()
301  IF(_arg_LINK_LIBS_APPLE AND APPLE)
302    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBS_APPLE})
303  ENDIF()
304  IF(_arg_LINK_LIBS_UNIX AND UNIX)
305    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBS_UNIX})
306  ENDIF()
307
308  # Visual Leak Detector specific stuff (avoids the include)
309  IF(VISUAL_LEAK_DETECTOR_ENABLE)
310    TARGET_LINK_LIBRARIES(${_target_name} debug ${VLD_LIBRARY})
311  ENDIF()
312
313  # RPATH settings for the installation
314  IF("${_target_type}" STREQUAL "LIBRARY")
315    IF(_arg_MODULE)
316      SET(_rpath "${MODULE_RPATH}")
317    ELSE()
318      SET(_rpath "${LIBRARY_RPATH}")
319    ENDIF()
320  ELSE()
321    SET(_rpath "${RUNTIME_RPATH}")
322  ENDIF()
323  SET_TARGET_PROPERTIES(${_target_name} PROPERTIES INSTALL_RPATH "${_rpath}")
324
325  # DEFINE_SYMBOL
326  IF(_arg_DEFINE_SYMBOL)
327    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES DEFINE_SYMBOL ${_arg_DEFINE_SYMBOL})
328  ELSEIF(NOT _arg_ORXONOX_EXTERNAL)
329    # Automatically add the macro definitions for our own libraries
330    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES DEFINE_SYMBOL "${_target_name_upper}_SHARED_BUILD")
331  ENDIF()
332
333  # VERSION
334  IF(_arg_VERSION)
335    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${_arg_VERSION})
336  ELSEIF(NOT _arg_ORXONOX_EXTERNAL AND NOT _arg_NO_VERSION AND NOT ${_target_type} STREQUAL "EXECUTABLE")
337    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${ORXONOX_VERSION})
338  ENDIF()
339
340  # OUTPUT_NAME
341  IF(_arg_OUTPUT_NAME)
342    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES OUTPUT_NAME  ${_arg_OUTPUT_NAME})
343  ENDIF()
344
345  # Second part of precompiled header files
346  IF(PCH_COMPILER_SUPPORT AND PCH_ENABLE_${_target_name_upper} AND _arg_PCH_FILE)
347    PRECOMPILED_HEADER_FILES_POST_TARGET(${_target_name} ${_arg_PCH_FILE})
348  ENDIF()
349
350  # Install all targets except for static ones (executables also have SHARED in _link_mode)
351  IF(${_link_mode} STREQUAL "SHARED" AND NOT _arg_NO_INSTALL)
352    IF(_arg_MODULE)
353      INSTALL(TARGETS ${_target_name}
354        RUNTIME DESTINATION ${MODULE_INSTALL_DIRECTORY}
355        LIBRARY DESTINATION ${MODULE_INSTALL_DIRECTORY}
356      )
357    ELSE()
358      INSTALL(TARGETS ${_target_name}
359        RUNTIME DESTINATION ${RUNTIME_INSTALL_DIRECTORY}
360        LIBRARY DESTINATION ${LIBRARY_INSTALL_DIRECTORY}
361      )
362    ENDIF()
363    IF(INSTALL_PDB_FILES) # MSVC specific: install debug symbols files
364      FOREACH(_config RelForDevs RelWithDebInfo)
365        GET_TARGET_PROPERTY(_location ${_target_name} LOCATION_${_config})
366        # Get absolute location without dll/exe extension
367        STRING(REGEX REPLACE "^(.+)\\.(dll|exe)$" "\\1" _location_we ${_location})
368        IF(_arg_MODULE)
369          INSTALL(FILES ${_location_we}.pdb
370            DESTINATION ${MODULE_INSTALL_DIRECTORY}
371            CONFIGURATIONS ${_config}
372          )
373        ELSE()
374          INSTALL(FILES ${_location_we}.pdb
375            DESTINATION ${RUNTIME_INSTALL_DIRECTORY}
376            CONFIGURATIONS ${_config}
377          )
378        ENDIF()
379      ENDFOREACH(_config)
380    ENDIF()
381  ENDIF()
382
383ENDMACRO(TU_ADD_TARGET)
384
385
386# Creates a helper file with name <name_of_the_library>${ORXONOX_MODULE_EXTENSION}
387# This helps finding dynamically loadable modules at runtime
388
389FUNCTION(ADD_MODULE _target)
390  # We use the properties to get the name because the librarys name may differ from
391  # the target name (for example orxonox <-> liborxonox)
392
393  GET_TARGET_PROPERTY(_target_loc ${_target} LOCATION)
394  GET_FILENAME_COMPONENT(_target_name ${_target_loc} NAME_WE)
395
396  IF(CMAKE_CONFIGURATION_TYPES)
397    FOREACH(_config ${CMAKE_CONFIGURATION_TYPES})
398      SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_config}/${_target_name}${ORXONOX_MODULE_EXTENSION})
399
400      FILE(WRITE ${_module_filename})
401
402      INSTALL(
403        FILES ${_module_filename}
404        DESTINATION ${MODULE_INSTALL_DIRECTORY}
405        CONFIGURATIONS ${_config}
406      )
407    ENDFOREACH()
408  ELSE()
409    SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_target_name}${ORXONOX_MODULE_EXTENSION})
410
411    FILE(WRITE ${_module_filename})
412
413    INSTALL(
414      FILES ${_module_filename}
415      DESTINATION ${MODULE_INSTALL_DIRECTORY}
416    )
417  ENDIF()
418ENDFUNCTION(ADD_MODULE)
Note: See TracBrowser for help on using the repository browser.