Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/lastmanstanding2/cmake/tools/TargetUtilities.cmake @ 8474

Last change on this file since 8474 was 7416, checked in by rgrieder, 14 years ago

Never insert even the tiniest thing that is for sure certain without testing…
Also fixed two typos.

  • Property svn:eol-style set to native
File size: 11.0 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
93  # Workaround: Source file properties get lost when leaving a subdirectory
94  # Therefore an "H" after a file means we have to set it as HEADER_FILE_ONLY
95  FOREACH(_file ${_arg_SOURCE_FILES})
96    IF(_file STREQUAL "H")
97      SET_SOURCE_FILES_PROPERTIES(${_last_file} PROPERTIES HEADER_FILE_ONLY TRUE)
98    ELSE()
99      SET(_last_file ${_file})
100      LIST(APPEND _${_target_name}_source_files ${_file})
101    ENDIF()
102  ENDFOREACH(_file)
103
104  # Assemble all header files of the library
105  IF(_arg_FIND_HEADER_FILES)
106    GET_ALL_HEADER_FILES(_${_target_name}_header_files)
107  ENDIF()
108
109  # Combine source and header files
110  SET(_${_target_name}_files
111    ${_${_target_name}_header_files}
112    ${_${_target_name}_source_files}
113  )
114  # Remove potential duplicates
115  LIST(REMOVE_DUPLICATES _${_target_name}_files)
116
117  # TOLUA_FILES
118  IF(_arg_TOLUA_FILES)
119    GENERATE_TOLUA_BINDINGS(${_target_name_capitalised} _${_target_name}_files
120                            INPUTFILES ${_arg_TOLUA_FILES})
121  ENDIF()
122
123  # First part (pre target) of precompiled header files
124  IF(PCH_COMPILER_SUPPORT AND _arg_PCH_FILE)
125    # Provide convenient option to control PCH
126    IF(_arg_PCH_NO_DEFAULT)
127      SET(PCH_DEFAULT FALSE)
128    ELSE()
129      SET(PCH_DEFAULT TRUE)
130    ENDIF()
131    CMAKE_DEPENDENT_OPTION(PCH_ENABLE_${_target_name_upper}
132      "Enable using precompiled header files for library ${_target_name}." ${PCH_DEFAULT} PCH_ENABLE OFF)
133
134    IF(PCH_ENABLE_${_target_name_upper})
135      PRECOMPILED_HEADER_FILES_PRE_TARGET(${_target_name} ${_arg_PCH_FILE} _${_target_name}_files EXCLUDE ${_arg_PCH_EXCLUDE})
136    ENDIF()
137  ENDIF()
138
139  # Generate the source groups
140  IF(MSVC AND NOT _arg_NO_SOURCE_GROUPS)
141    GENERATE_SOURCE_GROUPS(${_${_target_name}_files})
142
143    IF(NOT _arg_ORXONOX_EXTERNAL)
144      # Move the prereqs.h file to the config section
145      IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_target_name_capitalised}Prereqs.h)
146        SOURCE_GROUP("Config" FILES ${_target_name_capitalised}Prereqs.h)
147      ENDIF()
148      # Add config files to the config section
149      LIST(APPEND _${_target_name}_files ${ORXONOX_CONFIG_FILES})
150      SOURCE_GROUP("Config" FILES ${ORXONOX_CONFIG_FILES})
151    ENDIF()
152  ENDIF()
153
154  # Set link mode (SHARED/STATIC)
155  IF(MSVC AND _arg_NO_DLL_INTERFACE)
156    # Certain libraries don't have dllexport/dllimport and can't be linked shared with MSVC
157    SET(_link_mode STATIC)
158  ELSEIF(_arg_ORXONOX_EXTERNAL)
159    # Externals can be linked shared or statically
160    SET(_link_mode ${ORXONOX_EXTERNAL_LINK_MODE})
161  ELSE()
162    # All our own libraries are linked dynamically because of static symbols
163    SET(_link_mode SHARED)
164  ENDIF()
165
166  # No warnings needed from third party libraries
167  IF(_arg_ORXONOX_EXTERNAL)
168    REMOVE_COMPILER_FLAGS("-W3 -W4" MSVC)
169    ADD_COMPILER_FLAGS("-w")
170  ENDIF()
171
172  # Don't compile header files
173  FOREACH(_file ${_${_target_name}_files})
174    IF(NOT _file MATCHES "\\.(c|cc|cpp)")
175      SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
176    ENDIF()
177  ENDFOREACH(_file)
178
179
180
181  # Add the library/executable
182  IF("${_target_type}" STREQUAL "LIBRARY")
183    ADD_LIBRARY(${_target_name} ${_link_mode}
184                ${_arg_EXCLUDE_FROM_ALL} ${_${_target_name}_files})
185  ELSE()
186    ADD_EXECUTABLE(${_target_name} ${_arg_WIN32} ${_arg_EXCLUDE_FROM_ALL}
187                   ${_${_target_name}_files})
188  ENDIF()
189
190
191
192  # Change library prefix to "lib"
193  IF(MSVC AND ${_target_type} STREQUAL "LIBRARY")
194    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
195      PREFIX "lib"
196    )
197  ENDIF()
198
199  # MSVC hack to exclude external library sources from the intellisense database
200  # (IntelliSense stops working when adding "-Zm1000" as compile flag. "/Zm1000"
201  # would not work because of the slash)
202  IF(_arg_ORXONOX_EXTERNAL AND MSVC)
203    GET_TARGET_PROPERTY(_compile_flags ${_target_name} COMPILE_FLAGS)
204    IF(NOT _compile_flags)
205      SET(_compile_flags)
206    ENDIF()
207    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES COMPILE_FLAGS "${_compile_flags} -Zm1000")
208  ENDIF()
209
210  # Configure modules
211  IF (_arg_MODULE)
212    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
213      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Windows
214      LIBRARY_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Unix
215    )
216    ADD_MODULE(${_target_name})
217    # Ensure that the main program depends on the module
218    SET(ORXONOX_MODULES ${ORXONOX_MODULES} ${_target_name} CACHE STRING "" FORCE)
219  ENDIF()
220
221  # LINK_LIBRARIES
222  IF(_arg_LINK_LIBRARIES)
223    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBRARIES})
224  ENDIF()
225
226  # DEFINE_SYMBOL
227  IF(_arg_DEFINE_SYMBOL)
228    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES DEFINE_SYMBOL ${_arg_DEFINE_SYMBOL})
229  ELSEIF(NOT _arg_ORXONOX_EXTERNAL)
230    # Automatically add the macro definitions for our own libraries
231    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES DEFINE_SYMBOL "${_target_name_upper}_SHARED_BUILD")
232  ENDIF()
233
234  # VERSION
235  IF(_arg_VERSION)
236    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${_arg_VERSION})
237  ELSEIF(NOT _arg_ORXONOX_EXTERNAL AND NOT _arg_NO_VERSION AND NOT ${_target_type} STREQUAL "EXECUTABLE")
238    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${ORXONOX_VERSION})
239  ENDIF()
240
241  # OUTPUT_NAME
242  IF(_arg_OUTPUT_NAME)
243    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES OUTPUT_NAME  ${_arg_OUTPUT_NAME})
244  ENDIF()
245
246  # Second part of precompiled header files
247  IF(PCH_COMPILER_SUPPORT AND PCH_ENABLE_${_target_name_upper} AND _arg_PCH_FILE)
248    PRECOMPILED_HEADER_FILES_POST_TARGET(${_target_name} ${_arg_PCH_FILE})
249  ENDIF()
250
251  # Install all targets except for static ones (executables also have SHARED in _link_mode)
252  IF(${_link_mode} STREQUAL "SHARED" AND NOT _arg_NO_INSTALL)
253    IF(_arg_MODULE)
254      INSTALL(TARGETS ${_target_name}
255        RUNTIME DESTINATION ${MODULE_INSTALL_DIRECTORY}
256        LIBRARY DESTINATION ${MODULE_INSTALL_DIRECTORY}
257      )
258    ELSE()
259      INSTALL(TARGETS ${_target_name}
260        RUNTIME DESTINATION ${RUNTIME_INSTALL_DIRECTORY}
261        LIBRARY DESTINATION ${LIBRARY_INSTALL_DIRECTORY}
262      )
263    ENDIF()
264  ENDIF()
265
266ENDMACRO(TU_ADD_TARGET)
267
268
269# Creates a helper file with name <name_of_the_library>${ORXONOX_MODULE_EXTENSION}
270# This helps finding dynamically loadable modules at runtime
271
272FUNCTION(ADD_MODULE _target)
273  # We use the properties to get the name because the librarys name may differ from
274  # the target name (for example orxonox <-> liborxonox)
275
276  GET_TARGET_PROPERTY(_target_loc ${_target} LOCATION)
277  GET_FILENAME_COMPONENT(_target_name ${_target_loc} NAME_WE)
278
279  IF(CMAKE_CONFIGURATION_TYPES)
280    FOREACH(_config ${CMAKE_CONFIGURATION_TYPES})
281      SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_config}/${_target_name}${ORXONOX_MODULE_EXTENSION})
282
283      FILE(WRITE ${_module_filename})
284
285      INSTALL(
286        FILES ${_module_filename}
287        DESTINATION ${MODULE_INSTALL_DIRECTORY}
288        CONFIGURATIONS ${_config}
289      )
290    ENDFOREACH()
291  ELSE()
292    SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_target_name}${ORXONOX_MODULE_EXTENSION})
293
294    FILE(WRITE ${_module_filename})
295
296    INSTALL(
297      FILES ${_module_filename}
298      DESTINATION ${MODULE_INSTALL_DIRECTORY}
299    )
300  ENDIF()
301ENDFUNCTION(ADD_MODULE)
Note: See TracBrowser for help on using the repository browser.