configurecompiler.cmake 31.0 KB
Newer Older
1 2
include(${CMAKE_CURRENT_LIST_DIR}/configuretools.cmake)

3 4 5
# Set initial flags for each configuration

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
6 7 8 9
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
10

11 12
include(CheckCXXCompilerFlag)

13
# "configureoptimization.cmake" must be included after CLR_CMAKE_HOST_UNIX has been set.
14 15
include(${CMAKE_CURRENT_LIST_DIR}/configureoptimization.cmake)

16 17 18 19
#-----------------------------------------------------
# Initialize Cmake compiler flags and other variables
#-----------------------------------------------------

20
if (CLR_CMAKE_HOST_UNIX)
21
    add_compile_options(-g)
22 23
    add_compile_options(-Wall)
    if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
24 25
        add_compile_options(-Wno-null-conversion)
    else()
26
        add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Werror=conversion-null>)
27 28 29
    endif()
endif()

30 31 32 33
if (CMAKE_CONFIGURATION_TYPES) # multi-configuration generator?
    set(CMAKE_CONFIGURATION_TYPES "Debug;Checked;Release;RelWithDebInfo" CACHE STRING "" FORCE)
endif (CMAKE_CONFIGURATION_TYPES)

34 35
set(CMAKE_C_FLAGS_CHECKED "")
set(CMAKE_CXX_FLAGS_CHECKED "")
36 37 38
set(CMAKE_EXE_LINKER_FLAGS_CHECKED "")
set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "")

39 40 41 42 43 44 45
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "")
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "")

46 47
add_compile_definitions("$<$<CONFIG:DEBUG>:DEBUG;_DEBUG;_DBG;URTBLDENV_FRIENDLY=Debug;BUILDENV_DEBUG=1>")
add_compile_definitions("$<$<CONFIG:CHECKED>:DEBUG;_DEBUG;_DBG;URTBLDENV_FRIENDLY=Checked;BUILDENV_CHECKED=1>")
48
add_compile_definitions("$<$<OR:$<CONFIG:RELEASE>,$<CONFIG:RELWITHDEBINFO>>:NDEBUG;URTBLDENV_FRIENDLY=Retail>")
49

50
if (MSVC)
51
  add_linker_flag(/GUARD:CF)
52 53 54

  # Linker flags
  #
55
  set (WINDOWS_SUBSYSTEM_VERSION 6.01)
56

57
  if (CLR_CMAKE_HOST_ARCH_ARM)
58
    set(WINDOWS_SUBSYSTEM_VERSION 6.02) #windows subsystem - arm minimum is 6.02
59
  elseif(CLR_CMAKE_HOST_ARCH_ARM64)
60
    set(WINDOWS_SUBSYSTEM_VERSION 6.03) #windows subsystem - arm64 minimum is 6.03
61 62
  endif ()

63
  #Do not create Side-by-Side Assembly Manifest
64
  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO")
65
  # can handle addresses larger than 2 gigabytes
66
  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LARGEADDRESSAWARE")
67
  #shrink pdb size
68
  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /PDBCOMPRESS")
69

70 71 72
  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEBUG")
  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4197,4013,4254,4070,4221")
  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,${WINDOWS_SUBSYSTEM_VERSION}")
73 74

  set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /IGNORE:4221")
75

76 77 78
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG")
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /PDBCOMPRESS")
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:1572864")
79 80

  # Checked build specific flags
81 82 83
  add_linker_flag(/INCREMENTAL:NO CHECKED) # prevent "warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:REF' specification"
  add_linker_flag(/OPT:REF CHECKED)
  add_linker_flag(/OPT:NOICF CHECKED)
84 85

  # Release build specific flags
86 87 88 89
  add_linker_flag(/LTCG RELEASE)
  add_linker_flag(/OPT:REF RELEASE)
  add_linker_flag(/OPT:ICF RELEASE)
  add_linker_flag(/INCREMENTAL:NO RELEASE)
90 91 92
  set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")

  # ReleaseWithDebugInfo build specific flags
93 94 95
  add_linker_flag(/LTCG RELWITHDEBINFO)
  add_linker_flag(/OPT:REF RELWITHDEBINFO)
  add_linker_flag(/OPT:ICF RELWITHDEBINFO)
96 97 98
  set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")

  # Force uCRT to be dynamically linked for Release build
