-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
235 lines (215 loc) · 10 KB
/
CMakeLists.txt
File metadata and controls
235 lines (215 loc) · 10 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
cmake_minimum_required(VERSION 3.23)
project(netgraph_core LANGUAGES CXX)
# Silence pybind11 FindPython compatibility warning by selecting the modern mode
set(PYBIND11_FINDPYTHON NEW CACHE STRING "Use modern FindPython in pybind11")
# Optional C++ tests
option(NETGRAPH_CORE_BUILD_TESTS "Build C++ unit tests" OFF)
if(NETGRAPH_CORE_BUILD_TESTS)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
FetchContent_MakeAvailable(googletest)
enable_testing()
add_executable(netgraph_core_tests
tests/cpp/smoke_test.cpp
tests/cpp/flow_policy_tests.cpp
tests/cpp/strict_multidigraph_tests.cpp
tests/cpp/shortest_paths_tests.cpp
tests/cpp/flow_state_tests.cpp
tests/cpp/flow_graph_tests.cpp
tests/cpp/max_flow_tests.cpp
tests/cpp/k_shortest_paths_tests.cpp
tests/cpp/masking_tests.cpp
)
target_link_libraries(netgraph_core_tests PRIVATE netgraph_core GTest::gtest_main)
target_include_directories(netgraph_core_tests PRIVATE tests/cpp)
if(NETGRAPH_CORE_COVERAGE AND (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang"))
target_compile_options(netgraph_core_tests PRIVATE -O0 -g --coverage)
target_link_options(netgraph_core_tests PRIVATE --coverage)
endif()
include(GoogleTest)
gtest_discover_tests(netgraph_core_tests)
endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# macOS: enforce consistent deployment target and architecture for wheels/builds
if(APPLE)
# Allow environment to override, otherwise choose a sensible default
if(DEFINED ENV{MACOSX_DEPLOYMENT_TARGET})
set(CMAKE_OSX_DEPLOYMENT_TARGET "$ENV{MACOSX_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE)
elseif(NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
set(CMAKE_OSX_DEPLOYMENT_TARGET "15.0" CACHE STRING "" FORCE)
endif()
if(NOT DEFINED CMAKE_OSX_ARCHITECTURES)
# Default to arm64 on Apple Silicon hosts
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64")
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "" FORCE)
endif()
endif()
endif()
# Dependencies
find_package(pybind11 3 CONFIG QUIET)
if(NOT pybind11_FOUND)
message(STATUS "pybind11 not found via config; using FetchContent")
include(FetchContent)
FetchContent_Declare(
pybind11
GIT_REPOSITORY https://github.com/pybind/pybind11.git
GIT_TAG v3.0.0
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
FetchContent_MakeAvailable(pybind11)
endif()
add_library(netgraph_core STATIC
src/strict_multidigraph.cpp
src/shortest_paths.cpp
src/k_shortest_paths.cpp
src/max_flow.cpp
src/flow_state.cpp
src/flow_graph.cpp
src/flow_policy.cpp
src/cpu_backend.cpp
src/profiling.cpp
)
target_include_directories(netgraph_core PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_compile_definitions(netgraph_core PRIVATE _USE_MATH_DEFINES)
## C++ standard is set globally above.
target_compile_features(netgraph_core PUBLIC cxx_std_20)
# Warnings
if(MSVC)
target_compile_options(netgraph_core PRIVATE /W4 /permissive-)
else()
target_compile_options(netgraph_core PRIVATE -Wall -Wextra -Wpedantic)
endif()
# Python extension
pybind11_add_module(_netgraph_core bindings/python/module.cpp)
target_link_libraries(_netgraph_core PRIVATE netgraph_core)
target_compile_features(_netgraph_core PRIVATE cxx_std_20)
if(APPLE)
# Prefer maximum runtime compatibility for libc++ on macOS
target_compile_definitions(netgraph_core PUBLIC _LIBCPP_DISABLE_AVAILABILITY=1 _LIBCPP_ABI_VERSION=1)
target_compile_definitions(_netgraph_core PRIVATE _LIBCPP_DISABLE_AVAILABILITY=1 _LIBCPP_ABI_VERSION=1)
endif()
# =============================================================================
# Performance optimizations (disabled when coverage/sanitizers are enabled)
# =============================================================================
option(NETGRAPH_CORE_COVERAGE "Enable C++ coverage instrumentation" OFF)
option(NETGRAPH_CORE_SANITIZE "Enable Address/Undefined sanitizers" OFF)
option(NETGRAPH_CORE_NATIVE "Optimize for current CPU (not portable)" OFF)
option(NETGRAPH_CORE_FAST_MATH "Enable fast math (may affect precision)" OFF)
option(NETGRAPH_CORE_PGO_GENERATE "Instrument for PGO profile collection" OFF)
option(NETGRAPH_CORE_PGO_USE "Use PGO profile data (set NETGRAPH_CORE_PGO_DIR)" OFF)
set(NETGRAPH_CORE_PGO_DIR "${CMAKE_BINARY_DIR}/pgo" CACHE PATH "Directory for PGO profile data")
# Only apply optimizations when not in debug/instrumentation mode
if(NOT NETGRAPH_CORE_COVERAGE AND NOT NETGRAPH_CORE_SANITIZE)
# LTO (Link Time Optimization) - enables cross-module inlining
include(CheckIPOSupported)
check_ipo_supported(RESULT ipo_supported OUTPUT ipo_error)
if(ipo_supported)
message(STATUS "Enabling LTO (Link Time Optimization)")
set_target_properties(netgraph_core PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
set_target_properties(_netgraph_core PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
message(STATUS "LTO not supported: ${ipo_error}")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
# GCC-only: allow aggressive inlining by promising symbols won't be interposed
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(netgraph_core PRIVATE -fno-semantic-interposition)
target_compile_options(_netgraph_core PRIVATE -fno-semantic-interposition)
endif()
# Safe floating-point optimizations (we don't use errno, FP exceptions, or change rounding mode)
target_compile_options(netgraph_core PRIVATE -fno-math-errno -fno-trapping-math)
target_compile_options(_netgraph_core PRIVATE -fno-math-errno -fno-trapping-math)
# Aggressive loop optimizations
target_compile_options(netgraph_core PRIVATE -funroll-loops)
target_compile_options(_netgraph_core PRIVATE -funroll-loops)
# Native CPU instructions (AVX2, etc.) - only for local builds
if(NETGRAPH_CORE_NATIVE)
message(STATUS "Enabling native CPU optimizations (-march=native)")
target_compile_options(netgraph_core PRIVATE -march=native)
target_compile_options(_netgraph_core PRIVATE -march=native)
endif()
# Fast math - trades IEEE compliance for speed
if(NETGRAPH_CORE_FAST_MATH)
message(STATUS "Enabling fast math optimizations")
target_compile_options(netgraph_core PRIVATE -ffast-math)
target_compile_options(_netgraph_core PRIVATE -ffast-math)
endif()
# PGO (Profile-Guided Optimization) - uses runtime profile to guide inlining decisions
# GCC: -fprofile-generate/-fprofile-use, Clang: -fprofile-instr-*
if(NETGRAPH_CORE_PGO_GENERATE)
message(STATUS "PGO: Instrumenting for profile generation -> ${NETGRAPH_CORE_PGO_DIR}")
file(MAKE_DIRECTORY ${NETGRAPH_CORE_PGO_DIR})
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(netgraph_core PRIVATE -fprofile-generate=${NETGRAPH_CORE_PGO_DIR})
target_compile_options(_netgraph_core PRIVATE -fprofile-generate=${NETGRAPH_CORE_PGO_DIR})
target_link_options(netgraph_core PRIVATE -fprofile-generate=${NETGRAPH_CORE_PGO_DIR})
target_link_options(_netgraph_core PRIVATE -fprofile-generate=${NETGRAPH_CORE_PGO_DIR})
else()
# Clang/AppleClang: use LLVM instrumentation PGO
target_compile_options(netgraph_core PRIVATE -fprofile-instr-generate=${NETGRAPH_CORE_PGO_DIR}/default.profraw)
target_compile_options(_netgraph_core PRIVATE -fprofile-instr-generate=${NETGRAPH_CORE_PGO_DIR}/default.profraw)
target_link_options(netgraph_core PRIVATE -fprofile-instr-generate=${NETGRAPH_CORE_PGO_DIR}/default.profraw)
target_link_options(_netgraph_core PRIVATE -fprofile-instr-generate=${NETGRAPH_CORE_PGO_DIR}/default.profraw)
endif()
elseif(NETGRAPH_CORE_PGO_USE)
message(STATUS "PGO: Using profile data from ${NETGRAPH_CORE_PGO_DIR}")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(netgraph_core PRIVATE -fprofile-use=${NETGRAPH_CORE_PGO_DIR} -fprofile-correction)
target_compile_options(_netgraph_core PRIVATE -fprofile-use=${NETGRAPH_CORE_PGO_DIR} -fprofile-correction)
else()
# Clang/AppleClang: use merged .profdata file
target_compile_options(netgraph_core PRIVATE -fprofile-instr-use=${NETGRAPH_CORE_PGO_DIR}/default.profdata)
target_compile_options(_netgraph_core PRIVATE -fprofile-instr-use=${NETGRAPH_CORE_PGO_DIR}/default.profdata)
endif()
endif()
elseif(MSVC)
# /O2: full optimization, /GL: whole program optimization (MSVC's LTO)
target_compile_options(netgraph_core PRIVATE /O2 /GL)
target_compile_options(_netgraph_core PRIVATE /O2 /GL)
if(NETGRAPH_CORE_FAST_MATH)
target_compile_options(netgraph_core PRIVATE /fp:fast)
target_compile_options(_netgraph_core PRIVATE /fp:fast)
endif()
endif()
endif()
# =============================================================================
# Debug/instrumentation options (mutually exclusive with optimizations above)
# =============================================================================
if(NETGRAPH_CORE_COVERAGE)
message(STATUS "Enabling coverage instrumentation (disables optimizations)")
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
foreach(tgt netgraph_core _netgraph_core)
target_compile_options(${tgt} PRIVATE -O0 -g --coverage)
target_link_options(${tgt} PRIVATE --coverage)
endforeach()
else()
message(WARNING "NETGRAPH_CORE_COVERAGE requires GCC or Clang")
endif()
endif()
if(NETGRAPH_CORE_SANITIZE)
message(STATUS "Enabling sanitizers (disables optimizations)")
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
set(SAN_FLAGS "-fsanitize=address,undefined -fno-omit-frame-pointer")
foreach(tgt netgraph_core _netgraph_core)
target_compile_options(${tgt} PRIVATE ${SAN_FLAGS})
target_link_options(${tgt} PRIVATE ${SAN_FLAGS})
endforeach()
else()
message(WARNING "NETGRAPH_CORE_SANITIZE requires GCC or Clang")
endif()
endif()
# Install
install(TARGETS _netgraph_core
LIBRARY DESTINATION .
RUNTIME DESTINATION .
)