1include(CheckCXXCompilerFlag) 2include(CheckCCompilerFlag) 3 4if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) 5 set(ZSTD_HAVE_CHECK_LINKER_FLAG true) 6else () 7 set(ZSTD_HAVE_CHECK_LINKER_FLAG false) 8endif () 9if (ZSTD_HAVE_CHECK_LINKER_FLAG) 10 include(CheckLinkerFlag) 11endif() 12 13function(EnableCompilerFlag _flag _C _CXX _LD) 14 string(REGEX REPLACE "\\+" "PLUS" varname "${_flag}") 15 string(REGEX REPLACE "[^A-Za-z0-9]+" "_" varname "${varname}") 16 string(REGEX REPLACE "^_+" "" varname "${varname}") 17 string(TOUPPER "${varname}" varname) 18 if (_C) 19 CHECK_C_COMPILER_FLAG(${_flag} C_FLAG_${varname}) 20 if (C_FLAG_${varname}) 21 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flag}" PARENT_SCOPE) 22 endif () 23 endif () 24 if (_CXX) 25 CHECK_CXX_COMPILER_FLAG(${_flag} CXX_FLAG_${varname}) 26 if (CXX_FLAG_${varname}) 27 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}" PARENT_SCOPE) 28 endif () 29 endif () 30 if (_LD) 31 # We never add a linker flag with CMake < 3.18. We will 32 # implement CHECK_LINKER_FLAG() like feature for CMake < 3.18 33 # or require CMake >= 3.18 when we need to add a required 34 # linker flag in future. 35 # 36 # We also skip linker flags check for MSVC compilers (which includes 37 # clang-cl) since currently check_linker_flag() doesn't give correct 38 # results for this configuration, 39 # see: https://gitlab.kitware.com/cmake/cmake/-/issues/22023 40 if (ZSTD_HAVE_CHECK_LINKER_FLAG AND NOT MSVC) 41 CHECK_LINKER_FLAG(C ${_flag} LD_FLAG_${varname}) 42 else () 43 set(LD_FLAG_${varname} false) 44 endif () 45 if (LD_FLAG_${varname}) 46 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${_flag}" PARENT_SCOPE) 47 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${_flag}" PARENT_SCOPE) 48 endif () 49 endif () 50endfunction() 51 52macro(ADD_ZSTD_COMPILATION_FLAGS) 53 # We set ZSTD_HAS_NOEXECSTACK if we are certain we've set all the required 54 # compiler flags to mark the stack as non-executable. 55 set(ZSTD_HAS_NOEXECSTACK false) 56 57 if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" OR MINGW) #Not only UNIX but also WIN32 for MinGW 58 # It's possible to select the exact standard used for compilation. 59 # It's not necessary, but can be employed for specific purposes. 60 # Note that zstd source code is compatible with both C++98 and above 61 # and C-gnu90 (c90 + long long + variadic macros ) and above 62 # EnableCompilerFlag("-std=c++11" false true) # Set C++ compilation to c++11 standard 63 # EnableCompilerFlag("-std=c99" true false) # Set C compilation to c99 standard 64 if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC) 65 # clang-cl normally maps -Wall to -Weverything. 66 EnableCompilerFlag("/clang:-Wall" true true false) 67 else () 68 EnableCompilerFlag("-Wall" true true false) 69 endif () 70 EnableCompilerFlag("-Wextra" true true false) 71 EnableCompilerFlag("-Wundef" true true false) 72 EnableCompilerFlag("-Wshadow" true true false) 73 EnableCompilerFlag("-Wcast-align" true true false) 74 EnableCompilerFlag("-Wcast-qual" true true false) 75 EnableCompilerFlag("-Wstrict-prototypes" true false false) 76 # Enable asserts in Debug mode 77 if (CMAKE_BUILD_TYPE MATCHES "Debug") 78 EnableCompilerFlag("-DDEBUGLEVEL=1" true true false) 79 endif () 80 # Add noexecstack flags 81 # LDFLAGS 82 EnableCompilerFlag("-Wl,-z,noexecstack" false false true) 83 # CFLAGS & CXXFLAGS 84 EnableCompilerFlag("-Qunused-arguments" true true false) 85 EnableCompilerFlag("-Wa,--noexecstack" true true false) 86 # NOTE: Using 3 nested ifs because the variables are sometimes 87 # empty if the condition is false, and sometimes equal to false. 88 # This implicitly converts them to truthy values. There may be 89 # a better way to do this, but this reliably works. 90 if (${LD_FLAG_WL_Z_NOEXECSTACK}) 91 if (${C_FLAG_WA_NOEXECSTACK}) 92 if (${CXX_FLAG_WA_NOEXECSTACK}) 93 # We've succeeded in marking the stack as non-executable 94 set(ZSTD_HAS_NOEXECSTACK true) 95 endif() 96 endif() 97 endif() 98 elseif (MSVC) # Add specific compilation flags for Windows Visual 99 100 set(ACTIVATE_MULTITHREADED_COMPILATION "ON" CACHE BOOL "activate multi-threaded compilation (/MP flag)") 101 if (CMAKE_GENERATOR MATCHES "Visual Studio" AND ACTIVATE_MULTITHREADED_COMPILATION) 102 EnableCompilerFlag("/MP" true true false) 103 endif () 104 105 # UNICODE SUPPORT 106 EnableCompilerFlag("/D_UNICODE" true true false) 107 EnableCompilerFlag("/DUNICODE" true true false) 108 # Enable asserts in Debug mode 109 if (CMAKE_BUILD_TYPE MATCHES "Debug") 110 EnableCompilerFlag("/DDEBUGLEVEL=1" true true false) 111 endif () 112 endif () 113 114 # Remove duplicates compilation flags 115 foreach (flag_var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE 116 CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO 117 CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE 118 CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) 119 if( ${flag_var} ) 120 separate_arguments(${flag_var}) 121 string(REPLACE ";" " " ${flag_var} "${${flag_var}}") 122 endif() 123 endforeach () 124 125 if (MSVC AND ZSTD_USE_STATIC_RUNTIME) 126 foreach (flag_var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE 127 CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO 128 CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE 129 CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) 130 if ( ${flag_var} ) 131 string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") 132 endif() 133 endforeach () 134 endif () 135 136endmacro() 137