Skip to content

Commit aaffbd8

Browse files
committed
Create target directory structure in installation folder
This allows removing the extra RPATH manipulations in our CPython extensions
1 parent d5868ce commit aaffbd8

File tree

4 files changed

+30
-51
lines changed

4 files changed

+30
-51
lines changed

bindings/pyroot/cppyy/CPyCppyy/CMakeLists.txt

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,6 @@ set(libname cppyy)
5454
add_library(${libname} SHARED ${headers} ${sources})
5555
# Set the suffix to '.so' and the prefix to 'lib'
5656
set_target_properties(${libname} PROPERTIES ${ROOT_LIBRARY_PROPERTIES})
57-
# It is crucial to add the path to the other ROOT libraries for compatibility with pip build backends.
58-
# After the `pip install` step, the target install user directory will look like:
59-
# site-packages/
60-
# -- cppyy/
61-
# -- cppyy_backend/
62-
# -- libcppyy.so
63-
# -- libcppyy_backend.so
64-
# -- libROOTPythonizations.so
65-
# -- ROOT/
66-
# With most of the ROOT libraries being stored in `ROOT/lib`. The RPATH must then be updated for the CPython extension
67-
# shared libraries.
68-
set_target_properties(${libname} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:$ORIGIN/ROOT/lib")
6957
if(MSVC)
7058
target_link_libraries(${libname} PUBLIC cppyy_backend Python3::Python)
7159
set_target_properties(${libname} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)

bindings/pyroot/cppyy/cppyy-backend/CMakeLists.txt

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,13 @@ if(MSVC)
3131
endif()
3232
# Set the suffix to '.so' and the prefix to 'lib'
3333
set_target_properties(${libname} PROPERTIES ${ROOT_LIBRARY_PROPERTIES})
34-
3534
target_link_libraries(${libname} Core ${CMAKE_DL_LIBS})
3635

3736
# cppyy uses ROOT headers from binary directory
3837
add_dependencies(${libname} move_headers)
3938

4039
set_property(GLOBAL APPEND PROPERTY ROOT_EXPORTED_TARGETS ${libname})
4140

42-
# It is crucial to add the path to the other ROOT libraries for compatibility with pip build backends.
43-
# After the `pip install` step, the target install user directory will look like:
44-
# site-packages/
45-
# -- cppyy/
46-
# -- cppyy_backend/
47-
# -- libcppyy.so
48-
# -- libcppyy_backend.so
49-
# -- libROOTPythonizations.so
50-
# -- ROOT/
51-
# With most of the ROOT libraries being stored in `ROOT/lib`. The RPATH must then be updated for the CPython extension
52-
# shared libraries.
5341
if(NOT MSVC)
5442
# Make sure that relative RUNPATH to main ROOT libraries is always correct.
5543

@@ -64,8 +52,7 @@ if(NOT MSVC)
6452
else()
6553
set_target_properties(${libname} PROPERTIES
6654
BUILD_RPATH "$ORIGIN/${pymoduledir_to_libdir_build}"
67-
# ATTENTION: CRUCIAL! See comment above
68-
INSTALL_RPATH "$ORIGIN/${pymoduledir_to_libdir_install}:${CMAKE_INSTALL_RPATH}:$ORIGIN/ROOT/lib"
55+
INSTALL_RPATH "$ORIGIN/${pymoduledir_to_libdir_install}"
6956
)
7057
endif()
7158

bindings/pyroot/pythonizations/CMakeLists.txt

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ add_dependencies(${libname} ROOTPythonizationsPySources)
174174

175175
# Set the suffix to '.so' and the prefix to 'lib'
176176
set_target_properties(${libname} PROPERTIES ${ROOT_LIBRARY_PROPERTIES_NO_VERSION})
177-
target_link_libraries(${libname} PUBLIC ROOT::Core ROOT::Tree cppyy)
177+
target_link_libraries(${libname} PUBLIC Core Tree cppyy)
178178
if(MSVC)
179179
set_target_properties(${libname} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
180180
set_target_properties(${libname} PROPERTIES SUFFIX ".pyd")
@@ -228,18 +228,6 @@ else()
228228
LIBRARY_OUTPUT_DIRECTORY ${pymoduledir_build})
229229
endif()
230230

231-
# It is crucial to add the path to the other ROOT libraries for compatibility with pip build backends.
232-
# After the `pip install` step, the target install user directory will look like:
233-
# site-packages/
234-
# -- cppyy/
235-
# -- cppyy_backend/
236-
# -- libcppyy.so
237-
# -- libcppyy_backend.so
238-
# -- ROOT/
239-
# -- -- libROOTPythonizations.so
240-
# With most of the ROOT libraries being stored in `ROOT/lib`. The RPATH must then be updated for the CPython extension
241-
# shared libraries.
242-
243231
if(NOT MSVC)
244232
# Make sure that relative RUNPATH to main ROOT libraries is always correct.
245233

@@ -254,8 +242,7 @@ if(NOT MSVC)
254242
else()
255243
set_target_properties(${libname} PROPERTIES
256244
BUILD_RPATH "$ORIGIN/${pymoduledir_to_libdir_build}"
257-
# ATTENTION: NEXT PART IS CRUCIAL SEE COMMENT ABOVE
258-
INSTALL_RPATH "$ORIGIN/${pymoduledir_to_libdir_install}:${CMAKE_INSTALL_RPATH}:$ORIGIN/lib"
245+
INSTALL_RPATH "$ORIGIN/${pymoduledir_to_libdir_install}"
259246
)
260247
endif()
261248

setup.py

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
BUILD_DIR = tempfile.mkdtemp()
3737
INSTALL_DIR = tempfile.mkdtemp()
3838

39+
# Name given to an internal directory within the build directory
40+
# used to mimick the structure of the target installation directory
41+
# in the user Python environment, usually named "site-packages"
42+
ROOT_BUILD_INTERNAL_DIRNAME = "mock_site_packages"
43+
3944

4045
class ROOTBuild(_build):
4146
def run(self):
@@ -50,6 +55,12 @@ def run(self):
5055
"-Dbuiltin_lz4=ON -Dbuiltin_lzma=ON -Dbuiltin_zstd=ON -Dbuiltin_xxhash=ON " # builtins
5156
"-Dpyroot=ON -Ddataframe=ON -Dxrootd=ON -Dssl=ON -Dimt=ON "
5257
"-Droofit=ON "
58+
# Next 4 paths represent the structure of the target binaries/headers/libs
59+
# as the target installation directory of the Python environment would expect
60+
f"-DCMAKE_INSTALL_BINDIR={ROOT_BUILD_INTERNAL_DIRNAME}/ROOT/bin "
61+
f"-DCMAKE_INSTALL_INCLUDEDIR={ROOT_BUILD_INTERNAL_DIRNAME}/ROOT/include "
62+
f"-DCMAKE_INSTALL_LIBDIR={ROOT_BUILD_INTERNAL_DIRNAME}/ROOT/lib "
63+
f"-DCMAKE_INSTALL_PYTHONDIR={ROOT_BUILD_INTERNAL_DIRNAME} "
5364
f"-DCMAKE_INSTALL_PREFIX={INSTALL_DIR} -B {BUILD_DIR} -S {SOURCE_DIR}"
5465
)
5566
subprocess.run(configure_command, check=True)
@@ -79,16 +90,22 @@ def run(self):
7990
lib_dir = os.path.join(INSTALL_DIR, "lib")
8091

