CIRCT 23.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("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 "-DPython_EXECUTABLE={}".format(sys.executable.replace("\\", "/")),
74 "-DWHEEL_BUILD=ON",
75 ]
76
77 # Get the nanobind cmake directory from the isolated build environment.
78 # This is necessary because CMake's execute_process may not properly find
79 # nanobind installed in the isolated build environment.
80 try:
81 import nanobind
82
83 nanobind_dir = nanobind.cmake_dir()
84 cmake_args.append("-Dnanobind_DIR={}".format(
85 nanobind_dir.replace("\\", "/")))
86 except ImportError:
87 print("Skipping nanobind directory detection, nanobind not found.")
88
89 cxx = os.getenv("CXX")
90 if cxx is not None:
91 cmake_args.append("-DCMAKE_CXX_COMPILER={}".format(cxx))
92
93 cc = os.getenv("CC")
94 if cc is not None:
95 cmake_args.append("-DCMAKE_C_COMPILER={}".format(cc))
96
97 if "VCPKG_INSTALLATION_ROOT" in os.environ:
98 cmake_args.append(
99 f"-DCMAKE_TOOLCHAIN_FILE={os.environ['VCPKG_INSTALLATION_ROOT']}/scripts/buildsystems/vcpkg.cmake"
100 )
101
102 if "CIRCT_EXTRA_CMAKE_ARGS" in os.environ:
103 cmake_args += os.environ["CIRCT_EXTRA_CMAKE_ARGS"].split(" ")
104
105 # HACK: CMake fails to auto-detect static linked Python installations, which
106 # happens to be what exists on manylinux. We detect this and give it a dummy
107 # library file to reference (which is checks exists but never gets
108 # used).
109 if platform.system() == "Linux":
110 python_libdir = sysconfig.get_config_var('LIBDIR')
111 python_library = sysconfig.get_config_var('LIBRARY')
112 if python_libdir and not os.path.isabs(python_library):
113 python_library = os.path.join(python_libdir, python_library)
114 if python_library and not os.path.exists(python_library):
115 print("Detected static linked python. Faking a library for cmake.")
116 fake_libdir = os.path.join(cmake_build_dir, "fake_python", "lib")
117 os.makedirs(fake_libdir, exist_ok=True)
118 fake_library = os.path.join(fake_libdir,
119 sysconfig.get_config_var('LIBRARY'))
120 subprocess.check_call(["ar", "q", fake_library])
121 cmake_args.append("-DPython3_LIBRARY:PATH={}".format(fake_library))
122
123 # Finally run the cmake configure.
124 subprocess.check_call(["cmake", src_dir] + cmake_args, cwd=cmake_build_dir)
125 print(" ".join(["cmake", src_dir] + cmake_args))
126
127 # Run the build.
128 subprocess.check_call(
129 [
130 "cmake",
131 "--build",
132 ".",
133 "--parallel",
134 "--target",
135 "ESIRuntime",
136 ],
137 cwd=cmake_build_dir,
138 )
139
140 # Install the runtime directly into the target directory.
141 if os.path.exists(target_dir):
142 shutil.rmtree(target_dir)
143 subprocess.check_call(
144 [
145 "cmake",
146 "--install",
147 ".",
148 "--prefix",
149 os.path.join(target_dir, "esiaccel"),
150 "--component",
151 "ESIRuntime",
152 ],
153 cwd=cmake_build_dir,
154 )
155
156
157class NoopBuildExtension(build_ext):
158
159 def build_extension(self, ext):
160 pass
161
162
163setup(
164 name="esiaccel",
165 include_package_data=True,
166 ext_modules=[
167 CMakeExtension("esiaccel.esiCppAccel"),
168 ],
169 cmdclass={
170 "build": CustomBuild,
171 "build_ext": NoopBuildExtension,
172 "build_py": CMakeBuild,
173 },
174 zip_safe=False,
175 packages=find_namespace_packages(include=[
176 "esiaccel",
177 "esiaccel.*",
178 ]),
179)
static void print(TypedAttr val, llvm::raw_ostream &os)
__init__(self, name, sourcedir="")
Definition setup.py:45
build_extension(self, ext)
Definition setup.py:159
Definition setup.py:1