Open maichmueller opened 9 months ago
I tested out some more configurations and noticed that if I completely remove fmt
from the repo, then libfancyCppyy
will compile, but the linker even throws errors:
[0/2] Re-checking globbed directories...
[3/7] Generating fancy/fancy.map
CRITICAL: While parsing: /Users/maichmueller/GitHub/fanciful/src/libfancy/include/fancy/formatter.hpp:3[10] 'vector' file not found
[4/7] Generating fancy.cpp, fancy/libfancyCppyy.rootmap, fancy/libfancyCppyy_rdict.pcm
Warning: Unused class rule: fancy::TemplateVectorFormatter<*>
[6/7] Linking CXX shared library fancy/libfancyCppyy.dylib
FAILED: fancy/libfancyCppyy.dylib
: && /Library/Developer/CommandLineTools/usr/bin/c++ -stdlib=libc++ -O3 -DNDEBUG -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -dynamiclib -Wl,-headerpad_max_install_names -o fancy/libfancyCppyy.dylib -install_name @rpath/libfancyCppyy.dylib CMakeFiles/fancyCppyy.dir/fancy.cpp.o -Wl,-rpath,/Users/maichmueller/miniconda3/envs/cppyy/lib/python3.10/site-packages/cppyy_backend/lib -Wl,-rpath,/Users/maichmueller/GitHub/fanciful/cmake-build-release-on-build /Users/maichmueller/miniconda3/envs/cppyy/lib/python3.10/site-packages/cppyy_backend/lib/libCling.so libfancy_shared.dylib && :
ld: Undefined symbols:
CppyyLegacy::TVersionCheck::TVersionCheck(int), referenced from:
__GLOBAL__sub_I_fancy.cpp in fancy.cpp.o
CppyyLegacy::TGenericClassInfo::SetDestructor(void (*)(void*)), referenced from:
CppyyLegacy::GenerateInitInstanceLocal(fancy::VectorFormatter const*) in fancy.cpp.o
CppyyLegacy::TGenericClassInfo::SetDeleteArray(void (*)(void*)), referenced from:
CppyyLegacy::GenerateInitInstanceLocal(fancy::VectorFormatter const*) in fancy.cpp.o
CppyyLegacy::TGenericClassInfo::GetClass(), referenced from:
CppyyLegacy::fancycLcLVectorFormatter_Dictionary() in fancy.cpp.o
CppyyLegacy::TGenericClassInfo::SetDelete(void (*)(void*)), referenced from:
CppyyLegacy::GenerateInitInstanceLocal(fancy::VectorFormatter const*) in fancy.cpp.o
CppyyLegacy::TGenericClassInfo::TGenericClassInfo(char const*, char const*, int, std::type_info const&, CppyyLegacy::Internal::TInitBehavior const*, CppyyLegacy::TClass* (*)(), CppyyLegacy::TVirtualIsAProxy*, int, int), referenced from:
CppyyLegacy::GenerateInitInstanceLocal(fancy::VectorFormatter const*) in fancy.cpp.o
CppyyLegacy::TGenericClassInfo::~TGenericClassInfo(), referenced from:
CppyyLegacy::GenerateInitInstanceLocal(fancy::VectorFormatter const*) in fancy.cpp.o
CppyyLegacy::TROOT::RegisterModule(char const*, char const**, char const**, char const*, char const*, void (*)(), std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, int>>> const&, char const**, bool), referenced from:
(anonymous namespace)::TriggerDictionaryInitialization_libfancyCppyy_Impl() in fancy.cpp.o
CppyyLegacy::Internal::DefineBehavior(void*, void*), referenced from:
CppyyLegacy::GenerateInitInstanceLocal(fancy::VectorFormatter const*) in fancy.cpp.o
CppyyLegacy::TIsAProxy::TIsAProxy(std::type_info const&), referenced from:
CppyyLegacy::GenerateInitInstanceLocal(fancy::VectorFormatter const*) in fancy.cpp.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
I don't know where these symbols are normally found. I cannot figure out what is still broken exactly in this setup...
Since the documentation on how to marry cppyy with a cmake project is a little sparse,
Yes, the cmake
based code was contributed and I'm not familiar enough with cmake
to clean up some of its rough edges. It also generates modules that force bindings to most C++ entities, mostly for the benefit of dir()
and tab-completion (although cppyy's support for both has significantly improved since), which I consider wasteful. Additionally, to create the modules to force those bindings, libclang
is used to parse the headers, adding that additional dependency.
Although NWChemEx does not currently use cppyy anymore, it's cmake files off a better start: https://github.com/NWChemEx/NWXCMake/tree/master/cmake
cppyy conda env
Interesting, I wasn't aware that the conda folks had updated to 3.1.2. I thought they had remaining issues, but apparently those are for ARM and PPC.
build error log
Can you run with VERBOSE=1
to see the full rootcling
command? I suspect that it, too, needs to have the include headers handed to it (using -I
).
The last set of symbols are defined in the C++ code that rootcling generates. Here, too, it would be useful to run with VERSBOSE=1
to see the full linker command.
Hi,
first of thanks for this library! It is exactly what I am looking for to wrap some of my (template) heavy code for easy use in python. Alas, I cannot get it to work with existing CMake based projects and hope I can get some help here on how to get this to work reliably.
Since the documentation on how to marry cppyy with a cmake project is a little sparse, I relied on Camille Scotts's template for doing just that with some minor adaptations (this template is the basis for some of the repos mentioned in the documentation that use cppyy).
To showcase my attempts I have setup an example repo using this template. I will try to explain this repo quickly...
My process aims to build a single shared lib cmake target
fancy_shared
which links againstfmt
and is then wrapped by cppyy. External dependencies are loaded withConan
, i.efmt
as a static lib. I provide two header filesformatter.hpp
and a collector headerfancy.hpp
which merely includesformatter.hpp
. I provide a single cpp implementation fileformatter.cpp
. The cmake configuration shows:CMakeLists.txt essential details
``` find_package(fmt REQUIRED) add_library( fancy_shared SHARED ${PROJECT_SRC_DIR}/libfancy/impl/formatter.cpp ) set_target_properties( fancy_shared PROPERTIES LINKER_LANGUAGE CXX ) target_include_directories( fancy_shared PUBLIC ${PROJECT_SRC_DIR}/libfancy/include ) target_link_libraries( fancy_shared PUBLIC fmt::fmt ) set( BINDING_HEADERS formatter.hpp fancy.hpp ) list(TRANSFORM BINDING_HEADERS PREPEND "${PROJECT_SRC_DIR}/libfancy/include/fancy") cppyy_add_bindings( "fancy" "${PROJECT_VERSION}" "Michael Aichmueller" "m.aichmueller@gmail.com" LICENSE "MIT" LANGUAGE_STANDARD "20" SELECTION_XML ${CMAKE_SOURCE_DIR}/py/selection.xml INTERFACE_FILE ${CMAKE_SOURCE_DIR}/py/interface.hpp HEADERS ${BINDING_HEADERS} INCLUDE_DIRS #nothing here since linking against fancy_shared should propagate all relevant include directories LINK_LIBRARIES fancy_shared NAMESPACES fancy README_FILE README.md ) ```Since the template relies on a conda env to find and configure all the cppyy dependencies I do that as well:
The env list this builds on my system can be found here:
cppyy conda env
| Name | Version | Build | Channel | |--------------------|-----------|-------------------------|--------------------------------------| | bzip2 | 1.0.8 | h620ffc9_4 | | | ca-certificates | 2023.12.12| hca03da5_0 | | | certifi | 2023.11.17| pypi_0 | pypi | | charset-normalizer | 3.3.2 | pypi_0 | pypi | | colorama | 0.4.6 | pypi_0 | pypi | | conan | 2.0.14 | pypi_0 | pypi | | cppyy | 3.1.2 | pypi_0 | pypi | | cppyy-backend | 1.15.2 | pypi_0 | pypi | | cppyy-cling | 6.30.0 | pypi_0 | pypi | | cpycppyy | 1.12.16 | pypi_0 | pypi | | fasteners | 0.19 | pypi_0 | pypi | | idna | 3.6 | pypi_0 | pypi | | jinja2 | 3.1.2 | pypi_0 | pypi | | libclang | 14.0.6 | default_h1b80db6_1 | | | libclang13 | 14.0.6 | default_h24352ff_1 | | | libcxx | 14.0.6 | h848a8c0_0 | | | libffi | 3.4.4 | hca03da5_0 | | | libllvm14 | 14.0.6 | h7ec7a93_3 | | | markupsafe | 2.1.3 | pypi_0 | pypi | | ncurses | 6.4 | h313beb8_0 | | | openssl | 3.0.12 | h1a28f6b_0 | | | patch-ng | 1.17.4 | pypi_0 | pypi | | pip | 23.3.1 | py310hca03da5_0 | | | python | 3.10.13 | hb885b13_0 | | | python-clang | 14.0.6 | default_py310h2b98e1d_1 | | | python-dateutil | 2.8.2 | pypi_0 | pypi | | pyyaml | 6.0.1 | pypi_0 | pypi | | readline | 8.2 | h1a28f6b_0 | | | requests | 2.31.0 | pypi_0 | pypi | | setuptools | 68.2.2 | py310hca03da5_0 | | | six | 1.16.0 | pypi_0 | pypi | | sqlite | 3.41.2 | h80987f9_0 | | | tk | 8.6.12 | hb8d0fd4_0 | | | tzdata | 2023c | h04d1e81_0 | | | urllib3 | 1.26.18 | pypi_0 | pypi | | wheel | 0.41.2 | py310hca03da5_0 | | | xz | 5.4.5 | h80987f9_0 | | | zlib | 1.2.13 | h5a0b063_0 | |I fought a long battle with this setup and using
cmake-conan
wrappers to call the conan install commands, only to realize that they interfere somehow with finding the necessary cppyy Packages. So I ended up creating aconfigure.bash
script andbuild.bash
script to do what their names suggest manually. Running the shell scripts works well, all cppyy libs are found! Unfortunately, this is where the build runs into the first obstacle:build error log
``` ╰─ ./build.bash ─╯ [ 14%] Building CXX object CMakeFiles/fancy_shared.dir/src/libfancy/impl/formatter.cpp.o [ 28%] Linking CXX shared library libfancy_shared.dylib [ 28%] Built target fancy_shared [ 42%] Generating fancy.cpp, fancy/libfancyCppyy.rootmap, fancy/libfancyCppyy_rdict.pcm In file included from input_line_7:3: /Users/maichmueller/GitHub/fanciful/py/interface.hpp:1:10: fatal error: 'fancy/fancy.hpp' file not found #include "fancy/fancy.hpp" ^~~~~~~~~~~~~~~~~ Error: rootcling: compilation failure (./libfancyCppyy578970b8bd_dictUmbrella.h) make[3]: *** [fancy.cpp] Error 1 make[2]: *** [CMakeFiles/fancyCppyy.dir/all] Error 2 make[1]: *** [CMakeFiles/wheel.dir/rule] Error 2 make: *** [wheel] Error 2 ```My first question is: Since
fancy_shared
builds correctly, all relevant header files are included in this target. Linking against a cmake target which includes directories publicly propagates these directories, so shouldn't the targetfancyCppyy
(which is configured bycppyy_add_bindings
) receive this propagation here as well?Even if I don't understand why it is necessary, I can simply provide these directories again to hopefully make it compile:
but to no avail either :( ...
build error log
``` [ 42%] Generating fancy.cpp, fancy/libfancyCppyy.rootmap, fancy/libfancyCppyy_rdict.pcm In file included from input_line_7:3: In file included from /Users/maichmueller/GitHub/fanciful/py/interface.hpp:1: In file included from /Users/maichmueller/GitHub/fanciful/src/libfancy/include/fancy/fancy.hpp:3: /Users/maichmueller/GitHub/fanciful/src/libfancy/include/fancy/formatter.hpp:4:10: fatal error: 'fmt/format.h' file not found #includefmt
is not found bylibfancyCppyy
althoughlibfancy
finds it. Yet, alsodoes not change the error message of not finding the format headers either. Changing to
Ninja
as generator also reveals clearly that both thefmt
include directory as well as thefancy
include dirs are definitely included in the compilation call:Ninja build error log
``` [1/4] Generating fancy.cpp, fancy/libfancyCppyy.rootmap, fancy/libfancyCppyy_rdict.pcm FAILED: fancy.cpp fancy/libfancyCppyy.rootmap fancy/libfancyCppyy_rdict.pcm /Users/maichmueller/GitHub/fanciful/cmake-build-release-on-build/fancy.cpp /Users/maichmueller/GitHub/fanciful/cmake-build-release-on-build/fancy/libfancyCppyy.rootmap /Users/maichmueller/GitHub/fanciful/cmake-build-release-on-build/fancy/libfancyCppyy_rdict.pcm cd /Users/maichmueller/GitHub/fanciful/cmake-build-release-on-build/fancy && /Users/maichmueller/miniconda3/envs/cppyy/bin/genreflex /Users/maichmueller/GitHub/fanciful/py/interface.hpp --selection=/Users/maichmueller/GitHub/fanciful/py/selection.xml -o /Users/maichmueller/GitHub/fanciful/cmake-build-release-on-build/fancy.cpp --rootmap=/Users/maichmueller/GitHub/fanciful/cmake-build-release-on-build/fancy/libfancyCppyy.rootmap --rootmap-lib=libfancyCppyy.dylib -l libfancyCppyy.dylib -I/Users/maichmueller/GitHub/fanciful/src/libfancy/include;/Users/maichmueller/.conan2/p/b/fmtd0efce1662886/p/include --cxxflags -std=c++20 In file included from input_line_7:3: In file included from /Users/maichmueller/GitHub/fanciful/py/interface.hpp:1: In file included from /Users/maichmueller/GitHub/fanciful/src/libfancy/include/fancy/fancy.hpp:3: /Users/maichmueller/GitHub/fanciful/src/libfancy/include/fancy/formatter.hpp:5:10: fatal error: 'fmt/format.h' file not found #includeNotice the
-I/Users/maichmueller/GitHub/fanciful/src/libfancy/include;/Users/maichmueller/.conan2/p/b/fmtd0efce1662886/p/include
.The last line, rootcling 's complaint that the include directory of
fmt
is - in fact - a directory, is also mysterious to me. This is where I am lost without more insight into how rootlcing operates.This all is happening on Apple Silicon M2 using macos 14.1. However, I am running into the same (and more) trouble on an amd64 linux setup with the same process.
Any help on what I am doing wrong would be greatly appreciated!