-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
341 lines (296 loc) · 12 KB
/
CMakeLists.txt
File metadata and controls
341 lines (296 loc) · 12 KB
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
cmake_minimum_required(VERSION 3.13)
include(CMakePrintHelpers)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++")
endif()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif()
cmake_print_variables(CMAKE_BUILD_TYPE)
if(POLICY CMP0148)
cmake_policy(SET CMP0148 NEW)
endif()
# Set which targets to make, between a standalone executable and a Python lib
option(STANDALONE_BUILD_ENABLED "Build standalone executlbe" ON)
option(PYTHON_BUILD_ENABLED "Build Python library" ON)
option(TESTING_ENABLED "Build test library" OFF)
# Ensure that at least one build target is enabled
if(NOT STANDALONE_BUILD_ENABLED AND NOT PYTHON_BUILD_ENABLED AND NOT TESTING_ENABLED)
message(
FATAL_ERROR
"No build target enabled: Either STANDALONE_BUILD_ENABLED or PYTHON_BUILD_ENABLED or TESTING_ENABLED must be ON."
)
endif()
# Prevent in-source builds, which cause issues due to left over CMake caches
# For example:
# $ pip install . fails if any CMake caches are in the main project directory
cmake_print_variables(CMAKE_SOURCE_DIR)
cmake_print_variables(CMAKE_BINARY_DIR)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR
"In-source builds are not allowed. "
"Please create a separate build directory and run cmake from there. "
"E.g., $ mkdir build && cd build")
endif()
project(sana-fe)
add_compile_options(
-Wall -pedantic -Werror -g -fPIC -pthread
)
# Set default debug levels for tracing
if(NOT DEFINED DEBUG_LEVEL_ARCH)
set(DEBUG_LEVEL_ARCH 0)
endif()
if(NOT DEFINED DEBUG_LEVEL_DESCRIPTION)
set(DEBUG_LEVEL_DESCRIPTION 0)
endif()
if(NOT DEFINED DEBUG_LEVEL_MODELS)
set(DEBUG_LEVEL_MODELS 0)
endif()
if(NOT DEFINED DEBUG_LEVEL_NET)
set(DEBUG_LEVEL_NET 0)
endif()
if(NOT DEFINED DEBUG_LEVEL_PLUGINS)
set(DEBUG_LEVEL_PLUGINS 0)
endif()
if(NOT DEFINED DEBUG_LEVEL_PYMODULE)
set(DEBUG_LEVEL_PYMODULE 0)
endif()
if(NOT DEFINED DEBUG_LEVEL_CHIP)
set(DEBUG_LEVEL_CHIP 0)
endif()
if(NOT DEFINED DEBUG_LEVEL_SCHEDULER)
set(DEBUG_LEVEL_SCHEDULER 0)
endif()
# Validate debug levels
foreach(category ARCH CHIP DESCRIPTION MODELS NET PLUGINS PYMODULE SCHEDULER)
if(NOT DEBUG_LEVEL_${category} MATCHES "^[0-3]$")
message(FATAL_ERROR "DEBUG_LEVEL_${category} must be between 0 and 3")
endif()
# Add compile definitions for each category
add_compile_definitions(DEBUG_LEVEL_${category}=${DEBUG_LEVEL_${category}})
endforeach()
# Set conditional defaults based on build type
if(CMAKE_BUILD_TYPE STREQUAL "Release")
# Release build defaults
set(DEFAULT_STANDALONE_DEBUG ON)
set(DEFAULT_STANDALONE_SOURCE OFF) # No source info in release
set(DEFAULT_PYTHON_DEBUG OFF)
set(DEFAULT_PYTHON_SOURCE OFF)
else()
# Debug/other build defaults
set(DEFAULT_STANDALONE_DEBUG ON)
set(DEFAULT_STANDALONE_SOURCE ON)
set(DEFAULT_PYTHON_DEBUG ON)
set(DEFAULT_PYTHON_SOURCE ON)
endif()
# Define options with conditional defaults
option(ENABLE_STANDALONE_DEBUG "Enable debug prints for standalone build" ${DEFAULT_STANDALONE_DEBUG})
option(ENABLE_SOURCE_INFO_STANDALONE "Include source info in standalone debug prints" ${DEFAULT_STANDALONE_SOURCE})
option(ENABLE_PYTHON_DEBUG "Enable debug prints for Python build" ${DEFAULT_PYTHON_DEBUG})
option(ENABLE_SOURCE_INFO_PYTHON "Include source info in standalone debug prints" ${DEFAULT_PYTHON_SOURCE})
cmake_print_variables(ENABLE_STANDALONE_DEBUG ENABLE_SOURCE_INFO_STANDALONE ENABLE_PYTHON_DEBUG ENABLE_SOURCE_INFO_PYTHON)
set(SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/plugins")
cmake_print_variables(SRC_DIR)
file (GLOB SOURCE_FILES "${SRC_DIR}/*.cpp")
file (GLOB HEADER_FILES "${SRC_DIR}/*.hpp")
cmake_print_variables(SOURCE_FILES)
cmake_print_variables(HEADER_FILES)
# Get the latest commit hash
execute_process(
COMMAND git rev-parse HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT
OUTPUT_STRIP_TRAILING_WHITESPACE)
add_compile_definitions(GIT_COMMIT="${GIT_COMMIT}")
# Find Python using the new FindPython module
option(PYTHON_FROM_SETUP "Building via setup.py" OFF)
set(PYTHON_VERSION "" CACHE STRING "Python version to find (e.g., 3.10, 3.11). Leave empty for system default.")
cmake_print_variables(PYTHON_VERSION)
if(PYTHON_BUILD_ENABLED)
if(PYTHON_FROM_SETUP)
if(NOT DEFINED PYTHON_EXECUTABLE OR NOT DEFINED PYTHON_INCLUDE_DIRS)
message(FATAL_ERROR "PYTHON_EXECUTABLE and PYTHON_INCLUDE_DIRS must be provided when PYTHON_FROM_SETUP=ON")
endif()
else()
if(PYTHON_VERSION)
find_package(Python ${PYTHON_VERSION} EXACT COMPONENTS Interpreter Development REQUIRED)
else()
find_package(Python COMPONENTS Interpreter Development REQUIRED)
endif()
endif()
endif()
option(ENABLE_OPENMP "Enable OpenMP support for parallel processing" ON)
find_package(OpenMP)
find_package(Threads REQUIRED)
# OpenMP i.e. multithreaded builds are optional, but on by default
if (OpenMP_CXX_FOUND AND ENABLE_OPENMP)
message(STATUS "OpenMP found: ${OpenMP_CXX_VERSION} and enabled")
add_compile_options(-fopenmp)
else()
if(NOT OpenMP_CXX_FOUND)
message(STATUS "OpenMP not found - parallel code will be disabled")
else()
message(STATUS "OpenMP found but explicitly disabled - parallel code will be disabled")
endif()
endif()
############## rapid-yaml
project(ryml-quickstart LANGUAGES CXX)
set(RYML_VERSION "v0.10.0")
message(STATUS "FetchContent for tag: ${RYML_VERSION}")
set(RYML_INSTALL OFF)
set(RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS ON)
include(FetchContent)
FetchContent_Declare(ryml
GIT_REPOSITORY https://github.com/biojppm/rapidyaml.git
GIT_TAG ${RYML_VERSION}
GIT_SHALLOW FALSE # ensure submodules are checked out
)
FetchContent_MakeAvailable(ryml)
##### END OF rapid-yaml
message(STATUS "got ryml")
############## booksim2
project(booksim2-quickstart LANGUAGES CXX)
set(BOOKSIM_VERSION "bd249160e8059ac1ead52fa3d41daae9c17951bd")
set(BOOKSIM_INSTALL OFF)
set(BOOKSIM_GENERATE_PARSER OFF)
FetchContent_Declare(booksim
GIT_REPOSITORY https://github.com/SLAM-Lab/booksim2-sanafe.git
GIT_TAG ${BOOKSIM_VERSION}
GIT_SHALLOW FALSE
)
FetchContent_MakeAvailable(booksim)
if(NOT booksim_POPULATED)
FetchContent_Populate(booksim)
endif()
get_target_property(BOOKSIM_INCLUDE_DIRS booksim INTERFACE_INCLUDE_DIRECTORIES)
if(NOT BOOKSIM_INCLUDE_DIRS)
# Fallback for older CMake versions
set(BOOKSIM_INCLUDE_DIRS
${booksim_SOURCE_DIR}
${booksim_SOURCE_DIR}/src/arbiters
${booksim_SOURCE_DIR}/src/allocators
${booksim_SOURCE_DIR}/src/routers
${booksim_SOURCE_DIR}/src/networks
${booksim_SOURCE_DIR}/src/power
)
include_directories(${BOOKSIM_INCLUDE_DIRS})
endif()
#### END of booksim2
include_directories(${PYTHON_INCLUDE_DIRS})
cmake_print_variables(PyBind11_DIR)
# PyBind specific
if(PYTHON_BUILD_ENABLED)
if(PYTHON_FROM_SETUP)
# Force pybind11 to use the Python from setup.py
set(Python_EXECUTABLE ${PYTHON_EXECUTABLE})
set(Python_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS})
set(PYBIND11_PYTHON_VERSION "") # Don't let pybind11 override
message(STATUS "Forcing pybind11 to use Python: ${PYTHON_EXECUTABLE}")
endif()
find_package(pybind11 CONFIG)
if (NOT PYTHON_EXECUTABLE)
message("PYTHON_EXECUTABLE not set, default command: 'python3'")
set(PYTHON_EXECUTABLE "python3")
endif()
if(NOT pybind11_FOUND OR pybind11_FOUND STREQUAL "0")
message("PyBind11 not found, trying to set PYBIND_CMAKE_DIR using Python")
execute_process(
COMMAND "${PYTHON_EXECUTABLE}" -c "import pybind11; print(pybind11.get_cmake_dir())"
OUTPUT_VARIABLE PYBIND11_CMAKE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(PYBIND11_CMAKE_DIR)
message(STATUS "Found pybind11 at: ${PYBIND11_CMAKE_DIR}")
set(pybind11_DIR ${PYBIND11_CMAKE_DIR})
find_package(pybind11 CONFIG REQUIRED)
else() # pybind11 detection failed
message(FATAL_ERROR
"ERROR: Could not find pybind11\n"
"To fix this either:\n"
" 1. Make sure pybind11 is installed:\n"
" $ ${PYTHON_EXECUTABLE} -m pip install pybind11\n"
" 2. If pybind11 is already installed in a different Python,\n"
" the wrong Python environment may have been detected.\n"
" set the PYTHON_EXECUTABLE environment variable:\n"
" $ cmake -DPYTHON_EXECUTABLE=/path/to/correct/python ..\n"
"Current Python executable being detected:\n"
" ${PYTHON_EXECUTABLE}\n"
)
endif()
endif()
pybind11_add_module(
sanafecpp
${SOURCE_FILES}
)
target_link_libraries(sanafecpp PRIVATE ${PYTHON_LIBRARIES})
target_link_libraries(sanafecpp PRIVATE pybind11::pybind11)
target_link_libraries(sanafecpp PUBLIC ryml::ryml)
target_link_libraries(sanafecpp PUBLIC booksim)
target_link_libraries(sanafecpp PRIVATE ${CMAKE_DL_LIBS})
if (OpenMP_CXX_FOUND AND ENABLE_OPENMP)
target_link_libraries(sanafecpp PRIVATE OpenMP::OpenMP_CXX)
target_compile_definitions(sanafecpp PRIVATE HAVE_OPENMP)
endif()
target_link_libraries(sanafecpp PRIVATE Threads::Threads)
if(ENABLE_PYTHON_DEBUG)
target_compile_definitions(sanafecpp PRIVATE ENABLE_DEBUG_PRINTS)
if(ENABLE_SOURCE_INFO_PYTHON)
target_compile_definitions(sanafecpp PRIVATE ENABLE_SOURCE_INFO)
endif()
endif()
install(TARGETS sanafecpp
LIBRARY DESTINATION "${CMAKE_SOURCE_DIR}"
RUNTIME DESTINATION "${CMAKE_SOURCE_DIR}")
message(STATUS "Simulator files will be copied to project directory")
endif()
if(STANDALONE_BUILD_ENABLED)
add_executable(sim "${SRC_DIR}/main.cpp")
list(FILTER SOURCE_FILES EXCLUDE REGEX "pymodule.cpp")
list(FILTER SOURCE_FILES EXCLUDE REGEX "pytrace.cpp")
target_sources(sim PRIVATE ${SOURCE_FILES})
target_link_libraries(sim PUBLIC ryml::ryml)
target_link_libraries(sim PUBLIC booksim)
target_link_libraries(sim PRIVATE ${CMAKE_DL_LIBS})
if (OpenMP_CXX_FOUND AND ENABLE_OPENMP)
target_link_libraries(sim PRIVATE OpenMP::OpenMP_CXX)
target_compile_definitions(sim PRIVATE HAVE_OPENMP)
endif()
target_link_libraries(sim PRIVATE Threads::Threads)
if(ENABLE_STANDALONE_DEBUG)
target_compile_definitions(sim PRIVATE ENABLE_DEBUG_PRINTS)
if(ENABLE_SOURCE_INFO_STANDALONE)
target_compile_definitions(sim PRIVATE ENABLE_SOURCE_INFO)
endif()
endif()
install(TARGETS sim
LIBRARY DESTINATION "${CMAKE_SOURCE_DIR}"
RUNTIME DESTINATION "${CMAKE_SOURCE_DIR}")
message(STATUS "Simulator files will be copied to project directory")
endif()
if(TESTING_ENABLED)
list(FILTER SOURCE_FILES EXCLUDE REGEX "pymodule.cpp")
list(FILTER SOURCE_FILES EXCLUDE REGEX "pytrace.cpp")
add_library(sanafe SHARED ${SOURCE_FILES} ${HEADER_FILES})
target_link_libraries(sanafe PUBLIC ryml::ryml)
target_link_libraries(sanafe PUBLIC booksim)
target_link_libraries(sanafe PRIVATE ${CMAKE_DL_LIBS})
if (OpenMP_CXX_FOUND AND ENABLE_OPENMP)
target_link_libraries(sanafe PRIVATE OpenMP::OpenMP_CXX)
target_compile_definitions(sanafe PRIVATE HAVE_OPENMP)
endif()
target_link_libraries(sanafe PRIVATE Threads::Threads)
target_include_directories(sanafe PUBLIC
${CMAKE_SOURCE_DIR}/src
)
target_compile_definitions(sanafe PRIVATE ENABLE_DEBUG_PRINTS)
message(STATUS "Testing enabled")
include(CTest)
add_subdirectory(tests)
find_program(CTEST_MEMORYCHECK_COMMAND valgrind)
set(CTEST_MEMORYCHECK_COMMAND_OPTIONS "--leak-check=full --show-leak-kinds=all --track-origins=yes --error-exitcode=10")
endif()