Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8652 was 8650, checked in by rgrieder, 14 years ago

Also add tolua bind files to build units (for the sake of completeness ).

  • 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  # TOLUA_FILES
185  IF(_arg_TOLUA_FILES)
186    GENERATE_TOLUA_BINDINGS(${_target_name_capitalised} _${_target_name}_files
187                            INPUTFILES ${_arg_TOLUA_FILES})
188    # Workaround for XCode: The folder where the bind files are written to has
189    # to be present beforehand.
190    IF(CMAKE_CONFIGURATION_TYPES)
191      FOREACH(_dir ${CMAKE_CONFIGURATION_TYPES})
192        FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_dir})
193      ENDFOREACH(_dir)
194    ENDIF()
195  ENDIF()
196
197  # Mark files to be excluded from build units
198  IF(_arg_EXCLUDE_FROM_BUILD_UNITS)
199    SET_SOURCE_FILES_PROPERTIES(${_arg_EXCLUDE_FROM_BUILD_UNITS}
200      PROPERTIES EXCLUDE_FROM_BUILD_UNITS TRUE)
201  ENDIF()
202
203  # Full build units
204  IF(NOT _arg_ORXONOX_EXTERNAL AND ENABLE_BUILD_UNITS MATCHES "full")
205    GENERATE_BUILD_UNITS(${_target_name} _${_target_name}_files)
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.