Open matthewfeickert opened 1 week ago
Also maybe worth noting that if I change the CMakeLists.txt
for nanobind
from using NB_STATIC
nanobind_add_module(
# Name of the extension
nanobind_example_ext
# Target the stable ABI for Python 3.12+, which reduces
# the number of binary wheels that must be built. This
# does nothing on older Python versions
STABLE_ABI
# Build libnanobind statically and merge it into the
# extension (which itself remains a shared library)
#
# If your project builds multiple extensions, you can
# replace this flag by NB_SHARED to conserve space by
# reusing a shared libnanobind across libraries
NB_STATIC
# Source code goes here
"${CMAKE_CURRENT_SOURCE_DIR}/src/nanobind_example_ext.cpp"
)
to NB_SHARED
nanobind_add_module(
# Name of the extension
nanobind_example_ext
# Target the stable ABI for Python 3.12+, which reduces
# the number of binary wheels that must be built. This
# does nothing on older Python versions
STABLE_ABI
# Build libnanobind statically and merge it into the
# extension (which itself remains a shared library)
#
# If your project builds multiple extensions, you can
# replace this flag by NB_SHARED to conserve space by
# reusing a shared libnanobind across libraries
NB_SHARED
# Source code goes here
"${CMAKE_CURRENT_SOURCE_DIR}/src/nanobind_example_ext.cpp"
)
that I hit undefined references earlier on in the build
...
[ 88%] Linking CXX shared library ../x86_64-el9-gcc13-opt/lib/libnanobind.so
/opt/lcg/binutils/2.40-acaab/x86_64-el9/bin/ld: CMakeFiles/nanobind.dir/usr/AnalysisBaseExternals/25.2.30/InstallArea/x86_64-el9-gcc13-opt/lib/python3.11/site-packages/nanobind/src/nb_internals.cpp.o: in function `nanobind::detail::init(char const*)':
/usr/AnalysisBaseExternals/25.2.30/InstallArea/x86_64-el9-gcc13-opt/lib/python3.11/site-packages/nanobind/src/nb_internals.cpp:351: undefined reference to `PyInterpreterState_Get'
/opt/lcg/binutils/2.40-acaab/x86_64-el9/bin/ld: /usr/AnalysisBaseExternals/25.2.30/InstallArea/x86_64-el9-gcc13-opt/lib/python3.11/site-packages/nanobind/src/nb_internals.cpp:351: undefined reference to `PyInterpreterState_GetDict'
/opt/lcg/binutils/2.40-acaab/x86_64-el9/bin/ld: /usr/AnalysisBaseExternals/25.2.30/InstallArea/x86_64-el9-gcc13-opt/lib/python3.11/site-packages/nanobind/src/nb_internals.cpp:355: undefined reference to `PyUnicode_FromFormat'
/opt/lcg/binutils/2.40-acaab/x86_64-el9/bin/ld: /usr/AnalysisBaseExternals/25.2.30/InstallArea/x86_64-el9-gcc13-opt/lib/python3.11/site-packages/nanobind/src/nb_internals.cpp:359: undefined reference to `PyDict_GetItem'
/opt/lcg/binutils/2.40-acaab/x86_64-el9/bin/ld: /usr/AnalysisBaseExternals/25.2.30/InstallArea/x86_64-el9-gcc13-opt/lib/python3.11/site-packages/nanobind/src/nb_internals.cpp:362: undefined reference to `PyCapsule_GetPointer'
...
Maybe related: Library order in static linking (2013-07-09)
As @nilserik78 suggested seeing the actual command being given by enabling the CMake command CMAKE_VERBOSE_MAKEFILE=ON
for:
and for
So the explicit linking commands that work and fail (selected from the text above) are:
/opt/lcg/gcc/13.1.0-b3d18/x86_64-el9/bin/g++ -fPIC -O3 -DNDEBUG -Wl,-s -Wl,--gc-sections -shared -o nanobind_example_ext.cpython-311-x86_64-linux-gnu.so CMakeFiles/nanobind_example_ext.dir/src/nanobind_example_ext.cpp.o libnanobind-static.a
/opt/lcg/gcc/13.1.0-b3d18/x86_64-el9/bin/g++ -fPIC -march=x86-64-v2 -DNDEBUG -O2 -g -Wall -Wno-long-long -Wno-deprecated -Wno-unused-local-typedefs -Wwrite-strings -Wpointer-arith -Woverloaded-virtual -Wextra -Werror=return-type -pedantic -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined -Wl,-z,max-page-size=0x1000 -Wl,--hash-style=both -shared -o ../x86_64-el9-gcc13-opt/lib/nanobind_example_ext.cpython-311-x86_64-linux-gnu.so CMakeFiles/nanobind_example_ext.dir/src/nanobind_example_ext.cpp.o ../x86_64-el9-gcc13-opt/lib/libnanobind-static.a
I'll note that the failing ATLAS CMake linking has -Wl,--no-undefined
. Off the top of my head, I assume that if you want to edit CXXFLAGS
you need to catch them in a CMake variable, then manually edit them, and then reassign the CMake variable, or something like that.
After discussing with @nilserik78 today, I revised this repository to show multiple examples and then an issue.
As of https://github.com/matthewfeickert/atlas-cmake-nanobind-example/commit/9c812d48b94f427cdf010694406cba44c29137ac:
normal_cmake
directory there is thenanobind
simple example from the docs that builds and works fine with normal CMake and can be built withbuild_normal_cmake.sh
.atlas_cmake
directory there is a simple C++ library and program example (based off of @henryiii'ssimple-example
from his CMake book) that is structured to work with ATLAS CMake's structure. Namely:CMakeLists.txt
for the entire project (located atatlas_cmake/Projects/WorkDir
).package_filters.txt
that is passed to ATLAS CMake as theATLAS_PACKAGE_FILTER_FILE
CMake argument.CMakeLists.txt
for subprojects usingatlas_subdir
instead ofproject
.However, on the
feat/get-nanobind-example-working
branch, if I try to take thenanobind
docs example and naively port it over to build with ATLAS CMake then I get linking errors.The attached log is from running
(build_atlas_cmake_error.txt) and as can be seen from this snippet,
nanobind
exists and is found, but the linking goes very wrong with lots of undefined references to CPython's C-API exceptionsI haven't fully dug in here, but general advice and debugging suggestions would be welcome.
cc @kratsg @ekourlit @henryiii @lukasheinrich @nikoladze @jpivarski @Moelf @alexander-held