CIRCT  20.0.0git
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 
19 import os
20 import platform
21 import shutil
22 import subprocess
23 import sys
24 import sysconfig
25 
26 from distutils.command.build import build as _build
27 from setuptools import find_namespace_packages, setup, Extension
28 from setuptools.command.build_ext import build_ext
29 from 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 
43 class CMakeExtension(Extension):
44 
45  def __init__(self, name, sourcedir=""):
46  Extension.__init__(self, name, sources=[])
47  self.sourcedirsourcedir = os.path.abspath(sourcedir)
48 
49 
50 class 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  cmake_args = [
69  "-GNinja", # This build only works with Ninja on Windows.
70  "-DCMAKE_BUILD_TYPE={}".format(cfg), # not used on MSVC, but no harm
71  "-DPython3_EXECUTABLE={}".format(sys.executable.replace("\\", "/")),
72  "-DWHEEL_BUILD=ON",
73  ]
74  cxx = os.getenv("CXX")
75  if cxx is not None:
76  cmake_args.append("-DCMAKE_CXX_COMPILER={}".format(cxx))
77 
78  cc = os.getenv("CC")
79  if cc is not None:
80  cmake_args.append("-DCMAKE_C_COMPILER={}".format(cc))
81 
82  if "VCPKG_INSTALLATION_ROOT" in os.environ:
83  cmake_args.append(
84  f"-DCMAKE_TOOLCHAIN_FILE={os.environ['VCPKG_INSTALLATION_ROOT']}/scripts/buildsystems/vcpkg.cmake"
85  )
86 
87  if "CIRCT_EXTRA_CMAKE_ARGS" in os.environ:
88  cmake_args += os.environ["CIRCT_EXTRA_CMAKE_ARGS"].split(" ")
89 
90  # HACK: CMake fails to auto-detect static linked Python installations, which
91  # happens to be what exists on manylinux. We detect this and give it a dummy
92  # library file to reference (which is checks exists but never gets
93  # used).
94  if platform.system() == "Linux":
95  python_libdir = sysconfig.get_config_var('LIBDIR')
96  python_library = sysconfig.get_config_var('LIBRARY')
97  if python_libdir and not os.path.isabs(python_library):
98  python_library = os.path.join(python_libdir, python_library)
99  if python_library and not os.path.exists(python_library):
100  print("Detected static linked python. Faking a library for cmake.")
101  fake_libdir = os.path.join(cmake_build_dir, "fake_python", "lib")
102  os.makedirs(fake_libdir, exist_ok=True)
103  fake_library = os.path.join(fake_libdir,
104  sysconfig.get_config_var('LIBRARY'))
105  subprocess.check_call(["ar", "q", fake_library])
106  cmake_args.append("-DPython3_LIBRARY:PATH={}".format(fake_library))
107 
108  # Finally run the cmake configure.
109  subprocess.check_call(["cmake", src_dir] + cmake_args, cwd=cmake_build_dir)
110  print(" ".join(["cmake", src_dir] + cmake_args))
111 
112  # Run the build.
113  subprocess.check_call([
114  "cmake",
115  "--build",
116  ".",
117  "--parallel",
118  "--target",
119  "ESIRuntime",
120  ],
121  cwd=cmake_build_dir)
122 
123  # Install the runtime directly into the target directory.
124  if os.path.exists(target_dir):
125  shutil.rmtree(target_dir)
126  subprocess.check_call([
127  "cmake", "--install", ".", "--prefix",
128  os.path.join(target_dir, "esiaccel"), "--component", "ESIRuntime"
129  ],
130  cwd=cmake_build_dir)
131 
132 
133 class NoopBuildExtension(build_ext):
134 
135  def build_extension(self, ext):
136  pass
137 
138 
139 setup(name="esiaccel",
140  include_package_data=True,
141  ext_modules=[
142  CMakeExtension("esiaccel.esiCppAccel"),
143  ],
144  cmdclass={
145  "build": CustomBuild,
146  "built_ext": NoopBuildExtension,
147  "build_py": CMakeBuild,
148  },
149  zip_safe=False,
150  packages=find_namespace_packages(include=[
151  "esiaccel",
152  "esiaccel.*",
153  ]))
def run(self)
Definition: setup.py:52
def __init__(self, name, sourcedir="")
Definition: setup.py:45
def run(self)
Definition: setup.py:37
def build_extension(self, ext)
Definition: setup.py:135
Definition: setup.py:1