Skip to content

Commit

Permalink
Merge pull request #16632 from github/redsun82/bazel-fix
Browse files Browse the repository at this point in the history
Bazel: fix non-swift macOS builds
  • Loading branch information
redsun82 authored May 31, 2024
2 parents 67e2ea1 + 25ab1a9 commit 01c1acd
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 41 deletions.
6 changes: 2 additions & 4 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub

build --repo_env=CC=clang --repo_env=CXX=clang++

build:linux --cxxopt=-std=c++20 --host_cxxopt=-std=c++20
# we currently cannot built the swift extractor for ARM
build:macos --cxxopt=-std=c++20 --host_cxxopt=-std=c++20 --copt=-arch --copt=x86_64 --linkopt=-arch --linkopt=x86_64
build:windows --cxxopt=/std:c++20 --cxxopt=/Zc:preprocessor --host_cxxopt=/std:c++20 --host_cxxopt=/Zc:preprocessor
# we use transitions that break builds of `...`, so for `test` to work with that we need the following
test --build_tests_only

# this requires developer mode, but is required to have pack installer functioning
startup --windows_enable_symlinks
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/go-tests-other-os.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ on:
- .github/workflows/go-tests-other-os.yml
- .github/actions/**
- codeql-workspace.yml
- MODULE.bazel
- .bazelrc
- misc/bazel/**

permissions:
contents: read
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/go-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ on:
- .github/workflows/go-tests.yml
- .github/actions/**
- codeql-workspace.yml
- MODULE.bazel
- .bazelrc
- misc/bazel/**

permissions:
contents: read
Expand Down
3 changes: 3 additions & 0 deletions misc/bazel/internal/zipmerge/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ cc_library(
"zipmerge.cpp",
],
hdrs = ["zipmerge.h"],
copts = ["-std=c++20"],
)

cc_binary(
name = "zipmerge",
srcs = [
"zipmerge_main.cpp",
],
copts = ["-std=c++20"],
visibility = ["//visibility:public"],
deps = [
":lib",
Expand All @@ -21,6 +23,7 @@ cc_test(
name = "test",
size = "small",
srcs = ["zipmerge_test.cpp"],
copts = ["-std=c++20"],
data = glob(["test-files/*"]),
linkstatic = True, # required to build the test in the internal repo
deps = [
Expand Down
38 changes: 38 additions & 0 deletions misc/bazel/os.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
""" Os detection facilities. """

def os_select(
ctx = None,
*,
linux = None,
windows = None,
macos = None,
default = 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.
"""
choices = {
"linux": linux or default,
"windows": windows or default,
"macos": macos or default,
}
if not ctx:
return select({
"@platforms//os:%s" % os: v
for os, 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")

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"),
}
32 changes: 4 additions & 28 deletions misc/bazel/pkg.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,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")
load("//misc/bazel:os.bzl", "OS_DETECTION_ATTRS", "os_select")

def _make_internal(name):
def internal(suffix = "internal", *args):
Expand All @@ -15,11 +16,6 @@ def _make_internal(name):

return internal

_PLAT_DETECTION_ATTRS = {
"_windows": attr.label(default = "@platforms//os:windows"),
"_macos": attr.label(default = "@platforms//os:macos"),
}

_PLAT_PLACEHOLDER = "{CODEQL_PLATFORM}"

def _expand_path(path, platform):
Expand All @@ -28,28 +24,8 @@ def _expand_path(path, platform):
return ("arch", path)
return ("generic", path)

def _platform_select(
ctx = None,
*,
linux,
windows,
macos):
if ctx:
if ctx.target_platform_has_constraint(ctx.attr._windows[platform_common.ConstraintValueInfo]):
return windows
elif ctx.target_platform_has_constraint(ctx.attr._macos[platform_common.ConstraintValueInfo]):
return macos
else:
return linux
else:
return select({
"@platforms//os:linux": linux,
"@platforms//os:macos": macos,
"@platforms//os:windows": windows,
})

def _detect_platform(ctx = None):
return _platform_select(ctx, linux = "linux64", macos = "osx64", windows = "win64")
return os_select(ctx, linux = "linux64", macos = "osx64", windows = "win64")

def codeql_pkg_files(
*,
Expand Down Expand Up @@ -137,7 +113,7 @@ _extract_pkg_filegroup = rule(
"src": attr.label(providers = [PackageFilegroupInfo, DefaultInfo]),
"kind": attr.string(doc = "What part to extract", values = ["generic", "arch"]),
"arch_overrides": attr.string_list(doc = "A list of files that should be included in the arch package regardless of the path"),
} | _PLAT_DETECTION_ATTRS,
} | OS_DETECTION_ATTRS,
)

_ZipInfo = provider(fields = {"zips_to_prefixes": "mapping of zip files to prefixes"})
Expand Down Expand Up @@ -187,7 +163,7 @@ _zip_info_filter = rule(
attrs = {
"srcs": attr.label_list(doc = "_ZipInfos to transform", providers = [_ZipInfo]),
"kind": attr.string(doc = "Which zip kind to consider", values = ["generic", "arch"]),
} | _PLAT_DETECTION_ATTRS,
} | OS_DETECTION_ATTRS,
)

def _imported_zips_manifest_impl(ctx):
Expand Down
4 changes: 0 additions & 4 deletions swift/actions/build-and-test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ runs:
mkdir -p bazel-cache/{repository,disk}
echo build --repository_cache=bazel-cache/repository --disk_cache=bazel-cache/disk > local.bazelrc
echo test --test_output=errors >> local.bazelrc
# - name: Print unextracted entities
# shell: bash
# run: |
# bazel run //swift/extractor/print_unextracted
- uses: ./swift/actions/share-extractor-pack
- name: Build Swift extractor
shell: bash
Expand Down
114 changes: 109 additions & 5 deletions swift/rules.bzl
Original file line number Diff line number Diff line change
@@ -1,11 +1,109 @@
load("//misc/bazel:os.bzl", "os_select")

# TODO: make a shared library with the internal repos for transitions
# unfortunately github.com/fmeum/rules_meta doesn't work any more with latest bazel

def _transition_impl(settings, attr):
return {
"macos": {
"//command_line_option:copt": [
"-fno-rtti",
# we currently cannot built the swift extractor for ARM
"-arch",
"x86_64",
],
"//command_line_option:cxxopt": [
"-std=c++20",
# we currently cannot built the swift extractor for ARM
"-arch",
"x86_64",
],
"//command_line_option:linkopt": [
# we currently cannot built the swift extractor for ARM
"-arch",
"x86_64",
],
},
"linux": {
"//command_line_option:copt": [
"-fno-rtti",
],
"//command_line_option:cxxopt": [
"-std=c++20",
],
"//command_line_option:linkopt": [],
},
"windows": {
"//command_line_option:copt": [],
"//command_line_option:cxxopt": [
"/std:c++20",
"--cxxopt=/Zc:preprocessor",
],
"//command_line_option:linkopt": [],
},
}[attr.os]

_transition = transition(
implementation = _transition_impl,
inputs = [],
outputs = ["//command_line_option:copt", "//command_line_option:cxxopt", "//command_line_option:linkopt"],
)

def _cc_transition_impl(ctx):
src = ctx.attr.src[0]
default_info = src[DefaultInfo]
executable = default_info.files_to_run.executable
runfiles = default_info.default_runfiles
direct = []
if executable:
original_executable = executable
executable = ctx.actions.declare_file(original_executable.basename)
command = "cp %s %s" % (original_executable.path, executable.path)

ctx.actions.run_shell(
inputs = [original_executable],
outputs = [executable],
command = command,
)

# costly, but no other way to remove the internal exe from the runfiles
files = runfiles.files.to_list()
files.remove(original_executable)
files.append(executable)
runfiles = ctx.runfiles(files)

direct = [executable]

providers = [
DefaultInfo(
files = depset(direct),
runfiles = runfiles,
executable = executable,
),
]
for p in (OutputGroupInfo, CcInfo):
if p in src:
providers.append(src[p])

return providers

_cc_transition = rule(
implementation = _cc_transition_impl,
attrs = {
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
"src": attr.label(mandatory = True, cfg = _transition),
"os": attr.string(),
},
)

def _add_args(kwargs, kwarg, value):
kwargs[kwarg] = kwargs.get(kwarg, []) + value

def _wrap_cc(rule, kwargs):
_add_args(kwargs, "copts", [
# Required by LLVM/Swift
"-fno-rtti",
])
name = kwargs.pop("name")
visibility = kwargs.pop("visibility", None)
_add_args(kwargs, "features", [
# temporary, before we do universal merging
"-universal_binaries",
Expand All @@ -17,7 +115,13 @@ def _wrap_cc(rule, kwargs):
"@platforms//os:macos": [],
"//conditions:default": ["@platforms//:incompatible"],
}))
rule(**kwargs)
rule(name = "internal/" + name, visibility = ["//visibility:private"], **kwargs)
_cc_transition(
name = name,
visibility = visibility,
src = ":internal/" + name,
os = os_select(linux = "linux", macos = "macos", windows = "windows"),
)

def swift_cc_binary(**kwargs):
_wrap_cc(native.cc_binary, kwargs)
Expand Down

0 comments on commit 01c1acd

Please sign in to comment.