99 100
  add_linker_flag(/NODEFAULTLIB:libucrt.lib RELEASE)
  add_linker_flag(/DEFAULTLIB:ucrt.lib RELEASE)
101

102
elseif (CLR_CMAKE_HOST_UNIX)
103 104 105 106 107 108
  # Set the values to display when interactively configuring CMAKE_BUILD_TYPE
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "DEBUG;CHECKED;RELEASE;RELWITHDEBINFO")

  # Use uppercase CMAKE_BUILD_TYPE for the string comparisons below
  string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_CMAKE_BUILD_TYPE)

109 110
  set(CLR_SANITIZE_CXX_OPTIONS "")
  set(CLR_SANITIZE_LINK_OPTIONS "")
111 112 113 114 115 116 117

  # set the CLANG sanitizer flags for debug build
  if(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL CHECKED)
    # obtain settings from running enablesanitizers.sh
    string(FIND "$ENV{DEBUG_SANITIZERS}" "asan" __ASAN_POS)
    string(FIND "$ENV{DEBUG_SANITIZERS}" "ubsan" __UBSAN_POS)
    if ((${__ASAN_POS} GREATER -1) OR (${__UBSAN_POS} GREATER -1))
118 119 120
      list(APPEND CLR_SANITIZE_CXX_OPTIONS -fsanitize-blacklist=${CMAKE_CURRENT_SOURCE_DIR}/sanitizerblacklist.txt)
      set (CLR_CXX_SANITIZERS "")
      set (CLR_LINK_SANITIZERS "")
121
      if (${__ASAN_POS} GREATER -1)
122 123
        list(APPEND CLR_CXX_SANITIZERS address)
        list(APPEND CLR_LINK_SANITIZERS address)
124 125 126 127 128 129 130
        set(CLR_SANITIZE_CXX_FLAGS "${CLR_SANITIZE_CXX_FLAGS}address,")
        set(CLR_SANITIZE_LINK_FLAGS "${CLR_SANITIZE_LINK_FLAGS}address,")
        add_definitions(-DHAS_ASAN)
        message("Address Sanitizer (asan) enabled")
      endif ()
      if (${__UBSAN_POS} GREATER -1)
        # all sanitizier flags are enabled except alignment (due to heavy use of __unaligned modifier)
131
        list(APPEND CLR_CXX_SANITIZERS
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
          "bool"
          bounds
          enum
          float-cast-overflow
          float-divide-by-zero
          "function"
          integer
          nonnull-attribute
          null
          object-size
          "return"
          returns-nonnull-attribute
          shift
          unreachable
          vla-bound
          vptr)
        list(APPEND CLR_LINK_SANITIZERS
          undefined)
150 151
        message("Undefined Behavior Sanitizer (ubsan) enabled")
      endif ()
152 153 154 155
      list(JOIN CLR_CXX_SANITIZERS "," CLR_CXX_SANITIZERS_OPTIONS)
      list(APPEND CLR_SANITIZE_CXX_OPTIONS "-fsanitize=${CLR_CXX_SANITIZERS_OPTIONS}")
      list(JOIN CLR_LINK_SANITIZERS "," CLR_LINK_SANITIZERS_OPTIONS)
      list(APPEND CLR_SANITIZE_LINK_OPTIONS "-fsanitize=${CLR_LINK_SANITIZERS_OPTIONS}")
156 157 158

      # -fdata-sections -ffunction-sections: each function has own section instead of one per .o file (needed for --gc-sections)
      # -O1: optimization level used instead of -O0 to avoid compile error "invalid operand for inline asm constraint"
159 160
      add_compile_options("$<$<OR:$<CONFIG:DEBUG>,$<CONFIG:CHECKED>>:${CLR_SANITIZE_CXX_OPTIONS};-fdata-sections;--ffunction-sections;-O1>")
      add_linker_flag("${CLR_SANITIZE_LINK_OPTIONS}" DEBUG CHECKED)
161
      # -Wl and --gc-sections: drop unused sections\functions (similar to Windows /Gy function-level-linking)
162
      add_linker_flag("-Wl,--gc-sections" DEBUG CHECKED)
163 164
    endif ()
  endif(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL CHECKED)
165
endif(MSVC)
166 167 168 169 170 171 172

