Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/buildsystem2/cmake/FlagUtilities.cmake @ 2680

Last change on this file since 2680 was 2654, checked in by rgrieder, 16 years ago

Found some tabs…

  • Property svn:eol-style set to native
File size: 8.1 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 #    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 #
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")
48  ENDIF()
49
50  IF(NOT DEFINED _INTERNAL_${_varname} OR "${_INTERNAL_${_varname}}" STREQUAL "${${_varname}}")
51    SET(${_varname} "${_value}" CACHE ${_type} "${_docstring}" FORCE)
52    SET(_INTERNAL_${_varname} "${_value}" CACHE INTERNAL "Do not edit in any case!")
53  ENDIF()
54ENDMACRO(SET_CACHE)
55
56# Separates a string of flags. " -" or " /" denotes the start of a flag.
57# The same sequence inside double quotation marks is ignored.
58# Spaces not within quotes are cleaned meaningfully.
59# This macro cannot cope with semicolons in the flag string!
60MACRO(SEPARATE_FLAGS _flags _output_variable)
61  SET(_flags_prep " ${_flags} -")
62  STRING(REPLACE " " " ;" _flag_chunks ${_flags_prep}) # Max loop iterations
63  SET(_flag_string)
64  SET(_parsed_flags)
65  # Loop is necessary because the regex engine is greedy
66  FOREACH(_chunk ${_flag_chunks})
67    SET(_flag_string "${_flag_string}${_chunk}")
68    # Replace all " -" and " /" inside quotation marks
69    STRING(REGEX REPLACE "^(([^\"]*\"[^\"]*\")*[^\"]*\"[^\"]*) [/-]([^\"]*\")"
70           "\\1@39535493@\\3" _flag_string "${_flag_string}")
71    # Extract one flag if possible
72    SET(_flag)
73    STRING(REGEX REPLACE "^.* [/-](.+)( [/-].*$)" "-\\1" _flag "${_flag_string}")
74    STRING(REGEX REPLACE "^.* [/-](.+)( [/-].*$)" "\\2"  _flag_string "${_flag_string}")
75    IF(NOT _flag STREQUAL _flag_string)
76      LIST(APPEND _parsed_flags "${_flag}")
77    ENDIF(NOT _flag STREQUAL _flag_string)
78  ENDFOREACH(_chunk)
79
80  # Re-replace all " -" and " /" inside quotation marks
81  STRING(REGEX REPLACE "@39535493@" " -" ${_output_variable} "${_parsed_flags}")
82ENDMACRO(SEPARATE_FLAGS)
83
84# Internal macro, do not use
85# Modifies the flags according to the mode: set, add or remove
86# Also sets flags according to the CACHE and FORCE parameter.
87# If only CACHE is specified, SET_CACHE() is used.
88MACRO(_INTERNAL_PARSE_FLAGS _mode _flags _varname _write_to_cache _force)
89  SEPARATE_FLAGS("${_flags}" _arg_flag_list)
90
91  IF("${_mode}" STREQUAL "SET")
92    # SET
93    SET(_flag_list "${_arg_flag_list}")
94  ELSE()
95    # ADD or REMOVE
96    SEPARATE_FLAGS("${${_varname}}" _flag_list)
97    FOREACH(_flag ${_arg_flag_list})
98      LIST(${_mode} _flag_list "${_flag}")
99    ENDFOREACH(_flag)
100  ENDIF()
101
102  LIST(REMOVE_DUPLICATES _flag_list)
103  LIST(SORT _flag_list)
104  STRING(REPLACE ";" " " _flag_list "${_flag_list}")
105
106  IF(_write_to_cache)
107    IF(_force)
108      SET(${_varname} "${_flag_list}" CACHE STRING "${${_varname}}" FORCE)
109      SET(${_varname} "${_flag_list}" CACHE STRING "${${_varname}}" FORCE)
110    ELSE()
111      SET_CACHE(${_varname} STRING "${${_varname}}" "${_flag_list}")
112    ENDIF()
113  ELSE()
114    SET(${_varname} "${_flag_list}")
115  ENDIF()
116ENDMACRO(_INTERNAL_PARSE_FLAGS)
117
118# Internal macro, do not use
119# Parses the given additional arguments and sets the flags to the
120# corresponding variables.
121MACRO(_INTERNAL_PARSE_FLAGS_ARGS _mode _keys _key_postfix _flags)
122  SET(_langs)
123  SET(_build_types)
124  SET(_cond TRUE)
125  SET(_invert_condition FALSE)
126  SET(_write_to_cache FALSE)
127  SET(_force FALSE)
128  STRING(REPLACE ";" "|" _key_regex "${_keys}")
129  SET(_key_regex "^(${_key_regex})$")
130
131  FOREACH(_arg ${ARGN})
132    IF(_arg MATCHES "${_key_regex}")
133      LIST(APPEND _langs "${_arg}")
134    ELSEIF(   _arg MATCHES "^(Debug|Release|MinSizeRel|RelWithDebInfo)$"
135           OR _arg MATCHES "^(DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO)$")
136      STRING(TOUPPER "${_arg}" _upper_arg)
137      LIST(APPEND _build_types ${_upper_arg})
138    ELSEIF(_arg STREQUAL "ReleaseAll")
139      LIST(APPEND _build_types RELEASE MINSIZEREL RELWITHDEBINFO)
140    ELSEIF(_arg STREQUAL "CACHE")
141      SET(_write_to_cache TRUE)
142    ELSEIF(_arg STREQUAL "FORCE")
143      SET(_force TRUE)
144    ELSEIF(_arg MATCHES "^[Nn][Oo][Tt]$")
145      SET(_invert_condition TRUE)
146    ELSE()
147      IF(_invert_condition)
148        SET(_invert_condition FALSE)
149    IF(${_arg})
150          SET(_arg_cond FALSE)
151    ELSE()
152          SET(_arg_cond TRUE)
153    ENDIF()
154      ELSE()
155        SET(_arg_cond ${${_arg}})
156      ENDIF()
157      IF(_cond AND _arg_cond)
158        SET(_cond TRUE)
159      ELSE()
160        SET(_cond FALSE)
161      ENDIF()
162    ENDIF()
163  ENDFOREACH(_arg)
164
165  # No language specified, use all: C and CXX or EXE, SHARED and MODULE
166  IF(NOT DEFINED _langs)
167    SET(_langs ${_keys})
168  ENDIF()
169
170  IF(_cond)
171    FOREACH(_lang ${_langs})
172      SET(_varname "CMAKE_${_lang}${_key_postfix}_FLAGS")
173      IF(DEFINED _build_types)
174        FOREACH(_build_type ${_build_types})
175          _INTERNAL_PARSE_FLAGS(${_mode} "${_flags}" ${_varname}_${_build_type} ${_write_to_cache} ${_force})
176        ENDFOREACH(_build_type)
177      ELSE()
178        _INTERNAL_PARSE_FLAGS(${_mode} "${_flags}" ${_varname} ${_write_to_cache} ${_force})
179      ENDIF()
180    ENDFOREACH(_lang ${_langs})
181  ENDIF(_cond)
182ENDMACRO(_INTERNAL_PARSE_FLAGS_ARGS)
183
184
185# Compiler flags, additional arguments:
186# C, CXX: Specify a language, default is both
187MACRO(SET_COMPILER_FLAGS _flags)
188  _INTERNAL_PARSE_FLAGS_ARGS(SET "C;CXX" "" "${_flags}" "${ARGN}")
189ENDMACRO(SET_COMPILER_FLAGS)
190# Add flags (flags don't get added twice)
191MACRO(ADD_COMPILER_FLAGS _flags)
192  _INTERNAL_PARSE_FLAGS_ARGS(APPEND "C;CXX" "" "${_flags}" "${ARGN}")
193ENDMACRO(ADD_COMPILER_FLAGS)
194# Remove flags
195MACRO(REMOVE_COMPILER_FLAGS _flags)
196  _INTERNAL_PARSE_FLAGS_ARGS(REMOVE_ITEM "C;CXX" "" "${_flags}" "${ARGN}")
197ENDMACRO(REMOVE_COMPILER_FLAGS)
198
199# Linker flags, additional arguments:
200# EXE, SHARED, MODULE: Specify a linker mode, default is all three
201MACRO(SET_LINKER_FLAGS _flags)
202  _INTERNAL_PARSE_FLAGS_ARGS(SET "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
203ENDMACRO(SET_LINKER_FLAGS)
204# Add flags (flags don't get added twice)
205MACRO(ADD_LINKER_FLAGS _flags)
206  _INTERNAL_PARSE_FLAGS_ARGS(APPEND "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
207ENDMACRO(ADD_LINKER_FLAGS)
208# Remove flags
209MACRO(REMOVE_LINKER_FLAGS _flags)
210  _INTERNAL_PARSE_FLAGS_ARGS(REMOVE_ITEM "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
211ENDMACRO(REMOVE_LINKER_FLAGS)
Note: See TracBrowser for help on using the repository browser.