freepdfeditor/cmake/FreePDFEditorHardening.cmake

77 lines
3.0 KiB
CMake

# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2025 ai-ad4 and the FreePDFEditor contributors
# FreePDFEditorHardening.cmake
#
# Provides `freepdfeditor_apply_hardening(<target>)` which applies the release
# build hardening settings described in the engineering plan §7.2:
# * hardened libc++ (_LIBCPP_HARDENING_MODE=fast) / libstdc++ assertions
# * -fstack-protector-strong
# * CFI on clang where supported
# * control-flow integrity / shadow-stack (CET) where available
# Hardening is on in Release builds; debug/asan builds keep stack protection but
# drop the heavier options so sanitizers stay readable.
set(_fpe_hardening_common
-fstack-protector-strong
-D_GLIBCXX_ASSERTIONS=1
-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
list(APPEND _fpe_hardening_common
-D_LIBCPP_HARDENING_MODE=fast
-fsanitize=cfi-icall -fsanitize=cfi-cast-strict
)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64")
list(APPEND _fpe_hardening_common -fcf-protection=full) # CET/IBT
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64")
list(APPEND _fpe_hardening_common -fcf-protection=full) # CET/IBT & SHSTK
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
list(APPEND _fpe_hardening_common -fhardened)
endif()
endif()
set(_fpe_hardening_release ${_fpe_hardening_common})
# Sanitizer builds (asan/tsan presets) define their own flags; do not duplicate
# the libcxx hardening mode that interferes with sanitizer reports.
function(freepdfeditor_apply_hardening target)
get_target_property(_type ${target} TYPE)
if(_type STREQUAL "INTERFACE_LIBRARY")
return()
endif()
target_compile_options(${target} PRIVATE
$<$<CONFIG:Release,RelWithDebInfo>:${_fpe_hardening_release}>
$<$<CONFIG:Debug>:-fstack-protector-strong -D_GLIBCXX_ASSERTIONS=1>
)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_link_options(${target} PRIVATE
$<$<CONFIG:Release,RelWithDebInfo>:-Wl,-z,relro,-z,now -Wl,-z,noexecstack>
)
endif()
endfunction()
# Helper: standard warning set applied to every target.
function(freepdfeditor_apply_warnings target)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
target_compile_options(${target} PRIVATE
-Wall -Wextra -Wpedantic
-Wconversion -Wsign-conversion
-Wnon-virtual-dtor -Wold-style-cast
-Wshadow -Wformat=2 -Wundef
)
if(FREEPDFEDITOR_TREAT_WARNINGS_AS_ERRORS)
target_compile_options(${target} PRIVATE -Werror)
endif()
elseif(MSVC)
target_compile_options(${target} PRIVATE /permissive- /W4 /utf-8)
if(FREEPDFEDITOR_TREAT_WARNINGS_AS_ERRORS)
target_compile_options(${target} PRIVATE /WX)
endif()
endif()
endfunction()