Files
allwpilib/shared/bazel/rules/robotpy/robotpy_rules.bzl
PJ Reiniger 68d24bb29e [python] Improve robotpy generation (#8867)
The initial build file generation for robotpy projects was relatively
naive and purpose built to get `allwpilib` compiling, without supporting
all the available features.

This modifies the generation scripts to be able to support multiple
embedded libraries, which will be necessary for #8858, since `mrclib.so`
will need to be bundled along with the hal libraries. In addition some
cleanup was done to get the wheels looking more like what is in pypi.
2026-05-14 21:52:39 -07:00

202 lines
7.1 KiB
Python

load("@aspect_bazel_lib//lib:copy_file.bzl", "copy_file")
load("@pybind11_bazel//:build_defs.bzl", "pybind_extension", "pybind_library")
load("@rules_pycross//pycross:defs.bzl", "pycross_wheel_library")
load("@rules_python//python:defs.bzl", "py_library")
load("@rules_python//python:packaging.bzl", "py_wheel")
load("//shared/bazel/rules/robotpy:compatibility_select.bzl", "robotpy_compatibility_select")
def create_pybind_library(
name,
extension_name,
install_path,
generated_srcs = [],
extra_hdrs = [],
extra_srcs = [],
deps = [],
dynamic_deps = [],
semiwrap_header = [],
includes = [],
local_defines = []):
"""
Function to create a pybind C++ extension library that has been defined by a semiwrap config
Outputs:
<name>_pybind_library - A pybind_library that functions like a header-only cc_library. It will include all
of the extra_hdrs, resolve the include paths, and add a dependency on the semiwrap headers
<install_path + extension_name> - A pybind_extension that wraps the pybind_library and compiles all the source files.
Params:
extension_name - The name of the pybind extension. Should be sourced from pyproject
install_path - The subpath where the library will be installed. Should be source from pyproject
generated_srcs - List of auto-generated sources to be compiled into the extension.
extra_hdrs - Any non-autogenerated headers
extra_srcs - Any non-autogenerated sources
deps - cc_library deps used to create the pybind_library
dynamic_deps - cc_shared_library deps used to filter objects from the pybind_extension
semiwrap_header - Auto-generated file used to initialize the extension
includes - see cc_library#includes. Used during the creating of the pybind_library
local_defines - see cc_library#local_defines. Used during the compilation of the extension
"""
pybind_library(
name = "{}_pybind_library".format(name),
hdrs = extra_hdrs,
target_compatible_with = robotpy_compatibility_select(),
deps = deps + [
"//shared/bazel/rules/robotpy:semiwrap_headers",
],
includes = includes,
visibility = ["//visibility:public"],
tags = ["robotpy"],
)
extension_name = extension_name or "_{}".format(name)
pybind_extension(
name = install_path + extension_name,
srcs = extra_srcs + generated_srcs,
deps = [":{}_pybind_library".format(name)] + semiwrap_header,
dynamic_deps = dynamic_deps,
copts = select({
"@bazel_tools//src/conditions:darwin": [
"-Wno-deprecated-declarations",
"-Wno-overloaded-virtual",
"-Wno-pessimizing-move",
"-Wno-unused-value",
],
"@bazel_tools//src/conditions:linux_x86_64": [
"-Wno-attributes",
"-Wno-unused-value",
"-Wno-deprecated",
"-Wno-deprecated-declarations",
"-Wno-unused-parameter",
"-Wno-redundant-move",
"-Wno-unused-but-set-variable",
"-Wno-unused-variable",
"-Wno-pessimizing-move",
"-Wno-overloaded-virtual",
],
"@bazel_tools//src/conditions:windows": [
],
}),
target_compatible_with = robotpy_compatibility_select(),
local_defines = local_defines,
tags = ["robotpy"],
)
def robotpy_library(
name,
deps = [],
data = [],
strip_path_prefixes = None,
distribution = None,
summary = None,
project_urls = None,
author_email = None,
entry_points = None,
requires = None,
description_file = None,
python_requires = None,
**kwargs):
"""
Defines a python library that is wrapping a series of pybind extensions.
Outputs:
<name> - The python library
<name>-wheel - A wheel for the library
"""
py_library(
name = name + "-lib",
data = data,
deps = deps,
tags = ["robotpy"],
**kwargs
)
py_wheel(
name = "{}-wheel".format(name),
distribution = distribution,
stamp = 1,
version = "$(ROBOTPY_VERSION)",
summary = summary,
requires = requires,
project_urls = project_urls,
author_email = author_email,
deps = data + [":{}-lib".format(name)],
strip_path_prefixes = strip_path_prefixes,
entry_points = entry_points,
description_file = description_file,
python_requires = python_requires,
license = "BSD-3-Clause",
tags = ["robotpy"],
)
pycross_wheel_library(
name = "{}".format(name),
wheel = "{}-wheel".format(name),
deps = deps,
visibility = ["//visibility:public"],
tags = ["manual"],
)
def copy_native_file(name, library, base_path):
"""
Copies a compiled shared library into a naming format that can be used by robotpy rules. The libraries are named
differently on OSX / Linux / Windows and this creates a handy alias to for easier use downstream
"""
copy_file(
name = name + ".win_copy_lib",
src = library,
out = "{}lib/{}.dll".format(base_path, name),
tags = ["manual"],
visibility = ["//visibility:public"],
)
copy_file(
name = name + ".osx_copy_lib",
src = library,
out = "{}lib/lib{}.dylib".format(base_path, name),
tags = ["manual"],
visibility = ["//visibility:public"],
)
copy_file(
name = name + ".linux_copy_lib",
src = library,
out = "{}lib/lib{}.so".format(base_path, name),
tags = ["manual"],
visibility = ["//visibility:public"],
)
native.alias(
name = "{}.copy_lib".format(name),
actual = select({
"@bazel_tools//src/conditions:darwin": name + ".osx_copy_lib",
"@bazel_tools//src/conditions:windows": name + ".win_copy_lib",
"//conditions:default": name + ".linux_copy_lib",
}),
visibility = ["//visibility:public"],
tags = ["robotpy"],
)
def generate_native_files(name, pyproject_toml, pc_deps, libinit_files, pc_files):
cmd = "$(locations //shared/bazel/rules/robotpy/hatchlib_native_port:generate_native_lib_files) "
cmd += " $(location " + pyproject_toml + ")"
cmd += " $(location " + pc_files[0] + ") "
for pc_dep in pc_deps:
cmd += " $(location " + pc_dep + ")"
native.genrule(
name = name + ".gen",
srcs = [pyproject_toml],
outs = libinit_files + pc_files,
cmd = cmd,
tools = ["//shared/bazel/rules/robotpy/hatchlib_native_port:generate_native_lib_files"] + pc_deps,
visibility = ["//visibility:public"],
tags = ["robotpy"],
target_compatible_with = robotpy_compatibility_select(),
)
native.filegroup(
name = name + ".pc_wrapper",
srcs = pc_files,
)