# CLR_ADDITIONAL_LINKER_FLAGS - used for passing additional arguments to linker
# CLR_ADDITIONAL_COMPILER_OPTIONS - used for passing additional arguments to compiler
#
# For example:
#       ./build-native.sh cmakeargs "-DCLR_ADDITIONAL_COMPILER_OPTIONS=<...>" cmakeargs "-DCLR_ADDITIONAL_LINKER_FLAGS=<...>"
#
173
if(CLR_CMAKE_HOST_UNIX)
174 175 176
  foreach(ADDTL_LINKER_FLAG ${CLR_ADDITIONAL_LINKER_FLAGS})
    add_linker_flag(${ADDTL_LINKER_FLAG})
  endforeach()
177
endif(CLR_CMAKE_HOST_UNIX)
178

179
if(CLR_CMAKE_HOST_LINUX)
180
  add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-Wa,--noexecstack>)
181 182
  add_linker_flag(-Wl,--build-id=sha1)
  add_linker_flag(-Wl,-z,relro,-z,now)
183
elseif(CLR_CMAKE_HOST_FREEBSD)
184
  add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-Wa,--noexecstack>)
185
  add_linker_flag("-Wl,--build-id=sha1")
186
elseif(CLR_CMAKE_HOST_SUNOS)
A
Adeel 已提交
187
  add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-Wa,--noexecstack>)
188 189
  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector")
A
Adeel 已提交
190
  add_definitions(-D__EXTENSIONS__)
191
elseif(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
192
  add_definitions(-D_XOPEN_SOURCE)
193
endif()
194 195 196 197

#------------------------------------
# Definitions (for platform)
#-----------------------------------
198
if (CLR_CMAKE_HOST_ARCH_AMD64)
199
  set(ARCH_HOST_NAME x64)
200 201
  add_definitions(-DHOST_AMD64)
  add_definitions(-DHOST_64BIT)
202
elseif (CLR_CMAKE_HOST_ARCH_I386)
203
  set(ARCH_HOST_NAME x86)
204
  add_definitions(-DHOST_X86)
205
elseif (CLR_CMAKE_HOST_ARCH_ARM)
206
  set(ARCH_HOST_NAME arm)
207
  add_definitions(-DHOST_ARM)
208
elseif (CLR_CMAKE_HOST_ARCH_ARM64)
209
  set(ARCH_HOST_NAME arm64)
210 211
  add_definitions(-DHOST_ARM64)
  add_definitions(-DHOST_64BIT)
212 213 214 215
elseif (CLR_CMAKE_HOST_ARCH_S390X)
  set(ARCH_HOST_NAME s390x)
  add_definitions(-DHOST_S390X)
  add_definitions(-DHOST_64BIT)
216 217 218 219
else ()
  clr_unknown_arch()
endif ()

220 221 222
if (CLR_CMAKE_HOST_UNIX)
  if(CLR_CMAKE_HOST_LINUX)
    if(CLR_CMAKE_HOST_UNIX_AMD64)
223
      message("Detected Linux x86_64")
224
    elseif(CLR_CMAKE_HOST_UNIX_ARM)
225
      message("Detected Linux ARM")
226
    elseif(CLR_CMAKE_HOST_UNIX_ARM64)
227
      message("Detected Linux ARM64")
228
    elseif(CLR_CMAKE_HOST_UNIX_X86)
229
      message("Detected Linux i686")
230 231
    elseif(CLR_CMAKE_HOST_UNIX_S390X)
      message("Detected Linux s390x")
232 233 234
    else()
      clr_unknown_arch()
    endif()
235 236
  endif(CLR_CMAKE_HOST_LINUX)
endif(CLR_CMAKE_HOST_UNIX)
237

238
if (CLR_CMAKE_HOST_UNIX)
239
  add_definitions(-DHOST_UNIX)
240

241
  if(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
242
    add_definitions(-DHOST_OSX)
243 244 245 246 247 248 249
    if(CLR_CMAKE_HOST_UNIX_AMD64)
      message("Detected OSX x86_64")
    elseif(CLR_CMAKE_HOST_UNIX_ARM64)
      message("Detected OSX ARM64")
    else()
      clr_unknown_arch()
    endif()
250
  elseif(CLR_CMAKE_HOST_FREEBSD)
251
    message("Detected FreeBSD amd64")
252
  elseif(CLR_CMAKE_HOST_NETBSD)
253
    message("Detected NetBSD amd64")
254 255
  elseif(CLR_CMAKE_HOST_SUNOS)
    message("Detected SunOS amd64")
256
  endif(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
257
endif(CLR_CMAKE_HOST_UNIX)
258

259
if (CLR_CMAKE_HOST_WIN32)
260
  add_definitions(-DHOST_WINDOWS)
261

262 263 264 265
  # Define the CRT lib references that link into Desktop imports
  set(STATIC_MT_CRT_LIB  "libcmt$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib")
  set(STATIC_MT_VCRT_LIB  "libvcruntime$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib")
  set(STATIC_MT_CPP_LIB  "libcpmt$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib")
266
endif(CLR_CMAKE_HOST_WIN32)
267 268 269 270

# Architecture specific files folder name
if (CLR_CMAKE_TARGET_ARCH_AMD64)
    set(ARCH_SOURCES_DIR amd64)
271 272 273
    set(ARCH_TARGET_NAME x64)
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_AMD64>)
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_64BIT>)
274 275
elseif (CLR_CMAKE_TARGET_ARCH_ARM64)
    set(ARCH_SOURCES_DIR arm64)
276 277 278
    set(ARCH_TARGET_NAME arm64)
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_ARM64>)
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_64BIT>)
279 280
elseif (CLR_CMAKE_TARGET_ARCH_ARM)
    set(ARCH_SOURCES_DIR arm)
