From 7aa2a67d8381c9a88d69a3f53d74a7f079214263 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Mon, 9 Mar 2026 21:49:43 +0800 Subject: Establish a well-structured modern C++ project architecture Focus on code quality: Treat strict warnings as errors, memory checks with Sanitizers, Clang formatting and static analysis Performance optimization: LTO, ccache --- etc/build_type.cmake | 11 +++++++++++ etc/ccache.cmake | 5 +++++ etc/cflags.cmake | 16 ++++++++++++++++ etc/lto.cmake | 8 ++++++++ etc/scanners.cmake | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+) create mode 100644 etc/build_type.cmake create mode 100644 etc/ccache.cmake create mode 100644 etc/cflags.cmake create mode 100644 etc/lto.cmake create mode 100644 etc/scanners.cmake (limited to 'etc') diff --git a/etc/build_type.cmake b/etc/build_type.cmake new file mode 100644 index 0000000..69d019f --- /dev/null +++ b/etc/build_type.cmake @@ -0,0 +1,11 @@ +set(default_build_type "Debug") + +if (NOT (CMAKE_BUILD_TYPE_SHADOW STREQUAL CMAKE_BUILD_TYPE)) + if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message (STATUS "Setting build type to '${default_build_type}'") + set (CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE) + endif () + set (CMAKE_BUILD_TYPE_SHADOW ${CMAKE_BUILD_TYPE} CACHE STRING "used to detect changes in build type" FORCE) +endif () + +message (STATUS "Building in '${CMAKE_BUILD_TYPE}' mode.") diff --git a/etc/ccache.cmake b/etc/ccache.cmake new file mode 100644 index 0000000..aeceb8e --- /dev/null +++ b/etc/ccache.cmake @@ -0,0 +1,5 @@ +find_program(CCACHE_PROGRAM ccache) +if(CCACHE_PROGRAM) + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + message(STATUS "Found ccache: ${CCACHE_PROGRAM} - Compilation will be cached.") +endif() \ No newline at end of file diff --git a/etc/cflags.cmake b/etc/cflags.cmake new file mode 100644 index 0000000..ac08601 --- /dev/null +++ b/etc/cflags.cmake @@ -0,0 +1,16 @@ +set (CMAKE_CXX_STANDARD 23) +set (CMAKE_EXPORT_COMPILE_COMMANDS ON) + +set(SANITIZING_FLAGS -fno-sanitize-recover=all -fsanitize=undefined -fsanitize=address) + +# ask for more warnings from the compiler +set (CMAKE_BASE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Wextra -Weffc++ -Werror -Wshadow -Wpointer-arith -Wcast-qual -Wformat=2 -Wno-unqualified-std-cast-call -Wno-non-virtual-dtor") + +# Sanitizers +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Enabling Address and Undefined Behavior Sanitizers") + set(SANITIZING_FLAGS "-fno-sanitize-recover=all -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${SANITIZING_FLAGS} -g -O0") + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${SANITIZING_FLAGS}") +endif() \ No newline at end of file diff --git a/etc/lto.cmake b/etc/lto.cmake new file mode 100644 index 0000000..517ec14 --- /dev/null +++ b/etc/lto.cmake @@ -0,0 +1,8 @@ +include(CheckIPOSupported) +check_ipo_supported(RESULT ipo_supported OUTPUT error) +if(ipo_supported) + message(STATUS "IPO / LTO supported and enabled.") + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) +else() + message(STATUS "IPO / LTO not supported: <${error}>") +endif() \ No newline at end of file diff --git a/etc/scanners.cmake b/etc/scanners.cmake new file mode 100644 index 0000000..0a86f19 --- /dev/null +++ b/etc/scanners.cmake @@ -0,0 +1,52 @@ +# file (GLOB_RECURSE RayTracer_CC_FILES ${CMAKE_SOURCE_DIR}/src/*.cc) + +# file (GLOB_RECURSE ALL_SRC_FILES *.hh *.cc) + +# add_custom_target (format "clang-format" -i ${ALL_SRC_FILES} COMMENT "Formatting source code...") + + +find_program(CLANG_FORMAT_EXE clang-format) +if(CLANG_FORMAT_EXE) + file(GLOB_RECURSE ALL_FMT_FILES + "${CMAKE_SOURCE_DIR}/src/*.cc" + "${CMAKE_SOURCE_DIR}/src/*.cpp" + "${CMAKE_SOURCE_DIR}/src/*.h" + "${CMAKE_SOURCE_DIR}/src/*.hpp" + "${CMAKE_SOURCE_DIR}/apps/*.cc" + "${CMAKE_SOURCE_DIR}/apps/*.cpp" + ) + + add_custom_target(format + COMMAND ${CLANG_FORMAT_EXE} -i -style=file ${ALL_FMT_FILES} + COMMENT "Formatting source code..." + ) +else() + message(WARNING "clang-format not found! 'format' target will be disabled.") +endif() + +# clang-tidy +# find_program(CLANG_TIDY_EXE clang-tidy) +# if(CLANG_TIDY_EXE) +# message(STATUS "Clang-Tidy enabled: will run automatically during compilation.") +# set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE}") +# else() +# message(WARNING "clang-tidy not found! Static analysis will be disabled.") +# endif() + +foreach (tidy_target ${ALL_SRC_FILES}) + get_filename_component (basename ${tidy_target} NAME) + get_filename_component (dirname ${tidy_target} DIRECTORY) + get_filename_component (basedir ${dirname} NAME) + set (tidy_target_name "${basedir}__${basename}") + set (tidy_command clang-tidy --quiet -header-filter=.* -p=${PROJECT_BINARY_DIR} ${tidy_target}) + add_custom_target (tidy_${tidy_target_name} ${tidy_command}) + list (APPEND ALL_TIDY_TARGETS tidy_${tidy_target_name}) + + if (${tidy_target} IN_LIST RayTracer_CC_FILES) + list (APPEND RayTracer_TIDY_TARGETS tidy_${tidy_target_name}) + endif () +endforeach (tidy_target) + +add_custom_target (tidy DEPENDS ${RayTracer_TIDY_TARGETS}) + +add_custom_target (tidy-all DEPENDS ${ALL_TIDY_TARGETS}) -- cgit v1.2.3