CIRCT 22.0.0git
Loading...
Searching...
No Matches
setup.py
Go to the documentation of this file.
1# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2# See https://llvm.org/LICENSE.txt for license information.
3# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5# Build/install the ESI runtime python package.
6#
7# To install:
8# pip install .
9# To build a wheel:
10# pip wheel .
11#
12# It is recommended to build with Ninja and ccache. To do so, set environment
13# variables by prefixing to above invocations:
14# CC=clang CXX=clang++
15#
16# On CIs, it is often advantageous to re-use/control the CMake build directory.
17# This can be set with the PYCDE_CMAKE_BUILD_DIR env var.
18
19import os
20import platform
21import shutil
22import subprocess
23import sys
24import sysconfig
25
26from distutils.command.build import build as _build
27from setuptools import find_namespace_packages, setup, Extension
28from setuptools.command.build_ext import build_ext
29from setuptools.command.build_py import build_py
30
31_thisdir = os.path.abspath(os.path.dirname(__file__))
32
33
34# Build phase discovery is unreliable. Just tell it what phases to run.
36
37 def run(self):
38 self.run_command("build_py")
39 self.run_command("build_ext")
40 self.run_command("build_scripts")
41
42
43class CMakeExtension(Extension):
44
45 def __init__(self, name, sourcedir=""):
46 Extension.__init__(self, name, sources=[])
47 self.sourcedir = os.path.abspath(sourcedir)
48
49
50class CMakeBuild(build_py):
51
52 def run(self):
53 # Set up build dirs.
54 target_dir = os.path.abspath(self.build_lib)
55 cmake_build_dir = os.getenv("PYCDE_CMAKE_BUILD_DIR")
56 if not cmake_build_dir:
57 cmake_build_dir = os.path.abspath(
58 os.path.join(target_dir, "..", "cmake_build"))
59 src_dir = _thisdir
60
61 os.makedirs(cmake_build_dir, exist_ok=True)
62 cmake_cache_file = os.path.join(cmake_build_dir, "CMakeCache.txt")
63 if os.path.exists(cmake_cache_file):
64 os.remove(cmake_cache_file)
65
66 # Configure the build.
67 cfg = "Release"
68
69 cmake_args = [
70 "-GNinja", # This build only works with Ninja on Windows.
71 "-DCMAKE_BUILD_TYPE={}".format(cfg), # not used on MSVC, but no harm
72 "-DPython3_EXECUTABLE={}".format(sys.executable.replace("\\", "/")),
73 "-DWHEEL_BUILD=ON",
74 ]
75
76 # Get the nanobind cmake directory from the isolated build environment.
77 # This is necessary because CMake's execute_process may not properly find
78 # nanobind installed in the isolated build environment.
79 try:
80 import nanobind
81 nanobind_dir = nanobind.cmake_dir()
82 cmake_args.append("-Dnanobind_DIR={}".format(
83 nanobind_dir.replace("\\", "/")))
84 except ImportError:
85 print("Skipping nanobind directory detection, nanobind not found.")
86
87 cxx = os.getenv("CXX")
88 if cxx is not None:
89 cmake_args.append("-DCMAKE_CXX_COMPILER={}".format(cxx))
90
91 cc = os.getenv("CC")
92 if cc is not None:
93 cmake_args.append("-DCMAKE_C_COMPILER={}".format(cc))
94
95 if "VCPKG_INSTALLATION_ROOT" in os.environ:
96 cmake_args.append(
97 f"-DCMAKE_TOOLCHAIN_FILE={os.environ['VCPKG_INSTALLATION_ROOT']}/scripts/buildsystems/vcpkg.cmake"
98 )
99
100 if "CIRCT_EXTRA_CMAKE_ARGS" in os.environ:
101 cmake_args += os.environ["CIRCT_EXTRA_CMAKE_ARGS"].split(" ")
102
103 # HACK: CMake fails to auto-detect static linked Python installations, which
104 # happens to be what exists on manylinux. We detect this and give it a dummy
105 # library file to reference (which is checks exists but never gets
106 # used).
107 if platform.system() == "Linux":
108 python_libdir = sysconfig.get_config_var('LIBDIR')
109 python_library = sysconfig.get_config_var('LIBRARY')
110 if python_libdir and not os.path.isabs(python_library):
111 python_library = os.path.join(python_libdir, python_library)
112 if python_library and not os.path.exists(python_library):
113 print("Detected static linked python. Faking a library for cmake.")
114 fake_libdir = os.path.join(cmake_build_dir, "fake_python", "lib")
115 os.makedirs(fake_libdir, exist_ok=True)
116 fake_library = os.path.join(fake_libdir,
117 sysconfig.get_config_var('LIBRARY'))
118 subprocess.check_call(["ar", "q", fake_library])
119 cmake_args.append("-DPython3_LIBRARY:PATH={}".format(fake_library))
120
121 # Finally run the cmake configure.
122 subprocess.check_call(["cmake", src_dir] + cmake_args, cwd=cmake_build_dir)
123 print(" ".join(["cmake", src_dir] + cmake_args))
124
125 # Run the build.
126 subprocess.check_call([
127 "cmake",
128 "--build",
129 ".",
130 "--parallel",
131 "--target",
132 "ESIRuntime",
133 ],
134 cwd=cmake_build_dir)
135
136 # Install the runtime directly into the target directory.
137 if os.path.exists(target_dir):
138 shutil.rmtree(target_dir)
139 subprocess.check_call([
140 "cmake", "--install", ".", "--prefix",
141 os.path.join(target_dir, "esiaccel"), "--component", "ESIRuntime"
142 ],
143 cwd=cmake_build_dir)
144
145
146class NoopBuildExtension(build_ext):
147
148 def build_extension(self, ext):
149 pass
150
151
152setup(name="esiaccel",
153 include_package_data=True,
154 ext_modules=[
155 CMakeExtension("esiaccel.esiCppAccel"),
156 ],
157 cmdclass={
158 "build": CustomBuild,
159 "build_ext": NoopBuildExtension,
160 "build_py": CMakeBuild,
161 },
162 zip_safe=False,
163 packages=find_namespace_packages(include=[
164 "esiaccel",
165 "esiaccel.*",
166 ]))
static void print(TypedAttr val, llvm::raw_ostream &os)
__init__(self, name, sourcedir="")
Definition setup.py:45
build_extension(self, ext)
Definition setup.py:148
Definition setup.py:1