66
77import os
88import re
9- import shutil
109import subprocess
1110import sys
1211import tempfile
1615
1716
1817# Extract the project version from CMake generated ABI header.
19- # NOTE: When droping support for Python2 we can use
20- # tempfile.TemporaryDirectory() context manager instead of try...finally.
2118def get_version ():
2219 VERSION_REGEX = re .compile (
2320 r"^\s*#\s*define\s+OCIO_VERSION_FULL_STR\s+\"(.*)\"\s*$" , re .MULTILINE )
2421
2522 here = os .path .abspath (os .path .dirname (__file__ ))
26- dirpath = tempfile .mkdtemp ()
27-
28- try :
29- stdout = subprocess .check_output (["cmake" , here ], cwd = dirpath )
30- path = os .path .join (dirpath , "include" , "OpenColorIO" , "OpenColorABI.h" )
31- with open (path ) as f :
32- match = VERSION_REGEX .search (f .read ())
33- return match .group (1 )
34- except Exception as e :
35- raise RuntimeError (
36- "Unable to find OpenColorIO version: {}" .format (str (e ))
37- )
38- finally :
39- shutil .rmtree (dirpath )
23+
24+ with tempfile .TemporaryDirectory () as tmpdir :
25+ try :
26+ subprocess .check_call (["cmake" , here ], cwd = tmpdir )
27+ path = os .path .join (tmpdir , "include" , "OpenColorIO" , "OpenColorABI.h" )
28+ with open (path ) as f :
29+ match = VERSION_REGEX .search (f .read ())
30+ return match .group (1 )
31+ except Exception as e :
32+ raise RuntimeError (
33+ "Unable to find OpenColorIO version: {}" .format (str (e ))
34+ )
35+
36+
37+ # Call CMake find_package from a dummy script and return whether the package
38+ # has been found or not.
39+ def cmake_find_package (package_name ):
40+ with tempfile .TemporaryDirectory () as tmpdir :
41+ try :
42+ cmakelist_path = os .path .join (tmpdir , "CMakeLists.txt" )
43+ with open (cmakelist_path , "w" ) as f :
44+ f .write ("""
45+ cmake_minimum_required(VERSION 3.13)
46+ project(test LANGUAGES CXX)
47+
48+ find_package({} REQUIRED)
49+ """ .format (package_name )
50+ )
51+
52+ subprocess .check_call (
53+ ["cmake" , tmpdir ],
54+ cwd = tmpdir ,
55+ stdout = subprocess .DEVNULL ,
56+ stderr = subprocess .DEVNULL
57+ )
58+ return True
59+ except Exception as e :
60+ return False
4061
4162
4263# Convert distutils Windows platform specifiers to CMake -A arguments
@@ -59,6 +80,7 @@ def __init__(self, name, sourcedir=""):
5980class CMakeBuild (build_ext ):
6081 def build_extension (self , ext ):
6182 extdir = os .path .abspath (os .path .dirname (self .get_ext_fullpath (ext .name )))
83+ bindir = os .path .join (extdir , "bin" )
6284
6385 # required for auto-detection & inclusion of auxiliary "native" libs
6486 if not extdir .endswith (os .path .sep ):
@@ -73,12 +95,13 @@ def build_extension(self, ext):
7395
7496 cmake_args = [
7597 "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={}" .format (extdir ),
98+ "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY={}" .format (bindir ),
7699 "-DPython_EXECUTABLE={}" .format (sys .executable ),
77100 # Not used on MSVC, but no harm
78101 "-DCMAKE_BUILD_TYPE={}" .format (cfg ),
79- "-DBUILD_SHARED_LIBS=OFF " ,
80- "-DOCIO_BUILD_DOCS=ON " ,
81- "-DOCIO_BUILD_APPS=OFF " ,
102+ "-DBUILD_SHARED_LIBS=ON " ,
103+ "-DOCIO_USE_SOVERSION=OFF " ,
104+ "-DOCIO_BUILD_APPS=ON " ,
82105 "-DOCIO_BUILD_TESTS=OFF" ,
83106 "-DOCIO_BUILD_GPU_TESTS=OFF" ,
84107 # Make sure we build everything for the requested architecture(s)
@@ -121,7 +144,8 @@ def build_extension(self, ext):
121144 # Multi-config generators have a different way to specify configs
122145 if not single_config :
123146 cmake_args += [
124- "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}" .format (cfg .upper (), extdir )
147+ "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}" .format (cfg .upper (), extdir ),
148+ "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_{}={}" .format (cfg .upper (), bindir ),
125149 ]
126150 build_args += ["--config" , cfg ]
127151
@@ -131,6 +155,19 @@ def build_extension(self, ext):
131155 if archs :
132156 cmake_args += ["-DCMAKE_OSX_ARCHITECTURES={}" .format (";" .join (archs ))]
133157
158+ # When building the wheel, the install step is not executed so we need
159+ # to have the correct RPATH directly from the build tree output.
160+ cmake_args += ["-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON" ]
161+ if sys .platform .startswith ("linux" ):
162+ cmake_args += ["-DCMAKE_INSTALL_RPATH={}" .format ("$ORIGIN;$ORIGIN/.." )]
163+ if sys .platform .startswith ("darwin" ):
164+ cmake_args += ["-DCMAKE_INSTALL_RPATH={}" .format ("@loader_path;@loader_path/.." )]
165+
166+ # Documentation is used for Python docstrings but we allow to build
167+ # the wheel without docs to remove a hard dependency on doxygen.
168+ if cmake_find_package ("Doxygen" ):
169+ cmake_args += ["-DOCIO_BUILD_DOCS=ON" ]
170+
134171 # Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level
135172 # across all generators.
136173 if "CMAKE_BUILD_PARALLEL_LEVEL" not in os .environ :
@@ -156,11 +193,33 @@ def build_extension(self, ext):
156193 version = get_version (),
157194 package_dir = {
158195 'PyOpenColorIO' : 'src/bindings/python/package' ,
159- 'PyOpenColorIO.tests ' : 'tests/python ' ,
160- 'PyOpenColorIO.data ' : 'tests/data ' ,
196+ 'PyOpenColorIO.bin.pyocioamf ' : 'src/apps/pyocioamf ' ,
197+ 'PyOpenColorIO.bin.pyociodisplay ' : 'src/apps/pyociodisplay ' ,
161198 },
162- packages = ['PyOpenColorIO' , 'PyOpenColorIO.tests' , 'PyOpenColorIO.data' ],
199+ packages = [
200+ 'PyOpenColorIO' ,
201+ 'PyOpenColorIO.bin.pyocioamf' ,
202+ 'PyOpenColorIO.bin.pyociodisplay' ,
203+ ],
163204 ext_modules = [CMakeExtension ("PyOpenColorIO.PyOpenColorIO" )],
164205 cmdclass = {"build_ext" : CMakeBuild },
165- include_package_data = True
206+ include_package_data = True ,
207+ entry_points = {
208+ 'console_scripts' : [
209+ # Native applications
210+ 'ocioarchive=PyOpenColorIO.command_line:main' ,
211+ 'ociobakelut=PyOpenColorIO.command_line:main' ,
212+ 'ociocheck=PyOpenColorIO.command_line:main' ,
213+ 'ociochecklut=PyOpenColorIO.command_line:main' ,
214+ 'ocioconvert=PyOpenColorIO.command_line:main' ,
215+ 'ociodisplay=PyOpenColorIO.command_line:main' ,
216+ 'ociolutimage=PyOpenColorIO.command_line:main' ,
217+ 'ociomakeclf=PyOpenColorIO.command_line:main' ,
218+ 'ocioperf=PyOpenColorIO.command_line:main' ,
219+ 'ociowrite=PyOpenColorIO.command_line:main' ,
220+ # Python applications
221+ 'pyocioamf=PyOpenColorIO.bin.pyocioamf.pyocioamf:main' ,
222+ 'pyociodisplay=PyOpenColorIO.bin.pyociodisplay.pyociodisplay:main' ,
223+ ]
224+ },
166225)
0 commit comments