8 from distutils
import sysconfig
10 from setuptools
.command
import build_ext
13 HERE
= os
.path
.dirname(os
.path
.abspath(__file__
))
16 IS_WINDOWS
= sys
.platform
.startswith("win")
20 """Parse the version string from __init__.py."""
22 os
.path
.join(HERE
, "bindings", "python", "google_benchmark", "__init__.py")
26 line
for line
in init_file
if line
.startswith("__version__")
29 raise ValueError("__version__ not defined in __init__.py")
32 exec(version_line
, namespace
) # pylint: disable=exec-used
33 return namespace
["__version__"]
36 def _parse_requirements(path
):
37 with
open(os
.path
.join(HERE
, path
)) as requirements
:
40 for line
in requirements
41 if not (line
.isspace() or line
.startswith("#"))
45 class BazelExtension(setuptools
.Extension
):
46 """A C/C++ extension that is defined as a Bazel BUILD target."""
48 def __init__(self
, name
, bazel_target
):
49 self
.bazel_target
= bazel_target
50 self
.relpath
, self
.target_name
= posixpath
.relpath(bazel_target
, "//").split(
53 setuptools
.Extension
.__init
__(self
, name
, sources
=[])
56 class BuildBazelExtension(build_ext
.build_ext
):
57 """A command that runs Bazel to build a C/C++ extension."""
60 for ext
in self
.extensions
:
62 build_ext
.build_ext
.run(self
)
64 def bazel_build(self
, ext
):
65 """Runs the bazel build to create the package."""
66 with
open("WORKSPACE", "r") as workspace
:
67 workspace_contents
= workspace
.read()
69 with
open("WORKSPACE", "w") as workspace
:
72 r
'(?<=path = ").*(?=", # May be overwritten by setup\.py\.)',
73 sysconfig
.get_python_inc().replace(os
.path
.sep
, posixpath
.sep
),
78 if not os
.path
.exists(self
.build_temp
):
79 os
.makedirs(self
.build_temp
)
85 "--symlink_prefix=" + os
.path
.join(self
.build_temp
, "bazel-"),
86 "--compilation_mode=" + ("dbg" if self
.debug
else "opt"),
90 # Link with python*.lib.
91 for library_dir
in self
.library_dirs
:
92 bazel_argv
.append("--linkopt=/LIBPATH:" + library_dir
)
93 elif sys
.platform
== "darwin" and platform
.machine() == "x86_64":
94 bazel_argv
.append("--macos_minimum_os=10.9")
96 self
.spawn(bazel_argv
)
98 shared_lib_suffix
= ".dll" if IS_WINDOWS
else ".so"
99 ext_bazel_bin_path
= os
.path
.join(
103 ext
.target_name
+ shared_lib_suffix
,
106 ext_dest_path
= self
.get_ext_fullpath(ext
.name
)
107 ext_dest_dir
= os
.path
.dirname(ext_dest_path
)
108 if not os
.path
.exists(ext_dest_dir
):
109 os
.makedirs(ext_dest_dir
)
110 shutil
.copyfile(ext_bazel_bin_path
, ext_dest_path
)
114 name
="google_benchmark",
115 version
=_get_version(),
116 url
="https://github.com/google/benchmark",
117 description
="A library to benchmark code snippets.",
119 author_email
="benchmark-py@google.com",
120 # Contained modules and scripts.
121 package_dir
={"": "bindings/python"},
122 packages
=setuptools
.find_packages("bindings/python"),
123 install_requires
=_parse_requirements("bindings/python/requirements.txt"),
124 cmdclass
=dict(build_ext
=BuildBazelExtension
),
127 "google_benchmark._benchmark",
128 "//bindings/python/google_benchmark:_benchmark",
132 # PyPI package information.
134 "Development Status :: 4 - Beta",
135 "Intended Audience :: Developers",
136 "Intended Audience :: Science/Research",
137 "License :: OSI Approved :: Apache Software License",
138 "Programming Language :: Python :: 3.6",
139 "Programming Language :: Python :: 3.7",
140 "Programming Language :: Python :: 3.8",
141 "Topic :: Software Development :: Testing",
142 "Topic :: System :: Benchmark",
144 license
="Apache 2.0",
145 keywords
="benchmark",