]> git.uio.no Git - u/mrichter/AliRoot.git/blob - Vc/cmake/VcMacros.cmake
Vc package added (version 0.6.79-dev)
[u/mrichter/AliRoot.git] / Vc / cmake / VcMacros.cmake
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
18 get_filename_component(_currentDir "${CMAKE_CURRENT_LIST_FILE}" PATH)
19 include ("${_currentDir}/UserWarning.cmake")
20 include ("${_currentDir}/AddCompilerFlag.cmake")
21 include ("${_currentDir}/OptimizeForArchitecture.cmake")
22
23 macro(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}")
34       elseif(CMAKE_CXX_COMPILER MATCHES "/(opencc|openCC)$")
35          set(Vc_COMPILER_IS_OPEN64 true)
36          message(STATUS "Detected Compiler: Open64")
37       elseif(CMAKE_CXX_COMPILER MATCHES "/clang\\+\\+$")
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()
79 endmacro()
80
81 macro(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()
99 endmacro()
100
101 macro(vc_add_compiler_flag VAR _flag)
102    AddCompilerFlag("${_flag}" CXX_FLAGS ${VAR})
103 endmacro()
104
105 macro(vc_check_assembler)
106    if(APPLE)
107       if(NOT Vc_COMPILER_IS_CLANG)
108          message(WARNING "Apple does not provide an assembler with AVX support. Please use Clang instead of GCC.")
109       endif()
110    else(APPLE)
111       if(${ARGC} EQUAL 1)
112          set(_as "${ARGV1}")
113       else()
114          exec_program(${CMAKE_CXX_COMPILER} ARGS -print-prog-name=as OUTPUT_VARIABLE _as)
115          mark_as_advanced(_as)
116       endif()
117       if(NOT _as)
118          message(WARNING "Could not find 'as', the assembler used by GCC. Hoping everything will work out...")
119       else()
120          exec_program(${_as} ARGS --version OUTPUT_VARIABLE _as_version)
121          string(REGEX REPLACE "\\([^\\)]*\\)" "" _as_version "${_as_version}")
122          string(REGEX MATCH "[1-9]\\.[0-9]+(\\.[0-9]+)?" _as_version "${_as_version}")
123          if(_as_version VERSION_LESS "2.18.93")
124             message(WARNING "Your binutils is too old (${_as_version}). Some optimizations of Vc will be disabled.")
125             add_definitions(-DVC_NO_XGETBV) # old assembler doesn't know the xgetbv instruction
126          endif()
127       endif()
128    endif(APPLE)
129 endmacro()
130
131 macro(vc_check_fpmath)
132    # if compiling for 32 bit x86 we need to use the -mfpmath=sse since the x87 is broken by design
133    include (CheckCXXSourceRuns)
134    check_cxx_source_runs("int main() { return sizeof(void*) != 8; }" Vc_VOID_PTR_IS_64BIT)
135    if(NOT Vc_VOID_PTR_IS_64BIT)
136       exec_program(${CMAKE_C_COMPILER} ARGS -dumpmachine OUTPUT_VARIABLE _gcc_machine)
137       if(_gcc_machine MATCHES "[x34567]86")
138          vc_add_compiler_flag(Vc_DEFINITIONS "-mfpmath=sse")
139       endif(_gcc_machine MATCHES "[x34567]86")
140    endif()
141 endmacro()
142
143 macro(vc_set_preferred_compiler_flags)
144    vc_determine_compiler()
145
146    set(_add_warning_flags false)
147    set(_add_buildtype_flags false)
148    foreach(_arg ${ARGN})
149       if(_arg STREQUAL "WARNING_FLAGS")
150          set(_add_warning_flags true)
151       elseif(_arg STREQUAL "BUILDTYPE_FLAGS")
152          set(_add_buildtype_flags true)
153       endif()
154    endforeach()
155
156    set(Vc_SSE_INTRINSICS_BROKEN false)
157    set(Vc_AVX_INTRINSICS_BROKEN false)
158
159    if(Vc_COMPILER_IS_OPEN64)
160       ##################################################################################################
161       #                                             Open64                                             #
162       ##################################################################################################
163       if(_add_warning_flags)
164          AddCompilerFlag("-W")
165          AddCompilerFlag("-Wall")
166          AddCompilerFlag("-Wimplicit")
167          AddCompilerFlag("-Wswitch")
168          AddCompilerFlag("-Wformat")
169          AddCompilerFlag("-Wchar-subscripts")
170          AddCompilerFlag("-Wparentheses")
171          AddCompilerFlag("-Wmultichar")
172          AddCompilerFlag("-Wtrigraphs")
173          AddCompilerFlag("-Wpointer-arith")
174          AddCompilerFlag("-Wcast-align")
175          AddCompilerFlag("-Wreturn-type")
176          AddCompilerFlag("-Wno-unused-function")
177          AddCompilerFlag("-ansi")
178          AddCompilerFlag("-pedantic")
179          AddCompilerFlag("-Wno-long-long")
180          AddCompilerFlag("-Wshadow")
181          AddCompilerFlag("-Wold-style-cast")
182          AddCompilerFlag("-Wno-variadic-macros")
183       endif()
184       if(_add_buildtype_flags)
185          vc_set_gnu_buildtype_flags()
186       endif()
187
188       vc_check_assembler()
189    elseif(Vc_COMPILER_IS_GCC)
190       ##################################################################################################
191       #                                              GCC                                               #
192       ##################################################################################################
193       if(_add_warning_flags)
194          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")
195          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")
196          AddCompilerFlag("-Wimplicit")
197          AddCompilerFlag("-Wold-style-cast")
198          AddCompilerFlag("-Wno-variadic-macros")
199          if(Vc_GCC_VERSION VERSION_GREATER "4.5.2" AND Vc_GCC_VERSION VERSION_LESS "4.6.4")
200             # GCC gives bogus "array subscript is above array bounds" warnings in math.cpp
201             AddCompilerFlag("-Wno-array-bounds")
202          endif()
203       endif()
204       vc_add_compiler_flag(Vc_DEFINITIONS "-Wabi")
205       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.
206
207       if(_add_buildtype_flags)
208          vc_set_gnu_buildtype_flags()
209       endif()
210
211       # GCC 4.5.[01] fail at inlining some functions, creating functions with a single instructions,
212       # thus creating a large overhead.
213       if(Vc_GCC_VERSION VERSION_LESS "4.5.2" AND NOT Vc_GCC_VERSION VERSION_LESS "4.5.0")
214          UserWarning("GCC 4.5.0 and 4.5.1 have problems with inlining correctly. Setting early-inlining-insns=12 as workaround.")
215          AddCompilerFlag("--param early-inlining-insns=12")
216       endif()
217
218       if(Vc_GCC_VERSION VERSION_LESS "4.4.6")
219          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.")
220          set(Vc_AVX_INTRINSICS_BROKEN true)
221          if(Vc_GCC_VERSION VERSION_LESS "4.3.0")
222             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.")
223             set(Vc_SSE_INTRINSICS_BROKEN true)
224          endif()
225       endif()
226
227       if(Vc_GCC_VERSION VERSION_LESS 4.5.0)
228          UserWarning("GCC 4.4.x shows false positives for -Wparentheses, thus we rather disable the warning.")
229          string(REPLACE " -Wparentheses " " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
230          string(REPLACE " -Wparentheses " " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
231          set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -Wno-parentheses")
232       elseif(Vc_GCC_VERSION VERSION_EQUAL 4.7.0)
233          UserWarning("GCC 4.7.0 miscompiles at -O3, adding -fno-predictive-commoning to the compiler flags as workaround")
234          set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -fno-predictive-commoning")
235       endif()
236
237       vc_check_fpmath()
238       vc_check_assembler()
239    elseif(Vc_COMPILER_IS_INTEL)
240       ##################################################################################################
241       #                                          Intel Compiler                                        #
242       ##################################################################################################
243
244       if(_add_buildtype_flags)
245          set(CMAKE_CXX_FLAGS_RELEASE        "${CMAKE_CXX_FLAGS_RELEASE} -O3")
246          set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
247          set(CMAKE_C_FLAGS_RELEASE          "${CMAKE_C_FLAGS_RELEASE} -O3")
248          set(CMAKE_C_FLAGS_RELWITHDEBINFO   "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
249
250          set(ALIAS_FLAGS "-no-ansi-alias")
251          if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
252             # default ICC to -no-ansi-alias because otherwise tests/utils_sse fails. So far I suspect a miscompilation...
253             set(ENABLE_STRICT_ALIASING false CACHE BOOL "Enables strict aliasing rules for more aggressive optimizations")
254             if(ENABLE_STRICT_ALIASING)
255                set(ALIAS_FLAGS "-ansi-alias")
256             endif(ENABLE_STRICT_ALIASING)
257          endif()
258          set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}   ${ALIAS_FLAGS}")
259          set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ALIAS_FLAGS}")
260       endif()
261       vc_add_compiler_flag(Vc_DEFINITIONS "-diag-disable 913")
262    elseif(Vc_COMPILER_IS_MSVC)
263       if(_add_warning_flags)
264          AddCompilerFlag("/wd4800") # Disable warning "forcing value to bool"
265          AddCompilerFlag("/wd4996") # Disable warning about strdup vs. _strdup
266          AddCompilerFlag("/wd4244") # Disable warning "conversion from 'unsigned int' to 'float', possible loss of data"
267          AddCompilerFlag("/wd4146") # Disable warning "unary minus operator applied to unsigned type, result still unsigned"
268          AddCompilerFlag("/wd4227") # Disable warning "anachronism used : qualifiers on reference are ignored" (this is about 'restrict' usage on references, stupid MSVC)
269          AddCompilerFlag("/wd4722") # Disable warning "destructor never returns, potential memory leak" (warns about ~_UnitTest_Global_Object which we don't care about)
270          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)
271          add_definitions(-D_CRT_SECURE_NO_WARNINGS)
272       endif()
273
274       # MSVC does not support inline assembly on 64 bit! :(
275       # searching the help for xgetbv doesn't turn up anything. So just fall back to not supporting AVX on Windows :(
276       # TODO: apparently MSVC 2010 SP1 added _xgetbv
277       set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_NO_XGETBV")
278
279       # get rid of the min/max macros
280       set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DNOMINMAX")
281    elseif(Vc_COMPILER_IS_CLANG)
282       # for now I don't know of any arguments I want to pass. -march and stuff is tried by OptimizeForArchitecture...
283
284       # disable these warnings because clang shows them for function overloads that were discarded via SFINAE
285       vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-local-type-template-args")
286       vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-unnamed-type-template-args")
287    endif()
288
289    OptimizeForArchitecture()
290    set(Vc_DEFINITIONS "${Vc_ARCHITECTURE_FLAGS} ${Vc_DEFINITIONS}")
291
292    set(VC_IMPL "auto" CACHE STRING "Force the Vc implementation globally to the selected instruction set. \"auto\" lets Vc use the best available instructions.")
293    if(NOT VC_IMPL STREQUAL "auto")
294       set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_IMPL=${VC_IMPL}")
295       if(NOT VC_IMPL STREQUAL "Scalar")
296          set(_use_var "USE_${VC_IMPL}")
297          if(VC_IMPL STREQUAL "SSE")
298             set(_use_var "USE_SSE2")
299          endif()
300          if(NOT ${_use_var})
301             message(WARNING "The selected value for VC_IMPL (${VC_IMPL}) will not work because the relevant instructions are not enabled via compiler flags.")
302          endif()
303       endif()
304    endif()
305 endmacro()