From 529947e1c1a0f9c0cc82e3c7abe96bbfb4e5e039 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Thu, 27 May 2021 21:16:20 -0500 Subject: [PATCH 1/2] Removed DPCLSyclInterface library from MANIFEST.in Manifest is meant for source distributions, and binary libraries does not belong there. Added custom build_py step to copy shared object library from install/ to build_lib folder (build/lib.cpython-..../dpctl) Added custom post-build step to install command to remove hard links of versioned shared object library on linux, and recopy them from build_lib to installation folder. --- MANIFEST.in | 1 - setup.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 60dea3c369..d2fa8a807f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,5 +7,4 @@ include dpctl/_sycl_queue.h include dpctl/_sycl_queue_manager.h include dpctl/_sycl_event.h include dpctl/memory/_memory.h -include dpctl/*DPCTL*Interface.* include dpctl/tests/input_files/* diff --git a/setup.py b/setup.py index 8d885964eb..488dbe5835 100644 --- a/setup.py +++ b/setup.py @@ -17,11 +17,14 @@ import os import os.path import sys +import glob +import shutil import numpy as np import setuptools.command.build_ext as orig_build_ext import setuptools.command.develop as orig_develop import setuptools.command.install as orig_install +import setuptools.command.build_py as orig_build_py from Cython.Build import cythonize from setuptools import Extension, find_packages, setup @@ -251,6 +254,39 @@ def run(self): return super().run() +class build_py(orig_build_py.build_py): + def run(self): + dpctl_src_dir = self.get_package_dir("dpctl") + dpctl_build_dir = os.path.join(self.build_lib, "dpctl") + os.makedirs(dpctl_build_dir, exist_ok=True) + if IS_LIN: + for fn in glob.glob( + os.path.join(dpctl_src_dir, "*.so*") + ): + # Check if the file already exists before copying. The check is + # needed when dealing with symlinks. + if not os.path.exists( + os.path.join(dpctl_build_dir, os.path.basename(fn)) + ): + shutil.copy( + src=fn, + dst=dpctl_build_dir, + follow_symlinks=False, + ) + elif IS_WIN: + for fn in glob.glob( + os.path.join(dpctl_src_dir, "*.lib") + ): + shutil.copy(src=fn, dst=dpctl_build_dir) + + for fn in glob.glob( + os.path.join(dpctl_src_dir, "*.dll") + ): + shutil.copy(src=fn, dst=dpctl_build_dir) + else: + raise NotImplementedError("Unsupported platform") + return super().run() + class install(orig_install.install): description = "Installs dpctl into Python prefix" user_options = orig_install.install.user_options + [ @@ -308,7 +344,24 @@ def run(self): else: self.define = ",".join((pre_d, "CYTHON_TRACE")) cythonize(self.distribution.ext_modules) - return super().run() + ret = super().run() + if IS_LIN: + dpctl_build_dir = os.path.join( + os.path.dirname(__file__), + self.build_lib, + "dpctl" + ) + dpctl_install_dir = os.path.join(self.install_libbase, "dpctl") + for fn in glob.glob( + os.path.join(dpctl_install_dir, "*DPCTLSyclInterface.so*") + ): + os.remove(fn) + shutil.copy( + src=os.path.join(dpctl_build_dir, os.path.basename(fn)), + dst=dpctl_install_dir, + follow_symlinks=False, + ) + return ret class develop(orig_develop.develop): @@ -393,6 +446,7 @@ def _get_cmdclass(): cmdclass["install"] = install cmdclass["develop"] = develop cmdclass["build_ext"] = build_ext + cmdclass["build_py"] = build_py return cmdclass From bc4b92471cc3b0eb8cd931d9ba3ec9b75e1276d6 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Thu, 27 May 2021 21:18:57 -0500 Subject: [PATCH 2/2] Reenabled so-versioning now that setup.py has been tweaked to handle symlinks --- dpctl-capi/CMakeLists.txt | 22 +++++++++++----------- setup.py | 27 ++++++++++----------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/dpctl-capi/CMakeLists.txt b/dpctl-capi/CMakeLists.txt index 04e14892e5..77891d6ee7 100644 --- a/dpctl-capi/CMakeLists.txt +++ b/dpctl-capi/CMakeLists.txt @@ -151,6 +151,17 @@ target_link_libraries(DPCTLSyclInterface PRIVATE ${IntelSycl_OPENCL_LIBRARY} ) +include(GetProjectVersion) +# the get_version function is defined in the GetProjectVersion module and +# defines: VERSION, SEMVER, MAJOR, MINOR, PATCH. These variables are populated +# by parsing the output of git describe. +get_version() +set_target_properties(DPCTLSyclInterface + PROPERTIES + VERSION ${VERSION_MAJOR}.${VERSION_MINOR} + SOVERSION ${VERSION_MAJOR} +) + if(DPCTL_ENABLE_LO_PROGRAM_CREATION) target_include_directories(DPCTLSyclInterface PRIVATE @@ -158,17 +169,6 @@ if(DPCTL_ENABLE_LO_PROGRAM_CREATION) ) endif() -# FIXME: Turning off for release until conda build can be packaging symbolic links -# NOTE: Till we hit 1.0.0 we will keep using the MINOR version to set the API -# version of the library. -# include(GetProjectVersion) -# the get_version function is defined in the GetProjectVersion module and -# defines: VERSION, SEMVER, MAJOR, MINOR, PATCH. These variables are populated -# by parsing the output of git describe. -# get_version() -# set_target_properties(DPCTLSyclInterface PROPERTIES VERSION ${VERSION_MINOR}) -# set_target_properties(DPCTLSyclInterface PROPERTIES SOVERSION 1) - install(TARGETS DPCTLSyclInterface LIBRARY diff --git a/setup.py b/setup.py index 488dbe5835..7ac57e2de1 100644 --- a/setup.py +++ b/setup.py @@ -14,17 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +import glob import os import os.path -import sys -import glob import shutil +import sys import numpy as np import setuptools.command.build_ext as orig_build_ext +import setuptools.command.build_py as orig_build_py import setuptools.command.develop as orig_develop import setuptools.command.install as orig_install -import setuptools.command.build_py as orig_build_py from Cython.Build import cythonize from setuptools import Extension, find_packages, setup @@ -260,13 +260,11 @@ def run(self): dpctl_build_dir = os.path.join(self.build_lib, "dpctl") os.makedirs(dpctl_build_dir, exist_ok=True) if IS_LIN: - for fn in glob.glob( - os.path.join(dpctl_src_dir, "*.so*") - ): + for fn in glob.glob(os.path.join(dpctl_src_dir, "*.so*")): # Check if the file already exists before copying. The check is # needed when dealing with symlinks. if not os.path.exists( - os.path.join(dpctl_build_dir, os.path.basename(fn)) + os.path.join(dpctl_build_dir, os.path.basename(fn)) ): shutil.copy( src=fn, @@ -274,19 +272,16 @@ def run(self): follow_symlinks=False, ) elif IS_WIN: - for fn in glob.glob( - os.path.join(dpctl_src_dir, "*.lib") - ): + for fn in glob.glob(os.path.join(dpctl_src_dir, "*.lib")): shutil.copy(src=fn, dst=dpctl_build_dir) - for fn in glob.glob( - os.path.join(dpctl_src_dir, "*.dll") - ): + for fn in glob.glob(os.path.join(dpctl_src_dir, "*.dll")): shutil.copy(src=fn, dst=dpctl_build_dir) else: raise NotImplementedError("Unsupported platform") return super().run() + class install(orig_install.install): description = "Installs dpctl into Python prefix" user_options = orig_install.install.user_options + [ @@ -347,13 +342,11 @@ def run(self): ret = super().run() if IS_LIN: dpctl_build_dir = os.path.join( - os.path.dirname(__file__), - self.build_lib, - "dpctl" + os.path.dirname(__file__), self.build_lib, "dpctl" ) dpctl_install_dir = os.path.join(self.install_libbase, "dpctl") for fn in glob.glob( - os.path.join(dpctl_install_dir, "*DPCTLSyclInterface.so*") + os.path.join(dpctl_install_dir, "*DPCTLSyclInterface.so*") ): os.remove(fn) shutil.copy(