Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmake: Use build type targets to enable sanitizers #13855

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 8 additions & 49 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@
#/|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
#/|/
cmake_minimum_required(VERSION 3.13)
project(PrusaSlicer)

# Specify search path for CMake modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")

# This will define e.g. -DCMAKE_BUILD_TYPE=AddressSanitizer
include(DefineCompilerFlags)

project(PrusaSlicer LANGUAGES C CXX)

include("version.inc")
include(GNUInstallDirs)
Expand Down Expand Up @@ -38,8 +45,6 @@ option(SLIC3R_GUI "Compile PrusaSlicer with GUI components (OpenGL, wxWidg
option(SLIC3R_FHS "Assume PrusaSlicer is to be installed in a FHS directory structure" 0)
option(SLIC3R_PCH "Use precompiled headers" 1)
option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1)
option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0)
option(SLIC3R_UBSAN "Enable UBSan on Clang and GCC" 0)
option(SLIC3R_ENABLE_FORMAT_STEP "Enable compilation of STEP file support" ON)
option(SLIC3R_LOG_TO_FILE "Enable logging into file")
option(SLIC3R_REPO_URL "Preset repo URL")
Expand Down Expand Up @@ -175,9 +180,6 @@ foreach (DIR ${PREFIX_PATH_CHECK})
endif ()
endforeach ()

# Add our own cmake module path.
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules/)

enable_testing ()

# Enable C++17 language standard.
Expand Down Expand Up @@ -290,49 +292,6 @@ if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMP

endif()

if (SLIC3R_ASAN)
# ASAN should be available on MSVC starting with Visual Studio 2019 16.9
# https://devblogs.microsoft.com/cppblog/address-sanitizer-for-msvc-now-generally-available/
add_compile_options(-fsanitize=address)

if (NOT MSVC)
add_compile_options(-fno-omit-frame-pointer)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=address")
endif ()

if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan")
endif ()
endif ()

if (SLIC3R_UBSAN)
# Stacktrace for every report is enabled by default. It can be disabled by running PrusaSlicer with "UBSAN_OPTIONS=print_stacktrace=0".

# Define macro SLIC3R_UBSAN to allow detection in the source code if this sanitizer is enabled.
add_compile_definitions(SLIC3R_UBSAN)

# Clang supports much more useful checks than GCC, so when Clang is detected, another checks will be enabled.
# List of what GCC is checking: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html
# List of what Clang is checking: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(_ubsan_flags "-fsanitize=undefined,integer")
else ()
set(_ubsan_flags "-fsanitize=undefined")
endif ()

add_compile_options(${_ubsan_flags} -fno-omit-frame-pointer)

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${_ubsan_flags}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${_ubsan_flags}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${_ubsan_flags}")

if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lubsan")
endif ()
endif ()

if (APPLE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
Expand Down
58 changes: 58 additions & 0 deletions cmake/modules/DefineCompilerFlags.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright 2018-2025 Andreas Schneider <asn@cryptomilk.org>
#
# License: BSD-3-Clause
#
if (UNIX AND NOT WIN32)
# Activate with: -DCMAKE_BUILD_TYPE=Profiling
set(CMAKE_C_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the C compiler during PROFILING builds.")
set(CMAKE_CXX_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the CXX compiler during PROFILING builds.")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the linker during the creation of shared libraries during PROFILING builds.")
set(CMAKE_MODULE_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the linker during the creation of shared libraries during PROFILING builds.")
set(CMAKE_EXEC_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the linker during PROFILING builds.")

# Activate with: -DCMAKE_BUILD_TYPE=AddressSanitizer
set(CMAKE_C_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer"
CACHE STRING "Flags used by the C compiler during ADDRESSSANITIZER builds.")
set(CMAKE_CXX_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer"
CACHE STRING "Flags used by the CXX compiler during ADDRESSSANITIZER builds.")
set(CMAKE_SHARED_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.")
set(CMAKE_MODULE_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.")
set(CMAKE_EXEC_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
CACHE STRING "Flags used by the linker during ADDRESSSANITIZER builds.")

# Activate with: -DCMAKE_BUILD_TYPE=MemorySanitizer
set(CMAKE_C_FLAGS_MEMORYSANITIZER "-g -O2 -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer"
CACHE STRING "Flags used by the C compiler during MEMORYSANITIZER builds.")
set(CMAKE_CXX_FLAGS_MEMORYSANITIZER "-g -O2 -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer"
CACHE STRING "Flags used by the CXX compiler during MEMORYSANITIZER builds.")
set(CMAKE_SHARED_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
CACHE STRING "Flags used by the linker during the creation of shared libraries during MEMORYSANITIZER builds.")
set(CMAKE_MODULE_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
CACHE STRING "Flags used by the linker during the creation of shared libraries during MEMORYSANITIZER builds.")
set(CMAKE_EXEC_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
CACHE STRING "Flags used by the linker during MEMORYSANITIZER builds.")

# Activate with: -DCMAKE_BUILD_TYPE=UndefinedSanitizer
set(CMAKE_C_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
CACHE STRING "Flags used by the C compiler during UNDEFINEDSANITIZER builds.")
set(CMAKE_CXX_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
CACHE STRING "Flags used by the CXX compiler during UNDEFINEDSANITIZER builds.")
set(CMAKE_SHARED_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.")
set(CMAKE_MODULE_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.")
set(CMAKE_EXEC_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
CACHE STRING "Flags used by the linker during UNDEFINEDSANITIZER builds.")
elseif(MSVC)
set(CMAKE_C_FLAGS_ADDRESSSANITIZER "/O1 /fsanitize=address"
CACHE STRING "Flags used by the C compiler during ADDRESSSANITIZER builds.")
set(CMAKE_CXX_FLAGS_ADDRESSSANITIZER "/O1 /fsanitize=address"
CACHE STRING "Flags used by the CXX compiler during ADDRESSSANITIZER builds.")
endif()
4 changes: 3 additions & 1 deletion doc/How to build - Linux et al.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,12 @@ And that's it. It is now possible to run the freshly built PrusaSlicer binary:


## Useful CMake flags when building PrusaSlicer
- `-DSLIC3R_ASAN=ON` enables gcc/clang address sanitizer (defaults to `OFF`, requires gcc>4.8 or clang>3.1)
- `-DSLIC3R_GTK=3` to use GTK3 (defaults to `2`). Note that wxWidgets must be built against the same GTK version.
- `-DSLIC3R_STATIC=ON` for static build (defaults to `OFF`)
- `-DCMAKE_BUILD_TYPE=Debug` to build in debug mode (defaults to `Release`)
- `-DCMAKE_BUILD_TYPE=AddressSanitizer` to build with Address Sanitizer
- `-DCMAKE_BUILD_TYPE=UndefinedSanitizer` to build with Undefined Sanitizer
- `-DCMAKE_BUILD_TYPE=MemorySanitizer` to build with Memory Sanitizer
- `-DSLIC3R_GUI=no` to build the console variant of PrusaSlicer

See the CMake files to get the complete list.
Expand Down