]> git.uio.no Git - u/mrichter/AliRoot.git/blame - Vc/cmake/VcMacros.cmake
From Theodor Rascanu: These changes are necessary since we need to have the code...
[u/mrichter/AliRoot.git] / Vc / cmake / VcMacros.cmake
CommitLineData
f22341db 1# Macros for use with the Vc library. Vc can be found at http://code.compeng.uni-frankfurt.de/projects/vc
2#
3# The following macros are provided:
4# vc_determine_compiler
5# vc_set_preferred_compiler_flags
6#
7#=============================================================================
8# Copyright 2009-2012 Matthias Kretz <kretz@kde.org>
9#
10# Distributed under the OSI-approved BSD License (the "License");
11# see accompanying file CmakeCopyright.txt for details.
12#
13# This software is distributed WITHOUT ANY WARRANTY; without even the
14# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15# See the License for more information.
16#=============================================================================
17
18get_filename_component(_currentDir "${CMAKE_CURRENT_LIST_FILE}" PATH)
19include ("${_currentDir}/UserWarning.cmake")
20include ("${_currentDir}/AddCompilerFlag.cmake")
21include ("${_currentDir}/OptimizeForArchitecture.cmake")
22
23macro(vc_determine_compiler)
24 if(NOT DEFINED Vc_COMPILER_IS_INTEL)
25 set(Vc_COMPILER_IS_INTEL false)
26 set(Vc_COMPILER_IS_OPEN64 false)
27 set(Vc_COMPILER_IS_CLANG false)
28 set(Vc_COMPILER_IS_MSVC false)
29 set(Vc_COMPILER_IS_GCC false)
30 if(CMAKE_CXX_COMPILER MATCHES "/(icpc|icc)$")
31 set(Vc_COMPILER_IS_INTEL true)
32 exec_program(${CMAKE_C_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE Vc_ICC_VERSION)
33 message(STATUS "Detected Compiler: Intel ${Vc_ICC_VERSION}")
23a11150 34 elseif(CMAKE_CXX_COMPILER MATCHES "(opencc|openCC)$")
f22341db 35 set(Vc_COMPILER_IS_OPEN64 true)
36 message(STATUS "Detected Compiler: Open64")
23a11150 37 elseif(CMAKE_CXX_COMPILER MATCHES "clang\\+\\+$")
f22341db 38 set(Vc_COMPILER_IS_CLANG true)
39 message(STATUS "Detected Compiler: Clang")
40 elseif(MSVC)
41 set(Vc_COMPILER_IS_MSVC true)
42 message(STATUS "Detected Compiler: MSVC")
43 elseif(CMAKE_COMPILER_IS_GNUCXX)
44 set(Vc_COMPILER_IS_GCC true)
45 exec_program(${CMAKE_C_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE Vc_GCC_VERSION)
46 message(STATUS "Detected Compiler: GCC ${Vc_GCC_VERSION}")
47
48 # some distributions patch their GCC to return nothing or only major and minor version on -dumpversion.
49 # In that case we must extract the version number from --version.
50 if(NOT Vc_GCC_VERSION OR Vc_GCC_VERSION MATCHES "^[0-9]\\.[0-9]+$")
51 exec_program(${CMAKE_C_COMPILER} ARGS --version OUTPUT_VARIABLE Vc_GCC_VERSION)
52 string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" Vc_GCC_VERSION "${Vc_GCC_VERSION}")
53 message(STATUS "GCC Version from --version: ${Vc_GCC_VERSION}")
54 endif()
55
56 # some distributions patch their GCC to be API incompatible to what the FSF released. In
57 # those cases we require a macro to identify the distribution version
58 find_program(_lsb_release lsb_release)
59 mark_as_advanced(_lsb_release)
60 if(_lsb_release)
61 execute_process(COMMAND ${_lsb_release} -is OUTPUT_VARIABLE _distributor_id OUTPUT_STRIP_TRAILING_WHITESPACE)
62 execute_process(COMMAND ${_lsb_release} -rs OUTPUT_VARIABLE _distributor_release OUTPUT_STRIP_TRAILING_WHITESPACE)
63 string(TOUPPER "${_distributor_id}" _distributor_id)
64 if(_distributor_id STREQUAL "UBUNTU")
65 execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE _gcc_version)
66 string(REGEX MATCH "\\(.* ${Vc_GCC_VERSION}-([0-9]+).*\\)" _tmp "${_gcc_version}")
67 if(_tmp)
68 set(_patch ${CMAKE_MATCH_1})
69 string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _tmp "${_distributor_release}")
70 execute_process(COMMAND printf 0x%x%02x%02x ${CMAKE_MATCH_1} ${CMAKE_MATCH_2} ${_patch} OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE _tmp)
71 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -D__GNUC_UBUNTU_VERSION__=${_tmp}")
72 endif()
73 endif()
74 endif()
75 else()
76 message(WARNING "Untested/-supported Compiler for use with Vc.\nPlease fill out the missing parts in the CMake scripts and submit a patch to http://code.compeng.uni-frankfurt.de/projects/vc")
77 endif()
78 endif()
79endmacro()
80
81macro(vc_set_gnu_buildtype_flags)
82 set(CMAKE_CXX_FLAGS_DEBUG "-g3" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
83 set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG" CACHE STRING "Flags used by the compiler during release minsize builds." FORCE)
84 set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "Flags used by the compiler during release builds (/MD /Ob1 /Oi /Ot /Oy /Gs will produce slightly less optimized but smaller files)." FORCE)
85 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -g" CACHE STRING "Flags used by the compiler during Release with Debug Info builds." FORCE)
86 set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
87 set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}" CACHE STRING "Flags used by the compiler during release minsize builds." FORCE)
88 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "Flags used by the compiler during release builds (/MD /Ob1 /Oi /Ot /Oy /Gs will produce slightly less optimized but smaller files)." FORCE)
89 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" CACHE STRING "Flags used by the compiler during Release with Debug Info builds." FORCE)
90 if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
91 set(ENABLE_STRICT_ALIASING true CACHE BOOL "Enables strict aliasing rules for more aggressive optimizations")
92 if(NOT ENABLE_STRICT_ALIASING)
93 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-strict-aliasing ")
94 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-strict-aliasing ")
95 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fno-strict-aliasing ")
96 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fno-strict-aliasing ")
97 endif(NOT ENABLE_STRICT_ALIASING)
98 endif()
99endmacro()
100
101macro(vc_add_compiler_flag VAR _flag)
102 AddCompilerFlag("${_flag}" CXX_FLAGS ${VAR})
103endmacro()
104
105macro(vc_check_assembler)
106 if(APPLE)
107 if(NOT Vc_COMPILER_IS_CLANG)
3ea24db6 108 message(WARNING "Apple does not provide an assembler with AVX support. AVX will not be available. Please use Clang if you want to use AVX.")
109 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_NO_XGETBV")
110 set(Vc_AVX_INTRINSICS_BROKEN true)
f22341db 111 endif()
112 else(APPLE)
113 if(${ARGC} EQUAL 1)
114 set(_as "${ARGV1}")
115 else()
116 exec_program(${CMAKE_CXX_COMPILER} ARGS -print-prog-name=as OUTPUT_VARIABLE _as)
117 mark_as_advanced(_as)
118 endif()
119 if(NOT _as)
120 message(WARNING "Could not find 'as', the assembler used by GCC. Hoping everything will work out...")
121 else()
122 exec_program(${_as} ARGS --version OUTPUT_VARIABLE _as_version)
123 string(REGEX REPLACE "\\([^\\)]*\\)" "" _as_version "${_as_version}")
124 string(REGEX MATCH "[1-9]\\.[0-9]+(\\.[0-9]+)?" _as_version "${_as_version}")
125 if(_as_version VERSION_LESS "2.18.93")
126 message(WARNING "Your binutils is too old (${_as_version}). Some optimizations of Vc will be disabled.")
127 add_definitions(-DVC_NO_XGETBV) # old assembler doesn't know the xgetbv instruction
128 endif()
129 endif()
130 endif(APPLE)
131endmacro()
132
133macro(vc_check_fpmath)
134 # if compiling for 32 bit x86 we need to use the -mfpmath=sse since the x87 is broken by design
135 include (CheckCXXSourceRuns)
136 check_cxx_source_runs("int main() { return sizeof(void*) != 8; }" Vc_VOID_PTR_IS_64BIT)
137 if(NOT Vc_VOID_PTR_IS_64BIT)
138 exec_program(${CMAKE_C_COMPILER} ARGS -dumpmachine OUTPUT_VARIABLE _gcc_machine)
139 if(_gcc_machine MATCHES "[x34567]86")
140 vc_add_compiler_flag(Vc_DEFINITIONS "-mfpmath=sse")
141 endif(_gcc_machine MATCHES "[x34567]86")
142 endif()
143endmacro()
144
145macro(vc_set_preferred_compiler_flags)
146 vc_determine_compiler()
147
148 set(_add_warning_flags false)
149 set(_add_buildtype_flags false)
150 foreach(_arg ${ARGN})
151 if(_arg STREQUAL "WARNING_FLAGS")
152 set(_add_warning_flags true)
153 elseif(_arg STREQUAL "BUILDTYPE_FLAGS")
154 set(_add_buildtype_flags true)
155 endif()
156 endforeach()
157
158 set(Vc_SSE_INTRINSICS_BROKEN false)
159 set(Vc_AVX_INTRINSICS_BROKEN false)
160
161 if(Vc_COMPILER_IS_OPEN64)
162 ##################################################################################################
163 # Open64 #
164 ##################################################################################################
165 if(_add_warning_flags)
166 AddCompilerFlag("-W")
167 AddCompilerFlag("-Wall")
168 AddCompilerFlag("-Wimplicit")
169 AddCompilerFlag("-Wswitch")
170 AddCompilerFlag("-Wformat")
171 AddCompilerFlag("-Wchar-subscripts")
172 AddCompilerFlag("-Wparentheses")
173 AddCompilerFlag("-Wmultichar")
174 AddCompilerFlag("-Wtrigraphs")
175 AddCompilerFlag("-Wpointer-arith")
176 AddCompilerFlag("-Wcast-align")
177 AddCompilerFlag("-Wreturn-type")
178 AddCompilerFlag("-Wno-unused-function")
179 AddCompilerFlag("-ansi")
180 AddCompilerFlag("-pedantic")
181 AddCompilerFlag("-Wno-long-long")
182 AddCompilerFlag("-Wshadow")
183 AddCompilerFlag("-Wold-style-cast")
184 AddCompilerFlag("-Wno-variadic-macros")
185 endif()
186 if(_add_buildtype_flags)
187 vc_set_gnu_buildtype_flags()
188 endif()
189
190 vc_check_assembler()
191 elseif(Vc_COMPILER_IS_GCC)
192 ##################################################################################################
193 # GCC #
194 ##################################################################################################
195 if(_add_warning_flags)
196 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W -Wall -Wswitch -Wformat -Wchar-subscripts -Wparentheses -Wmultichar -Wtrigraphs -Wpointer-arith -Wcast-align -Wreturn-type -Wno-unused-function -ansi -pedantic -Wno-long-long -Wshadow")
197 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Wall -Wswitch -Wformat -Wchar-subscripts -Wparentheses -Wmultichar -Wtrigraphs -Wpointer-arith -Wcast-align -Wreturn-type -Wno-unused-function -ansi -pedantic -Wno-long-long -Wshadow")
198 AddCompilerFlag("-Wimplicit")
199 AddCompilerFlag("-Wold-style-cast")
200 AddCompilerFlag("-Wno-variadic-macros")
201 if(Vc_GCC_VERSION VERSION_GREATER "4.5.2" AND Vc_GCC_VERSION VERSION_LESS "4.6.4")
202 # GCC gives bogus "array subscript is above array bounds" warnings in math.cpp
203 AddCompilerFlag("-Wno-array-bounds")
204 endif()
205 endif()
206 vc_add_compiler_flag(Vc_DEFINITIONS "-Wabi")
207 vc_add_compiler_flag(Vc_DEFINITIONS "-fabi-version=0") # ABI version 4 is required to make __m128 and __m256 appear as different types. 0 should give us the latest version.
208
209 if(_add_buildtype_flags)
210 vc_set_gnu_buildtype_flags()
211 endif()
212
213 # GCC 4.5.[01] fail at inlining some functions, creating functions with a single instructions,
214 # thus creating a large overhead.
215 if(Vc_GCC_VERSION VERSION_LESS "4.5.2" AND NOT Vc_GCC_VERSION VERSION_LESS "4.5.0")
216 UserWarning("GCC 4.5.0 and 4.5.1 have problems with inlining correctly. Setting early-inlining-insns=12 as workaround.")
217 AddCompilerFlag("--param early-inlining-insns=12")
218 endif()
219
220 if(Vc_GCC_VERSION VERSION_LESS "4.4.6")
221 UserWarning("Your GCC is older than 4.4.6. This is known to cause problems/bugs. Please update to the latest GCC if you can.")
222 set(Vc_AVX_INTRINSICS_BROKEN true)
223 if(Vc_GCC_VERSION VERSION_LESS "4.3.0")
224 UserWarning("Your GCC is older than 4.3.0. It is unable to handle the full set of SSE2 intrinsics. All SSE code will be disabled. Please update to the latest GCC if you can.")
225 set(Vc_SSE_INTRINSICS_BROKEN true)
226 endif()
227 endif()
228
229 if(Vc_GCC_VERSION VERSION_LESS 4.5.0)
230 UserWarning("GCC 4.4.x shows false positives for -Wparentheses, thus we rather disable the warning.")
231 string(REPLACE " -Wparentheses " " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
232 string(REPLACE " -Wparentheses " " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
233 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -Wno-parentheses")
234 elseif(Vc_GCC_VERSION VERSION_EQUAL 4.7.0)
235 UserWarning("GCC 4.7.0 miscompiles at -O3, adding -fno-predictive-commoning to the compiler flags as workaround")
236 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -fno-predictive-commoning")
237 endif()
238
239 vc_check_fpmath()
240 vc_check_assembler()
241 elseif(Vc_COMPILER_IS_INTEL)
242 ##################################################################################################
243 # Intel Compiler #
244 ##################################################################################################
245
246 if(_add_buildtype_flags)
247 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
248 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
249 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
250 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
251
252 set(ALIAS_FLAGS "-no-ansi-alias")
253 if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
254 # default ICC to -no-ansi-alias because otherwise tests/utils_sse fails. So far I suspect a miscompilation...
255 set(ENABLE_STRICT_ALIASING false CACHE BOOL "Enables strict aliasing rules for more aggressive optimizations")
256 if(ENABLE_STRICT_ALIASING)
257 set(ALIAS_FLAGS "-ansi-alias")
258 endif(ENABLE_STRICT_ALIASING)
259 endif()
260 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ALIAS_FLAGS}")
261 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ALIAS_FLAGS}")
262 endif()
263 vc_add_compiler_flag(Vc_DEFINITIONS "-diag-disable 913")
264 elseif(Vc_COMPILER_IS_MSVC)
265 if(_add_warning_flags)
266 AddCompilerFlag("/wd4800") # Disable warning "forcing value to bool"
267 AddCompilerFlag("/wd4996") # Disable warning about strdup vs. _strdup
268 AddCompilerFlag("/wd4244") # Disable warning "conversion from 'unsigned int' to 'float', possible loss of data"
269 AddCompilerFlag("/wd4146") # Disable warning "unary minus operator applied to unsigned type, result still unsigned"
270 AddCompilerFlag("/wd4227") # Disable warning "anachronism used : qualifiers on reference are ignored" (this is about 'restrict' usage on references, stupid MSVC)
271 AddCompilerFlag("/wd4722") # Disable warning "destructor never returns, potential memory leak" (warns about ~_UnitTest_Global_Object which we don't care about)
272 AddCompilerFlag("/wd4748") # Disable warning "/GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function" (I don't get it)
273 add_definitions(-D_CRT_SECURE_NO_WARNINGS)
274 endif()
275
276 # MSVC does not support inline assembly on 64 bit! :(
277 # searching the help for xgetbv doesn't turn up anything. So just fall back to not supporting AVX on Windows :(
278 # TODO: apparently MSVC 2010 SP1 added _xgetbv
279 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_NO_XGETBV")
280
281 # get rid of the min/max macros
282 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DNOMINMAX")
283 elseif(Vc_COMPILER_IS_CLANG)
284 # for now I don't know of any arguments I want to pass. -march and stuff is tried by OptimizeForArchitecture...
285
286 # disable these warnings because clang shows them for function overloads that were discarded via SFINAE
287 vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-local-type-template-args")
288 vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-unnamed-type-template-args")
289 endif()
290
291 OptimizeForArchitecture()
292 set(Vc_DEFINITIONS "${Vc_ARCHITECTURE_FLAGS} ${Vc_DEFINITIONS}")
293
294 set(VC_IMPL "auto" CACHE STRING "Force the Vc implementation globally to the selected instruction set. \"auto\" lets Vc use the best available instructions.")
295 if(NOT VC_IMPL STREQUAL "auto")
296 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_IMPL=${VC_IMPL}")
297 if(NOT VC_IMPL STREQUAL "Scalar")
298 set(_use_var "USE_${VC_IMPL}")
299 if(VC_IMPL STREQUAL "SSE")
300 set(_use_var "USE_SSE2")
301 endif()
302 if(NOT ${_use_var})
303 message(WARNING "The selected value for VC_IMPL (${VC_IMPL}) will not work because the relevant instructions are not enabled via compiler flags.")
304 endif()
305 endif()
306 endif()
307endmacro()