Loading [MathJax]/jax/output/HTML-CSS/config.js
CIRCT 21.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 circt-core python package.
6# Note that this includes a relatively large build of LLVM (~2400 C++ files)
7# and can take a considerable amount of time, especially with defaults.
8# To install:
9# pip install .
10# To build a wheel:
11# pip wheel .
12#
13# It is recommended to build with Ninja and ccache. To do so, set environment
14# variables by prefixing to above invocations:
15# CMAKE_GENERATOR=Ninja \
16# CMAKE_C_COMPILER_LAUNCHER=ccache \
17# CMAKE_CXX_COMPILER_LAUNCHER=ccache
18#
19# On CIs, it is often advantageous to re-use/control the CMake build directory.
20# This can be set with the CIRCT_CMAKE_BUILD_DIR env var.
21#
22# By default, this will use the llvm-project submodule included with CIRCT.
23# This can be overridden with the CIRCT_LLVM_DIR env var.
24
25import os
26import platform
27import shutil
28import subprocess
29import sys
30import sysconfig
31
32from distutils.command.build import build as _build
33from setuptools import find_namespace_packages, setup, Extension
34from setuptools.command.build_ext import build_ext
35from setuptools.command.build_py import build_py
36
37
38# Build phase discovery is unreliable. Just tell it what phases to run.
40
41 def run(self):
42 self.run_command("build_py")
43 self.run_command("build_ext")
44 self.run_command("build_scripts")
45
46
47class CMakeExtension(Extension):
48
49 def __init__(self, name, sourcedir=""):
50 Extension.__init__(self, name, sources=[])
51 self.sourcedir = os.path.abspath(sourcedir)
52
53
54class CMakeBuild(build_py):
55
56 def run(self):
57 target_dir = self.build_lib
58 circt_dir = os.path.abspath(
59 os.path.join(os.path.dirname(__file__), "..", "..", ".."))
60 cmake_build_dir = os.getenv("CIRCT_CMAKE_BUILD_DIR")
61 if not cmake_build_dir:
62 cmake_build_dir = os.path.join(circt_dir, "build")
63 cmake_install_dir = os.path.join(cmake_build_dir, "..", "install")
64 llvm_dir = os.getenv("CIRCT_LLVM_DIR")
65 if not llvm_dir:
66 llvm_dir = os.path.join(circt_dir, "llvm", "llvm")
67
68 # Use Ninja if available.
69 exist_ninja = shutil.which("ninja") is not None
70 cmake_generator = ["-G", "Ninja"] if exist_ninja else []
71
72 # Use lld if available.
73 exist_lld = shutil.which("lld") is not None
74 cmake_linker = ["-DLLVM_USE_LINKER=lld"] if exist_lld else []
75 cmake_args = [
76 "-DCMAKE_BUILD_TYPE=Release", # not used on MSVC, but no harm
77 "-DCMAKE_INSTALL_PREFIX={}".format(os.path.abspath(cmake_install_dir)),
78 # Use the minimum macOS deployment target that supports all c++17
79 # features.
80 #
81 # See: Notes column of https://developer.apple.com/xcode/cpp/#c++17
82 "-DCMAKE_OSX_DEPLOYMENT_TARGET=10.15",
83 "-DPython3_EXECUTABLE={}".format(sys.executable.replace("\\", "/")),
84 "-DLLVM_ENABLE_PROJECTS=mlir",
85 "-DLLVM_EXTERNAL_PROJECTS=circt",
86 "-DLLVM_EXTERNAL_CIRCT_SOURCE_DIR={}".format(circt_dir),
87 "-DLLVM_TARGETS_TO_BUILD=host",
88 "-DMLIR_ENABLE_BINDINGS_PYTHON=ON",
89 "-DMLIR_BINDINGS_PYTHON_NB_DOMAIN=circt",
90 "-DCIRCT_BINDINGS_PYTHON_ENABLED=ON",
91 "-DCIRCT_RELEASE_TAG_ENABLED=ON",
92 "-DCIRCT_RELEASE_TAG=firtool"
93 ] + cmake_linker + cmake_generator
94
95 # HACK: CMake fails to auto-detect static linked Python installations, which
96 # happens to be what exists on manylinux. We detect this and give it a dummy
97 # library file to reference (which is checks exists but never gets
98 # used).
99 if platform.system() == "Linux":
100 python_libdir = sysconfig.get_config_var('LIBDIR')
101 python_library = sysconfig.get_config_var('LIBRARY')
102 if python_libdir and not os.path.isabs(python_library):
103 python_library = os.path.join(python_libdir, python_library)
104 if python_library and not os.path.exists(python_library):
105 print("Detected static linked python. Faking a library for cmake.")
106 fake_libdir = os.path.join(cmake_build_dir, "fake_python", "lib")
107 os.makedirs(fake_libdir, exist_ok=True)
108 fake_library = os.path.join(fake_libdir,
109 sysconfig.get_config_var('LIBRARY'))
110 subprocess.check_call(["ar", "q", fake_library])
111 cmake_args.append("-DPython3_LIBRARY:PATH={}".format(fake_library))
112
113 os.makedirs(cmake_build_dir, exist_ok=True)
114 if os.path.exists(cmake_install_dir):
115 shutil.rmtree(cmake_install_dir)
116 cmake_cache_file = os.path.join(cmake_build_dir, "CMakeCache.txt")
117 if os.path.exists(cmake_cache_file):
118 os.remove(cmake_cache_file)
119 subprocess.check_call(["cmake", llvm_dir] + cmake_args, cwd=cmake_build_dir)
120 subprocess.check_call(
121 ["cmake", "--build", ".", "--target", "install-CIRCTPythonModules"],
122 cwd=cmake_build_dir)
123 if os.path.exists(target_dir):
124 os.remove(target_dir)
125 shutil.copytree(os.path.join(cmake_install_dir, "python_packages",
126 "circt_core"),
127 target_dir,
128 symlinks=False)
129
130
131class NoopBuildExtension(build_ext):
132
133 def build_extension(self, ext):
134 pass
135
136
137setup(
138 name="circt",
139 version="0.0.1",
140 author="Mike Urbach",
141 author_email="mikeurbach@gmail.com",
142 description="CIRCT Python Bindings",
143 long_description="",
144 include_package_data=True,
145 ext_modules=[
146 CMakeExtension("circt._mlir_libs._mlir"),
147 CMakeExtension("circt._mlir_libs._circt"),
148 ],
149 cmdclass={
150 "build": CustomBuild,
151 "built_ext": NoopBuildExtension,
152 "build_py": CMakeBuild,
153 },
154 zip_safe=False,
155 packages=find_namespace_packages(include=[
156 "circt",
157 "circt.*",
158 ]),
159)
static void print(TypedAttr val, llvm::raw_ostream &os)
__init__(self, name, sourcedir="")
Definition setup.py:49
Definition setup.py:1