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(
100 self
.build_temp
, 'bazel-bin',
101 ext
.relpath
, ext
.target_name
+ shared_lib_suffix
)
103 ext_dest_path
= self
.get_ext_fullpath(ext
.name
)
104 ext_dest_dir
= os
.path
.dirname(ext_dest_path
)
105 if not os
.path
.exists(ext_dest_dir
):
106 os
.makedirs(ext_dest_dir
)
107 shutil
.copyfile(ext_bazel_bin_path
, ext_dest_path
)
111 name
="google_benchmark",
112 version
=_get_version(),
113 url
="https://github.com/google/benchmark",
114 description
="A library to benchmark code snippets.",
116 author_email
="benchmark-py@google.com",
117 # Contained modules and scripts.
118 package_dir
={"": "bindings/python"},
119 packages
=setuptools
.find_packages("bindings/python"),
120 install_requires
=_parse_requirements("bindings/python/requirements.txt"),
121 cmdclass
=dict(build_ext
=BuildBazelExtension
),
124 "google_benchmark._benchmark",
125 "//bindings/python/google_benchmark:_benchmark",
129 # PyPI package information.
131 "Development Status :: 4 - Beta",
132 "Intended Audience :: Developers",
133 "Intended Audience :: Science/Research",
134 "License :: OSI Approved :: Apache Software License",
135 "Programming Language :: Python :: 3.6",
136 "Programming Language :: Python :: 3.7",
137 "Programming Language :: Python :: 3.8",
138 "Topic :: Software Development :: Testing",
139 "Topic :: System :: Benchmark",
141 license
="Apache 2.0",
142 keywords
="benchmark",