281
    set(ARCH_TARGET_NAME arm)
282
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_ARM>)
283
elseif (CLR_CMAKE_TARGET_ARCH_I386)
284
    set(ARCH_TARGET_NAME x86)
285
    set(ARCH_SOURCES_DIR i386)
286
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_X86>)
287 288 289 290 291
elseif (CLR_CMAKE_TARGET_ARCH_S390X)
    set(ARCH_TARGET_NAME s390x)
    set(ARCH_SOURCES_DIR s390x)
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_S390X>)
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_64BIT>)
292 293 294 295 296 297 298
else ()
    clr_unknown_arch()
endif ()

#--------------------------------------
# Compile Options
#--------------------------------------
299
if (CLR_CMAKE_HOST_UNIX)
300 301 302 303
  # Disable frame pointer optimizations so profilers can get better call stacks
  add_compile_options(-fno-omit-frame-pointer)

  # The -fms-extensions enable the stuff like __if_exists, __declspec(uuid()), etc.
J
Jan Kotas 已提交
304
  add_compile_options(-fms-extensions)
305 306 307 308 309 310 311
  #-fms-compatibility      Enable full Microsoft Visual C++ compatibility
  #-fms-extensions         Accept some non-standard constructs supported by the Microsoft compiler

  # Make signed arithmetic overflow of addition, subtraction, and multiplication wrap around
  # using twos-complement representation (this is normally undefined according to the C++ spec).
  add_compile_options(-fwrapv)

