Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions defs.bzl
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
codeql_platform = select({
"@platforms//os:linux": "linux64",
"@platforms//os:macos": "osx64",
"@platforms//os:windows": "win64",
})
load("//misc/bazel:os.bzl", "codeql_platform_select")

codeql_platform = codeql_platform_select(
linux64 = "linux64",
linux_arm64 = "linux-arm64",
osx64 = "osx64",
win64 = "win64",
)
11 changes: 11 additions & 0 deletions misc/bazel/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
load("@rules_shell//shell:sh_library.bzl", "sh_library")

# Matches the Linux arm64 target, used to give it a distinct `CODEQL_PLATFORM` string
# (`linux-arm64`). Every other configuration keeps its OS-only string.
config_setting(
name = "linux_arm64",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:arm64",
],
visibility = ["//visibility:public"],
)

sh_library(
name = "sh_runfiles",
srcs = ["runfiles.sh"],
Expand Down
88 changes: 69 additions & 19 deletions misc/bazel/os.bzl
Original file line number Diff line number Diff line change
@@ -1,38 +1,88 @@
""" Os detection facilities. """

def os_select(
def codeql_platform_select(
ctx = None,
*,
linux = None,
windows = None,
macos = None,
default = None):
linux64 = None,
linux_arm64 = None,
osx64 = None,
win64 = None,
otherwise = None):
"""
This can work both in a macro and a rule context to choose something based on the current OS.
If used in a rule implementation, you need to pass `ctx` and add `OS_DETECTION_ATTRS` to the
rule attributes.
Choose a value based on the target CodeQL platform, discriminating the four platforms CodeQL
knows about: `linux64` (Linux on x86_64), `linux_arm64` (Linux on arm64), `osx64` (macOS, any
architecture) and `win64` (Windows on x86_64). Any platform left unspecified uses `otherwise`.

There is deliberately no fallback between `linux64` and `linux_arm64`: if you want the same value
for both (i.e. you only care about the OS, not the architecture), use `os_select` instead.

This works both in a macro context (`ctx = None`, returning a `select`) and in a rule context
(passing `ctx`, which then needs `OS_DETECTION_ATTRS` on the rule attributes).
"""

def _or_otherwise(value):
return value if value != None else otherwise

linux_arm64_setting = Label("//misc/bazel:linux_arm64")
choices = {
"linux": linux or default,
"windows": windows or default,
"macos": macos or default,
linux_arm64_setting: _or_otherwise(linux_arm64),
"@platforms//os:linux": _or_otherwise(linux64),
"@platforms//os:macos": _or_otherwise(osx64),
"@platforms//os:windows": _or_otherwise(win64),
}
if not ctx:
return select({
"@platforms//os:%s" % os: v
for os, v in choices.items()
setting: v
for setting, v in choices.items()
if v != None
})

for os, v in choices.items():
if ctx.target_platform_has_constraint(getattr(ctx.attr, "_%s_constraint" % os)[platform_common.ConstraintValueInfo]):
if v == None:
fail("%s not supported by %s" % (os, ctx.label))
return v
fail("Unknown OS detected")
def has(constraint):
return ctx.target_platform_has_constraint(getattr(ctx.attr, "_%s_constraint" % constraint)[platform_common.ConstraintValueInfo])

if has("linux"):
result = choices[linux_arm64_setting] if has("arm64") else choices["@platforms//os:linux"]
elif has("macos"):
result = choices["@platforms//os:macos"]
elif has("windows"):
result = choices["@platforms//os:windows"]
else:
fail("Unknown OS detected")
if result == None:
fail("platform not supported by %s" % ctx.label)
return result

def os_select(
ctx = None,
*,
linux = None,
windows = None,
macos = None,
posix = None,
default = None):
"""
Choose a value based on the target OS, ignoring the architecture. This is a thin, OS-only wrapper
around `codeql_platform_select` (Linux gets the same value on both x86_64 and arm64).
`posix` is a convenience for the value shared by `linux` and `macos`; it is mutually exclusive
with both. See `codeql_platform_select` for macro vs rule usage.
"""
if posix != None:
if linux != None or macos != None:
fail("`posix` is mutually exclusive with `linux` and `macos`")
linux = posix
macos = posix
return codeql_platform_select(
ctx,
linux64 = linux,
linux_arm64 = linux,
osx64 = macos,
win64 = windows,
otherwise = default,
)

OS_DETECTION_ATTRS = {
"_windows_constraint": attr.label(default = "@platforms//os:windows"),
"_macos_constraint": attr.label(default = "@platforms//os:macos"),
"_linux_constraint": attr.label(default = "@platforms//os:linux"),
"_arm64_constraint": attr.label(default = "@platforms//cpu:arm64"),
}
14 changes: 10 additions & 4 deletions misc/bazel/pkg.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_fil
load("@rules_pkg//pkg:pkg.bzl", "pkg_zip")
load("@rules_pkg//pkg:providers.bzl", "PackageFilegroupInfo", "PackageFilesInfo")
load("@rules_python//python:defs.bzl", "py_binary", "py_test")
load("//misc/bazel:os.bzl", "OS_DETECTION_ATTRS", "os_select")
load("//misc/bazel:os.bzl", "OS_DETECTION_ATTRS", "codeql_platform_select")

def _make_internal(name):
def internal(suffix = "internal", *args):
Expand All @@ -26,7 +26,13 @@ def _expand_path(path, platform):
return ("common", path)

def _detect_platform(ctx = None):
return os_select(ctx, linux = "linux64", macos = "osx64", windows = "win64")
return codeql_platform_select(
ctx,
linux64 = "linux64",
linux_arm64 = "linux-arm64",
Comment thread
redsun82 marked this conversation as resolved.
osx64 = "osx64",
win64 = "win64",
)

def codeql_pkg_files(
*,
Expand Down Expand Up @@ -458,12 +464,12 @@ def codeql_pack(
`zips` is a map from `.zip` files to prefixes to import.
The distinction between arch-specific and common contents is made based on whether the paths (including possible
prefixes added by rules) contain the special `{CODEQL_PLATFORM}` placeholder, which in case it is present will also
be replaced by the appropriate platform (`linux64`, `win64` or `osx64`).
be replaced by the appropriate platform (`linux64`, `linux-arm64`, `win64` or `osx64`).
Specific file paths can be placed in the arch-specific package by adding them to `arch_overrides`, even if their
path doesn't contain the `CODEQL_PLATFORM` placeholder.

The codeql pack rules will expand the `{CODEQL_PLATFORM}` marker in paths, and use that to split the files into a common and an arch-specific part.
This placeholder will be replaced by the appropriate platform (`linux64`, `win64` or `osx64`).
This placeholder will be replaced by the appropriate platform (`linux64`, `linux-arm64`, `win64` or `osx64`).
`arch_overrides` is a list of files that should be included in the arch-specific bits of the pack, even if their path doesn't
contain the `{CODEQL_PLATFORM}` marker.
All files in the pack will be prefixed with `name`, unless `pack_prefix` is set, then is used instead.
Expand Down
Loading