Skip to content

Commit c5681ff

Browse files
committed
wip
1 parent e02438f commit c5681ff

File tree

4 files changed

+303
-0
lines changed

4 files changed

+303
-0
lines changed

CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,22 @@ project(sparrow-ipc CXX)
55
set(CMAKE_CXX_STANDARD 20)
66
set(CMAKE_CXX_STANDARD_REQUIRED ON)
77
set(CMAKE_CXX_SCAN_FOR_MODULES OFF)
8+
include(CMakeDependentOption)
89

910
set(SPARROW_IPC_COMPILE_DEFINITIONS "" CACHE STRING "List of public compile definitions of the sparrow-ipc target")
1011

12+
# Linter options
13+
# =============
14+
OPTION(ACTIVATE_LINTER "Create targets to run clang-format" OFF)
15+
MESSAGE(STATUS "🔧 Activate linter: ${ACTIVATE_LINTER}")
16+
cmake_dependent_option(ACTIVATE_LINTER_DURING_COMPILATION "Run linter during the compilation" ON "ACTIVATE_LINTER" OFF)
17+
18+
if(ACTIVATE_LINTER)
19+
include(clang-format)
20+
include(clang-tidy)
21+
endif()
22+
23+
1124
# Build options
1225
# =============
1326

@@ -108,6 +121,11 @@ else()
108121
target_compile_definitions(sparrow-ipc PRIVATE SPARROW_IPC_EXPORTS)
109122
endif()
110123

124+
target_compile_options(sparrow-ipc
125+
PRIVATE
126+
${compile_options}
127+
)
128+
111129
target_include_directories(sparrow-ipc PUBLIC ${SPARROW_IPC_INCLUDE_DIR} PRIVATE ${SPARROW_IPC_SOURCE_DIR} )
112130
target_link_libraries(sparrow-ipc PRIVATE flatbuffers_interface)
113131
target_link_libraries(sparrow-ipc PUBLIC flatbuffers::flatbuffers sparrow::sparrow)

cmake/clang-format.cmake

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
set(CLANG-FORMAT_MINIMUM_MAJOR_VERSION 18)
2+
3+
function(get_clang_format_version clang_format_path)
4+
set(CLANG_FORMAT_VERSION_OUTPUT "")
5+
execute_process(
6+
COMMAND ${clang_format_path} --version
7+
OUTPUT_VARIABLE CLANG_FORMAT_VERSION_OUTPUT
8+
)
9+
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" CLANG_FORMAT_VERSION_OUTPUT ${CLANG_FORMAT_VERSION_OUTPUT})
10+
set(CLANG_FORMAT_MAJOR_VERSION ${CMAKE_MATCH_1} PARENT_SCOPE)
11+
set(CLANG_FORMAT_MINOR_VERSION ${CMAKE_MATCH_2} PARENT_SCOPE)
12+
set(CLANG_FORMAT_PATCH_VERSION ${CMAKE_MATCH_3} PARENT_SCOPE)
13+
endfunction()
14+
15+
function(check_clang-format_version validator_result_var item)
16+
set(${validator_result_var} FALSE PARENT_SCOPE)
17+
get_clang_format_version(${item})
18+
if (CLANG_FORMAT_MAJOR_VERSION LESS CLANG-FORMAT_MINIMUM_MAJOR_VERSION)
19+
message(DEBUG "clang-format found at ${item} | version: ${CLANG_FORMAT_MAJOR_VERSION}.${CLANG_FORMAT_MINOR_VERSION}.${CLANG_FORMAT_PATCH_VERSION}")
20+
message(DEBUG "but version is lower than ${CLANG-FORMAT_MINIMUM_MAJOR_VERSION}")
21+
set(${validator_result_var} FALSE PARENT_SCOPE)
22+
else()
23+
set(${validator_result_var} TRUE PARENT_SCOPE)
24+
endif()
25+
endfunction()
26+
27+
function(print_clang_format_install_instructions)
28+
message(STATUS "🛠️ Please install clang-format to enable code formatting")
29+
message(STATUS "Can be installed via conda-forge: https://prefix.dev/channels/conda-forge/packages/clang-format")
30+
if(UNIX)
31+
if(APPLE)
32+
message(STATUS "🍎 On MacOS, you can install clang-format with:")
33+
message(STATUS "\t> brew install clang-format")
34+
else()
35+
message(STATUS "🐧 On Ubuntu, you can install clang-format with:")
36+
message(STATUS "\t> sudo apt-get install clang-format")
37+
endif()
38+
elseif(WIN32)
39+
message(STATUS "🪟 On Windows, you can install clang-format with:")
40+
message(STATUS "\t> winget llvm")
41+
endif()
42+
endfunction()
43+
44+
find_program(CLANG_FORMAT clang-format
45+
VALIDATOR check_clang-format_version)
46+
47+
if(NOT CLANG_FORMAT)
48+
message(WARNING "❗ clang-format not found")
49+
50+
print_clang_format_install_instructions()
51+
else()
52+
get_clang_format_version(${CLANG_FORMAT})
53+
message(STATUS "✅ clang-format (version: ${CLANG_FORMAT_MAJOR_VERSION}.${CLANG_FORMAT_MINOR_VERSION}.${CLANG_FORMAT_PATCH_VERSION}) found at ${CLANG_FORMAT}")
54+
55+
# list all files to format
56+
set(
57+
FORMAT_PATTERNS
58+
include/*.hpp
59+
test/*.cpp
60+
test/*.hpp
61+
CACHE STRING
62+
"; separated patterns relative to the project source dir to format"
63+
)
64+
65+
set(ALL_FILES_TO_FORMAT "")
66+
foreach(PATTERN ${FORMAT_PATTERNS})
67+
file(GLOB_RECURSE FILES_TO_FORMAT ${CMAKE_SOURCE_DIR}/${PATTERN})
68+
list(APPEND ALL_FILES_TO_FORMAT ${FILES_TO_FORMAT})
69+
endforeach()
70+
71+
add_custom_target(
72+
clang-format
73+
COMMAND ${CLANG_FORMAT} -i -style=file ${ALL_FILES_TO_FORMAT}
74+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
75+
COMMENT "Running clang-format on all files"
76+
)
77+
78+
add_custom_target(
79+
clang-format_dry_run
80+
COMMAND ${CLANG_FORMAT} --dry-run -style=file ${ALL_FILES_TO_FORMAT}
81+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
82+
COMMENT "Running dry clang-format on all files"
83+
)
84+
endif()

cmake/clang-tidy.cmake

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
if(CMAKE_GENERATOR MATCHES "Ninja|Unix Makefiles")
2+
message(STATUS "🔧 CMAKE_EXPORT_COMPILE_COMMANDS will be used to enable clang-tidy")
3+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
4+
else()
5+
message(WARNING "🚧 CMAKE_EXPORT_COMPILE_COMMANDS can't be used because the CMAKE_GENERATOR is ${CMAKE_GENERATOR}.
6+
You have to use Ninja or Unix Makefiles.
7+
Without CMAKE_EXPORT_COMPILE_COMMANDS, clang-tidy will not work.
8+
CMAKE_EXPORT_COMPILE_COMMANDS is used to generate a JSON file that contains all the compiler commands used to build the project.
9+
This file is used by clang-tidy to know how to compile the project.")
10+
endif()
11+
12+
set(CLANG-TIDY_MINIMUM_MAJOR_VERSION 18)
13+
14+
function(get_clang_tidy_version clang_tidy_path)
15+
set(CLANG_TIDY_VERSION_OUTPUT "")
16+
execute_process(
17+
COMMAND ${clang_tidy_path} --version
18+
OUTPUT_VARIABLE CLANG_TIDY_VERSION_OUTPUT
19+
)
20+
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" CLANG_TIDY_VERSION_OUTPUT ${CLANG_TIDY_VERSION_OUTPUT})
21+
set(CLANG_TIDY_MAJOR_VERSION ${CMAKE_MATCH_1} PARENT_SCOPE)
22+
set(CLANG_TIDY_MINOR_VERSION ${CMAKE_MATCH_2} PARENT_SCOPE)
23+
set(CLANG_TIDY_PATCH_VERSION ${CMAKE_MATCH_3} PARENT_SCOPE)
24+
endfunction()
25+
26+
function(check_clang-tidy_version validator_result_var item)
27+
set(${validator_result_var} FALSE PARENT_SCOPE)
28+
get_clang_tidy_version(${item})
29+
if (CLANG_TIDY_MAJOR_VERSION LESS CLANG-TIDY_MINIMUM_MAJOR_VERSION)
30+
message(DEBUG "clang-tidy (version: ${CLANG_TIDY_MAJOR_VERSION}.${CLANG_TIDY_MINOR_VERSION}.${CLANG_TIDY_PATCH_VERSION}) found at ${item}")
31+
message(DEBUG "but clang-tidy with version >= ${CLANG-TIDY_MINIMUM_MAJOR_VERSION} must be used.")
32+
set(${validator_result_var} FALSE PARENT_SCOPE)
33+
else()
34+
set(${validator_result_var} TRUE PARENT_SCOPE)
35+
endif()
36+
endfunction()
37+
38+
function(print_clang_tidy_install_instructions)
39+
message(STATUS "🛠️ Please install clang-tidy to enable code formatting")
40+
if(UNIX)
41+
if(APPLE)
42+
message(STATUS "🍎 On MacOS, you can install clang-tidy with:")
43+
message(STATUS "\t> brew install clang-tidy")
44+
else()
45+
message(STATUS "🐧 On Ubuntu, you can install clang-tidy with:")
46+
message(STATUS "\t> sudo apt-get install clang-tidy")
47+
endif()
48+
elseif(WIN32)
49+
message(STATUS "🪟 On Windows, you can install clang-tidy with:")
50+
message(STATUS "\t> winget llvm")
51+
endif()
52+
endfunction()
53+
54+
find_program(CLANG_TIDY clang-tidy
55+
VALIDATOR check_clang-tidy_version)
56+
57+
if(NOT CLANG_TIDY)
58+
message(WARNING "❗clang-tidy with version >= ${CLANG-TIDY_MINIMUM_MAJOR_VERSION} not found")
59+
60+
print_clang_tidy_install_instructions()
61+
else()
62+
get_clang_tidy_version(${CLANG_TIDY})
63+
message(STATUS "✅ clang-tidy (version: ${CLANG_TIDY_MAJOR_VERSION}.${CLANG_TIDY_MINOR_VERSION}.${CLANG_TIDY_PATCH_VERSION}) found at ${CLANG_TIDY}")
64+
65+
if(ACTIVATE_LINTER_DURING_COMPILATION)
66+
message(STATUS "🔧 clang-tidy will be activated during compilation")
67+
set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY})
68+
else()
69+
message(STATUS "🔧 clang-tidy will not be activated during compilation")
70+
set(CMAKE_CXX_CLANG_TIDY "")
71+
endif()
72+
73+
find_package (Python COMPONENTS Interpreter)
74+
if(Python_Interpreter_FOUND)
75+
message(DEBUG "Python found at ${Python_EXECUTABLE}")
76+
get_filename_component(CLANG_TIDY_FOLDER ${CLANG_TIDY} DIRECTORY)
77+
find_file(CLANG_TIDY_PYTHON_SCRIPT run-clang-tidy PATHS ${CLANG_TIDY_FOLDER} NO_DEFAULT_PATH)
78+
if(CLANG_TIDY_PYTHON_SCRIPT)
79+
message(DEBUG "run-clang-tidy.py found at ${CLANG_TIDY_PYTHON_SCRIPT}")
80+
endif()
81+
set(CLANG_TIDY_COMMAND ${Python_EXECUTABLE} ${CLANG_TIDY_PYTHON_SCRIPT})
82+
else()
83+
set(CLANG_TIDY_COMMAND ${CLANG_TIDY})
84+
endif()
85+
86+
set(CLANG_TIDY_COMMON_ARGUMENTS
87+
$<$<NOT:$<BOOL:CLANG_TIDY_PYTHON_SCRIPT>>:->-use-color
88+
-p ${CMAKE_BINARY_DIR})
89+
90+
set(
91+
PATTERNS
92+
include/*.hpp
93+
test/*.cpp
94+
test/*.hpp
95+
CACHE STRING
96+
"; separated patterns relative to the project source dir to analyse"
97+
)
98+
99+
set(ALL_FILES_TO_FORMAT "")
100+
foreach(PATTERN ${PATTERNS})
101+
file(GLOB_RECURSE FILES_TO_ANALYZE ${CMAKE_SOURCE_DIR}/${PATTERN})
102+
list(APPEND ALL_FILES_TO_ANALYZE ${FILES_TO_ANALYZE})
103+
endforeach()
104+
105+
add_custom_target(
106+
clang-tidy
107+
COMMAND ${CLANG_TIDY_COMMAND} $<$<NOT:$<BOOL:CLANG_TIDY_PYTHON_SCRIPT>>:->-fix ${CLANG_TIDY_COMMON_ARGUMENTS} ${ALL_FILES_TO_ANALYZE}
108+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
109+
COMMENT "Running clang-tidy on all files"
110+
)
111+
112+
add_custom_target(
113+
clang-tidy_dry_run
114+
COMMAND ${CLANG_TIDY_COMMAND} ${CLANG_TIDY_COMMON_ARGUMENTS}
115+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
116+
COMMENT "Running dry clang-tidy on all files"
117+
)
118+
endif()

cmake/compile_options.cmake

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
2+
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
3+
set(compile_options
4+
/bigobj
5+
/permissive-
6+
/WX # treat warnings as errors
7+
/W4 # Baseline reasonable warnings
8+
/we4242 # 'identifier': conversion from 'type1' to 'type1', possible loss of data
9+
/we4244 # conversion from 'type1' to 'type_2', possible loss of data
10+
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
11+
/we4263 # 'function': member function does not override any base class virtual member function
12+
/we4265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may not be destructed correctly
13+
/we4287 # 'operator': unsigned/negative constant mismatch
14+
/we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside the for-loop scope
15+
/we4296 # 'operator': expression is always 'boolean_value'
16+
/we4311 # 'variable': pointer truncation from 'type1' to 'type2'
17+
/we4545 # expression before comma evaluates to a function which is missing an argument list
18+
/we4546 # function call before comma missing argument list
19+
/we4547 # 'operator': operator before comma has no effect; expected operator with side-effect
20+
/we4549 # 'operator': operator before comma has no effect; did you intend 'operator'?
21+
/we4555 # expression has no effect; expected expression with side- effect
22+
/we4619 # pragma warning: there is no warning number 'number'
23+
/we4640 # Enable warning on thread un-safe static member initialization
24+
/we4826 # Conversion from 'type1' to 'type_2' is sign-extended. This may cause unexpected runtime behavior.
25+
/we4905 # wide string literal cast to 'LPSTR'
26+
/we4906 # string literal cast to 'LPWSTR'
27+
/we4928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied
28+
/we5038 # data member 'member1' will be initialized after data member 'member2'
29+
/Zc:__cplusplus
30+
PARENT_SCOPE)
31+
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
32+
set(compile_options
33+
-Wall # reasonable and standard
34+
-Wcast-align # warn for potential performance problem casts
35+
-Wconversion # warn on type conversions that may lose data
36+
-Wdouble-promotion # warn if float is implicitly promoted to double
37+
-Werror # treat warnings as errors
38+
-Wextra
39+
-Wformat=2 # warn on security issues around functions that format output (i.e., printf)
40+
-Wimplicit-fallthrough # Warns when case statements fall-through. (Included with -Wextra in GCC, not in clang)
41+
-Wmisleading-indentation # warn if indentation implies blocks where blocks do not exist
42+
-Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps catch hard to track down memory errors
43+
-Wnull-dereference # warn if a null dereference is detected
44+
-Wold-style-cast # warn for c-style casts
45+
-Woverloaded-virtual # warn if you overload (not override) a virtual function
46+
-Wshadow # warn the user if a variable declaration shadows one from a parent context
47+
-Wsign-conversion # warn on sign conversions
48+
-Wunused # warn on anything being unused
49+
$<$<CXX_COMPILER_ID:Clang>:-Wno-c++98-compat> # do not warn on use of non-C++98 standard
50+
$<$<CXX_COMPILER_ID:Clang>:-Wno-c++98-compat-pedantic>
51+
$<$<CXX_COMPILER_ID:Clang>:-Wno-documentation>
52+
$<$<CXX_COMPILER_ID:Clang>:-Wno-extra-semi-stmt>
53+
$<$<CXX_COMPILER_ID:Clang>:-Wno-c++20-compat>
54+
$<$<CXX_COMPILER_ID:Clang>:-Wno-pre-c++20-compat-pedantic>
55+
$<$<CXX_COMPILER_ID:Clang>:-Wno-reserved-identifier>
56+
$<$<CXX_COMPILER_ID:Clang>:-Wno-undef>
57+
$<$<CXX_COMPILER_ID:Clang>:-Wno-switch-default>
58+
$<$<CXX_COMPILER_ID:Clang>:-Wno-switch-enum>
59+
$<$<CXX_COMPILER_ID:Clang>:-Wno-missing-prototypes>
60+
$<$<CXX_COMPILER_ID:Clang>:-Wno-unused-template>
61+
$<$<CXX_COMPILER_ID:Clang>:-Wno-unsafe-buffer-usage>
62+
$<$<CXX_COMPILER_ID:Clang>:-Wno-documentation-unknown-command>
63+
$<$<CXX_COMPILER_ID:Clang>:-Wno-float-equal>
64+
$<$<CXX_COMPILER_ID:Clang>:-Wno-exit-time-destructors>
65+
$<$<CXX_COMPILER_ID:Clang>:-Wno-global-constructors>
66+
$<$<CXX_COMPILER_ID:Clang>:-Wno-newline-eof>
67+
$<$<CXX_COMPILER_ID:Clang>:-Wno-ctad-maybe-unsupported>
68+
$<$<CXX_COMPILER_ID:GNU>:-Wno-maybe-uninitialized>
69+
$<$<CXX_COMPILER_ID:GNU>:-Wno-array-bounds>
70+
$<$<CXX_COMPILER_ID:GNU>:-Wno-stringop-overread>
71+
$<$<CXX_COMPILER_ID:GNU>:-Wduplicated-branches> # warn if if / else branches have duplicated code
72+
$<$<CXX_COMPILER_ID:GNU>:-Wduplicated-cond> # warn if if / else chain has duplicated conditions
73+
$<$<CXX_COMPILER_ID:GNU>:-Wlogical-op> # warn about logical operations being used where bitwise were probably wanted
74+
$<$<CXX_COMPILER_ID:GNU>:-Wno-subobject-linkage> # suppress warnings about subobject linkage
75+
)
76+
if (NOT "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
77+
set(compile_options ${compile_options} -ftemplate-backtrace-limit=0 -pedantic)
78+
endif()
79+
80+
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11.3)
81+
set(compile_options ${compile_optoins} PRIVATE "-Wno-error=shift-negative-value")
82+
endif()
83+
endif()

0 commit comments

Comments
 (0)