312
  if(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
313 314 315
    # We cannot enable "stack-protector-strong" on OS X due to a bug in clang compiler (current version 7.0.2)
    add_compile_options(-fstack-protector)
  else()
316 317 318 319
    check_cxx_compiler_flag(-fstack-protector-strong COMPILER_SUPPORTS_F_STACK_PROTECTOR_STRONG)
    if (COMPILER_SUPPORTS_F_STACK_PROTECTOR_STRONG)
      add_compile_options(-fstack-protector-strong)
    endif()
320
  endif(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
321

322 323
  # Suppress warnings-as-errors in release branches to reduce servicing churn
  if (PRERELEASE)
324
    add_compile_options(-Werror)
325
  endif(PRERELEASE)
326

327 328 329 330
  # Disabled common warnings
  add_compile_options(-Wno-unused-variable)
  add_compile_options(-Wno-unused-value)
  add_compile_options(-Wno-unused-function)
H
hev 已提交
331
  add_compile_options(-Wno-tautological-compare)
332

333 334 335 336 337
  check_cxx_compiler_flag(-Wimplicit-fallthrough COMPILER_SUPPORTS_W_IMPLICIT_FALLTHROUGH)
  if (COMPILER_SUPPORTS_W_IMPLICIT_FALLTHROUGH)
    add_compile_options(-Wimplicit-fallthrough)
  endif()

338
  #These seem to indicate real issues
339
  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>)
340

341
  if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
342 343
    # The -ferror-limit is helpful during the porting, it makes sure the compiler doesn't stop
    # after hitting just about 20 errors.
344 345 346 347 348 349 350 351 352 353
    add_compile_options(-ferror-limit=4096)

    # Disabled warnings
    add_compile_options(-Wno-unused-private-field)
    # Explicit constructor calls are not supported by clang (this->ClassName::ClassName())
    add_compile_options(-Wno-microsoft)
    # There are constants of type BOOL used in a condition. But BOOL is defined as int
    # and so the compiler thinks that there is a mistake.
    add_compile_options(-Wno-constant-logical-operand)
    # We use pshpack1/2/4/8.h and poppack.h headers to set and restore packing. However
354
    # clang 6.0 complains when the packing change lifetime is not contained within
355 356 357 358 359 360 361 362 363 364 365
    # a header file.
    add_compile_options(-Wno-pragma-pack)

    add_compile_options(-Wno-unknown-warning-option)

    # The following warning indicates that an attribute __attribute__((__ms_struct__)) was applied
    # to a struct or a class that has virtual members or a base class. In that case, clang
    # may not generate the same object layout as MSVC.
    add_compile_options(-Wno-incompatible-ms-struct)
  else()
    add_compile_options(-Wno-unused-but-set-variable)
S
Sinan Kaya 已提交
366
    add_compile_options(-Wno-unknown-pragmas)
367 368 369 370 371 372 373
    add_compile_options(-Wno-uninitialized)
    add_compile_options(-Wno-strict-aliasing)
    add_compile_options(-Wno-array-bounds)
    check_cxx_compiler_flag(-Wclass-memaccess COMPILER_SUPPORTS_W_CLASS_MEMACCESS)
    if (COMPILER_SUPPORTS_W_CLASS_MEMACCESS)
      add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-class-memaccess>)
    endif()
374
    check_cxx_compiler_flag(-faligned-new COMPILER_SUPPORTS_F_ALIGNED_NEW)
A
Adeel 已提交
375
    if (COMPILER_SUPPORTS_F_ALIGNED_NEW)
376
      add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-faligned-new>)
A
Adeel 已提交
377
    endif()
378
  endif()
379 380

  # Some architectures (e.g., ARM) assume char type is unsigned while CoreCLR assumes char is signed
381
  # as x64 does. It has been causing issues in ARM (https://github.com/dotnet/runtime/issues/5778)
382
  add_compile_options(-fsigned-char)
383

384 385 386
  # We mark the function which needs exporting with DLLEXPORT
  add_compile_options(-fvisibility=hidden)

387
  # Specify the minimum supported version of macOS
388
  if(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
    # Mac Catalyst needs a special CFLAG, exclusive with mmacosx-version-min
    if(CLR_CMAKE_TARGET_MACCATALYST)
      # Somewhere between CMake 3.17 and 3.19.4, it became impossible to not pass
      # a value for mmacosx-version-min (blank CMAKE_OSX_DEPLOYMENT_TARGET gets
      # replaced with a default value, and always gets expanded to an OS version.
      # https://gitlab.kitware.com/cmake/cmake/-/issues/20132
      # We need to disable the warning that -tagret replaces -mmacosx-version-min
      add_compile_options(-Wno-overriding-t-option)
      add_link_options(-Wno-overriding-t-option)
      if(CLR_CMAKE_HOST_ARCH_ARM64)
        add_compile_options(-target arm64-apple-ios14.2-macabi)
        add_link_options(-target arm64-apple-ios14.2-macabi)
      elseif(CLR_CMAKE_HOST_ARCH_AMD64)
        add_compile_options(-target x86_64-apple-ios13.5-macabi)
        add_link_options(-target x86_64-apple-ios13.5-macabi)
      else()
        clr_unknown_arch()
      endif()
407
    else()
408 409 410 411 412 413 414 415 416 417 418 419 420
      if(CLR_CMAKE_HOST_ARCH_ARM64)
        # 'pthread_jit_write_protect_np' is only available on macOS 11.0 or newer
        set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=11.0)
        add_compile_options(-arch arm64)
      elseif(CLR_CMAKE_HOST_ARCH_AMD64)
        set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=10.13)
        add_compile_options(-arch x86_64)
      else()
        clr_unknown_arch()
      endif()
      add_compile_options(${MACOS_VERSION_MIN_FLAGS})
      add_linker_flag(${MACOS_VERSION_MIN_FLAGS})
    endif(CLR_CMAKE_TARGET_MACCATALYST)