8192
# Copy ROOT installation tree to the ROOT package directory in the pip installation path
82-
self.copy_tree(INSTALL_DIR, os.path.join(install_path, "ROOT"))
83-
84-
# Copy cppyy packages separately
85-
self.copy_tree(os.path.join(lib_dir, "cppyy"), os.path.join(install_path, "cppyy"))
86-
self.copy_tree(os.path.join(lib_dir, "cppyy_backend"), os.path.join(install_path, "cppyy_backend"))
87-
88-
# Finally copy CPython extension libraries
89-
self.copy_file(os.path.join(lib_dir, "libcppyy.so"), install_path)
90-
self.copy_file(os.path.join(lib_dir, "libcppyy_backend.so"), install_path)
91-
self.copy_file(os.path.join(lib_dir, "ROOT", "libROOTPythonizations.so"), os.path.join(install_path, "ROOT"))
93+
self.copy_tree(os.path.join(INSTALL_DIR, ROOT_BUILD_INTERNAL_DIRNAME), install_path)
94+
95+
root_package_dir = os.path.join(install_path, "ROOT")
96+
97+
# After the copy of the "mock" package structure from the ROOT installations, these are the
98+
# leftover directories that still need to be copied
99+
self.copy_tree(os.path.join(INSTALL_DIR, "cmake"), os.path.join(root_package_dir, "cmake"))
100+
self.copy_tree(os.path.join(INSTALL_DIR, "config"), os.path.join(root_package_dir, "config"))
101+
self.copy_tree(os.path.join(INSTALL_DIR, "etc"), os.path.join(root_package_dir, "etc"))
102+
self.copy_tree(os.path.join(INSTALL_DIR, "fonts"), os.path.join(root_package_dir, "fonts"))
103+
self.copy_tree(os.path.join(INSTALL_DIR, "icons"), os.path.join(root_package_dir, "icons"))
104+
self.copy_tree(os.path.join(INSTALL_DIR, "macros"), os.path.join(root_package_dir, "macros"))
105+
self.copy_tree(os.path.join(INSTALL_DIR, "man"), os.path.join(root_package_dir, "man"))
106+
self.copy_tree(os.path.join(INSTALL_DIR, "README"), os.path.join(root_package_dir, "README"))
107+
self.copy_tree(os.path.join(INSTALL_DIR, "tutorials"), os.path.join(root_package_dir, "tutorials"))
108+
self.copy_file(os.path.join(INSTALL_DIR, "LICENSE"), os.path.join(root_package_dir, "LICENSE"))
92109

93110
def get_outputs(self):
94111
outputs = _install.get_outputs(self)

0 commit comments

Comments
 (0)