CIRCT 20.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 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 "-DCIRCT_BINDINGS_PYTHON_ENABLED=ON",
90 "-DCIRCT_RELEASE_TAG_ENABLED=ON",
91 "-DCIRCT_RELEASE_TAG=firtool"
92 ] + cmake_linker + cmake_generator
93
94 # HACK: CMake fails to auto-detect static linked Python installations, which
95 # happens to be what exists on manylinux. We detect this and give it a dummy
96 # library file to reference (which is checks exists but never gets
97 # used).
98 if platform.system() == "Linux":
99 python_libdir = sysconfig.get_config_var('LIBDIR')
100 python_library = sysconfig.get_config_var('LIBRARY')
101 if python_libdir and not os.path.isabs(python_library):
102 python_library = os.path.join(python_libdir, python_library)
103 if python_library and not os.path.exists(python_library):
104 print("Detected static linked python. Faking a library for cmake.")
105 fake_libdir = os.path.join(cmake_build_dir, "fake_python", "lib")
106 os.makedirs(fake_libdir, exist_ok=True)
107 fake_library = os.path.join(fake_libdir,
108 sysconfig.get_config_var('LIBRARY'))
109 subprocess.check_call(["ar", "q", fake_library])
110 cmake_args.append("-DPython3_LIBRARY:PATH={}".format(fake_library))
111
112 os.makedirs(cmake_build_dir, exist_ok=True)
113 if os.path.exists(cmake_install_dir):
114 shutil.rmtree(cmake_install_dir)
115 cmake_cache_file = os.path.join(cmake_build_dir, "CMakeCache.txt")
116 if os.path.exists(cmake_cache_file):
117 os.remove(cmake_cache_file)
118 subprocess.check_call(["cmake", llvm_dir] + cmake_args, cwd=cmake_build_dir)
119 subprocess.check_call(
120 ["cmake", "--build", ".", "--target", "install-CIRCTPythonModules"],
121 cwd=cmake_build_dir)
122 if os.path.exists(target_dir):
123 os.remove(target_dir)
124 shutil.copytree(os.path.join(cmake_install_dir, "python_packages",
125 "circt_core"),
126 target_dir,
127 symlinks=False)
128
129
130class NoopBuildExtension(build_ext):
131
132 def build_extension(self, ext):
133 pass
134
135
136setup(
137 name="circt",
138 version="0.0.1",
139 author="Mike Urbach",
140 author_email="mikeurbach@gmail.com",
141 description="CIRCT Python Bindings",
142 long_description="",
143 include_package_data=True,
144 ext_modules=[
145 CMakeExtension("circt._mlir_libs._mlir"),
146 CMakeExtension("circt._mlir_libs._circt"),
147 ],
148 cmdclass={
149 "build": CustomBuild,
150 "built_ext": NoopBuildExtension,
151 "build_py": CMakeBuild,
152 },
153 zip_safe=False,
154 packages=find_namespace_packages(include=[
155 "circt",
156 "circt.*",
157 ]),
158)
static void print(TypedAttr val, llvm::raw_ostream &os)
__init__(self, name, sourcedir="")
Definition setup.py:49
Definition setup.py:1