421
  endif(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
422

423
endif(CLR_CMAKE_HOST_UNIX)
424

425
if(CLR_CMAKE_TARGET_UNIX)
426
  add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_UNIX>)
427 428
  # Contracts are disabled on UNIX.
  add_definitions(-DDISABLE_CONTRACTS)
429
  if(CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST)
430
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_OSX>)
A
Adeel 已提交
431
  elseif(CLR_CMAKE_TARGET_FREEBSD)
432
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_FREEBSD>)
A
Adeel 已提交
433
  elseif(CLR_CMAKE_TARGET_LINUX)
434
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_LINUX>)
A
Adeel 已提交
435
  elseif(CLR_CMAKE_TARGET_NETBSD)
436
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_NETBSD>)
437
  elseif(CLR_CMAKE_TARGET_SUNOS)
438
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_SUNOS>)
A
Adeel 已提交
439
  elseif(CLR_CMAKE_TARGET_ANDROID)
440
    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_ANDROID>)
441
  endif()
442
else(CLR_CMAKE_TARGET_UNIX)
443
  add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_WINDOWS>)
444 445
endif(CLR_CMAKE_TARGET_UNIX)

446
if(CLR_CMAKE_HOST_UNIX_ARM)
S
Sinan Kaya 已提交
447 448 449 450
   if (NOT DEFINED CLR_ARM_FPU_TYPE)
     set(CLR_ARM_FPU_TYPE vfpv3)
   endif(NOT DEFINED CLR_ARM_FPU_TYPE)

451 452 453
   # Because we don't use CMAKE_C_COMPILER/CMAKE_CXX_COMPILER to use clang
   # we have to set the triple by adding a compiler argument
   add_compile_options(-mthumb)
S
Sinan Kaya 已提交
454 455 456 457 458
   add_compile_options(-mfpu=${CLR_ARM_FPU_TYPE})
   if (NOT DEFINED CLR_ARM_FPU_CAPABILITY)
     set(CLR_ARM_FPU_CAPABILITY 0x7)
   endif(NOT DEFINED CLR_ARM_FPU_CAPABILITY)
   add_definitions(-DCLR_ARM_FPU_CAPABILITY=${CLR_ARM_FPU_CAPABILITY})
459 460 461 462 463
   add_compile_options(-march=armv7-a)
   if(ARM_SOFTFP)
     add_definitions(-DARM_SOFTFP)
     add_compile_options(-mfloat-abi=softfp)
   endif(ARM_SOFTFP)
464
endif(CLR_CMAKE_HOST_UNIX_ARM)
465

N
Next Turn 已提交
466 467 468 469
if(CLR_CMAKE_HOST_UNIX_X86)
  add_compile_options(-msse2)
endif()

470
if(CLR_CMAKE_HOST_UNIX)
471
  add_compile_options(${CLR_ADDITIONAL_COMPILER_OPTIONS})
472
endif(CLR_CMAKE_HOST_UNIX)
473

474
if (MSVC)
475 476
  # Compile options for targeting windows

477
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/nologo>) # Suppress Startup Banner
478 479 480 481 482
  # /W3 is added by default by CMake, so remove it
  string(REPLACE "/W3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  string(REPLACE "/W3" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
  # set default warning level to 3 but allow targets to override it.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/W$<GENEX_EVAL:$<IF:$<BOOL:$<TARGET_PROPERTY:MSVC_WARNING_LEVEL>>,$<TARGET_PROPERTY:MSVC_WARNING_LEVEL>,3>>>)
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/WX>) # treat warnings as errors
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Oi>) # enable intrinsics
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Oy->) # disable suppressing of the creation of frame pointers on the call stack for quicker function calls
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Gm->) # disable minimal rebuild
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zp8>) # pack structs on 8-byte boundary
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Gy>) # separate functions for linker
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/GS>) # Explicitly enable the buffer security checks
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/fp:precise>) # Enable precise floating point

  # disable C++ RTTI
  # /GR is added by default by CMake, so remove it manually.
  string(REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")

  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/FC>) # use full pathnames in diagnostics
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/MP>) # Build with Multiple Processes (number of processes equal to the number of processors)
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zm200>) # Specify Precompiled Header Memory Allocation Limit of 150MB
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zc:strictStrings>) # Disable string-literal to char* or wchar_t* conversion
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zc:wchar_t>) # wchar_t is a built-in type.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zc:inline>) # All inline functions must have their definition available in the current translation unit.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zc:forScope>) # Enforce standards-compliant for scope.

