diff --git a/RELEASE.md b/RELEASE.md index fbefc6b7..c90a1acc 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -23,6 +23,13 @@ area instead of a single file, so the bindings build in parallel and editing one binding header recompiles only its unit. The module's contents and registration order are unchanged. +- The Python extension is no longer link-time optimized by default. The hot + loops are header templates compiled at ``-O3`` inside the extension and + LTO cannot reach the static ``aare_core``, so it only added a 20 s + single-threaded link and made the binary 15 % smaller. LTO follows the + standard CMake property now: + ``set_property(TARGET _aare PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)`` or + ``-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON`` restores it. ## 2026.9.30 diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 9510a5ab..f53ce76a 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -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 $)