Skip to content

Commit ff85fae

Browse files
committed
Release v0.3.2: Fix ODR violation in profiling
1 parent d0df313 commit ff85fae

6 files changed

Lines changed: 42 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.3.2] - 2025-12-12
9+
10+
### Fixed
11+
12+
- **Profiling**: Fix ODR violation that caused empty stats when profiling was enabled. Moved `profiling_enabled()` and `ProfilingStats::instance()` definitions from inline header to `profiling.cpp` to ensure a single instance when static library is linked into the Python module.
13+
814
## [0.3.1] - 2025-12-08
915

1016
### Added

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ add_library(netgraph_core STATIC
7979
src/flow_graph.cpp
8080
src/flow_policy.cpp
8181
src/cpu_backend.cpp
82+
src/profiling.cpp
8283
)
8384
target_include_directories(netgraph_core PUBLIC
8485
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>

include/netgraph/core/profiling.hpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ From Python:
2424

2525
#include <chrono>
2626
#include <cstdint>
27-
#include <cstdlib>
2827
#include <iostream>
2928
#include <mutex>
3029
#include <string>
@@ -33,21 +32,14 @@ From Python:
3332
namespace netgraph::core {
3433

3534
// Check once at startup, cache result. Returns true if NGRAPH_CORE_PROFILE=1.
36-
inline bool profiling_enabled() noexcept {
37-
static const bool enabled = [] {
38-
const char* env = std::getenv("NGRAPH_CORE_PROFILE");
39-
return env && env[0] == '1';
40-
}();
41-
return enabled;
42-
}
35+
// Defined in profiling.cpp to avoid ODR violations with static library linking.
36+
bool profiling_enabled() noexcept;
4337

4438
// Singleton collecting profiling statistics.
4539
class ProfilingStats {
4640
public:
47-
static ProfilingStats& instance() {
48-
static ProfilingStats inst;
49-
return inst;
50-
}
41+
// Defined in profiling.cpp to avoid ODR violations with static library linking.
42+
static ProfilingStats& instance();
5143

5244
void record(const char* name, double micros) {
5345
std::lock_guard<std::mutex> lock(mutex_);

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
44

55
[project]
66
name = "netgraph-core"
7-
version = "0.3.1"
7+
version = "0.3.2"
88
description = "C++ implementation of graph algorithms for network flow analysis and traffic engineering with Python bindings"
99
readme = "README.md"
1010
requires-python = ">=3.11"

python/netgraph_core/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
__all__ = ["__version__"]
44

5-
__version__ = "0.3.1"
5+
__version__ = "0.3.2"

src/profiling.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
Profiling implementation - singleton definitions.
3+
4+
These are defined in a .cpp file (not inline in the header) to avoid ODR
5+
violations when linking a static library into a shared library (Python module).
6+
With inline definitions, separate static variable instances can exist in each
7+
translation unit, causing profiling data to be recorded in one instance while
8+
being read from another.
9+
*/
10+
#include "netgraph/core/profiling.hpp"
11+
12+
#include <cstdlib>
13+
14+
namespace netgraph::core {
15+
16+
bool profiling_enabled() noexcept {
17+
static const bool enabled = [] {
18+
const char* env = std::getenv("NGRAPH_CORE_PROFILE");
19+
return env && env[0] == '1';
20+
}();
21+
return enabled;
22+
}
23+
24+
ProfilingStats& ProfilingStats::instance() {
25+
static ProfilingStats inst;
26+
return inst;
27+
}
28+
29+
} // namespace netgraph::core

0 commit comments

Comments
 (0)