Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/questsystem5/cmake/FlagUtilities.cmake @ 2907

Last change on this file since 2907 was 2907, checked in by dafrick, 16 years ago

Merging of the current QuestSystem branch.

  • Property svn:eol-style set to native
File size: 8.3 KB
RevLine 
[2626]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 #    Sets the compiler/linker flags. After the flags you can specify more args:
24 #    Release, Debug, RelWithDebInfo, MinSizeRel: Build configs (inclusive)
25 #    ReleaseAll: Sets the flags of all three release builds
26 #    CACHE: Values are witten with SET_CACHE (see above)
27 #    FORCE: When writing to the cache, the values are set anyway
28 #    Any variable names (like WIN32, MSVC, etc.): Condition (combined with AND)
29 #    You can suffix the condition with a NOT if you wish
30 #  Functions:
31 #    [ADD/SET/REMOVE]_[COMPILER/LINKER]_FLAGS
32 #  Caution: -If you use CACHE after calling the macro without CACHE, the value
33 #            Will not get written unless FORCE is specified.
34 #          - Also be aware to always specify the flags in quotes.
35 #  Example:
36 #    REMOVE_COMPILER_FLAGS("/Gm "asdf" -q"test -foo" CXX ReleaseAll NOT UNIX)
37 #    This will only remove the CXX (C++) flags on a non Unix system for the
38 #    Release, RelWithDebInfo and MinSizeRel configurations. The macros should
39 #    be able to cope with "test -foo" that is like another flag in the string.
40 #
[2620]41
42# Write to the cache by force, but only if the user didn't edit the value
43# Additional argument is the value (may also be a list)
44MACRO(SET_CACHE _varname _type _docstring)
45  SET(_value ${ARGN})
46  IF(NOT "${_type}" MATCHES "^(STRING|BOOL|PATH|FILEPATH)$")
47    MESSAGE(FATAL_ERROR "${_type} is not a valid CACHE entry type")
[2624]48  ENDIF()
[2620]49
50  IF(NOT DEFINED _INTERNAL_${_varname} OR "${_INTERNAL_${_varname}}" STREQUAL "${${_varname}}")
51    SET(${_varname} "${_value}" CACHE ${_type} "${_docstring}" FORCE)
[2643]52    SET(_INTERNAL_${_varname} "${_value}" CACHE INTERNAL "Do not edit in any case!")
[2624]53  ENDIF()
[2620]54ENDMACRO(SET_CACHE)
55
[2907]56# Visual studio (esp. IntelliSense) doesn't like dashes to specify arguments
57# Always use foward slashes instead
58IF(MSVC)
59  SET(ARGUMENT_STARTER "/")
60ELSE()
61  SET(ARGUMENT_STARTER "-")
62ENDIF(MSVC)
63
[2620]64# Separates a string of flags. " -" or " /" denotes the start of a flag.
65# The same sequence inside double quotation marks is ignored.
66# Spaces not within quotes are cleaned meaningfully.
67# This macro cannot cope with semicolons in the flag string!
68MACRO(SEPARATE_FLAGS _flags _output_variable)
69  SET(_flags_prep " ${_flags} -")
70  STRING(REPLACE " " " ;" _flag_chunks ${_flags_prep}) # Max loop iterations
71  SET(_flag_string)
72  SET(_parsed_flags)
73  # Loop is necessary because the regex engine is greedy
74  FOREACH(_chunk ${_flag_chunks})
75    SET(_flag_string "${_flag_string}${_chunk}")
76    # Replace all " -" and " /" inside quotation marks
77    STRING(REGEX REPLACE "^(([^\"]*\"[^\"]*\")*[^\"]*\"[^\"]*) [/-]([^\"]*\")"
78           "\\1@39535493@\\3" _flag_string "${_flag_string}")
79    # Extract one flag if possible
80    SET(_flag)
[2907]81    STRING(REGEX REPLACE "^.* [/-](.+)( [/-].*$)" "${ARGUMENT_STARTER}\\1" _flag "${_flag_string}")
[2620]82    STRING(REGEX REPLACE "^.* [/-](.+)( [/-].*$)" "\\2"  _flag_string "${_flag_string}")
83    IF(NOT _flag STREQUAL _flag_string)
84      LIST(APPEND _parsed_flags "${_flag}")
85    ENDIF(NOT _flag STREQUAL _flag_string)
86  ENDFOREACH(_chunk)
87
88  # Re-replace all " -" and " /" inside quotation marks
89  STRING(REGEX REPLACE "@39535493@" " -" ${_output_variable} "${_parsed_flags}")
90ENDMACRO(SEPARATE_FLAGS)
91
92# Internal macro, do not use
93# Modifies the flags according to the mode: set, add or remove
94# Also sets flags according to the CACHE and FORCE parameter.
95# If only CACHE is specified, SET_CACHE() is used.
96MACRO(_INTERNAL_PARSE_FLAGS _mode _flags _varname _write_to_cache _force)
97  SEPARATE_FLAGS("${_flags}" _arg_flag_list)
98
99  IF("${_mode}" STREQUAL "SET")
100    # SET
101    SET(_flag_list "${_arg_flag_list}")
[2624]102  ELSE()
[2620]103    # ADD or REMOVE
104    SEPARATE_FLAGS("${${_varname}}" _flag_list)
105    FOREACH(_flag ${_arg_flag_list})
106      LIST(${_mode} _flag_list "${_flag}")
107    ENDFOREACH(_flag)
[2624]108  ENDIF()
[2620]109
110  LIST(REMOVE_DUPLICATES _flag_list)
111  LIST(SORT _flag_list)
112  STRING(REPLACE ";" " " _flag_list "${_flag_list}")
113
114  IF(_write_to_cache)
115    IF(_force)
116      SET(${_varname} "${_flag_list}" CACHE STRING "${${_varname}}" FORCE)
117      SET(${_varname} "${_flag_list}" CACHE STRING "${${_varname}}" FORCE)
[2624]118    ELSE()
[2620]119      SET_CACHE(${_varname} STRING "${${_varname}}" "${_flag_list}")
[2624]120    ENDIF()
121  ELSE()
[2620]122    SET(${_varname} "${_flag_list}")
[2624]123  ENDIF()
[2620]124ENDMACRO(_INTERNAL_PARSE_FLAGS)
125
126# Internal macro, do not use
127# Parses the given additional arguments and sets the flags to the
128# corresponding variables.
129MACRO(_INTERNAL_PARSE_FLAGS_ARGS _mode _keys _key_postfix _flags)
130  SET(_langs)
131  SET(_build_types)
132  SET(_cond TRUE)
133  SET(_invert_condition FALSE)
134  SET(_write_to_cache FALSE)
135  SET(_force FALSE)
136  STRING(REPLACE ";" "|" _key_regex "${_keys}")
137  SET(_key_regex "^(${_key_regex})$")
138
139  FOREACH(_arg ${ARGN})
140    IF(_arg MATCHES "${_key_regex}")
141      LIST(APPEND _langs "${_arg}")
142    ELSEIF(   _arg MATCHES "^(Debug|Release|MinSizeRel|RelWithDebInfo)$"
143           OR _arg MATCHES "^(DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO)$")
144      STRING(TOUPPER "${_arg}" _upper_arg)
145      LIST(APPEND _build_types ${_upper_arg})
146    ELSEIF(_arg STREQUAL "ReleaseAll")
147      LIST(APPEND _build_types RELEASE MINSIZEREL RELWITHDEBINFO)
148    ELSEIF(_arg STREQUAL "CACHE")
149      SET(_write_to_cache TRUE)
150    ELSEIF(_arg STREQUAL "FORCE")
151      SET(_force TRUE)
152    ELSEIF(_arg MATCHES "^[Nn][Oo][Tt]$")
153      SET(_invert_condition TRUE)
[2624]154    ELSE()
[2620]155      IF(_invert_condition)
156        SET(_invert_condition FALSE)
[2654]157    IF(${_arg})
[2620]158          SET(_arg_cond FALSE)
[2654]159    ELSE()
[2620]160          SET(_arg_cond TRUE)
[2654]161    ENDIF()
[2624]162      ELSE()
[2620]163        SET(_arg_cond ${${_arg}})
[2624]164      ENDIF()
[2620]165      IF(_cond AND _arg_cond)
166        SET(_cond TRUE)
[2624]167      ELSE()
[2620]168        SET(_cond FALSE)
[2624]169      ENDIF()
170    ENDIF()
[2620]171  ENDFOREACH(_arg)
172
173  # No language specified, use all: C and CXX or EXE, SHARED and MODULE
174  IF(NOT DEFINED _langs)
175    SET(_langs ${_keys})
[2624]176  ENDIF()
[2620]177
178  IF(_cond)
179    FOREACH(_lang ${_langs})
180      SET(_varname "CMAKE_${_lang}${_key_postfix}_FLAGS")
181      IF(DEFINED _build_types)
182        FOREACH(_build_type ${_build_types})
183          _INTERNAL_PARSE_FLAGS(${_mode} "${_flags}" ${_varname}_${_build_type} ${_write_to_cache} ${_force})
184        ENDFOREACH(_build_type)
[2624]185      ELSE()
[2620]186        _INTERNAL_PARSE_FLAGS(${_mode} "${_flags}" ${_varname} ${_write_to_cache} ${_force})
[2624]187      ENDIF()
[2620]188    ENDFOREACH(_lang ${_langs})
189  ENDIF(_cond)
190ENDMACRO(_INTERNAL_PARSE_FLAGS_ARGS)
191
192
193# Compiler flags, additional arguments:
194# C, CXX: Specify a language, default is both
195MACRO(SET_COMPILER_FLAGS _flags)
196  _INTERNAL_PARSE_FLAGS_ARGS(SET "C;CXX" "" "${_flags}" "${ARGN}")
197ENDMACRO(SET_COMPILER_FLAGS)
198# Add flags (flags don't get added twice)
199MACRO(ADD_COMPILER_FLAGS _flags)
200  _INTERNAL_PARSE_FLAGS_ARGS(APPEND "C;CXX" "" "${_flags}" "${ARGN}")
201ENDMACRO(ADD_COMPILER_FLAGS)
202# Remove flags
203MACRO(REMOVE_COMPILER_FLAGS _flags)
204  _INTERNAL_PARSE_FLAGS_ARGS(REMOVE_ITEM "C;CXX" "" "${_flags}" "${ARGN}")
205ENDMACRO(REMOVE_COMPILER_FLAGS)
206
207# Linker flags, additional arguments:
208# EXE, SHARED, MODULE: Specify a linker mode, default is all three
209MACRO(SET_LINKER_FLAGS _flags)
210  _INTERNAL_PARSE_FLAGS_ARGS(SET "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
211ENDMACRO(SET_LINKER_FLAGS)
212# Add flags (flags don't get added twice)
213MACRO(ADD_LINKER_FLAGS _flags)
214  _INTERNAL_PARSE_FLAGS_ARGS(APPEND "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
215ENDMACRO(ADD_LINKER_FLAGS)
216# Remove flags
217MACRO(REMOVE_LINKER_FLAGS _flags)
218  _INTERNAL_PARSE_FLAGS_ARGS(REMOVE_ITEM "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
219ENDMACRO(REMOVE_LINKER_FLAGS)
Note: See TracBrowser for help on using the repository browser.