@@ -34,8 +34,9 @@ mark_as_advanced(FORCE
3434
3535option (STRICT_WARNINGS "Enable strict compiler warnings" ON )
3636option (WARNINGS_AS_ERRORS "Treat all warnings as errors" OFF )
37- option (BUILD_EXAMPLES "Build examples" OFF )
38- option (BUILD_TESTS "Build tests" OFF )
37+
38+ option (BUILD_EXAMPLES "Build examples" ON )
39+ option (BUILD_TESTS "Build tests" ON )
3940
4041# -----------------------------------------------------------------------------
4142# DEPENDENCIES
@@ -44,6 +45,8 @@ option(BUILD_TESTS "Build tests" OFF)
4445# We want doxygen for the documentation.
4546find_package (Doxygen )
4647
48+ find_program (CLANG_TIDY_EXE NAMES clang-tidy )
49+
4750# -----------------------------------------------------------------------------
4851# LIBRARY
4952# -----------------------------------------------------------------------------
@@ -61,30 +64,54 @@ target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17)
6164# -----------------------------------------------------------------------------
6265
6366if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" )
64- # Disable warnings that suggest using MSVC-specific safe functions
67+ # Disable warnings for MSVC-specific "safe" functions like strcpy_s, etc.,
68+ # which are not portable and may clutter warning logs.
6569 target_compile_definitions (${PROJECT_NAME} INTERFACE _CRT_SECURE_NO_WARNINGS )
6670
71+ # Disable warning C4702: unreachable code.
72+ add_compile_options (/wd4702 )
73+
6774 if (WARNINGS_AS_ERRORS)
75+ # Treat all warnings as errors to enforce stricter code quality.
6876 target_compile_options (${PROJECT_NAME} INTERFACE /WX )
6977 endif ()
70- elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
71- if (WARNINGS_AS_ERRORS)
72- target_compile_options (${PROJECT_NAME} INTERFACE -Werror )
73- endif ()
74- endif ()
7578
76- if (STRICT_WARNINGS)
77- if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" )
78- # Mark system headers as external for MSVC explicitly
79- # https://devblogs.microsoft.com/cppblog/broken-warnings-theory
79+ if (STRICT_WARNINGS)
80+ # Enable external header management to suppress warnings in system and
81+ # external headers, making it easier to focus on project-specific issues.
8082 target_compile_options (${PROJECT_NAME} INTERFACE /experimental:external )
8183 target_compile_options (${PROJECT_NAME} INTERFACE /external:I ${CMAKE_BINARY_DIR} )
8284 target_compile_options (${PROJECT_NAME} INTERFACE /external:anglebrackets )
8385 target_compile_options (${PROJECT_NAME} INTERFACE /external:W0 )
8486
87+ # Use a high warning level to catch as many potential issues as possible.
8588 target_compile_options (${PROJECT_NAME} INTERFACE /W4 )
86- elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
87- target_compile_options (${PROJECT_NAME} INTERFACE -Wall -Wextra -Wconversion -pedantic )
89+
90+ # Enforce standards-compliant behavior to avoid relying on MSVC-specific extensions.
91+ target_compile_options (${PROJECT_NAME} INTERFACE /permissive- )
92+ endif ()
93+
94+ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
95+ if (WARNINGS_AS_ERRORS)
96+ # Treat all warnings as errors to enforce stricter code quality.
97+ target_compile_options (${PROJECT_NAME} INTERFACE -Werror )
98+ endif ()
99+
100+ if (STRICT_WARNINGS)
101+ # Enable a broad set of warnings to catch common and subtle issues:
102+ target_compile_options (${PROJECT_NAME} INTERFACE
103+ -Wall # Enable most general-purpose warnings.
104+ -Wextra # Enable extra warnings not included in -Wall.
105+ -Wconversion # Warn about implicit type conversions that may lose data.
106+ -pedantic # Enforce strict compliance with the C++ standard.
107+ -Wshadow # Warn about variable shadowing, which can cause subtle bugs.
108+ -Wnon-virtual-dtor # Warn when a class with virtual functions lacks a virtual destructor.
109+ -Wnull-dereference # Warn about potential null pointer dereferences.
110+ -Wformat=2 # Enable strict checks for printf/scanf format strings.
111+ -Woverloaded-virtual # Warn when a derived class function hides a base class virtual function.
112+ -Wfloat-equal # Warn about direct comparisons of floating-point values, which can be imprecise.
113+ )
114+
88115 endif ()
89116endif ()
90117
@@ -96,7 +123,6 @@ if(BUILD_EXAMPLES)
96123
97124 # Add the example.
98125 add_executable (${PROJECT_NAME} _example examples/example.cpp )
99- # Set the linked libraries.
100126 target_link_libraries (${PROJECT_NAME} _example PUBLIC ${PROJECT_NAME} )
101127
102128endif ()
@@ -122,59 +148,132 @@ if(BUILD_TESTS)
122148 target_link_libraries (${PROJECT_NAME} _test_shift ${PROJECT_NAME} )
123149 add_test (${PROJECT_NAME} _test_shift_run ${PROJECT_NAME} _test_shift )
124150
125- # add_executable(${PROJECT_NAME}_test_operators ${PROJECT_SOURCE_DIR}/ tests/test_operators .cpp)
126- # target_link_libraries(${PROJECT_NAME}_test_operators ${PROJECT_NAME})
127- # add_test(${PROJECT_NAME}_test_operators_run ${PROJECT_NAME}_test_operators )
151+ add_executable (${PROJECT_NAME} _test_comparison tests/test_comparison .cpp )
152+ target_link_libraries (${PROJECT_NAME} _test_comparison ${PROJECT_NAME} )
153+ add_test (${PROJECT_NAME} _test_comparison_run ${PROJECT_NAME} _test_comparison )
128154
129- # add_executable(${PROJECT_NAME}_test_comparison tests/test_comparison .cpp)
130- # target_link_libraries(${PROJECT_NAME}_test_comparison ${PROJECT_NAME})
131- # add_test(${PROJECT_NAME}_test_comparison_run ${PROJECT_NAME}_test_comparison )
155+ add_executable (${PROJECT_NAME} _test_math ${PROJECT_SOURCE_DIR} / tests/test_math .cpp )
156+ target_link_libraries (${PROJECT_NAME} _test_math ${PROJECT_NAME} )
157+ add_test (${PROJECT_NAME} _test_math_run ${PROJECT_NAME} _test_math )
132158
133159endif ()
134160
161+ # -----------------------------------------------------------------------------
162+ # CODE ANALYSIS
163+ # -----------------------------------------------------------------------------
164+
165+ if (CLANG_TIDY_EXE)
166+ file (GLOB_RECURSE PROJECT_HEADERS_AND_SOURCES
167+ "${PROJECT_SOURCE_DIR} /include/**/*.hpp"
168+ "${PROJECT_SOURCE_DIR} /include/**/*.hh"
169+ "${PROJECT_SOURCE_DIR} /include/**/*.h"
170+ "${PROJECT_SOURCE_DIR} /include/*.hpp"
171+ "${PROJECT_SOURCE_DIR} /include/*.hh"
172+ "${PROJECT_SOURCE_DIR} /include/*.h"
173+ "${PROJECT_SOURCE_DIR} /src/**/*.cpp"
174+ "${PROJECT_SOURCE_DIR} /src/**/*.cc"
175+ "${PROJECT_SOURCE_DIR} /src/**/*.c"
176+ "${PROJECT_SOURCE_DIR} /src/*.cpp"
177+ "${PROJECT_SOURCE_DIR} /src/*.cc"
178+ "${PROJECT_SOURCE_DIR} /src/*.c"
179+ )
180+ add_custom_target (
181+ ${PROJECT_NAME} _clang_tidy
182+ COMMAND ${CLANG_TIDY_EXE}
183+ --p=${CMAKE_BINARY_DIR}
184+ ${PROJECT_HEADERS_AND_SOURCES}
185+ COMMENT "Running clang-tidy"
186+ VERBATIM
187+ )
188+ add_custom_target (
189+ ${PROJECT_NAME} _clang_tidy_fix
190+ COMMAND ${CLANG_TIDY_EXE}
191+ --fix --fix-errors
192+ --p=${CMAKE_BINARY_DIR}
193+ ${PROJECT_HEADERS_AND_SOURCES}
194+ COMMENT "Running clang-tidy-fix"
195+ VERBATIM
196+ )
197+ endif ()
198+
135199# -----------------------------------------------------------------------------
136200# DOCUMENTATION
137201# -----------------------------------------------------------------------------
138202
139203if (DOXYGEN_FOUND)
140204
141- # Record the options that describe how to populate the specified content.
142- FetchContent_Declare (
143- doxygenawesome
205+ # FetchContent: Doxygen Awesome CSS
206+ FetchContent_Declare (doxygenawesome
144207 GIT_REPOSITORY https://github.com/jothepro/doxygen-awesome-css
145- GIT_TAG 4cd62308d825fe0396d2f66ffbab45d0e247724c # 2.0.3
208+ GIT_TAG main
146209 )
147- # Retrieve the properties related to the content.
148- FetchContent_GetProperties (doxygenawesome)
149- # If not populated, make the content available.
150- if (NOT doxygenawesome_POPULATED)
151- message (STATUS "Retrieving `doxygen-awesome-css`..." )
152- # Ensures the named dependencies have been populated.
153- FetchContent_MakeAvailable (doxygenawesome)
154- # Hide fetchcontent variables, otherwise with ccmake it's a mess.
155- mark_as_advanced (FORCE
156- FETCHCONTENT_QUIET FETCHCONTENT_BASE_DIR FETCHCONTENT_FULLY_DISCONNECTED FETCHCONTENT_UPDATES_DISCONNECTED
157- FETCHCONTENT_UPDATES_DISCONNECTED_DOXYGENAWESOME FETCHCONTENT_SOURCE_DIR_DOXYGENAWESOME
158- )
159- endif ()
210+ FetchContent_MakeAvailable (doxygenawesome)
211+
212+ # Hide FetchContent variables to avoid clutter in ccmake.
213+ mark_as_advanced (FORCE
214+ FETCHCONTENT_UPDATES_DISCONNECTED_DOXYGENAWESOME
215+ FETCHCONTENT_SOURCE_DIR_DOXYGENAWESOME
216+ )
217+
218+ # Read the file with the version.
219+ file (READ ${PROJECT_SOURCE_DIR} /include/bvlib/bitvector.hpp version_file )
220+ # Extract the version.
221+ string (REGEX MATCH "BVLIB_MAJOR_VERSION ([0-9]*)" _ ${version_file} )
222+ set (PROJECT_MAJOR_VERSION ${CMAKE_MATCH_1} )
223+ string (REGEX MATCH "BVLIB_MINOR_VERSION ([0-9]*)" _ ${version_file} )
224+ set (PROJECT_MINOR_VERSION ${CMAKE_MATCH_1} )
225+ string (REGEX MATCH "BVLIB_MICRO_VERSION ([0-9]*)" _ ${version_file} )
226+ set (PROJECT_MICRO_VERSION ${CMAKE_MATCH_1} )
160227
161- # = CUSTOMIZATION =========================================================
162- set (DOXYGEN_PROJECT_NAME "Bitvector Library" )
163- set (DOXYGEN_USE_MDFILE_AS_MAINPAGE README.md)
228+ # Customization: Doxygen Configuration
229+ set (DOXYGEN_WARN_FORMAT "$file:$line:1: $text" )
230+ set (DOXYGEN_PROJECT_NAME BVLib)
231+ set (DOXYGEN_PROJECT_BRIEF "A simple bitvector library for C++" )
232+ set (DOXYGEN_PROJECT_NUMBER "${PROJECT_MAJOR_VERSION} .${PROJECT_MINOR_VERSION} .${PROJECT_MICRO_VERSION} " )
233+ set (DOXYGEN_USE_MDFILE_AS_MAINPAGE ${PROJECT_SOURCE_DIR} /README.md)
164234 set (DOXYGEN_SHOW_INCLUDE_FILES NO )
165235 set (DOXYGEN_GENERATE_TREEVIEW YES )
236+ set (DOXYGEN_GENERATE_LATEX NO )
237+ set (DOXYGEN_GENERATE_MAN NO )
238+
239+ # Styling and UX enhancements using Doxygen Awesome
166240 set (DOXYGEN_HTML_HEADER ${doxygenawesome_SOURCE_DIR} /doxygen-custom/header.html)
167241 set (DOXYGEN_HTML_EXTRA_STYLESHEET ${doxygenawesome_SOURCE_DIR} /doxygen-awesome.css)
168242 set (DOXYGEN_HTML_EXTRA_FILES
169243 ${doxygenawesome_SOURCE_DIR} /doxygen-awesome-fragment-copy-button.js
170244 ${doxygenawesome_SOURCE_DIR} /doxygen-awesome-paragraph-link.js
171245 ${doxygenawesome_SOURCE_DIR} /doxygen-awesome-darkmode-toggle.js
172246 )
247+
248+ # Set stricter warnings for better documentation quality
249+ set (DOXYGEN_WARN_IF_UNDOCUMENTED YES )
250+ set (DOXYGEN_WARN_IF_DOC_ERROR YES )
251+ set (DOXYGEN_WARN_NO_PARAMDOC YES )
252+ set (DOXYGEN_WARN_AS_ERROR YES ) # Treat warnings as errors for CI
253+
254+ # Exclude certain files or directories from documentation (if needed)
255+ set (DOXYGEN_EXCLUDE_PATTERNS "${PROJECT_SOURCE_DIR} /tests/*" "${PROJECT_SOURCE_DIR} /examples/*" )
256+
257+ # Add Doxygen documentation target.
258+ file (GLOB_RECURSE PROJECT_HEADERS_AND_SOURCES
259+ "${PROJECT_SOURCE_DIR} /include/**/*.hpp"
260+ "${PROJECT_SOURCE_DIR} /include/**/*.hh"
261+ "${PROJECT_SOURCE_DIR} /include/**/*.h"
262+ "${PROJECT_SOURCE_DIR} /include/*.hpp"
263+ "${PROJECT_SOURCE_DIR} /include/*.hh"
264+ "${PROJECT_SOURCE_DIR} /include/*.h"
265+ "${PROJECT_SOURCE_DIR} /src/**/*.cpp"
266+ "${PROJECT_SOURCE_DIR} /src/**/*.cc"
267+ "${PROJECT_SOURCE_DIR} /src/**/*.c"
268+ "${PROJECT_SOURCE_DIR} /src/*.cpp"
269+ "${PROJECT_SOURCE_DIR} /src/*.cc"
270+ "${PROJECT_SOURCE_DIR} /src/*.c"
271+ )
173272 doxygen_add_docs (
174273 ${PROJECT_NAME} _documentation
175274 ${PROJECT_SOURCE_DIR} /README.md
176- ${PROJECT_SOURCE_DIR} /include/bvlib/bitvector.hpp
177- ${PROJECT_SOURCE_DIR} /include/bvlib/math.hpp
178- ${PROJECT_SOURCE_DIR} /include/bvlib/io.hpp
275+ ${PROJECT_SOURCE_DIR} /LICENSE.md
276+ ${PROJECT_HEADERS_AND_SOURCES}
277+ COMMENT "Generating Doxygen documentation"
179278 )
180279endif ()
0 commit comments