Build the python extension without pybind11's forced LTO

pybind11_add_module links pybind11::lto, which adds full -flto to the
extension and ignores the target's INTERPROCEDURAL_OPTIMIZATION property.
That link ran single-threaded for 19-22 s and was the longest step of the
build. LTO cannot reach aare_core (a plain static library) and the hot
loops are header templates compiled at -O3 inside the extension anyway.

Pass NO_EXTRAS so the standard CMake property decides (off by default),
and re-add the extras pybind11 would have applied: pybind11_strip for
optimized builds and pybind11::windows_extras (/bigobj, /MP) on MSVC.
set_property(TARGET _aare PROPERTY INTERPROCEDURAL_OPTIMIZATION ON) or
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON brings LTO back as ThinLTO.

Measured on a clean Release build with tests: 42 s -> 28 s, extension
link 19 s -> 0.1 s, exports identical, all tests pass. The stripped
binary grows from 4.7 MB to 5.6 MB. Pedestal, eta and the aare_core code
paths (fits, calibration, decoding) run at the same speed; the
ClusterFinder micro-benchmark is consistently 1-2 % slower without LTO.
This commit is contained in:
Erik Fröjdh committed 2026-10-06 22:02:15 +02:00
1 parent 89b7a9ef20
commit b40727ebdc
2 files changed
+25

No files matched your search

+18
View File
@@ -20,8 +20,16 @@ endif()
# The compiled python extension: one translation unit per binding area so they
# compile in parallel; see src/module.cpp for the registration order.
#
# Without NO_EXTRAS pybind11 links pybind11::lto, which forces full LTO on the
# extension regardless of the target's INTERPROCEDURAL_OPTIMIZATION property.
# LTO cannot reach aare_core (a plain static library) and the templated hot
# paths are already compiled at -O3 inside the extension, so it only adds a long
# single-threaded link step. With NO_EXTRAS the standard target property decides
# (off by default); the other extras are re-added below.
pybind11_add_module(
_aare # name of the module
NO_EXTRAS
src/module.cpp
src/bind_io.cpp
src/bind_hist.cpp
@@ -38,6 +46,16 @@ set_target_properties(_aare PROPERTIES LIBRARY_OUTPUT_DIRECTORY
${CMAKE_BINARY_DIR})
target_link_libraries(_aare PRIVATE aare_core aare_compiler_flags)
# The pybind11_add_module extras that NO_EXTRAS skipped, LTO excepted
if(MSVC)
target_link_libraries(_aare PRIVATE pybind11::windows_extras) # /bigobj, /MP
elseif(CMAKE_BUILD_TYPE)
string(TOUPPER "${CMAKE_BUILD_TYPE}" _aare_build_type)
if(NOT _aare_build_type MATCHES "DEBUG|RELWITHDEBINFO|NONE")
pybind11_strip(_aare) # strip symbols from optimized builds
endif()
endif()
target_include_directories(
_aare SYSTEM
PRIVATE $<TARGET_PROPERTY:aare::Minuit2,INTERFACE_INCLUDE_DIRECTORIES>)