• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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