Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2624 was 2624, checked in by rgrieder, 15 years ago

Replaced most of the ELSE(…) and ENDIF(…) with ELSE() and ENDIF(). Kept the shorter and the spreaded ones for better clarity since that's what it originally was thought for. But I can really pollute the code when having long conditions and lots of IFs.

  • Property svn:eol-style set to native
File size: 7.6 KB
Line 
1#    AddSourceFiles.cmake - CMake Module to include source files in subdirectories.
2#    Author: Reto '1337' Grieder (2008)
3#
4#    This program is free software; you can redistribute it and/or modify
5#    it under the terms of the GNU General Public License as published by
6#    the Free Software Foundation; either version 2 of the License, or
7#    (at your option) any later version.
8#
9#    This program is distributed in the hope that it will be useful,
10#    but WITHOUT ANY WARRANTY; without even the implied warranty of
11#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12#    GNU General Public License for more details.
13#
14#    You should have received a copy of the GNU General Public License
15#    along with this program; if not, write to the Free Software
16#    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
17
18
19# Write to the cache by force, but only if the user didn't edit the value
20# Additional argument is the value (may also be a list)
21MACRO(SET_CACHE _varname _type _docstring)
22  SET(_value ${ARGN})
23  IF(NOT "${_type}" MATCHES "^(STRING|BOOL|PATH|FILEPATH)$")
24    MESSAGE(FATAL_ERROR "${_type} is not a valid CACHE entry type")
25  ENDIF()
26
27  IF(NOT DEFINED _INTERNAL_${_varname} OR "${_INTERNAL_${_varname}}" STREQUAL "${${_varname}}")
28    SET(${_varname} "${_value}" CACHE ${_type} "${_docstring}" FORCE)
29  ENDIF()
30  SET(_INTERNAL_${_varname} "${_value}" CACHE INTERNAL "Do not edit in any case!")
31ENDMACRO(SET_CACHE)
32
33# Separates a string of flags. " -" or " /" denotes the start of a flag.
34# The same sequence inside double quotation marks is ignored.
35# Spaces not within quotes are cleaned meaningfully.
36# This macro cannot cope with semicolons in the flag string!
37MACRO(SEPARATE_FLAGS _flags _output_variable)
38  SET(_flags_prep " ${_flags} -")
39  STRING(REPLACE " " " ;" _flag_chunks ${_flags_prep}) # Max loop iterations
40  SET(_flag_string)
41  SET(_parsed_flags)
42  # Loop is necessary because the regex engine is greedy
43  FOREACH(_chunk ${_flag_chunks})
44    SET(_flag_string "${_flag_string}${_chunk}")
45    # Replace all " -" and " /" inside quotation marks
46    STRING(REGEX REPLACE "^(([^\"]*\"[^\"]*\")*[^\"]*\"[^\"]*) [/-]([^\"]*\")"
47           "\\1@39535493@\\3" _flag_string "${_flag_string}")
48    # Extract one flag if possible
49    SET(_flag)
50    STRING(REGEX REPLACE "^.* [/-](.+)( [/-].*$)" "-\\1" _flag "${_flag_string}")
51    STRING(REGEX REPLACE "^.* [/-](.+)( [/-].*$)" "\\2"  _flag_string "${_flag_string}")
52    IF(NOT _flag STREQUAL _flag_string)
53      LIST(APPEND _parsed_flags "${_flag}")
54    ENDIF(NOT _flag STREQUAL _flag_string)
55  ENDFOREACH(_chunk)
56
57  # Re-replace all " -" and " /" inside quotation marks
58  STRING(REGEX REPLACE "@39535493@" " -" ${_output_variable} "${_parsed_flags}")
59ENDMACRO(SEPARATE_FLAGS)
60
61# Internal macro, do not use
62# Modifies the flags according to the mode: set, add or remove
63# Also sets flags according to the CACHE and FORCE parameter.
64# If only CACHE is specified, SET_CACHE() is used.
65MACRO(_INTERNAL_PARSE_FLAGS _mode _flags _varname _write_to_cache _force)
66  SEPARATE_FLAGS("${_flags}" _arg_flag_list)
67
68  IF("${_mode}" STREQUAL "SET")
69    # SET
70    SET(_flag_list "${_arg_flag_list}")
71  ELSE()
72    # ADD or REMOVE
73    SEPARATE_FLAGS("${${_varname}}" _flag_list)
74    FOREACH(_flag ${_arg_flag_list})
75      LIST(${_mode} _flag_list "${_flag}")
76    ENDFOREACH(_flag)
77  ENDIF()
78
79  LIST(REMOVE_DUPLICATES _flag_list)
80  LIST(SORT _flag_list)
81  STRING(REPLACE ";" " " _flag_list "${_flag_list}")
82
83  IF(_write_to_cache)
84    IF(_force)
85      SET(${_varname} "${_flag_list}" CACHE STRING "${${_varname}}" FORCE)
86      SET(${_varname} "${_flag_list}" CACHE STRING "${${_varname}}" FORCE)
87    ELSE()
88      SET_CACHE(${_varname} STRING "${${_varname}}" "${_flag_list}")
89    ENDIF()
90  ELSE()
91    SET(${_varname} "${_flag_list}")
92  ENDIF()
93ENDMACRO(_INTERNAL_PARSE_FLAGS)
94
95# Internal macro, do not use
96# Parses the given additional arguments and sets the flags to the
97# corresponding variables.
98MACRO(_INTERNAL_PARSE_FLAGS_ARGS _mode _keys _key_postfix _flags)
99  SET(_langs)
100  SET(_build_types)
101  SET(_cond TRUE)
102  SET(_invert_condition FALSE)
103  SET(_write_to_cache FALSE)
104  SET(_force FALSE)
105  STRING(REPLACE ";" "|" _key_regex "${_keys}")
106  SET(_key_regex "^(${_key_regex})$")
107
108  FOREACH(_arg ${ARGN})
109    IF(_arg MATCHES "${_key_regex}")
110      LIST(APPEND _langs "${_arg}")
111    ELSEIF(   _arg MATCHES "^(Debug|Release|MinSizeRel|RelWithDebInfo)$"
112           OR _arg MATCHES "^(DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO)$")
113      STRING(TOUPPER "${_arg}" _upper_arg)
114      LIST(APPEND _build_types ${_upper_arg})
115    ELSEIF(_arg STREQUAL "ReleaseAll")
116      LIST(APPEND _build_types RELEASE MINSIZEREL RELWITHDEBINFO)
117    ELSEIF(_arg STREQUAL "CACHE")
118      SET(_write_to_cache TRUE)
119    ELSEIF(_arg STREQUAL "FORCE")
120      SET(_force TRUE)
121    ELSEIF(_arg MATCHES "^[Nn][Oo][Tt]$")
122      SET(_invert_condition TRUE)
123    ELSE()
124      IF(_invert_condition)
125        SET(_invert_condition FALSE)
126        IF(${_arg})
127          SET(_arg_cond FALSE)
128        ELSE()
129          SET(_arg_cond TRUE)
130        ENDIF()
131      ELSE()
132        SET(_arg_cond ${${_arg}})
133      ENDIF()
134      IF(_cond AND _arg_cond)
135        SET(_cond TRUE)
136      ELSE()
137        SET(_cond FALSE)
138      ENDIF()
139    ENDIF()
140  ENDFOREACH(_arg)
141
142  # No language specified, use all: C and CXX or EXE, SHARED and MODULE
143  IF(NOT DEFINED _langs)
144    SET(_langs ${_keys})
145  ENDIF()
146
147  IF(_cond)
148    FOREACH(_lang ${_langs})
149      SET(_varname "CMAKE_${_lang}${_key_postfix}_FLAGS")
150      IF(DEFINED _build_types)
151        FOREACH(_build_type ${_build_types})
152          _INTERNAL_PARSE_FLAGS(${_mode} "${_flags}" ${_varname}_${_build_type} ${_write_to_cache} ${_force})
153        ENDFOREACH(_build_type)
154      ELSE()
155        _INTERNAL_PARSE_FLAGS(${_mode} "${_flags}" ${_varname} ${_write_to_cache} ${_force})
156      ENDIF()
157    ENDFOREACH(_lang ${_langs})
158  ENDIF(_cond)
159ENDMACRO(_INTERNAL_PARSE_FLAGS_ARGS)
160
161
162# Sets the compiler/linker flags. After the flags you can specify more args:
163# Release, Debug, RelWithDebInfo, MinSizeRel: Build configs (inclusive)
164# ReleaseAll: Sets the flags of all three release builds
165# CACHE: Values are witten with SET_CACHE (see above)
166# FORCE: When writing to the cache, the values are set anyway
167# Any variable names (like WIN32, MSVC, etc.): Condition (combined with AND)
168#   You can suffix the condition with a NOT if you wish
169
170# Caution: -If you use CACHE after calling the macro without CACHE, the value
171#           Will not get written unless FORCE is specified.
172#          - Also be aware to always specify the flags in quotes.
173
174# Compiler flags, additional arguments:
175# C, CXX: Specify a language, default is both
176MACRO(SET_COMPILER_FLAGS _flags)
177  _INTERNAL_PARSE_FLAGS_ARGS(SET "C;CXX" "" "${_flags}" "${ARGN}")
178ENDMACRO(SET_COMPILER_FLAGS)
179# Add flags (flags don't get added twice)
180MACRO(ADD_COMPILER_FLAGS _flags)
181  _INTERNAL_PARSE_FLAGS_ARGS(APPEND "C;CXX" "" "${_flags}" "${ARGN}")
182ENDMACRO(ADD_COMPILER_FLAGS)
183# Remove flags
184MACRO(REMOVE_COMPILER_FLAGS _flags)
185  _INTERNAL_PARSE_FLAGS_ARGS(REMOVE_ITEM "C;CXX" "" "${_flags}" "${ARGN}")
186ENDMACRO(REMOVE_COMPILER_FLAGS)
187
188# Linker flags, additional arguments:
189# EXE, SHARED, MODULE: Specify a linker mode, default is all three
190MACRO(SET_LINKER_FLAGS _flags)
191  _INTERNAL_PARSE_FLAGS_ARGS(SET "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
192ENDMACRO(SET_LINKER_FLAGS)
193# Add flags (flags don't get added twice)
194MACRO(ADD_LINKER_FLAGS _flags)
195  _INTERNAL_PARSE_FLAGS_ARGS(APPEND "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
196ENDMACRO(ADD_LINKER_FLAGS)
197# Remove flags
198MACRO(REMOVE_LINKER_FLAGS _flags)
199  _INTERNAL_PARSE_FLAGS_ARGS(REMOVE_ITEM "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
200ENDMACRO(REMOVE_LINKER_FLAGS)
Note: See TracBrowser for help on using the repository browser.