Skip to content

Commit

Permalink
Merge pull request #5 from nicholasjng/stable-abi-builds
Browse files Browse the repository at this point in the history
Implement stable ABI builds
  • Loading branch information
nicholasjng authored Mar 6, 2024
2 parents 1bfdcab + 5bc9ecf commit 5c29b43
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 62 deletions.
106 changes: 106 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
@@ -1,3 +1,109 @@
load("@bazel_skylib//lib:selects.bzl", "selects")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_flag")

licenses(["notice"])

exports_files(["LICENSE"])

bool_flag(
name = "minsize",
build_setting_default = False,
)

config_setting(
name = "with_sizeopts",
flag_values = {":minsize": "True"},
)

config_setting(
name = "without_sizeopts",
flag_values = {":minsize": "False"},
)

string_flag(
name = "py-limited-api",
build_setting_default = "unset",
values = [
"cp312",
"cp313",
"unset",
],
)

config_setting(
name = "cp312",
flag_values = {":py-limited-api": "cp312"},
)

config_setting(
name = "cp313",
flag_values = {":py-limited-api": "cp313"},
)

config_setting(
name = "pyunlimitedapi",
flag_values = {":py-limited-api": "unset"},
)

selects.config_setting_group(
name = "unix",
match_any = [
"@platforms//os:linux",
"@platforms//os:macos",
],
)

# Config setting indicating that stable ABI extension build was requested.
selects.config_setting_group(
name = "stable-abi",
match_any = [
":cp312",
":cp313",
],
)

# A stable ABI build on Linux or Mac.
# This requires a different extension name (.abi3.so instead of just .so).
selects.config_setting_group(
name = "stable-abi-unix",
match_all = [
":stable-abi",
":unix",
],
)

# An unlimited Python ABI build on Linux or Mac. Produces a regular .so file.
selects.config_setting_group(
name = "unstable-abi-unix",
match_all = [
":pyunlimitedapi",
":unix",
],
)

# Is the currently configured C++ compiler not MSVC?
selects.config_setting_group(
name = "nonmsvc",
match_any = [
"@rules_cc//cc/compiler:gcc",
"@rules_cc//cc/compiler:clang",
"@rules_cc//cc/compiler:clang-cl",
"@rules_cc//cc/compiler:mingw-gcc",
],
)

selects.config_setting_group(
name = "msvc_and_minsize",
match_all = [
"@rules_cc//cc/compiler:msvc-cl",
":with_sizeopts",
],
)

selects.config_setting_group(
name = "nonmsvc_and_minsize",
match_all = [
":nonmsvc",
":with_sizeopts",
],
)
15 changes: 9 additions & 6 deletions build_defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ which can then be included e.g. as a `data` input in a ``native.py_library``.
"""

load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
load("@nanobind_bazel//:helpers.bzl", "extension_name")

NANOBIND_COPTS = select({
Label("@nanobind//:msvc"): [],
Label("@rules_cc//cc/compiler:msvc-cl"): [],
"//conditions:default": ["-fexceptions", "-fvisibility=hidden"],
})

Expand All @@ -40,7 +41,6 @@ def nanobind_extension(
features = [],
deps = [],
**kwargs):
# TODO: This might need a different suffix depending on SABI yes/no.
native.cc_binary(
name = name + ".so",
srcs = srcs,
Expand All @@ -52,6 +52,12 @@ def nanobind_extension(
**kwargs
)

copy_file(
name = name + "_copy_so_to_abi3_so",
src = name + ".so",
out = name + ".abi3.so",
)

copy_file(
name = name + "_copy_so_to_pyd",
src = name + ".so",
Expand All @@ -60,10 +66,7 @@ def nanobind_extension(

native.alias(
name = name,
actual = select({
"@platforms//os:windows": name + ".pyd",
"//conditions:default": name + ".so",
}),
actual = extension_name(name),
)

def nanobind_library(
Expand Down
29 changes: 26 additions & 3 deletions helpers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,30 @@

def sizeopts():
return select({
"@nanobind//:msvc_and_minsize": ["/Os"],
"@nanobind//:nonmsvc_and_minsize": ["-Os"],
"@nanobind//:without_sizeopts": [],
"@nanobind_bazel//:msvc_and_minsize": ["/Os"],
"@nanobind_bazel//:nonmsvc_and_minsize": ["-Os"],
"@nanobind_bazel//:without_sizeopts": [],
})

def sizedefs():
return select({
"@nanobind_bazel//:with_sizeopts": ["NB_COMPACT_ASSERTS"],
"@nanobind_bazel//:without_sizeopts": [],
})

# Define the Python version hex if stable ABI builds are requested.
def pyversionhex():
return select({
"@nanobind_bazel//:cp312": ["Py_LIMITED_API=0x030C0000"],
"@nanobind_bazel//:cp313": ["Py_LIMITED_API=0x030D0000"],
"@nanobind_bazel//:pyunlimitedapi": [],
})

# Get the name for a built nanobind extension based on target platform
# and stable ABI build yes/no.
def extension_name(name):
return select({
"@platforms//os:windows": name + ".pyd",
"@nanobind_bazel//:stable-abi-unix": name + ".abi3.so",
"@nanobind_bazel//:unstable-abi-unix": name + ".so",
})
58 changes: 5 additions & 53 deletions nanobind.BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -5,62 +5,13 @@ Size optimizations used: -Os, LTO
Linker optimizations used: LTCG (MSVC on Windows), linker response file (macOS only).
"""

