-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCompilerOptions.cmake
More file actions
157 lines (137 loc) · 9.43 KB
/
CompilerOptions.cmake
File metadata and controls
157 lines (137 loc) · 9.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
add_library(compiler_options INTERFACE)
add_library(${PROJECT_NAME}::CompilerOptions ALIAS compiler_options)
# This file doesn't contain compile options, that are already set by juce::juce_recommended_config_flags:
# https://github.com/juce-framework/JUCE/blob/master/extras/Build/CMake/JUCEHelperTargets.cmake
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") # Using GNU or Clang compiler ("GNU-style" C++ compiler)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") # Only Clang compiler
# Align loops to the boundary
# Otherwise this error message occurs on Mac with AVX and manual memory alignment:
# "note: if you supply your own aligned allocation functions, use -faligned-allocation to silence this diagnostic"
target_compile_options(compiler_options INTERFACE "-faligned-allocation")
endif()
# -fPIC is needed for position-indipendent code to overcome the following error while linking:
# "relocation R_X86_64_32S against symbol `stdout@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC"
target_compile_options(compiler_options INTERFACE "-fPIC")
# This option lets the compiler make aggressive, potentially-lossy assumptions about floating-point math
# https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math
target_compile_options(compiler_options INTERFACE "-ffast-math")
# Debugger data in DEBUG mode
target_compile_options(compiler_options INTERFACE "$<$<CONFIG:Debug>:-g>")
# No optimization in DEBUG mode. Not meant for benchmarking.
target_compile_options(compiler_options INTERFACE "$<$<CONFIG:Debug>:-O0>")
# Full (but stable) Optimization in RELEASE mode
target_compile_options(compiler_options INTERFACE "$<$<CONFIG:Release>:-O3>")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") # Using Microsoft Visual Studio C++
# /Gy: Allows the compiler to package individual functions in the form of packaged functions (COMDATs). [Microsoft Docs]
# The main advantage of this is that if you have identical functions the linker can collapse them all down into one actual piece of code ("COMDAT folding"). [StackOverflow]
# /nologo: Suppresses the display of the copyright banner when the compiler starts up and display of informational messages during compiling. [Microsoft Docs]
# /permissive-: Specify standards conformance mode to the compiler. Use this option to help you identify and fix conformance issues in your code, to make it both more correct and more portable. [Microsoft Docs]
target_compile_options(compiler_options INTERFACE "/Gy;/nologo;/permissive-;")
# Debugger data in DEBUG mode (MSVC)
target_compile_options(compiler_options INTERFACE "$<$<CONFIG:Debug>:/Zi>")
# No optimization in DEBUG mode. Not meant for benchmarking. (MSVC)
target_compile_options(compiler_options INTERFACE "$<$<CONFIG:Debug>:/Od>")
# Full (but stable) Optimization in RELEASE mode
target_compile_options(compiler_options INTERFACE "$<$<CONFIG:Release>:/O2>")
# Replaces some function calls with intrinsic or otherwise special forms of the function that help your application run faster. (MSVC)
target_compile_options(compiler_options INTERFACE "/Oi")
# Build with Multiple Processes (MSVC)
target_compile_options(compiler_options INTERFACE "/MP")
# Exception handling with standard C++ stack unwinding (s) and assume that extern "C" never throw a C++ exception (c) (MSVC)
target_compile_options(compiler_options INTERFACE "/EHsc")
# Allows the compiler to reorder, combine, or simplify floating-point operations to optimize floating-point code for speed and space.
# https://docs.microsoft.com/en-us/cpp/build/reference/fp-specify-floating-point-behavior?view=msvc-170#fast
target_compile_options(compiler_options INTERFACE "/fp:fast")
endif()
# Sanitizers
set(SANITIZERS "")
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
# Address Sanatizer
# list(APPEND SANITIZERS "address") # TODO (JohT) Enable this again when failing unit tests are fixed
# Undefined Sanatizer
list(APPEND SANITIZERS "undefined")
# Thread Sanatizer (cannot be used with address sanatizer)
list(APPEND SANITIZERS "thread")
endif()
# Enable MSVC Address Sanitizer
# if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") # Using Microsoft Visual Studio C++
# Activate Address Sanitizer
# https://docs.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-170
# target_compile_options(compiler_options INTERFACE "/fsanitize=address")
# To overcome "LNK2038: mismatch detected for 'annotate_vector': value '0' doesn't match value '1'"
# "_DISABLE_VECTOR_ANNOTATION" is activated.
# https://docs.microsoft.com/en-us/cpp/sanitizers/error-container-overflow?view=msvc-170
# target_compile_definitions(compiler_options INTERFACE _DISABLE_VECTOR_ANNOTATION)
# endif()
# Options to overwrite the used CPU vectorization extension of the build host system.
option(ENFORCE_VECTOR_EXTENSION_SSE2 "Enforces SSE2 vector extension if available (Default=OFF)")
option(ENFORCE_VECTOR_EXTENSION_AVX "Enforces AVX vector extension if available (Default=OFF)")
option(ENFORCE_VECTOR_EXTENSION_AVX2 "Enforces AVX2 vector extension if available (Default=OFF)")
# Detect SSE2
cmake_host_system_information(RESULT HOST_HAS_SSE2 QUERY HAS_SSE2)
# Detect CPU instruction set extensions for vectorization (AVX, AVX2, AVX512)
# Specifies the architecture for code generation on x64 [AVX|AVX2|AVX512]
# Introduced around 2013, AVX2 should probably be supported by most PCs nowadays
# except for some mini PC CPUs like the Intel Celeron N3450 (Mid 2016, No AVX).
include(findAVX)
# Enable CLang Vectorization
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU")
if (CXX_AVX512_FOUND AND NOT ENFORCE_VECTOR_EXTENSION_SSE2 AND NOT ENFORCE_VECTOR_EXTENSION_AVX AND NOT ENFORCE_VECTOR_EXTENSION_AVX2)
target_compile_options(compiler_options INTERFACE "-mavx512f;-mavx512dq;-mavx512vl;-mavx512bw;-mfma")
elseif (CXX_AVX2_FOUND AND NOT ENFORCE_VECTOR_EXTENSION_SSE2 AND NOT ENFORCE_VECTOR_EXTENSION_AVX)
target_compile_options(compiler_options INTERFACE "-mavx2;-mfma")
elseif (CXX_AVX_FOUND AND NOT ENFORCE_VECTOR_EXTENSION_SSE2)
target_compile_options(compiler_options INTERFACE "-mavx")
elseif (HOST_HAS_SSE2 AND ENFORCE_VECTOR_EXTENSION_SSE2)
target_compile_options(compiler_options INTERFACE "-msse2")
endif()
endif()
# Enable MSVC Vectorization
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
if (CXX_AVX512_FOUND AND NOT ENFORCE_VECTOR_EXTENSION_SSE2 AND NOT ENFORCE_VECTOR_EXTENSION_AVX AND NOT ENFORCE_VECTOR_EXTENSION_AVX2)
target_compile_options(compiler_options INTERFACE "/arch:AVX512")
elseif (CXX_AVX2_FOUND AND NOT ENFORCE_VECTOR_EXTENSION_SSE2 AND NOT ENFORCE_VECTOR_EXTENSION_AVX)
target_compile_options(compiler_options INTERFACE "/arch:AVX2")
elseif (CXX_AVX_FOUND AND NOT ENFORCE_VECTOR_EXTENSION_SSE2)
target_compile_options(compiler_options INTERFACE "/arch:AVX")
elseif (HOST_HAS_SSE2 AND NOT ENFORCE_VECTOR_EXTENSION_SSE2)
target_compile_options(compiler_options INTERFACE "/arch:SSE2")
endif()
endif()
# Enable CLang Vectorization reports
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang")
target_compile_options(compiler_options INTERFACE "-Rpass=loop-vectorize")
target_compile_options(compiler_options INTERFACE "-Rpass-missed=loop-vectorize")
target_compile_options(compiler_options INTERFACE "-Rpass-analysis=loop-vectorize")
target_compile_options(compiler_options INTERFACE "-fsave-optimization-record")
target_compile_options(compiler_options INTERFACE "$<$<CONFIG:Release>:-gline-tables-only>")
target_compile_options(compiler_options INTERFACE "-gcolumn-info")
endif()
# Enable MSVC Vectorization Reports
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
# Report successfully and unsuccessfully vectorized loops
target_compile_options(compiler_options INTERFACE "/Qvec-report:2")
endif()
# Enable GNU C Vectorization + Reports
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") # Using GNU C++ Compiler
# Enable vectorization (also default at optimization parameter -O3)
target_compile_options(compiler_options INTERFACE "-ftree-vectorize")
# Print information when an optimization from vectorization passes is successfully
target_compile_options(compiler_options INTERFACE "-fopt-info-vec-optimized")
# Print information about missed optimization opportunities from vectorization passes
target_compile_options(compiler_options INTERFACE "-fopt-info-vec-missed")
endif()
# The Memory Sanatizer is only supported by Clang for Linux.
# Since GNU C++ is used for Linux, it will never be used.
#if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# list(APPEND SANITIZERS "memory")
#endif()
list(JOIN SANITIZERS ";-fsanitize=" LIST_OF_SANITIZERS)
if((LIST_OF_SANITIZERS) AND (NOT "${LIST_OF_SANITIZERS}" STREQUAL ""))
set(SANITIZERS_COMPILE_OPTIONS "-fsanitize=${LIST_OF_SANITIZERS};-fno-omit-frame-pointer")
target_compile_options(compiler_options INTERFACE "$<$<CONFIG:Debug>:${SANITIZERS_COMPILE_OPTIONS}>")
target_link_libraries(compiler_options INTERFACE "$<$<CONFIG:Debug>:${SANITIZERS_COMPILE_OPTIONS}>")
endif()
# Displays the chosen target's compile options:
get_target_property(FINAL_COMPILE_OPTIONS compiler_options INTERFACE_COMPILE_OPTIONS)
message(STATUS "Compiler definitions added to target compiler_options for compiler ${CMAKE_CXX_COMPILER_ID} and build type ${CMAKE_BUILD_TYPE}: ${FINAL_COMPILE_OPTIONS}")