2017-03-16 16:24:33 +01:00
|
|
|
include(CheckCCompilerFlag)
|
2025-06-09 07:24:03 +00:00
|
|
|
if(CMAKE_CXX_COMPILER)
|
|
|
|
|
include(CheckCXXCompilerFlag)
|
|
|
|
|
endif()
|
2024-12-12 11:39:40 -08:00
|
|
|
|
|
|
|
|
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
|
2023-02-15 06:38:50 +09:00
|
|
|
set(ZSTD_HAVE_CHECK_LINKER_FLAG true)
|
2024-12-12 11:39:40 -08:00
|
|
|
else ()
|
|
|
|
|
set(ZSTD_HAVE_CHECK_LINKER_FLAG false)
|
2023-02-15 06:38:50 +09:00
|
|
|
endif ()
|
|
|
|
|
if (ZSTD_HAVE_CHECK_LINKER_FLAG)
|
|
|
|
|
include(CheckLinkerFlag)
|
|
|
|
|
endif()
|
2017-03-16 16:24:33 +01:00
|
|
|
|
2022-12-21 15:02:27 -08:00
|
|
|
function(EnableCompilerFlag _flag _C _CXX _LD)
|
2017-04-20 15:54:17 -07:00
|
|
|
string(REGEX REPLACE "\\+" "PLUS" varname "${_flag}")
|
|
|
|
|
string(REGEX REPLACE "[^A-Za-z0-9]+" "_" varname "${varname}")
|
|
|
|
|
string(REGEX REPLACE "^_+" "" varname "${varname}")
|
|
|
|
|
string(TOUPPER "${varname}" varname)
|
2017-03-16 16:24:33 +01:00
|
|
|
if (_C)
|
2017-04-20 15:54:17 -07:00
|
|
|
CHECK_C_COMPILER_FLAG(${_flag} C_FLAG_${varname})
|
|
|
|
|
if (C_FLAG_${varname})
|
2017-04-20 15:55:48 -07:00
|
|
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flag}" PARENT_SCOPE)
|
2017-03-16 16:24:33 +01:00
|
|
|
endif ()
|
|
|
|
|
endif ()
|
2025-06-09 21:55:06 +00:00
|
|
|
if (_CXX AND CMAKE_CXX_COMPILER)
|
2017-04-20 15:54:17 -07:00
|
|
|
CHECK_CXX_COMPILER_FLAG(${_flag} CXX_FLAG_${varname})
|
|
|
|
|
if (CXX_FLAG_${varname})
|
2017-04-20 15:55:48 -07:00
|
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}" PARENT_SCOPE)
|
2017-03-16 16:24:33 +01:00
|
|
|
endif ()
|
|
|
|
|
endif ()
|
2022-12-21 15:02:27 -08:00
|
|
|
if (_LD)
|
2023-02-15 06:38:50 +09:00
|
|
|
# We never add a linker flag with CMake < 3.18. We will
|
|
|
|
|
# implement CHECK_LINKER_FLAG() like feature for CMake < 3.18
|
|
|
|
|
# or require CMake >= 3.18 when we need to add a required
|
|
|
|
|
# linker flag in future.
|
2023-03-22 22:13:57 +01:00
|
|
|
#
|
|
|
|
|
# We also skip linker flags check for MSVC compilers (which includes
|
|
|
|
|
# clang-cl) since currently check_linker_flag() doesn't give correct
|
|
|
|
|
# results for this configuration,
|
|
|
|
|
# see: https://gitlab.kitware.com/cmake/cmake/-/issues/22023
|
|
|
|
|
if (ZSTD_HAVE_CHECK_LINKER_FLAG AND NOT MSVC)
|
2023-02-15 06:38:50 +09:00
|
|
|
CHECK_LINKER_FLAG(C ${_flag} LD_FLAG_${varname})
|
|
|
|
|
else ()
|
|
|
|
|
set(LD_FLAG_${varname} false)
|
|
|
|
|
endif ()
|
2022-12-21 15:02:27 -08:00
|
|
|
if (LD_FLAG_${varname})
|
|
|
|
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${_flag}" PARENT_SCOPE)
|
|
|
|
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${_flag}" PARENT_SCOPE)
|
|
|
|
|
endif ()
|
|
|
|
|
endif ()
|
2017-03-16 16:24:33 +01:00
|
|
|
endfunction()
|
|
|
|
|
|
2025-04-01 22:47:45 +02:00
|
|
|
macro(ADD_ZSTD_COMPILATION_FLAGS _C _CXX _LD)
|
[cmake] Fix -z noexecstack portability
Summary:
Issue reported by @ryandesign and @MarcusCalhoun-Lopez.
CMake doesn't support spaces in flags. This caused older versions of gcc to
ignore the unknown flag "-z noexecstack" on MacOS since it was interpreted as a
single flag, not two separate flags. Then, during compilation it was treated as
"-z" "noexecstack", which was correctly forwarded to the linker. But the MacOS
linker does not support `-z noexecstack` so compilation failed.
The fix is to use `-Wl,-z,noexecstack`. This is never misinterpreted by a
compiler. However, not all compilers support this syntax to forward flags to the
linker. To fix this issue, we check if all the relevant `noexecstack` flags have
been successfully set, and if they haven't we disable assembly.
See also PR#4056 and PR#4061. I decided to go a different route because this is
simpler. It might not successfully set these flags on some compilers, but in that
case it also disables assembly, so they aren't required.
Test Plan:
```
mkdir build-cmake
cmake ../build/cmake/CMakeLists.txt
make -j
```
See that the linker flag is successfully detected & that assembly is enabled.
Run the same commands on MacOS which doesn't support `-Wl,-z,noexecstack` and see
that everything compiles and that `LD_FLAG_WL_Z_NOEXECSTACK` and
`ZSTD_HAS_NOEXECSTACK` are both false.
2024-12-20 09:40:32 -08:00
|
|
|
# We set ZSTD_HAS_NOEXECSTACK if we are certain we've set all the required
|
|
|
|
|
# compiler flags to mark the stack as non-executable.
|
|
|
|
|
set(ZSTD_HAS_NOEXECSTACK false)
|
|
|
|
|
|
2017-03-21 13:44:33 -07:00
|
|
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" OR MINGW) #Not only UNIX but also WIN32 for MinGW
|
2022-06-19 14:52:32 -07:00
|
|
|
# It's possible to select the exact standard used for compilation.
|
|
|
|
|
# It's not necessary, but can be employed for specific purposes.
|
|
|
|
|
# Note that zstd source code is compatible with both C++98 and above
|
|
|
|
|
# and C-gnu90 (c90 + long long + variadic macros ) and above
|
|
|
|
|
# EnableCompilerFlag("-std=c++11" false true) # Set C++ compilation to c++11 standard
|
2024-06-19 21:04:50 +02:00
|
|
|
# EnableCompilerFlag("-std=c99" true false) # Set C compilation to c99 standard
|
2021-05-02 14:46:12 +01:00
|
|
|
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC)
|
|
|
|
|
# clang-cl normally maps -Wall to -Weverything.
|
2025-04-01 22:47:45 +02:00
|
|
|
EnableCompilerFlag("/clang:-Wall" _C _CXX false)
|
2021-05-02 14:46:12 +01:00
|
|
|
else ()
|
2025-04-01 22:47:45 +02:00
|
|
|
EnableCompilerFlag("-Wall" _C _CXX false)
|
2021-05-02 14:46:12 +01:00
|
|
|
endif ()
|
2025-04-01 22:47:45 +02:00
|
|
|
EnableCompilerFlag("-Wextra" _C _CXX false)
|
|
|
|
|
EnableCompilerFlag("-Wundef" _C _CXX false)
|
|
|
|
|
EnableCompilerFlag("-Wshadow" _C _CXX false)
|
|
|
|
|
EnableCompilerFlag("-Wcast-align" _C _CXX false)
|
|
|
|
|
EnableCompilerFlag("-Wcast-qual" _C _CXX false)
|
|
|
|
|
EnableCompilerFlag("-Wstrict-prototypes" _C false false)
|
2020-01-13 11:52:33 -08:00
|
|
|
# Enable asserts in Debug mode
|
|
|
|
|
if (CMAKE_BUILD_TYPE MATCHES "Debug")
|
2025-04-01 22:47:45 +02:00
|
|
|
EnableCompilerFlag("-DDEBUGLEVEL=1" _C _CXX false)
|
2020-01-13 11:52:33 -08:00
|
|
|
endif ()
|
2022-12-21 15:02:27 -08:00
|
|
|
# Add noexecstack flags
|
|
|
|
|
# LDFLAGS
|
2025-04-01 22:47:45 +02:00
|
|
|
EnableCompilerFlag("-Wl,-z,noexecstack" false false _LD)
|
2022-12-21 15:02:27 -08:00
|
|
|
# CFLAGS & CXXFLAGS
|
2025-04-01 22:47:45 +02:00
|
|
|
EnableCompilerFlag("-Qunused-arguments" _C _CXX false)
|
|
|
|
|
EnableCompilerFlag("-Wa,--noexecstack" _C _CXX false)
|
[cmake] Fix -z noexecstack portability
Summary:
Issue reported by @ryandesign and @MarcusCalhoun-Lopez.
CMake doesn't support spaces in flags. This caused older versions of gcc to
ignore the unknown flag "-z noexecstack" on MacOS since it was interpreted as a
single flag, not two separate flags. Then, during compilation it was treated as
"-z" "noexecstack", which was correctly forwarded to the linker. But the MacOS
linker does not support `-z noexecstack` so compilation failed.
The fix is to use `-Wl,-z,noexecstack`. This is never misinterpreted by a
compiler. However, not all compilers support this syntax to forward flags to the
linker. To fix this issue, we check if all the relevant `noexecstack` flags have
been successfully set, and if they haven't we disable assembly.
See also PR#4056 and PR#4061. I decided to go a different route because this is
simpler. It might not successfully set these flags on some compilers, but in that
case it also disables assembly, so they aren't required.
Test Plan:
```
mkdir build-cmake
cmake ../build/cmake/CMakeLists.txt
make -j
```
See that the linker flag is successfully detected & that assembly is enabled.
Run the same commands on MacOS which doesn't support `-Wl,-z,noexecstack` and see
that everything compiles and that `LD_FLAG_WL_Z_NOEXECSTACK` and
`ZSTD_HAS_NOEXECSTACK` are both false.
2024-12-20 09:40:32 -08:00
|
|
|
# NOTE: Using 3 nested ifs because the variables are sometimes
|
|
|
|
|
# empty if the condition is false, and sometimes equal to false.
|
|
|
|
|
# This implicitly converts them to truthy values. There may be
|
|
|
|
|
# a better way to do this, but this reliably works.
|
|
|
|
|
if (${LD_FLAG_WL_Z_NOEXECSTACK})
|
|
|
|
|
if (${C_FLAG_WA_NOEXECSTACK})
|
|
|
|
|
if (${CXX_FLAG_WA_NOEXECSTACK})
|
|
|
|
|
# We've succeeded in marking the stack as non-executable
|
|
|
|
|
set(ZSTD_HAS_NOEXECSTACK true)
|
|
|
|
|
endif()
|
|
|
|
|
endif()
|
|
|
|
|
endif()
|
2017-03-16 16:24:33 +01:00
|
|
|
elseif (MSVC) # Add specific compilation flags for Windows Visual
|
2016-01-07 16:37:00 +06:00
|
|
|
|
2017-03-16 16:24:33 +01:00
|
|
|
set(ACTIVATE_MULTITHREADED_COMPILATION "ON" CACHE BOOL "activate multi-threaded compilation (/MP flag)")
|
2017-05-24 10:48:10 +02:00
|
|
|
if (CMAKE_GENERATOR MATCHES "Visual Studio" AND ACTIVATE_MULTITHREADED_COMPILATION)
|
2025-04-01 22:47:45 +02:00
|
|
|
EnableCompilerFlag("/MP" _C _CXX false)
|
2017-03-16 16:24:33 +01:00
|
|
|
endif ()
|
2022-06-19 14:52:32 -07:00
|
|
|
|
2016-01-10 17:20:52 +06:00
|
|
|
# UNICODE SUPPORT
|
2025-04-01 22:47:45 +02:00
|
|
|
EnableCompilerFlag("/D_UNICODE" _C _CXX false)
|
|
|
|
|
EnableCompilerFlag("/DUNICODE" _C _CXX false)
|
2020-01-13 11:52:33 -08:00
|
|
|
# Enable asserts in Debug mode
|
|
|
|
|
if (CMAKE_BUILD_TYPE MATCHES "Debug")
|
2025-04-01 22:47:45 +02:00
|
|
|
EnableCompilerFlag("/DDEBUGLEVEL=1" _C _CXX false)
|
2020-01-13 11:52:33 -08:00
|
|
|
endif ()
|
2016-01-07 16:37:00 +06:00
|
|
|
endif ()
|
|
|
|
|
|
|
|
|
|
# Remove duplicates compilation flags
|
2018-12-22 19:31:59 -06:00
|
|
|
foreach (flag_var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
2017-03-16 16:24:33 +01:00
|
|
|
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
|
|
|
|
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
|
|
|
|
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
2018-12-24 08:37:07 -06:00
|
|
|
if( ${flag_var} )
|
|
|
|
|
separate_arguments(${flag_var})
|
|
|
|
|
string(REPLACE ";" " " ${flag_var} "${${flag_var}}")
|
|
|
|
|
endif()
|
2018-12-22 19:31:50 -06:00
|
|
|
endforeach ()
|
2016-01-07 16:37:00 +06:00
|
|
|
|
2017-05-24 10:48:10 +02:00
|
|
|
if (MSVC AND ZSTD_USE_STATIC_RUNTIME)
|
2018-12-22 19:31:59 -06:00
|
|
|
foreach (flag_var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
2017-03-16 16:24:33 +01:00
|
|
|
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
|
|
|
|
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
|
|
|
|
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
2018-12-24 08:37:07 -06:00
|
|
|
if ( ${flag_var} )
|
|
|
|
|
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
|
|
|
|
endif()
|
2018-12-22 19:31:50 -06:00
|
|
|
endforeach ()
|
2016-01-07 16:37:00 +06:00
|
|
|
endif ()
|
|
|
|
|
|
2018-12-22 19:31:50 -06:00
|
|
|
endmacro()
|