Skip to content

Commit 01c1acd

Browse files
authored
Merge pull request github#16632 from github/redsun82/bazel-fix
Bazel: fix non-swift macOS builds
2 parents 67e2ea1 + 25ab1a9 commit 01c1acd

File tree

8 files changed

+162
-41
lines changed

8 files changed

+162
-41
lines changed

.bazelrc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
1010

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

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

1816
# this requires developer mode, but is required to have pack installer functioning
1917
startup --windows_enable_symlinks

.github/workflows/go-tests-other-os.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ on:
77
- .github/workflows/go-tests-other-os.yml
88
- .github/actions/**
99
- codeql-workspace.yml
10+
- MODULE.bazel
11+
- .bazelrc
12+
- misc/bazel/**
1013

1114
permissions:
1215
contents: read

.github/workflows/go-tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ on:
1515
- .github/workflows/go-tests.yml
1616
- .github/actions/**
1717
- codeql-workspace.yml
18+
- MODULE.bazel
19+
- .bazelrc
20+
- misc/bazel/**
1821

1922
permissions:
2023
contents: read

misc/bazel/internal/zipmerge/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ cc_library(
44
"zipmerge.cpp",
55
],
66
hdrs = ["zipmerge.h"],
7+
copts = ["-std=c++20"],
78
)
89

910
cc_binary(
1011
name = "zipmerge",
1112
srcs = [
1213
"zipmerge_main.cpp",
1314
],
15+
copts = ["-std=c++20"],
1416
visibility = ["//visibility:public"],
1517
deps = [
1618
":lib",
@@ -21,6 +23,7 @@ cc_test(
2123
name = "test",
2224
size = "small",
2325
srcs = ["zipmerge_test.cpp"],
26+
copts = ["-std=c++20"],
2427
data = glob(["test-files/*"]),
2528
linkstatic = True, # required to build the test in the internal repo
2629
deps = [

misc/bazel/os.bzl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
""" Os detection facilities. """
2+
3+
def os_select(
4+
ctx = None,
5+
*,
6+
linux = None,
7+
windows = None,
8+
macos = None,
9+
default = None):
10+
"""
11+
This can work both in a macro and a rule context to choose something based on the current OS.
12+
If used in a rule implementation, you need to pass `ctx` and add `OS_DETECTION_ATTRS` to the
13+
rule attributes.
14+
"""
15+
choices = {
16+
"linux": linux or default,
17+
"windows": windows or default,
18+
"macos": macos or default,
19+
}
20+
if not ctx:
21+
return select({
22+
"@platforms//os:%s" % os: v
23+
for os, v in choices.items()
24+
if v != None
25+
})
26+
27+
for os, v in choices.items():
28+
if ctx.target_platform_has_constraint(getattr(ctx.attr, "_%s_constraint" % os)[platform_common.ConstraintValueInfo]):
29+
if v == None:
30+
fail("%s not supported by %s" % (os, ctx.label))
31+
return v
32+
fail("Unknown OS detected")
33+
34+
OS_DETECTION_ATTRS = {
35+
"_windows_constraint": attr.label(default = "@platforms//os:windows"),
36+
"_macos_constraint": attr.label(default = "@platforms//os:macos"),
37+
"_linux_constraint": attr.label(default = "@platforms//os:linux"),
38+
}

misc/bazel/pkg.bzl

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_fil
77
load("@rules_pkg//pkg:pkg.bzl", "pkg_zip")
88
load("@rules_pkg//pkg:providers.bzl", "PackageFilegroupInfo", "PackageFilesInfo")
99
load("@rules_python//python:defs.bzl", "py_binary")
10+
load("//misc/bazel:os.bzl", "OS_DETECTION_ATTRS", "os_select")
1011

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

1617
return internal
1718

18-
_PLAT_DETECTION_ATTRS = {
19-
"_windows": attr.label(default = "@platforms//os:windows"),
20-
"_macos": attr.label(default = "@platforms//os:macos"),
21-
}
22-
2319
_PLAT_PLACEHOLDER = "{CODEQL_PLATFORM}"
2420

2521
def _expand_path(path, platform):
@@ -28,28 +24,8 @@ def _expand_path(path, platform):
2824
return ("arch", path)
2925
return ("generic", path)
3026

31-
def _platform_select(
32-
ctx = None,
33-
*,
34-
linux,
35-
windows,
36-
macos):
37-
if ctx:
38-
if ctx.target_platform_has_constraint(ctx.attr._windows[platform_common.ConstraintValueInfo]):
39-
return windows
40-
elif ctx.target_platform_has_constraint(ctx.attr._macos[platform_common.ConstraintValueInfo]):
41-
return macos
42-
else:
43-
return linux
44-
else:
45-
return select({
46-
"@platforms//os:linux": linux,
47-
"@platforms//os:macos": macos,
48-
"@platforms//os:windows": windows,
49-
})
50-
5127
def _detect_platform(ctx = None):
52-
return _platform_select(ctx, linux = "linux64", macos = "osx64", windows = "win64")
28+
return os_select(ctx, linux = "linux64", macos = "osx64", windows = "win64")
5329

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

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

193169
def _imported_zips_manifest_impl(ctx):

swift/actions/build-and-test/action.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ runs:
4444
mkdir -p bazel-cache/{repository,disk}
4545
echo build --repository_cache=bazel-cache/repository --disk_cache=bazel-cache/disk > local.bazelrc
4646
echo test --test_output=errors >> local.bazelrc
47-
# - name: Print unextracted entities
48-
# shell: bash
49-
# run: |
50-
# bazel run //swift/extractor/print_unextracted
5147
- uses: ./swift/actions/share-extractor-pack
5248
- name: Build Swift extractor
5349
shell: bash

swift/rules.bzl

Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,109 @@
1+
load("//misc/bazel:os.bzl", "os_select")
2+
3+
# TODO: make a shared library with the internal repos for transitions
4+
# unfortunately github.com/fmeum/rules_meta doesn't work any more with latest bazel
5+
6+
def _transition_impl(settings, attr):
7+
return {
8+
"macos": {
9+
"//command_line_option:copt": [
10+
"-fno-rtti",
11+
# we currently cannot built the swift extractor for ARM
12+
"-arch",
13+
"x86_64",
14+
],
15+
"//command_line_option:cxxopt": [
16+
"-std=c++20",
17+
# we currently cannot built the swift extractor for ARM
18+
"-arch",
19+
"x86_64",
20+
],
21+
"//command_line_option:linkopt": [
22+
# we currently cannot built the swift extractor for ARM
23+
"-arch",
24+
"x86_64",
25+
],
26+
},
27+
"linux": {
28+
"//command_line_option:copt": [
29+
"-fno-rtti",
30+
],
31+
"//command_line_option:cxxopt": [
32+
"-std=c++20",
33+
],
34+
"//command_line_option:linkopt": [],
35+
},
36+
"windows": {
37+
"//command_line_option:copt": [],
38+
"//command_line_option:cxxopt": [
39+
"/std:c++20",
40+
"--cxxopt=/Zc:preprocessor",
41+
],
42+
"//command_line_option:linkopt": [],
43+
},
44+
}[attr.os]
45+
46+
_transition = transition(
47+
implementation = _transition_impl,
48+
inputs = [],
49+
outputs = ["//command_line_option:copt", "//command_line_option:cxxopt", "//command_line_option:linkopt"],
50+
)
51+
52+
def _cc_transition_impl(ctx):
53+
src = ctx.attr.src[0]
54+
default_info = src[DefaultInfo]
55+
executable = default_info.files_to_run.executable
56+
runfiles = default_info.default_runfiles
57+
direct = []
58+
if executable:
59+
original_executable = executable
60+
executable = ctx.actions.declare_file(original_executable.basename)
61+
command = "cp %s %s" % (original_executable.path, executable.path)
62+
63+
ctx.actions.run_shell(
64+
inputs = [original_executable],
65+
outputs = [executable],
66+
command = command,
67+
)
68+
69+
# costly, but no other way to remove the internal exe from the runfiles
70+
files = runfiles.files.to_list()
71+
files.remove(original_executable)
72+
files.append(executable)
73+
runfiles = ctx.runfiles(files)
74+
75+
direct = [executable]
76+
77+
providers = [
78+
DefaultInfo(
79+
files = depset(direct),
80+
runfiles = runfiles,
81+
executable = executable,
82+
),
83+
]
84+
for p in (OutputGroupInfo, CcInfo):
85+
if p in src:
86+
providers.append(src[p])
87+
88+
return providers
89+
90+
_cc_transition = rule(
91+
implementation = _cc_transition_impl,
92+
attrs = {
93+
"_allowlist_function_transition": attr.label(
94+
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
95+
),
96+
"src": attr.label(mandatory = True, cfg = _transition),
97+
"os": attr.string(),
98+
},
99+
)
100+
1101
def _add_args(kwargs, kwarg, value):
2102
kwargs[kwarg] = kwargs.get(kwarg, []) + value
3103

4104
def _wrap_cc(rule, kwargs):
5-
_add_args(kwargs, "copts", [
6-
# Required by LLVM/Swift
7-
"-fno-rtti",
8-
])
105+
name = kwargs.pop("name")
106+
visibility = kwargs.pop("visibility", None)
9107
_add_args(kwargs, "features", [
10108
# temporary, before we do universal merging
11109
"-universal_binaries",
@@ -17,7 +115,13 @@ def _wrap_cc(rule, kwargs):
17115
"@platforms//os:macos": [],
18116
"//conditions:default": ["@platforms//:incompatible"],
19117
}))
20-
rule(**kwargs)
118+
rule(name = "internal/" + name, visibility = ["//visibility:private"], **kwargs)
119+
_cc_transition(
120+
name = name,
121+
visibility = visibility,
122+
src = ":internal/" + name,
123+
os = os_select(linux = "linux", macos = "macos", windows = "windows"),
124+
)
21125

22126
def swift_cc_binary(**kwargs):
23127
_wrap_cc(native.cc_binary, kwargs)

0 commit comments

Comments
 (0)