[bazel] Build and publish ntcoreffi too (#8147)

This commit is contained in:
Austin Schuh
2025-08-02 21:59:50 -07:00
committed by GitHub
parent 1ab705b354
commit 0dd77e55cb
7 changed files with 238 additions and 0 deletions

View File

@@ -76,6 +76,7 @@ publish_all(
"//hal:wpiHal-cpp_publish", "//hal:wpiHal-cpp_publish",
"//ntcore:ntcore-cpp_publish", "//ntcore:ntcore-cpp_publish",
"//ntcore:ntcore-java_publish", "//ntcore:ntcore-java_publish",
"//ntcoreffi:ntcoreffi-cpp_publish",
"//outlineviewer:outlineviewer_publish", "//outlineviewer:outlineviewer_publish",
"//romiVendordep:romiVendordep-cpp_publish", "//romiVendordep:romiVendordep-cpp_publish",
"//romiVendordep:romiVendordep-java_publish", "//romiVendordep:romiVendordep-java_publish",

59
ntcoreffi/BUILD.bazel Normal file
View File

@@ -0,0 +1,59 @@
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_python//python:defs.bzl", "py_binary")
load("//shared/bazel/rules:cc_rules.bzl", "wpilib_cc_library", "wpilib_cc_shared_library")
load("//shared/bazel/rules:packaging.bzl", "package_shared_cc_project")
py_binary(
name = "generate_exported_symbols",
srcs = [
"generate_exported_symbols.py",
],
)
genrule(
name = "do_generate_exported_symbols",
srcs = ["src/main/native/symbols.txt"],
outs = ["src/generated/headers/ExportedSymbols.h"],
cmd = "$(location :generate_exported_symbols) --output $(OUTS) --symbols $(SRCS)",
tools = [":generate_exported_symbols"],
)
cc_library(
name = "exported_symbols",
hdrs = [
"src/generated/headers/ExportedSymbols.h",
],
strip_include_prefix = "src/generated/headers/",
)
wpilib_cc_library(
name = "ntcoreffi",
srcs = glob([
"src/main/native/c/**",
"src/main/native/cpp/**",
]),
hdrs = glob(["src/main/native/include/**"]),
include_license_files = True,
strip_include_prefix = "src/main/native/include",
visibility = ["//visibility:public"],
deps = [
":exported_symbols",
"//ntcore",
"//wpinet",
"//wpiutil",
],
)
wpilib_cc_shared_library(
name = "shared/ntcoreffi",
symbols = "src/main/native/symbols.txt",
use_debug_name = False,
visibility = ["//visibility:public"],
deps = [":ntcoreffi"],
)
package_shared_cc_project(
name = "ntcoreffi",
maven_artifact_name = "ntcoreffi-cpp",
maven_group_id = "edu.wpi.first.ntcoreffi",
)

View File

@@ -0,0 +1,31 @@
#!/usr/bin/python
import argparse
from pathlib import Path
def generate_symbol_text(output_directory, symbols):
with open(output_directory, "w") as out:
with open(symbols, "r") as f:
for line in f:
out.write(f"AddFunctionToLink({line.strip()});\n")
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--symbols",
help="Read the symbols from this file",
type=Path,
)
parser.add_argument(
"--output",
help="Output the generated symbols to this file",
type=Path,
)
args = parser.parse_args()
generate_symbol_text(args.output, args.symbols)
if __name__ == "__main__":
main()

View File

@@ -6,6 +6,7 @@ load("@rules_cc//cc:find_cc_toolchain.bzl", "CC_TOOLCHAIN_ATTRS", "find_cpp_tool
load("@rules_cc//cc/common:cc_common.bzl", "cc_common") load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
load("@rules_pkg//:mappings.bzl", "pkg_files") load("@rules_pkg//:mappings.bzl", "pkg_files")
load("@rules_pkg//:pkg.bzl", "pkg_zip") load("@rules_pkg//:pkg.bzl", "pkg_zip")
load("//shared/bazel/rules/gen:defs.bzl", "gen_versionscript")
# Copied from bazel since it isn't exposed publicly that I can find. # Copied from bazel since it isn't exposed publicly that I can find.
# https://github.com/bazelbuild/bazel/blob/cc4e3b25a89cd8294406d9489ece706cfcc019bd/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl#L272 # https://github.com/bazelbuild/bazel/blob/cc4e3b25a89cd8294406d9489ece706cfcc019bd/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl#L272
@@ -328,6 +329,8 @@ def wpilib_cc_shared_library(
use_debug_name = True, use_debug_name = True,
features = None, features = None,
win_def_file = None, win_def_file = None,
symbols = None,
additional_linker_inputs = None,
**kwargs): **kwargs):
"""Builds a cc_shared_library with some wpilib conventions applied. """Builds a cc_shared_library with some wpilib conventions applied.
@@ -341,6 +344,7 @@ def wpilib_cc_shared_library(
user_link_flags: User link flags to add to the linking process. Note: user_link_flags: User link flags to add to the linking process. Note:
this gets augmented with extra flags to produce libfoo.so this gets augmented with extra flags to produce libfoo.so
or libfood.so if in debug mode. or libfood.so if in debug mode.
additional_linker_inputs: Additional inputs to provide to the linking process.
use_debug_name: If true, (default): when in debug mode, produce use_debug_name: If true, (default): when in debug mode, produce
libfood.so, otherwise produce libfoo.so. This matches the libfood.so, otherwise produce libfoo.so. This matches the
wpilib convention for debug library naming. JNI libraries wpilib convention for debug library naming. JNI libraries
@@ -349,6 +353,7 @@ def wpilib_cc_shared_library(
win_def_file: The .def file used to specify symbols used in linking on win_def_file: The .def file used to specify symbols used in linking on
Windows. This is selected automatically such that it is Windows. This is selected automatically such that it is
only used on Windows. only used on Windows.
symbols: The symbols to export in the shared library.
""" """
folder, lib = _folder_prefix(name) folder, lib = _folder_prefix(name)
@@ -356,6 +361,33 @@ def wpilib_cc_shared_library(
if not features: if not features:
features = [] features = []
if symbols:
if win_def_file:
fail("Can't specify symbols and win_def_file")
exports_target = name + "_exports"
gen_versionscript(
name = exports_target,
src = symbols,
lib_name = lib,
format = select({
"@platforms//os:linux": "linux",
"@platforms//os:osx": "osx",
"@platforms//os:windows": "windows",
}),
)
additional_linker_inputs = (additional_linker_inputs or []) + select({
"@platforms//os:windows": [],
"//conditions:default": [exports_target],
})
user_link_flags = (user_link_flags or []) + select({
"@platforms//os:linux": ["-Wl,--version-script,$(location " + exports_target + ")"],
"@platforms//os:osx": ["-Wl,-exported_symbols_list,$(location " + exports_target + ")"],
"@platforms//os:windows": [],
})
win_def_file = exports_target
if auto_export_windows_symbols: if auto_export_windows_symbols:
features.append("windows_export_all_symbols") features.append("windows_export_all_symbols")
@@ -379,6 +411,7 @@ def wpilib_cc_shared_library(
user_link_flags = user_link_flags, user_link_flags = user_link_flags,
features = features, features = features,
visibility = visibility, visibility = visibility,
additional_linker_inputs = additional_linker_inputs,
# Only include a .def file on windows. This makes it so we can mark # Only include a .def file on windows. This makes it so we can mark
# the .def file as only compatible with windows. # the .def file as only compatible with windows.
win_def_file = select({ win_def_file = select({

View File

@@ -1,5 +1,14 @@
load("@rules_python//python:defs.bzl", "py_binary") load("@rules_python//python:defs.bzl", "py_binary")
exports_files(["defs.bzl"])
py_binary(
name = "gen_versionscript",
srcs = ["gen_versionscript.py"],
main = "gen_versionscript.py",
visibility = ["//visibility:public"],
)
py_binary( py_binary(
name = "gen_resources", name = "gen_resources",
srcs = ["gen_resources.py"], srcs = ["gen_resources.py"],

View File

@@ -0,0 +1,56 @@
"""Starlark rule for generating a version script from a symbols file."""
def _gen_versionscript_impl(ctx):
ext = ".txt"
if ctx.attr.format == "windows":
ext = ".def"
elif ctx.attr.format == "osx":
ext = ".list"
output_file = ctx.actions.declare_file(ctx.label.name + ext)
ctx.actions.run(
outputs = [output_file],
inputs = [ctx.file.src],
executable = ctx.executable._tool,
arguments = [
"--input",
ctx.file.src.path,
"--output",
output_file.path,
"--lib_name",
ctx.attr.lib_name,
"--format",
ctx.attr.format,
],
mnemonic = "GenVersionScript",
progress_message = "Generating version script for %{label}",
)
return [DefaultInfo(files = depset([output_file]), runfiles = ctx.runfiles(files = [output_file])), OutputGroupInfo(version_script_file = depset([output_file]))]
gen_versionscript = rule(
implementation = _gen_versionscript_impl,
attrs = {
"format": attr.string(
mandatory = True,
values = ["linux", "windows", "osx"],
doc = "The output format.",
),
"lib_name": attr.string(
mandatory = True,
doc = "The name of the library.",
),
"src": attr.label(
mandatory = True,
allow_single_file = True,
doc = "The input symbols file.",
),
"_tool": attr.label(
default = Label("//shared/bazel/rules/gen:gen_versionscript"),
executable = True,
cfg = "exec",
),
},
doc = "Generates a version script from a symbols file.",
)

View File

@@ -0,0 +1,49 @@
import argparse
# Quick script to generate a version script for each OS from a list of symbols.
def main():
parser = argparse.ArgumentParser(description="Generate a version script.")
parser.add_argument("--input", required=True, help="Input symbols file")
parser.add_argument("--output", required=True, help="Output version script file")
parser.add_argument(
"--lib_name", required=True, help="Name of the library for the version script"
)
parser.add_argument(
"--format",
required=True,
choices=["linux", "windows", "osx"],
help="Output format",
)
args = parser.parse_args()
with open(args.input, "r") as f:
symbols = f.read().splitlines()
with open(args.output, "w") as f:
if args.format == "linux":
f.write(f"{args.lib_name} {{\n")
f.write(" global: ")
for symbol in symbols:
symbol = symbol.strip()
if symbol:
f.write(f"{symbol}; ")
f.write("\n local: *;\n")
f.write("};\n")
elif args.format == "windows":
f.write(f"LIBRARY {args.lib_name}\n")
f.write("EXPORTS\n")
for symbol in symbols:
symbol = symbol.strip()
if symbol:
f.write(f" {symbol}\n")
elif args.format == "osx":
for symbol in symbols:
symbol = symbol.strip()
if symbol:
f.write(f"_{symbol}\n")
if __name__ == "__main__":
main()