load("@bazel_skylib//lib:selects.bzl", "selects")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("@nanobind_bazel//:helpers.bzl", "sizeopts")
load("@nanobind_bazel//:helpers.bzl", "pyversionhex", "sizedefs", "sizeopts")

licenses(["notice"])

# TODO: Change this when cleaning up exports later.
package(default_visibility = ["//visibility:public"])

bool_flag(
name = "minsize",
build_setting_default = False,
)

config_setting(
name = "with_sizeopts",
flag_values = {":minsize": "True"},
)

config_setting(
name = "without_sizeopts",
flag_values = {":minsize": "False"},
)

config_setting(
name = "msvc",
flag_values = {"@bazel_tools//tools/cpp:compiler": "msvc-cl"},
)

# Is the currently configured C++ compiler not MSVC?
selects.config_setting_group(
name = "nonmsvc",
match_any = [
"@rules_cc//cc/compiler:gcc",
"@rules_cc//cc/compiler:clang",
"@rules_cc//cc/compiler:clang-cl",
"@rules_cc//cc/compiler:mingw-gcc",
],
)

selects.config_setting_group(
name = "msvc_and_minsize",
match_all = [
":msvc",
":with_sizeopts",
],
)

selects.config_setting_group(
name = "nonmsvc_and_minsize",
match_all = [
":nonmsvc",
":with_sizeopts",
],
)

cc_library(
name = "nanobind",
srcs = glob(["src/*.cpp"]),
Expand All @@ -69,29 +20,30 @@ cc_library(
"//conditions:default": [],
}),
copts = select({
":msvc": [
"@rules_cc//cc/compiler:msvc-cl": [
"/EHsc", # exceptions
"/GL", # LTO / whole program optimization
],
# clang and gcc, across all platforms.
"//conditions:default": [
"-fexceptions",
"-flto",
"-Os",
],
}) + sizeopts(),
defines = pyversionhex(),
includes = [
"ext/robin_map/include",
"include",
],
linkopts = select({
":msvc": ["/LTCG"], # MSVC.
"@rules_cc//cc/compiler:msvc-cl": ["/LTCG"], # MSVC.
"@platforms//os:macos": [
"-Wl,@$(location :cmake/darwin-ld-cpython.sym)", # Apple.
"-Wl,-dead_strip",
],
"//conditions:default": [],
}),
local_defines = sizedefs(), # sizeopts apply to nanobind only.
textual_hdrs = glob(
[
"include/**/*.h",
Expand Down

0 comments on commit 5c29b43

Please sign in to comment.