505
  # Disable Warnings:
506 507 508 509 510 511 512 513 514 515 516
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4065>) # switch statement contains 'default' but no 'case' labels
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4100>) # 'identifier' : unreferenced formal parameter
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4127>) # conditional expression is constant
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4189>) # local variable is initialized but not referenced
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4200>) # nonstandard extension used : zero-sized array in struct/union
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4201>) # nonstandard extension used : nameless struct/union
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4245>) # conversion from 'type1' to 'type2', signed/unsigned mismatch
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4291>) # no matching operator delete found; memory will not be freed if initialization throws an exception
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4456>) # declaration of 'identifier' hides previous local declaration
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4457>) # declaration of 'identifier' hides function parameter
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4458>) # declaration of 'identifier' hides class member
517
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4733>) # Inline asm assigning to 'FS:0' : handler not registered as safe handler
518 519 520 521
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4838>) # conversion from 'type_1' to 'type_2' requires a narrowing conversion
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4960>) # 'function' is too big to be profiled
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4961>) # No profile data was merged into '.pgd file', profile-guided optimizations disabled
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd5105>) # macro expansion producing 'defined' has undefined behavior
522 523

  # Treat Warnings as Errors:
524 525 526 527 528 529 530
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4007>) # 'main' : must be __cdecl.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4013>) # 'function' undefined - assuming extern returning int.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4102>) # "'%$S' : unreferenced label".
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4551>) # Function call missing argument list.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4700>) # Local used w/o being initialized.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4640>) # 'instance' : construction of local static object is not thread-safe
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4806>) # Unsafe operation involving type 'bool'.
531 532

  # Set Warning Level 3:
533 534 535 536 537 538 539 540
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34092>) # Sizeof returns 'unsigned long'.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34121>) # Structure is sensitive to alignment.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34125>) # Decimal digit in octal sequence.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34130>) # Logical operation on address of string constant.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34132>) # Const object should be initialized.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34212>) # Function declaration used ellipsis.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34530>) # C++ exception handler used, but unwind semantics are not enabled. Specify -GX.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w35038>) # data member 'member1' will be initialized after data member 'member2'.
541 542

  # Set Warning Level 4:
543
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w44177>) # Pragma data_seg s/b at global scope.
544

545 546 547
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zi>) # enable debugging information
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/ZH:SHA_256>) # use SHA256 for generating hashes of compiler processed source files.
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/source-charset:utf-8>) # Force MSVC to compile source as UTF-8.
548

549
  if (CLR_CMAKE_HOST_ARCH_I386)
550
    add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Gz>)
551
  endif (CLR_CMAKE_HOST_ARCH_I386)
552

553
  add_compile_options($<$<AND:$<COMPILE_LANGUAGE:C,CXX>,$<OR:$<CONFIG:Release>,$<CONFIG:Relwithdebinfo>>>:/GL>)
554

555
  if (CLR_CMAKE_HOST_ARCH_AMD64)
556 557
    # The generator expression in the following command means that the /homeparams option is added only for debug builds for C and C++ source files
    add_compile_options($<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:C,CXX>>:/homeparams>) # Force parameters passed in registers to be written to the stack
558
  endif (CLR_CMAKE_HOST_ARCH_AMD64)
559 560

  # enable control-flow-guard support for native components for non-Arm64 builds
561 562
  # Added using variables instead of add_compile_options to let individual projects override it
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /guard:cf")
563
  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /guard:cf")
564

565 566 567 568 569 570
  # Statically linked CRT (libcmt[d].lib, libvcruntime[d].lib and libucrt[d].lib) by default. This is done to avoid
  # linking in VCRUNTIME140.DLL for a simplified xcopy experience by reducing the dependency on VC REDIST.
  #
  # For Release builds, we shall dynamically link into uCRT [ucrtbase.dll] (which is pushed down as a Windows Update on downlevel OS) but
  # wont do the same for debug/checked builds since ucrtbased.dll is not redistributable and Debug/Checked builds are not
  # production-time scenarios.
