Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/kicklib/cmake/tools/TargetUtilities.cmake @ 8246

Last change on this file since 8246 was 8233, checked in by rgrieder, 14 years ago

Removed config files from individual targets for MSVC because search results turn up 15 times or so.
Instead, added a new target 'config' (for MSVC only) that includes OrxonoxConfig.h and SpecialConfig.h.

  • Property svn:eol-style set to native
File size: 13.5 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
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    # Workaround for XCode: The folder where the bind files are written to has
172    # to be present beforehand.
173    IF(CMAKE_CONFIGURATION_TYPES)
174      FOREACH(_dir ${CMAKE_CONFIGURATION_TYPES})
175        FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_dir})
176      ENDFOREACH(_dir)
177    ENDIF()
178  ENDIF()
179
180  # First part (pre target) of precompiled header files
181  IF(PCH_COMPILER_SUPPORT AND _arg_PCH_FILE)
182    # Provide convenient option to control PCH
183    IF(_arg_PCH_NO_DEFAULT)
184      SET(PCH_DEFAULT FALSE)
185    ELSE()
186      SET(PCH_DEFAULT TRUE)
187    ENDIF()
188    CMAKE_DEPENDENT_OPTION(PCH_ENABLE_${_target_name_upper}
189      "Enable using precompiled header files for library ${_target_name}." ${PCH_DEFAULT} PCH_ENABLE OFF)
190
191    IF(PCH_ENABLE_${_target_name_upper})
192      PRECOMPILED_HEADER_FILES_PRE_TARGET(${_target_name} ${_arg_PCH_FILE} _${_target_name}_files EXCLUDE ${_arg_PCH_EXCLUDE})
193    ENDIF()
194  ENDIF()
195
196  # Generate the source groups
197  IF(MSVC AND NOT _arg_NO_SOURCE_GROUPS)
198    GENERATE_SOURCE_GROUPS(${_${_target_name}_files})
199
200    IF(NOT _arg_ORXONOX_EXTERNAL)
201      # Move the ...Prereqs.h and the PCH files to the 'Config' section
202      IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_target_name_capitalised}Prereqs.h)
203        SOURCE_GROUP("Config" FILES ${_target_name_capitalised}Prereqs.h)
204      ENDIF()
205      IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_arg_PCH_FILE})
206        SOURCE_GROUP("Config" FILES ${CMAKE_CURRENT_SOURCE_DIR}/${_arg_PCH_FILE})
207      ENDIF()
208    ENDIF()
209  ENDIF()
210
211  # Set link mode (SHARED/STATIC)
212  IF(MSVC AND _arg_NO_DLL_INTERFACE)
213    # Certain libraries don't have dllexport/dllimport and can't be linked shared with MSVC
214    SET(_link_mode STATIC)
215  ELSEIF(_arg_ORXONOX_EXTERNAL)
216    # Externals can be linked shared or statically
217    SET(_link_mode ${ORXONOX_EXTERNAL_LINK_MODE})
218  ELSE()
219    # All our own libraries are linked dynamically because of static symbols
220    SET(_link_mode SHARED)
221  ENDIF()
222
223  # No warnings needed from third party libraries
224  IF(_arg_ORXONOX_EXTERNAL)
225    REMOVE_COMPILER_FLAGS("-W3 -W4" MSVC)
226    ADD_COMPILER_FLAGS("-w" NOT MSVC)
227    ADD_COMPILER_FLAGS("-W0" MSVC)
228  ENDIF()
229
230  # Don't compile header files
231  FOREACH(_file ${_${_target_name}_files})
232    IF(NOT _file MATCHES "\\.(c|cc|cpp|cxx|mm)$")
233      SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
234    ENDIF()
235  ENDFOREACH(_file)
236
237
238
239  # Add the library/executable
240  IF("${_target_type}" STREQUAL "LIBRARY")
241    ADD_LIBRARY(${_target_name} ${_link_mode}
242                ${_arg_EXCLUDE_FROM_ALL} ${_${_target_name}_files})
243  ELSE()
244    ADD_EXECUTABLE(${_target_name} ${_arg_WIN32} ${_arg_EXCLUDE_FROM_ALL}
245                   ${_${_target_name}_files})
246  ENDIF()
247
248
249
250  # Change library prefix to "lib"
251  IF(MSVC AND ${_target_type} STREQUAL "LIBRARY")
252    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
253      PREFIX "lib"
254    )
255  ENDIF()
256
257  # MSVC hack to exclude external library sources from the intellisense database
258  # (IntelliSense stops working when adding "-Zm1000" as compile flag. "/Zm1000"
259  # would not work because of the slash)
260  IF(_arg_ORXONOX_EXTERNAL AND MSVC)
261    GET_TARGET_PROPERTY(_compile_flags ${_target_name} COMPILE_FLAGS)
262    IF(NOT _compile_flags)
263      SET(_compile_flags)
264    ENDIF()
265    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES COMPILE_FLAGS "${_compile_flags} -Zm1000")
266  ENDIF()
267
268  # Configure modules
269  IF (_arg_MODULE)
270    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
271      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Windows
272      LIBRARY_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Unix
273    )
274    ADD_MODULE(${_target_name})
275    # Ensure that the main program depends on the module
276    SET(ORXONOX_MODULES ${ORXONOX_MODULES} ${_target_name} CACHE STRING "" FORCE)
277  ENDIF()
278
279  # Static library flags are not globally available
280  IF(ORXONOX_STATIC_LINKER_FLAGS)
281    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES STATIC_LIBRARY_FLAGS ${ORXONOX_STATIC_LINKER_FLAGS})
282  ENDIF()
283
284  # LINK_LIBRARIES
285  IF(_arg_LINK_LIBRARIES)
286    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBRARIES})
287  ENDIF()
288
289  # DEFINE_SYMBOL
290  IF(_arg_DEFINE_SYMBOL)
291    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES DEFINE_SYMBOL ${_arg_DEFINE_SYMBOL})
292  ELSEIF(NOT _arg_ORXONOX_EXTERNAL)
293    # Automatically add the macro definitions for our own libraries
294    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES DEFINE_SYMBOL "${_target_name_upper}_SHARED_BUILD")
295  ENDIF()
296
297  # VERSION
298  IF(_arg_VERSION)
299    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${_arg_VERSION})
300  ELSEIF(NOT _arg_ORXONOX_EXTERNAL AND NOT _arg_NO_VERSION AND NOT ${_target_type} STREQUAL "EXECUTABLE")
301    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${ORXONOX_VERSION})
302  ENDIF()
303
304  # OUTPUT_NAME
305  IF(_arg_OUTPUT_NAME)
306    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES OUTPUT_NAME  ${_arg_OUTPUT_NAME})
307  ENDIF()
308
309  # Second part of precompiled header files
310  IF(PCH_COMPILER_SUPPORT AND PCH_ENABLE_${_target_name_upper} AND _arg_PCH_FILE)
311    PRECOMPILED_HEADER_FILES_POST_TARGET(${_target_name} ${_arg_PCH_FILE})
312  ENDIF()
313
314  # Install all targets except for static ones (executables also have SHARED in _link_mode)
315  IF(${_link_mode} STREQUAL "SHARED" AND NOT _arg_NO_INSTALL)
316    IF(_arg_MODULE)
317      INSTALL(TARGETS ${_target_name}
318        RUNTIME DESTINATION ${MODULE_INSTALL_DIRECTORY}
319        LIBRARY DESTINATION ${MODULE_INSTALL_DIRECTORY}
320      )
321    ELSE()
322      INSTALL(TARGETS ${_target_name}
323        RUNTIME DESTINATION ${RUNTIME_INSTALL_DIRECTORY}
324        LIBRARY DESTINATION ${LIBRARY_INSTALL_DIRECTORY}
325      )
326    ENDIF()
327  ENDIF()
328
329ENDMACRO(TU_ADD_TARGET)
330
331
332# Creates a helper file with name <name_of_the_library>${ORXONOX_MODULE_EXTENSION}
333# This helps finding dynamically loadable modules at runtime
334
335FUNCTION(ADD_MODULE _target)
336  # We use the properties to get the name because the librarys name may differ from
337  # the target name (for example orxonox <-> liborxonox)
338
339  GET_TARGET_PROPERTY(_target_loc ${_target} LOCATION)
340  GET_FILENAME_COMPONENT(_target_name ${_target_loc} NAME_WE)
341
342  IF(CMAKE_CONFIGURATION_TYPES)
343    FOREACH(_config ${CMAKE_CONFIGURATION_TYPES})
344      SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_config}/${_target_name}${ORXONOX_MODULE_EXTENSION})
345
346      FILE(WRITE ${_module_filename})
347
348      INSTALL(
349        FILES ${_module_filename}
350        DESTINATION ${MODULE_INSTALL_DIRECTORY}
351        CONFIGURATIONS ${_config}
352      )
353    ENDFOREACH()
354  ELSE()
355    SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_target_name}${ORXONOX_MODULE_EXTENSION})
356
357    FILE(WRITE ${_module_filename})
358
359    INSTALL(
360      FILES ${_module_filename}
361      DESTINATION ${MODULE_INSTALL_DIRECTORY}
362    )
363  ENDIF()
364ENDFUNCTION(ADD_MODULE)
Note: See TracBrowser for help on using the repository browser.