mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-25 10:07:36 +03:00
feat: Introduce stable Bazel build
The initial migration to a Bazel based build. All attempts have been made to maintain configuration parity with the upstream build.
This commit is contained in:
parent
54eaed1d8b
commit
7f192e9919
29 changed files with 6564 additions and 1 deletions
113
tools/autoconf.bzl
Normal file
113
tools/autoconf.bzl
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
"Utilities for replicating autoconf behavior"
|
||||
|
||||
load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template")
|
||||
|
||||
def define_macro_if(macro, condition):
|
||||
"""Controls conditional macro definition based on a build condition.
|
||||
|
||||
Args:
|
||||
macro: String macro name to define
|
||||
condition: Build condition that should enable the macro
|
||||
|
||||
Returns:
|
||||
A select dictionary mapping conditions to substitution dictionaries
|
||||
"""
|
||||
|
||||
return select({
|
||||
condition: define_macro(macro),
|
||||
"//conditions:default": undefine_macro(macro),
|
||||
})
|
||||
|
||||
def define_macro_if_with(macro, condition, value):
|
||||
"""Conditionally defines a macro with a specific value based on a build condition.
|
||||
|
||||
Args:
|
||||
macro: String macro name to define
|
||||
condition: Build condition that should enable the macro
|
||||
value: Value to assign to the macro when defined
|
||||
|
||||
Returns:
|
||||
A select dictionary mapping conditions to substitution dictionaries
|
||||
"""
|
||||
|
||||
return select({
|
||||
condition: define_macro_with(macro, value),
|
||||
"//conditions:default": undefine_macro(macro),
|
||||
})
|
||||
|
||||
def define_macro(macro):
|
||||
"""Unconditionally defines a macro.
|
||||
|
||||
Args:
|
||||
macro: String macro name to define
|
||||
|
||||
Returns:
|
||||
A substitution dictionary for the macro
|
||||
"""
|
||||
|
||||
return {"#undef {}".format(macro): "#define {}".format(macro)}
|
||||
|
||||
def define_macro_if_any(macro, conditions):
|
||||
"""Defines a macro if any of the specified conditions are met.
|
||||
|
||||
Args:
|
||||
macro: String macro name to define
|
||||
conditions: List of build conditions that should individually enable the macro
|
||||
|
||||
Returns:
|
||||
A select dictionary mapping conditions to substitution dictionaries
|
||||
"""
|
||||
|
||||
substitutions = {}
|
||||
defined = define_macro(macro)
|
||||
for condition in conditions:
|
||||
substitutions[condition] = defined
|
||||
|
||||
substitutions["//conditions:default"] = undefine_macro(macro)
|
||||
|
||||
return select(substitutions)
|
||||
|
||||
def define_macro_with(macro, value):
|
||||
"""Unconditionally defines a macro with a specific value.
|
||||
|
||||
Args:
|
||||
macro: String macro name to define
|
||||
value: Value to assign to the macro
|
||||
|
||||
Returns:
|
||||
A substitution dictionary for the macro with value
|
||||
"""
|
||||
|
||||
return {"#undef {}".format(macro): "#define {} {}".format(macro, value)}
|
||||
|
||||
def undefine_macro(macro):
|
||||
"""Explicitly undefines a macro with a commented annotation.
|
||||
|
||||
Args:
|
||||
macro: String macro name to undefine
|
||||
|
||||
Returns:
|
||||
A substitution dictionary that replaces the undef with a comment
|
||||
"""
|
||||
|
||||
return {"#undef {}".format(macro): "/* #UNDEF {} */".format(macro)}
|
||||
|
||||
def configure_header(name, substitutions, **kwargs):
|
||||
"""Generates a header file with autoconf-style macro substitutions.
|
||||
|
||||
Args:
|
||||
name: Target name
|
||||
substitutions: Dictionary of substitutions to apply
|
||||
**kwargs: Additional arguments passed to expand_template
|
||||
|
||||
Returns:
|
||||
The processed header file with all substitutions applied
|
||||
"""
|
||||
|
||||
return expand_template(
|
||||
name = name,
|
||||
# The expand_template substitutions are applied serially and overlapping macro names can interfere with each other.
|
||||
# Explicitly marking that a macro has been processed such that the template string no longer matches prevents this.
|
||||
substitutions = substitutions | {"#UNDEF": "#undef"},
|
||||
**kwargs
|
||||
)
|
||||
50
tools/cc.bzl
Normal file
50
tools/cc.bzl
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
"Project specific configuration of rules_cc"
|
||||
|
||||
load("@bazel_skylib//lib:selects.bzl", "selects")
|
||||
|
||||
_COPTS_GCC_COMPATIBLE = [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Wsign-compare",
|
||||
"-Wundef",
|
||||
"-Wno-format-zero-length",
|
||||
"-Wpointer-arith",
|
||||
"-Wno-missing-braces",
|
||||
"-Wno-missing-field-initializers",
|
||||
"-Wimplicit-fallthrough",
|
||||
"-pipe",
|
||||
]
|
||||
|
||||
_COPTS_GCC = _COPTS_GCC_COMPATIBLE + ["-Wno-missing-attributes"]
|
||||
|
||||
_COPTS_MSVC_COMPATIBLE = [
|
||||
"/Zi",
|
||||
"/MT",
|
||||
"/W3",
|
||||
"/FS",
|
||||
]
|
||||
|
||||
# Platform and compiler COPTS consistent with configure/make
|
||||
COPTS = ["-D_REENTRANT"] + select({
|
||||
"@rules_cc//cc/compiler:clang": _COPTS_GCC_COMPATIBLE + ["-Wshorten-64-to-32"],
|
||||
"@rules_cc//cc/compiler:gcc": _COPTS_GCC,
|
||||
"@rules_cc//cc/compiler:mingw-gcc": _COPTS_GCC,
|
||||
"@rules_cc//cc/compiler:msvc-cl": _COPTS_MSVC_COMPATIBLE,
|
||||
"@rules_cc//cc/compiler:clang-cl": _COPTS_MSVC_COMPATIBLE,
|
||||
"//conditions:default": [],
|
||||
}) + selects.with_or({
|
||||
("@platforms//os:windows", "//settings/platform:darwin"): [],
|
||||
"//settings/compiler:gcc_compatible": ["-fvisibility=hidden"],
|
||||
"//conditions:default": [],
|
||||
}) + selects.with_or({
|
||||
("@platforms//os:android", "@platforms//os:linux"): [
|
||||
"-DPIC",
|
||||
"-D_GNU_SOURCE",
|
||||
],
|
||||
"@platforms//os:freebsd": [
|
||||
"-DPIC",
|
||||
"-D_BSD_SOURCE",
|
||||
],
|
||||
"@platforms//os:macos": ["-DPIC"],
|
||||
"//conditions:default": [],
|
||||
})
|
||||
109
tools/transition.bzl
Normal file
109
tools/transition.bzl
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
"Transition build and platform settings"
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "CcInfo")
|
||||
|
||||
PLATFORM = select({
|
||||
"@platforms//os:freebsd": "freebsd",
|
||||
"@platforms//os:linux": "linux",
|
||||
"@platforms//os:windows": "windows",
|
||||
"//settings/platform:darwin": "darwin",
|
||||
"//conditions:default": "unknown",
|
||||
})
|
||||
|
||||
def _platform_constraints_transition_impl(settings, attr):
|
||||
# Assume typical defaults for target platforms
|
||||
default_settings = {
|
||||
"//settings/flags:enable_zone_allocator": {"darwin": "yes", "default": "no"},
|
||||
"//settings/platform:glibc_overrides_support": {"linux": "yes", "default": "no"},
|
||||
"//settings/platform:lg_page": {"darwin": "14", "default": "12"},
|
||||
"//settings/platform:memalign_support": {"linux": "yes", "default": "no"},
|
||||
"//settings/platform:malloc_size_support": {"darwin": "yes", "default": "no"},
|
||||
"//settings/platform:usable_size_const": {"linux": "", "default": "const"},
|
||||
"//settings/platform:valloc_support": {"darwin": "yes", "linux": "yes", "default": "no"},
|
||||
}
|
||||
|
||||
result = {}
|
||||
for label, platform_defaults in default_settings.items():
|
||||
configured_value = settings[label]
|
||||
|
||||
# If unset, use platform-specific default or universal fallback
|
||||
result[label] = (platform_defaults.get(attr.platform, platform_defaults["default"]) if configured_value == "__auto__" else configured_value)
|
||||
|
||||
# Apply explicitly passed settings
|
||||
boolean_settings = ["//settings:enable_jet", "//settings/flags:enable_fill"]
|
||||
for setting in boolean_settings:
|
||||
result[setting] = attr.settings[Label(setting)] == "True" if Label(setting) in attr.settings else settings[setting]
|
||||
|
||||
string_settings = ["//settings:with_test", "//settings/flags:jemalloc_prefix"]
|
||||
for setting in string_settings:
|
||||
result[setting] = attr.settings[Label(setting)] if Label(setting) in attr.settings else settings[setting]
|
||||
|
||||
# Equivalent of JEMALLOC_CPREFIX=`echo ${JEMALLOC_PREFIX} | tr "a-z" "A-Z"`
|
||||
result["//settings/flags:jemalloc_cprefix"] = result["//settings/flags:jemalloc_prefix"].upper()
|
||||
|
||||
return result
|
||||
|
||||
_platform_constraints_transition = transition(
|
||||
implementation = _platform_constraints_transition_impl,
|
||||
inputs = [
|
||||
"//settings:enable_jet",
|
||||
"//settings:with_test",
|
||||
"//settings/flags:jemalloc_prefix",
|
||||
"//settings/flags:jemalloc_cprefix",
|
||||
"//settings/flags:enable_fill",
|
||||
"//settings/flags:enable_zone_allocator",
|
||||
"//settings/platform:glibc_overrides_support",
|
||||
"//settings/platform:lg_page",
|
||||
"//settings/platform:malloc_size_support",
|
||||
"//settings/platform:memalign_support",
|
||||
"//settings/platform:usable_size_const",
|
||||
"//settings/platform:valloc_support",
|
||||
],
|
||||
outputs = [
|
||||
"//settings:enable_jet",
|
||||
"//settings:with_test",
|
||||
"//settings/flags:jemalloc_prefix",
|
||||
"//settings/flags:jemalloc_cprefix",
|
||||
"//settings/flags:enable_fill",
|
||||
"//settings/flags:enable_zone_allocator",
|
||||
"//settings/platform:glibc_overrides_support",
|
||||
"//settings/platform:lg_page",
|
||||
"//settings/platform:malloc_size_support",
|
||||
"//settings/platform:memalign_support",
|
||||
"//settings/platform:usable_size_const",
|
||||
"//settings/platform:valloc_support",
|
||||
],
|
||||
)
|
||||
|
||||
def _transition_default_constraints_impl(ctx):
|
||||
target = ctx.attr.src[0]
|
||||
providers = [DefaultInfo, CcInfo, InstrumentedFilesInfo, OutputGroupInfo]
|
||||
|
||||
return [target[provider] for provider in providers if provider in target]
|
||||
|
||||
transition_default_constraints = rule(
|
||||
doc = "Configure detects target platform constraints. The target platform should declare these, but " +
|
||||
"intelligent defaults can be set for the majority of cases.",
|
||||
implementation = _transition_default_constraints_impl,
|
||||
attrs = {
|
||||
"src": attr.label(cfg = _platform_constraints_transition),
|
||||
"platform": attr.string(
|
||||
doc = "Hack to inject platform constraints into the transition to apply unset defaults",
|
||||
mandatory = True,
|
||||
values = [
|
||||
"freebsd",
|
||||
"linux",
|
||||
"darwin",
|
||||
"windows",
|
||||
"unknown",
|
||||
],
|
||||
),
|
||||
"settings": attr.label_keyed_string_dict(
|
||||
doc = "Settings to explicitly transition",
|
||||
default = {},
|
||||
),
|
||||
"_allowlist_function_transition": attr.label(
|
||||
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
|
||||
),
|
||||
},
|
||||
)
|
||||
27
tools/version.bzl
Normal file
27
tools/version.bzl
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
"Version string utilities."
|
||||
|
||||
def parse_version(version):
|
||||
"""Parses raw version string into a structured version object.
|
||||
|
||||
Returns:
|
||||
struct: Contains version components:
|
||||
- full: Full version
|
||||
- gid: Version git id
|
||||
- major: Major version number
|
||||
- minor: Minor version number
|
||||
- patch: Patch version number
|
||||
- bugfix: Bugfix version
|
||||
- nrev: Revision number
|
||||
"""
|
||||
prefix, gid = version.split("-bcr", 2)
|
||||
major, minor, patch = prefix.split(".", 3)
|
||||
|
||||
return struct(
|
||||
full = prefix,
|
||||
gid = "0",
|
||||
major = major,
|
||||
minor = minor,
|
||||
patch = patch,
|
||||
bugfix = "0",
|
||||
nrev = "0",
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue