-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
198 lines (195 loc) · 9.86 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
#------------------------------------------------------------------------------------------
# Determine if CircularBuffer is built as a standalone project or included by other projects
set(CIRCULARBUFFER_STANDALONE_PROJECT OFF)
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(CIRCULARBUFFER_STANDALONE_PROJECT ON)
endif()
#------------------------------------------------------------------------------------------
# Get the name of the folder and use it as the project name
get_filename_component(PARENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" PARENT_DIR_NAME ${PARENT_DIR_NAME})
project(${PARENT_DIR_NAME} VERSION 1.0 DESCRIPTION "A Circularbuffer function library" LANGUAGES CXX)
#------------------------------------------------------------------------------------------
# Set the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#------------------------------------------------------------------------------------------
# Print out the build type
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
#------------------------------------------------------------------------------------------
if(CIRCULARBUFFER_STANDALONE_PROJECT)
if(MSVC)
# MSVC specific warning flags
add_library(common_options INTERFACE)
target_compile_options(common_options INTERFACE /W4) # Equivalent to -Wall in GCC/Clang
else()
# GCC/Clang specific warning flags
add_library(common_options INTERFACE)
target_compile_options(common_options INTERFACE -Wall -Wextra -Wpedantic -pedantic-errors -Werror=format-security -fasynchronous-unwind-tables)
endif()
endif()
#------------------------------------------------------------------------------------------
# Set the runtime output directory only if this is a standalone project
if(CIRCULARBUFFER_STANDALONE_PROJECT)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# Optionally, to set these directories only for specific build configurations (Debug, Release, etc.),
# you can use the following approach:
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/bin)
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin)
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/lib)
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/lib)
# set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/lib)
# set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/lib)
# Diagnostic output
message(STATUS "ARCHIVE_OUTPUT_DIRECTORY: ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}")
message(STATUS "LIBRARY_OUTPUT_DIRECTORY: ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}")
message(STATUS "RUNTIME_OUTPUT_DIRECTORY: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
endif()
#------------------------------------------------------------------------------------------
# Offer switches for the type of the library and optional builds
option(BUILD_CIRCULARBUFFER_SHARED_LIBS "Build using shared libraries" ON)
option(BUILD_CIRCULARBUFFER_EXAMPLE "Build CircularBuffer example" ${CIRCULARBUFFER_STANDALONE_PROJECT})
option(BUILD_CIRCULARBUFFER_TESTS "Build CircularBuffer tests" ${CIRCULARBUFFER_STANDALONE_PROJECT})
option(BUILD_CIRCULARBUFFER_BENCHMARK "Build CircularBuffer benchmarks" ${CIRCULARBUFFER_STANDALONE_PROJECT})
option(BUILD_CIRCULARBUFFER_MULTI_THREADING "Enable multi-threading support." OFF)
set(CIRCULARBUFFER_MULTI_THREADING BUILD_CIRCULARBUFFER_MULTI_THREADING CACHE BOOL "Enable multi-threading support.")
set(HAS_TBB OFF CACHE BOOL "Set to TRUE if TBB is found, otherwise FALSE")
#------------------------------------------------------------------------------------------
# Force colored output
option(FORCE_COLORED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." OFF)
if(${FORCE_COLORED_OUTPUT})
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
add_compile_options(-fdiagnostics-color=always)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_compile_options(-fcolor-diagnostics)
endif()
endif()
#------------------------------------------------------------------------------------------
# Define the source and include directories
set(CIRCULARBUFFER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(CIRCULARBUFFER_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
#------------------------------------------------------------------------------------------
# Find TBB
find_package(TBB QUIET)
if(TBB_FOUND)
set(HAS_TBB ON)
add_definitions(-DHAS_TBB=1)
message(STATUS "Intel TBB found: ${TBB_VERSION}")
else()
set(HAS_TBB OFF)
endif()
#------------------------------------------------------------------------------------------
# Define the source files
set(CIRCULARBUFFER_SOURCES
${CIRCULARBUFFER_SOURCE_DIR}/CircularBufferFixed.cpp
${CIRCULARBUFFER_SOURCE_DIR}/CircularBufferDynamic.cpp
${CIRCULARBUFFER_SOURCE_DIR}/CircularBuffer.cpp
)
#------------------------------------------------------------------------------------------
# Check if the library should be built as a shared library
if(BUILD_CIRCULARBUFFER_SHARED_LIBS)
add_library(${PROJECT_NAME} SHARED ${CIRCULARBUFFER_SOURCES})
# If needed, set properties specific to shared libraries here
else()
add_library(${PROJECT_NAME} STATIC ${CIRCULARBUFFER_SOURCES})
# If needed, set properties specific to static libraries here
endif()
#------------------------------------------------------------------------------------------
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CIRCULARBUFFER_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>
)
#------------------------------------------------------------------------------------------
# Alias for CircularBuffer library
add_library(CircularBuffer::circularbuffer ALIAS ${PROJECT_NAME})
#------------------------------------------------------------------------------------------
# Set CIRCULARBUFFER_LIBRARIES variable
if(CIRCULARBUFFER_STANDALONE_PROJECT)
set(CIRCULARBUFFER_LIBRARIES CircularBuffer::circularbuffer)
else()
set(CIRCULARBUFFER_LIBRARIES CircularBuffer::circularbuffer PARENT_SCOPE)
endif()
message(STATUS "CIRCULARBUFFER_LIBRARIES: ${CIRCULARBUFFER_LIBRARIES}")
#------------------------------------------------------------------------------------------
# Conditional compilation and warnings
if(BUILD_CIRCULARBUFFER_MULTI_THREADING)
if(HAS_TBB)
message(STATUS "Multi-threading enabled with Intel TBB.")
target_link_libraries(${PROJECT_NAME} PRIVATE TBB::tbb)
add_definitions(-DCIRCULARBUFFER_MULTI_THREADING=1)
else()
add_definitions(-DCIRCULARBUFFER_MULTI_THREADING=0)
message(WARNING "Multi-threading is enabled, but Intel TBB is not found. Compiling without multi-threading support.")
endif()
endif()
#------------------------------------------------------------------------------------------
# Building examples
if(BUILD_CIRCULARBUFFER_EXAMPLE)
set(CIRCULARBUFFER_EXAMPLE_NAME "${PROJECT_NAME}_example")
add_executable(${CIRCULARBUFFER_EXAMPLE_NAME} example/main.cpp)
target_link_libraries(${CIRCULARBUFFER_EXAMPLE_NAME} PRIVATE ${PROJECT_NAME})
endif()
#------------------------------------------------------------------------------------------
# Compiler-specific flags
if(MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "/O2 /MD")
set(CMAKE_CXX_FLAGS_DEBUG "/Od /MDd")
target_compile_options(${PROJECT_NAME} PRIVATE
"$<$<CONFIG:Release>:/O2>"
"$<$<CONFIG:Debug>:/Od>"
"$<$<CONFIG:Debug>:/Zi>"
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_link_options(${PROJECT_NAME} PRIVATE /DEBUG)
endif()
set_target_properties(${PROJECT_NAME} PROPERTIES
WINDOWS_EXPORT_ALL_SYMBOLS TRUE
)
else()
# For non-MSVC compilers
target_compile_options(${PROJECT_NAME} PRIVATE
"$<$<CONFIG:Release>:-O3>"
)
# Conditionally include AddressSanitizer flags only if standalone and in Debug mode
if(CIRCULARBUFFER_STANDALONE_PROJECT AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang|GNU")
set(SANITIZE_FLAGS "$<$<CONFIG:Debug>:-fsanitize=address>")
target_compile_options(${PROJECT_NAME} PRIVATE
"$<$<CONFIG:Debug>:-g>"
"$<$<CONFIG:Debug>:-O0>"
${SANITIZE_FLAGS}
)
target_link_options(${PROJECT_NAME} PRIVATE ${SANITIZE_FLAGS})
endif()
endif()
#------------------------------------------------------------------------------------------
# Enable testing and add the test directory if this is a standalone project
if(BUILD_CIRCULARBUFFER_TESTS AND CIRCULARBUFFER_STANDALONE_PROJECT)
enable_testing()
add_subdirectory(test)
endif()
#------------------------------------------------------------------------------------------
# Enable benchmarks and add the benchmark directory if this is a standalone project
if(BUILD_CIRCULARBUFFER_BENCHMARK AND CIRCULARBUFFER_STANDALONE_PROJECT)
add_subdirectory(benchmark)
endif()
#------------------------------------------------------------------------------------------
# Export the library targets (only if it's a standalone project)
if(CIRCULARBUFFER_STANDALONE_PROJECT)
include(GNUInstallDirs)
install(TARGETS ${PROJECT_NAME} EXPORT CircularBufferTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(DIRECTORY ${CIRCULARBUFFER_INCLUDE_DIR}/${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT CircularBufferTargets
FILE CircularBufferTargets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
endif()
#------------------------------------------------------------------------------------------