Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 66 additions & 37 deletions bindings/pyroot/cppyy/CPyCppyy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,95 +15,125 @@ set(headers

set(sources
src/API.cxx
src/CallContext.cxx
src/Converters.cxx
src/CPPClassMethod.cxx
src/CPPConstructor.cxx
src/CPPDataMember.cxx
src/CPPEnum.cxx
src/CPPExcInstance.cxx
src/CPPFunction.cxx
src/CPPGetSetItem.cxx
src/CPPInstance.cxx
src/CPPMethod.cxx
src/CPPOperator.cxx
src/CPPOverload.cxx
src/CPPScope.cxx
src/CPPGetSetItem.cxx
src/CPyCppyyModule.cxx
src/CallContext.cxx
src/Converters.cxx
src/CustomPyTypes.cxx
src/Dispatcher.cxx
src/DispatchPtr.cxx
src/Dispatcher.cxx
src/Executors.cxx
src/LowLevelViews.cxx
src/MemoryRegulator.cxx
src/ProxyWrappers.cxx
src/PyException.cxx
src/PyResult.cxx
src/PyStrings.cxx
src/Pythonize.cxx
src/TemplateProxy.cxx
src/PyException.cxx
src/PyResult.cxx
src/TupleOfInstances.cxx
src/TypeManip.cxx
src/Utility.cxx
)

file(RELATIVE_PATH PYTHONDIR_TO_LIBDIR "${CMAKE_INSTALL_FULL_PYTHONDIR}" "${CMAKE_INSTALL_FULL_LIBDIR}")

set(libname cppyy)

add_library(${libname} SHARED ${headers} ${sources})
add_library(CPyCppyy SHARED ${headers} ${sources})
# Set the suffix to '.so' and the prefix to 'lib'
set_target_properties(${libname} PROPERTIES ${ROOT_LIBRARY_PROPERTIES})
set_target_properties(CPyCppyy PROPERTIES ${ROOT_LIBRARY_PROPERTIES})
target_link_libraries(CPyCppyy PRIVATE Core)
if(MSVC)
target_link_libraries(${libname} PRIVATE cppyy_backend)
target_link_libraries(${libname} PUBLIC Python3::Python)
set_target_properties(${libname} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
set_target_properties(${libname} PROPERTIES PREFIX "lib")
set_target_properties(${libname} PROPERTIES SUFFIX ".pyd")
target_link_libraries(CPyCppyy PRIVATE cppyy_backend)
target_link_libraries(CPyCppyy PUBLIC Python3::Python)
set_target_properties(CPyCppyy PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
elseif(APPLE)
target_link_libraries(${libname} PRIVATE -Wl,-bind_at_load -Wl,-w -Wl,-undefined -Wl,dynamic_lookup cppyy_backend)
target_link_libraries(CPyCppyy PRIVATE -Wl,-bind_at_load -Wl,-w -Wl,-undefined -Wl,dynamic_lookup cppyy_backend)
else()
target_link_libraries(${libname} PRIVATE -Wl,--unresolved-symbols=ignore-all cppyy_backend)
target_link_libraries(CPyCppyy PRIVATE -Wl,--unresolved-symbols=ignore-all cppyy_backend)
endif()

if(NOT MSVC)
target_compile_options(${libname} PRIVATE -Wno-strict-aliasing)
target_compile_options(CPyCppyy PRIVATE -Wno-strict-aliasing)
endif()
if(NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MSVC)
target_compile_options(${libname} PRIVATE
target_compile_options(CPyCppyy PRIVATE
-Wno-unused-but-set-parameter)
endif()


add_library(cppyy SHARED src/CPyCppyyPyModule.cxx)

# Set the suffix to '.so' and the prefix to 'lib'
set_target_properties(cppyy PROPERTIES ${ROOT_LIBRARY_PROPERTIES})
if(MSVC)
target_link_libraries(cppyy PRIVATE CPyCppyy)
set_target_properties(cppyy PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
set_target_properties(cppyy PROPERTIES PREFIX "lib")
set_target_properties(cppyy PROPERTIES SUFFIX ".pyd")
elseif(APPLE)
target_link_libraries(cppyy PRIVATE -Wl,-bind_at_load -Wl,-w -Wl,-undefined -Wl,dynamic_lookup CPyCppyy)
else()
target_link_libraries(cppyy PRIVATE -Wl,--unresolved-symbols=ignore-all CPyCppyy)
endif()

# Avoid warnings due to invalid function casts from C++ functions in CPyCppyy
# to CPython API function typedefs (e.g. PyCFunction). This is a common pattern
# in CPython extension implementations, explicitly encouraged by the official
# CPython docs for C/C++ extensions. see
# https://docs.python.org/3/extending/extending.html#keyword-parameters-for-extension-functions
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(${libname} PRIVATE -Wno-cast-function-type)
target_compile_options(CPyCppyy PRIVATE -Wno-cast-function-type)
endif()

# Disables warnings in Python 3.8 caused by the temporary extra filed for tp_print compatibility
# (see https://github.com/python/cpython/blob/3.8/Include/cpython/object.h#L260).
# Note that Python 3.8 is the lowers Python version that is still supported by
# ROOT, so this compile option can be completely removed soon.
if(NOT MSVC AND Python3_VERSION VERSION_LESS 3.9)
target_compile_options(${libname} PRIVATE -Wno-missing-field-initializers)
target_compile_options(CPyCppyy PRIVATE -Wno-missing-field-initializers)
endif()

target_compile_definitions(${libname} PRIVATE NO_CPPYY_LEGACY_NAMESPACE)
target_compile_definitions(CPyCppyy PRIVATE NO_CPPYY_LEGACY_NAMESPACE)

target_include_directories(${libname}
SYSTEM PUBLIC ${Python3_INCLUDE_DIRS})
target_include_directories(CPyCppyy SYSTEM PUBLIC ${Python3_INCLUDE_DIRS})

target_include_directories(${libname}
PRIVATE
${CMAKE_BINARY_DIR}/ginclude
target_include_directories(CPyCppyy
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

set_property(GLOBAL APPEND PROPERTY ROOT_EXPORTED_TARGETS ${libname})
if(NOT MSVC)
# Make sure that relative RUNPATH to main ROOT libraries is always correct.

file(RELATIVE_PATH pymoduledir_to_libdir_build ${localruntimedir} "${localruntimedir}")
file(RELATIVE_PATH pymoduledir_to_libdir_install ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_PYTHONDIR} "${CMAKE_INSTALL_FULL_LIBDIR}")

if(APPLE)
set_target_properties(cppyy PROPERTIES
BUILD_RPATH "@loader_path/${pymoduledir_to_libdir_build}"
INSTALL_RPATH "@loader_path/${pymoduledir_to_libdir_install}"
)
else()
set_target_properties(cppyy PROPERTIES
BUILD_RPATH "$ORIGIN/${pymoduledir_to_libdir_build}"
INSTALL_RPATH "$ORIGIN/${pymoduledir_to_libdir_install}"
)
endif()

endif()

set_property(GLOBAL APPEND PROPERTY ROOT_EXPORTED_TARGETS CPyCppyy)
set_property(GLOBAL APPEND PROPERTY ROOT_EXPORTED_TARGETS cppyy)

if(NOT MSVC)
# Make sure that relative RUNPATH to main ROOT libraries is always correct.
Expand All @@ -126,18 +156,17 @@ if(NOT MSVC)
endif()

# Install library
install(TARGETS ${libname} EXPORT ${CMAKE_PROJECT_NAME}Exports
install(TARGETS CPyCppyy EXPORT ${CMAKE_PROJECT_NAME}Exports
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libraries
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries)
if (NOT MSVC AND NOT CMAKE_INSTALL_LIBDIR STREQUAL CMAKE_INSTALL_PYTHONDIR)
# add a symlink to ${libname} in CMAKE_INSTALL_PYTHONDIR
set(LIB_FILE_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${libname}.so)
install(CODE "file(CREATE_LINK ${PYTHONDIR_TO_LIBDIR}/${LIB_FILE_NAME}
\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_PYTHONDIR}/${LIB_FILE_NAME} SYMBOLIC)")
endif()

file(COPY ${headers} DESTINATION ${CMAKE_BINARY_DIR}/include/CPyCppyy)
install(TARGETS cppyy EXPORT ${CMAKE_PROJECT_NAME}Exports
RUNTIME DESTINATION ${CMAKE_INSTALL_PYTHONDIR} COMPONENT libraries
LIBRARY DESTINATION ${CMAKE_INSTALL_PYTHONDIR} COMPONENT libraries
ARCHIVE DESTINATION ${CMAKE_INSTALL_PYTHONDIR} COMPONENT libraries)

file(COPY ${headers} DESTINATION ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/CPyCppyy)
install(FILES ${headers}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/CPyCppyy
COMPONENT headers)
47 changes: 23 additions & 24 deletions bindings/pyroot/cppyy/CPyCppyy/src/CPyCppyyModule.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1064,21 +1064,18 @@ static struct PyModuleDef moduledef = {
cpycppyymodule_clear,
nullptr
};
#endif

namespace CPyCppyy {

//----------------------------------------------------------------------------
#define CPYCPPYY_INIT_ERROR return nullptr
extern "C" PyObject* PyInit_libcppyy()
#else
#define CPYCPPYY_INIT_ERROR return
extern "C" void initlibcppyy()
#endif
PyObject* Init()
{
// Initialization of extension module libcppyy.

// load commonly used python strings
if (!CPyCppyy::CreatePyStrings())
CPYCPPYY_INIT_ERROR;
return nullptr;

// setup interpreter
#if PY_VERSION_HEX < 0x03090000
Expand Down Expand Up @@ -1107,7 +1104,7 @@ extern "C" void initlibcppyy()
gThisModule = Py_InitModule(const_cast<char*>("libcppyy"), gCPyCppyyMethods);
#endif
if (!gThisModule)
CPYCPPYY_INIT_ERROR;
return nullptr;

// keep gThisModule, but do not increase its reference count even as it is borrowed,
// or a self-referencing cycle would be created
Expand All @@ -1121,58 +1118,58 @@ extern "C" void initlibcppyy()

// inject meta type
if (!Utility::InitProxy(gThisModule, &CPPScope_Type, "CPPScope"))
CPYCPPYY_INIT_ERROR;
return nullptr;

// inject object proxy type
if (!Utility::InitProxy(gThisModule, &CPPInstance_Type, "CPPInstance"))
CPYCPPYY_INIT_ERROR;
return nullptr;

// inject exception object proxy type
if (!Utility::InitProxy(gThisModule, &CPPExcInstance_Type, "CPPExcInstance"))
CPYCPPYY_INIT_ERROR;
return nullptr;

// inject method proxy type
if (!Utility::InitProxy(gThisModule, &CPPOverload_Type, "CPPOverload"))
CPYCPPYY_INIT_ERROR;
return nullptr;

// inject template proxy type
if (!Utility::InitProxy(gThisModule, &TemplateProxy_Type, "TemplateProxy"))
CPYCPPYY_INIT_ERROR;
return nullptr;

// inject property proxy type
if (!Utility::InitProxy(gThisModule, &CPPDataMember_Type, "CPPDataMember"))
CPYCPPYY_INIT_ERROR;
return nullptr;

// inject custom data types
#if PY_VERSION_HEX < 0x03000000
if (!Utility::InitProxy(gThisModule, &RefFloat_Type, "Double"))
CPYCPPYY_INIT_ERROR;
return nullptr;

if (!Utility::InitProxy(gThisModule, &RefInt_Type, "Long"))
CPYCPPYY_INIT_ERROR;
return nullptr;
#endif

if (!Utility::InitProxy(gThisModule, &CustomInstanceMethod_Type, "InstanceMethod"))
CPYCPPYY_INIT_ERROR;
return nullptr;

if (!Utility::InitProxy(gThisModule, &TupleOfInstances_Type, "InstanceArray"))
CPYCPPYY_INIT_ERROR;
return nullptr;

if (!Utility::InitProxy(gThisModule, &LowLevelView_Type, "LowLevelView"))
CPYCPPYY_INIT_ERROR;
return nullptr;

if (!Utility::InitProxy(gThisModule, &PyNullPtr_t_Type, "nullptr_t"))
CPYCPPYY_INIT_ERROR;
return nullptr;

// custom iterators
if (PyType_Ready(&InstanceArrayIter_Type) < 0)
CPYCPPYY_INIT_ERROR;
return nullptr;

if (PyType_Ready(&IndexIter_Type) < 0)
CPYCPPYY_INIT_ERROR;
return nullptr;

if (PyType_Ready(&VectorIter_Type) < 0)
CPYCPPYY_INIT_ERROR;
return nullptr;

// inject identifiable nullptr and default
gNullPtrObject = (PyObject*)&_CPyCppyy_NullPtrStruct;
Expand Down Expand Up @@ -1209,6 +1206,8 @@ extern "C" void initlibcppyy()

#if PY_VERSION_HEX >= 0x03000000
Py_INCREF(gThisModule);
return gThisModule;
#endif
return gThisModule;
}

} // namespace CPyCppyy
12 changes: 12 additions & 0 deletions bindings/pyroot/cppyy/CPyCppyy/src/CPyCppyyModule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef CPYCPPYY_CPYCPPYYMODULE_H
#define CPYCPPYY_CPYCPPYYMODULE_H

#include "Python.h"

namespace CPyCppyy {

PyObject *Init();

}

#endif // !CPYCPPYY_CPYCPPYYMODULE_H
13 changes: 13 additions & 0 deletions bindings/pyroot/cppyy/CPyCppyy/src/CPyCppyyPyModule.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "CPyCppyyModule.h"

//----------------------------------------------------------------------------
#if PY_VERSION_HEX >= 0x03000000
extern "C" PyObject* PyInit_libcppyy() {
#else
extern "C" void initlibcppyy() {
#endif
PyObject *thisModule = CPyCppyy::Init();
#if PY_VERSION_HEX >= 0x03000000
return thisModule;
#endif
}
5 changes: 1 addition & 4 deletions bindings/pyroot/pythonizations/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ add_dependencies(${libname} ROOTPythonizationsPySources)

# Set the suffix to '.so' and the prefix to 'lib'
set_target_properties(${libname} PROPERTIES ${ROOT_LIBRARY_PROPERTIES_NO_VERSION})
target_link_libraries(${libname} PUBLIC Core Tree cppyy)
target_link_libraries(${libname} PUBLIC Core Tree CPyCppyy)
if(MSVC)
set_target_properties(${libname} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
set_target_properties(${libname} PROPERTIES SUFFIX ".pyd")
Expand All @@ -184,9 +184,6 @@ else()
target_link_libraries(${libname} PUBLIC -Wl,--unresolved-symbols=ignore-all)
endif()

target_include_directories(${libname}
SYSTEM PRIVATE ${Python3_INCLUDE_DIRS})

target_include_directories(${libname}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>)

Expand Down
1 change: 1 addition & 0 deletions bindings/pyroot/pythonizations/test/import_load_libs.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class ImportLoadLibs(unittest.TestCase):
"libresolv",
# cppyy and Python libraries
"libcppyy.*",
"libCPyCppyy.*",
"libROOTPythonizations.*",
"libpython.*",
"libutil.*",
Expand Down
2 changes: 1 addition & 1 deletion bindings/tpython/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ROOT_STANDARD_LIBRARY_PACKAGE(ROOTTPython
DEPENDENCIES
Core
LIBRARIES
cppyy
CPyCppyy
# We link libTPython against Python libraries to compensate for the fact that libcppyy
# is built with unresolved symbols. If we didn't do this, invoking TPython from C++
# would not work.
Expand Down
Loading