Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/tutorial/cmake/FlagUtilities.cmake @ 3008

Last change on this file since 3008 was 2710, checked in by rgrieder, 16 years ago

Merged buildsystem3 containing buildsystem2 containing Adi's buildsystem branch back to the trunk.
Please update the media directory if you were not using buildsystem3 before.

  • 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.