Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/tutoriallevel/cmake/tools/TargetUtilities.cmake @ 8043

Last change on this file since 8043 was 7818, checked in by rgrieder, 14 years ago

Merged changes related to Visual Leak Detector and source file handling from sandbox QT to trunk.

  • Property svn:eol-style set to native
File size: 13.2 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 #      VERSION:           Set version to the binary
46 #      SOURCE_FILES:      Source files for the target
47 #      DEFINE_SYMBOL:     Sets the DEFINE_SYMBOL target property
48 #      TOLUA_FILES:       Files with tolua interface
49 #      PCH_FILE:          Precompiled header file
50 #      PCH_EXCLUDE:       Source files to be excluded from PCH support
51 #      OUTPUT_NAME:       If you want a different name than the target name
52 #  Note:
53 #    This function also installs the target!
54 #  Prerequisistes:
55 #    ORXONOX_DEFAULT_LINK, ORXONOX_CONFIG_FILES
56 #  Parameters:
57 #    _target_name, ARGN for the macro arguments
58 #
59
60INCLUDE(CMakeDependentOption)
61INCLUDE(CapitaliseName)
62INCLUDE(GenerateToluaBindings)
63INCLUDE(ParseMacroArguments)
64INCLUDE(SourceFileUtilities)
65IF(PCH_COMPILER_SUPPORT)
66  INCLUDE(PrecompiledHeaderFiles)
67ENDIF()
68
69MACRO(ORXONOX_ADD_LIBRARY _target_name)
70  TU_ADD_TARGET(${_target_name} LIBRARY "MODULE" ${ARGN})
71ENDMACRO(ORXONOX_ADD_LIBRARY)
72
73MACRO(ORXONOX_ADD_EXECUTABLE _target_name)
74  TU_ADD_TARGET(${_target_name} EXECUTABLE "WIN32" ${ARGN})
75ENDMACRO(ORXONOX_ADD_EXECUTABLE)
76
77
78MACRO(TU_ADD_TARGET _target_name _target_type _additional_switches)
79  CAPITALISE_NAME(${_target_name} _target_name_capitalised)
80  STRING(TOUPPER "${_target_name}" _target_name_upper)
81
82  # Specify all possible options (either switch or with add. arguments)
83  SET(_switches   FIND_HEADER_FILES  EXCLUDE_FROM_ALL  ORXONOX_EXTERNAL
84                  NO_DLL_INTERFACE   NO_SOURCE_GROUPS  PCH_NO_DEFAULT 
85                  NO_INSTALL         NO_VERSION        ${_additional_switches})
86  SET(_list_names LINK_LIBRARIES     VERSION           SOURCE_FILES
87                  DEFINE_SYMBOL      TOLUA_FILES       PCH_FILE
88                  PCH_EXCLUDE        OUTPUT_NAME)
89
90  PARSE_MACRO_ARGUMENTS("${_switches}" "${_list_names}" ${ARGN})
91
92  # Process source files with support for compilations
93  # Note: All file paths are relative to the root source directory, even the
94  #       name of the compilation file.
95  SET(_${_target_name}_source_files)
96  SET(_get_compilation_file FALSE)
97  SET(_add_to_compilation FALSE)
98  FOREACH(_file ${_arg_SOURCE_FILES})
99    IF(_file STREQUAL "COMPILATION_BEGIN")
100      # Next file is the name of the compilation
101      SET(_get_compilation_file TRUE)
102    ELSEIF(_file STREQUAL "COMPILATION_END")
103      IF(NOT _compilation_file)
104        MESSAGE(FATAL_ERROR "No name provided for source file compilation")
105      ENDIF()
106      IF(NOT _compilation_include_string)
107        MESSAGE(STATUS "Warning: Empty source file compilation!")
108      ENDIF()
109      IF(NOT DISABLE_COMPILATIONS)
110        IF(EXISTS ${_compilation_file})
111          FILE(READ ${_compilation_file} _include_string_file)
112        ENDIF()
113        IF(NOT _compilation_include_string STREQUAL "${_include_string_file}")
114          FILE(WRITE ${_compilation_file} "${_compilation_include_string}")
115        ENDIF()
116        LIST(APPEND _${_target_name}_source_files ${_compilation_file})
117      ENDIF()
118      SET(_add_to_compilation FALSE)
119    ELSEIF(_get_compilation_file)
120      SET(_compilation_file ${CMAKE_BINARY_DIR}/${_file})
121      SET(_get_compilation_file FALSE)
122      SET(_add_to_compilation TRUE)
123      SET(_compilation_include_string)
124    ELSE()
125      # Default, add source file
126
127      # Prepare relative paths
128      IF(NOT _file MATCHES "^(.\\:|\\/)")
129        # Path can be relative to the current source directory if the file was
130        # not added with the source file macros. Otherwise there is a "./" at
131        # the beginning of each file and the filename is relative
132        # to the CMAKE_SOURCE_DIR
133        STRING(REGEX REPLACE "^\\.\\/(.+)$" "\\1" _temp ${_file})
134        IF(NOT ${_temp} STREQUAL ${_file})
135          SET(_file ${CMAKE_SOURCE_DIR}/${_temp})
136        ELSE()
137          SET(_file ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
138        ENDIF()
139      ENDIF()
140
141      LIST(APPEND _${_target_name}_source_files ${_file})
142
143      # Handle compilations
144      IF(_add_to_compilation AND NOT DISABLE_COMPILATIONS)
145        IF(_file MATCHES "\\.(c|cc|cpp|cxx)$")
146          SET(_compilation_include_string "${_compilation_include_string}#include \"${_file}\"\n")
147        ENDIF()
148        # Don't compile these files, even if they are source files
149        SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
150      ENDIF()
151    ENDIF()
152  ENDFOREACH(_file)
153
154  # Assemble all header files of the library
155  IF(_arg_FIND_HEADER_FILES)
156    GET_ALL_HEADER_FILES(_${_target_name}_header_files)
157  ENDIF()
158
159  # Combine source and header files
160  SET(_${_target_name}_files
161    ${_${_target_name}_header_files}
162    ${_${_target_name}_source_files}
163  )
164  # Remove potential duplicates
165  LIST(REMOVE_DUPLICATES _${_target_name}_files)
166
167  # TOLUA_FILES
168  IF(_arg_TOLUA_FILES)
169    GENERATE_TOLUA_BINDINGS(${_target_name_capitalised} _${_target_name}_files
170                            INPUTFILES ${_arg_TOLUA_FILES})
171  ENDIF()
172
173  # First part (pre target) of precompiled header files
174  IF(PCH_COMPILER_SUPPORT AND _arg_PCH_FILE)
175    # Provide convenient option to control PCH
176    IF(_arg_PCH_NO_DEFAULT)
177      SET(PCH_DEFAULT FALSE)
178    ELSE()
179      SET(PCH_DEFAULT TRUE)
180    ENDIF()
181    CMAKE_DEPENDENT_OPTION(PCH_ENABLE_${_target_name_upper}
182      "Enable using precompiled header files for library ${_target_name}." ${PCH_DEFAULT} PCH_ENABLE OFF)
183
184    IF(PCH_ENABLE_${_target_name_upper})
185      PRECOMPILED_HEADER_FILES_PRE_TARGET(${_target_name} ${_arg_PCH_FILE} _${_target_name}_files EXCLUDE ${_arg_PCH_EXCLUDE})
186    ENDIF()
187  ENDIF()
188
189  # Generate the source groups
190  IF(MSVC AND NOT _arg_NO_SOURCE_GROUPS)
191    GENERATE_SOURCE_GROUPS(${_${_target_name}_files})
192
193    IF(NOT _arg_ORXONOX_EXTERNAL)
194      # Move the prereqs.h file to the config section
195      IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_target_name_capitalised}Prereqs.h)
196        SOURCE_GROUP("Config" FILES ${_target_name_capitalised}Prereqs.h)
197      ENDIF()
198      # Add config files to the config section
199      LIST(APPEND _${_target_name}_files ${ORXONOX_CONFIG_FILES})
200      SOURCE_GROUP("Config" FILES ${ORXONOX_CONFIG_FILES})
201    ENDIF()
202  ENDIF()
203
204  # Set link mode (SHARED/STATIC)
205  IF(MSVC AND _arg_NO_DLL_INTERFACE)
206    # Certain libraries don't have dllexport/dllimport and can't be linked shared with MSVC
207    SET(_link_mode STATIC)
208  ELSEIF(_arg_ORXONOX_EXTERNAL)
209    # Externals can be linked shared or statically
210    SET(_link_mode ${ORXONOX_EXTERNAL_LINK_MODE})
211  ELSE()
212    # All our own libraries are linked dynamically because of static symbols
213    SET(_link_mode SHARED)
214  ENDIF()
215
216  # No warnings needed from third party libraries
217  IF(_arg_ORXONOX_EXTERNAL)
218    REMOVE_COMPILER_FLAGS("-W3 -W4" MSVC)
219    ADD_COMPILER_FLAGS("-w")
220  ENDIF()
221
222  # Don't compile header files
223  FOREACH(_file ${_${_target_name}_files})
224    IF(NOT _file MATCHES "\\.(c|cc|cpp|cxx)$")
225      SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
226    ENDIF()
227  ENDFOREACH(_file)
228
229
230
231  # Add the library/executable
232  IF("${_target_type}" STREQUAL "LIBRARY")
233    ADD_LIBRARY(${_target_name} ${_link_mode}
234                ${_arg_EXCLUDE_FROM_ALL} ${_${_target_name}_files})
235  ELSE()
236    ADD_EXECUTABLE(${_target_name} ${_arg_WIN32} ${_arg_EXCLUDE_FROM_ALL}
237                   ${_${_target_name}_files})
238  ENDIF()
239
240
241
242  # Change library prefix to "lib"
243  IF(MSVC AND ${_target_type} STREQUAL "LIBRARY")
244    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
245      PREFIX "lib"
246    )
247  ENDIF()
248
249  # MSVC hack to exclude external library sources from the intellisense database
250  # (IntelliSense stops working when adding "-Zm1000" as compile flag. "/Zm1000"
251  # would not work because of the slash)
252  IF(_arg_ORXONOX_EXTERNAL AND MSVC)
253    GET_TARGET_PROPERTY(_compile_flags ${_target_name} COMPILE_FLAGS)
254    IF(NOT _compile_flags)
255      SET(_compile_flags)
256    ENDIF()
257    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES COMPILE_FLAGS "${_compile_flags} -Zm1000")
258  ENDIF()
259
260  # Configure modules
261  IF (_arg_MODULE)
262    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
263      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Windows
264      LIBRARY_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Unix
265    )
266    ADD_MODULE(${_target_name})
267    # Ensure that the main program depends on the module
268    SET(ORXONOX_MODULES ${ORXONOX_MODULES} ${_target_name} CACHE STRING "" FORCE)
269  ENDIF()
270
271  # Static library flags are not globally available
272  IF(ORXONOX_STATIC_LINKER_FLAGS)
273    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES STATIC_LIBRARY_FLAGS ${ORXONOX_STATIC_LINKER_FLAGS})
274  ENDIF()
275
276  # LINK_LIBRARIES
277  IF(_arg_LINK_LIBRARIES)
278    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBRARIES})
279  ENDIF()
280
281  # DEFINE_SYMBOL
282  IF(_arg_DEFINE_SYMBOL)
283    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES DEFINE_SYMBOL ${_arg_DEFINE_SYMBOL})
284  ELSEIF(NOT _arg_ORXONOX_EXTERNAL)
285    # Automatically add the macro definitions for our own libraries
286    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES DEFINE_SYMBOL "${_target_name_upper}_SHARED_BUILD")
287  ENDIF()
288
289  # VERSION
290  IF(_arg_VERSION)
291    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${_arg_VERSION})
292  ELSEIF(NOT _arg_ORXONOX_EXTERNAL AND NOT _arg_NO_VERSION AND NOT ${_target_type} STREQUAL "EXECUTABLE")
293    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${ORXONOX_VERSION})
294  ENDIF()
295
296  # OUTPUT_NAME
297  IF(_arg_OUTPUT_NAME)
298    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES OUTPUT_NAME  ${_arg_OUTPUT_NAME})
299  ENDIF()
300
301  # Second part of precompiled header files
302  IF(PCH_COMPILER_SUPPORT AND PCH_ENABLE_${_target_name_upper} AND _arg_PCH_FILE)
303    PRECOMPILED_HEADER_FILES_POST_TARGET(${_target_name} ${_arg_PCH_FILE})
304  ENDIF()
305
306  # Install all targets except for static ones (executables also have SHARED in _link_mode)
307  IF(${_link_mode} STREQUAL "SHARED" AND NOT _arg_NO_INSTALL)
308    IF(_arg_MODULE)
309      INSTALL(TARGETS ${_target_name}
310        RUNTIME DESTINATION ${MODULE_INSTALL_DIRECTORY}
311        LIBRARY DESTINATION ${MODULE_INSTALL_DIRECTORY}
312      )
313    ELSE()
314      INSTALL(TARGETS ${_target_name}
315        RUNTIME DESTINATION ${RUNTIME_INSTALL_DIRECTORY}
316        LIBRARY DESTINATION ${LIBRARY_INSTALL_DIRECTORY}
317      )
318    ENDIF()
319  ENDIF()
320
321ENDMACRO(TU_ADD_TARGET)
322
323
324# Creates a helper file with name <name_of_the_library>${ORXONOX_MODULE_EXTENSION}
325# This helps finding dynamically loadable modules at runtime
326
327FUNCTION(ADD_MODULE _target)
328  # We use the properties to get the name because the librarys name may differ from
329  # the target name (for example orxonox <-> liborxonox)
330
331  GET_TARGET_PROPERTY(_target_loc ${_target} LOCATION)
332  GET_FILENAME_COMPONENT(_target_name ${_target_loc} NAME_WE)
333
334  IF(CMAKE_CONFIGURATION_TYPES)
335    FOREACH(_config ${CMAKE_CONFIGURATION_TYPES})
336      SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_config}/${_target_name}${ORXONOX_MODULE_EXTENSION})
337
338      FILE(WRITE ${_module_filename})
339
340      INSTALL(
341        FILES ${_module_filename}
342        DESTINATION ${MODULE_INSTALL_DIRECTORY}
343        CONFIGURATIONS ${_config}
344      )
345    ENDFOREACH()
346  ELSE()
347    SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_target_name}${ORXONOX_MODULE_EXTENSION})
348
349    FILE(WRITE ${_module_filename})
350
351    INSTALL(
352      FILES ${_module_filename}
353      DESTINATION ${MODULE_INSTALL_DIRECTORY}
354    )
355  ENDIF()
356ENDFUNCTION(ADD_MODULE)
Note: See TracBrowser for help on using the repository browser.