571
  set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<AND:$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>,$<NOT:$<BOOL:$<TARGET_PROPERTY:DAC_COMPONENT>>>>:Debug>)
572 573

  add_compile_options($<$<COMPILE_LANGUAGE:ASM_MASM>:/ZH:SHA_256>)
574

575 576 577
  if (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64)
    # Contracts work too slow on ARM/ARM64 DEBUG/CHECKED.
    add_definitions(-DDISABLE_CONTRACTS)
578 579
  endif (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64)

580 581
  # Don't display the output header when building RC files.
  add_compile_options($<$<COMPILE_LANGUAGE:RC>:/nologo>)
582
endif (MSVC)
583 584 585

if(CLR_CMAKE_ENABLE_CODE_COVERAGE)

586
  if(CLR_CMAKE_HOST_UNIX)
587 588 589 590 591 592 593
    string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_CMAKE_BUILD_TYPE)
    if(NOT UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG)
      message( WARNING "Code coverage results with an optimised (non-Debug) build may be misleading" )
    endif(NOT UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG)

    add_compile_options(-fprofile-arcs)
    add_compile_options(-ftest-coverage)
594
    add_linker_flag(--coverage)
595 596
  else()
    message(FATAL_ERROR "Code coverage builds not supported on current platform")
597
  endif(CLR_CMAKE_HOST_UNIX)
598 599

endif(CLR_CMAKE_ENABLE_CODE_COVERAGE)
600

601
if (CMAKE_GENERATOR MATCHES "(Makefile|Ninja)")
602
  set(CMAKE_RC_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
603
endif()
604 605 606 607 608 609 610 611 612 613 614 615 616 617

# Ensure other tools are present
if (CLR_CMAKE_HOST_WIN32)
    if(CLR_CMAKE_HOST_ARCH_ARM)

      # Explicitly specify the assembler to be used for Arm32 compile
      file(TO_CMAKE_PATH "$ENV{VCToolsInstallDir}\\bin\\HostX86\\arm\\armasm.exe" CMAKE_ASM_COMPILER)

      set(CMAKE_ASM_MASM_COMPILER ${CMAKE_ASM_COMPILER})
      message("CMAKE_ASM_MASM_COMPILER explicitly set to: ${CMAKE_ASM_MASM_COMPILER}")

      # Enable generic assembly compilation to avoid CMake generate VS proj files that explicitly
      # use ml[64].exe as the assembler.
      enable_language(ASM)
618 619 620 621 622
      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded         "")
      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL      "")
      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug    "")
      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
      set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -g <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
623

624
    elseif(CLR_CMAKE_HOST_ARCH_ARM64)
625 626 627 628 629 630 631 632 633 634

      # Explicitly specify the assembler to be used for Arm64 compile
      file(TO_CMAKE_PATH "$ENV{VCToolsInstallDir}\\bin\\HostX86\\arm64\\armasm64.exe" CMAKE_ASM_COMPILER)

      set(CMAKE_ASM_MASM_COMPILER ${CMAKE_ASM_COMPILER})
      message("CMAKE_ASM_MASM_COMPILER explicitly set to: ${CMAKE_ASM_MASM_COMPILER}")

      # Enable generic assembly compilation to avoid CMake generate VS proj files that explicitly
      # use ml[64].exe as the assembler.
      enable_language(ASM)
635 636 637 638 639
      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded         "")
      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL      "")
      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug    "")
      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
      set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -g <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
640 641
    else()
      enable_language(ASM_MASM)
642 643 644 645
      set(CMAKE_ASM_MASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded         "")
      set(CMAKE_ASM_MASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL      "")
      set(CMAKE_ASM_MASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug    "")
      set(CMAKE_ASM_MASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
646 647 648 649 650 651 652 653 654 655 656 657
    endif()

    # Ensure that MC is present
    find_program(MC mc)
    if (MC STREQUAL "MC-NOTFOUND")
        message(FATAL_ERROR "MC not found")
    endif()

else (CLR_CMAKE_HOST_WIN32)
    enable_language(ASM)

endif(CLR_CMAKE_HOST_WIN32)