Skip to content

Commit c8cf342

Browse files
author
Siddhartha Bagaria
authored
Add a test for darwin to linux cross-compilation (#99)
Two changes were needed to make cross-compilation actually work: 1. The target triple needed to be provided. 2. C++ standard flags needed to be revised. The test checks both linkstatic and fully_static modes. Fixes #20.
1 parent f2ea034 commit c8cf342

File tree

5 files changed

+168
-59
lines changed

5 files changed

+168
-59
lines changed

.github/workflows/tests.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ jobs:
1717
steps:
1818
- uses: actions/checkout@v2
1919
- name: test
20-
env:
21-
BAZELISK_GITHUB_TOKEN: ${{ secrets.BAZELISK_GITHUB_TOKEN }}
2220
run: tests/scripts/${{ matrix.script }}
2321
container_test:
2422
runs-on: ubuntu-latest
@@ -32,6 +30,10 @@ jobs:
3230
steps:
3331
- uses: actions/checkout@v2
3432
- name: test
35-
env:
36-
BAZELISK_GITHUB_TOKEN: ${{ secrets.BAZELISK_GITHUB_TOKEN }}
3733
run: tests/scripts/${{ matrix.script }}_test.sh
34+
xcompile_test:
35+
runs-on: macos-latest
36+
steps:
37+
- uses: actions/checkout@v2
38+
- name: test
39+
run: tests/scripts/run_xcompile_tests.sh

platforms/BUILD.bazel

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright 2021 The Bazel Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
platform(
16+
name = "linux-x86_64",
17+
constraint_values = [
18+
"@platforms//os:linux",
19+
"@platforms//cpu:x86_64",
20+
],
21+
)
22+
23+
platform(
24+
name = "linux-aarch64",
25+
constraint_values = [
26+
"@platforms//os:osx",
27+
"@platforms//cpu:aarch64",
28+
],
29+
)
30+
31+
platform(
32+
name = "darwin-x86_64",
33+
constraint_values = [
34+
"@platforms//os:osx",
35+
"@platforms//cpu:x86_64",
36+
],
37+
)

tests/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@ cc_library(
2020
hdrs = ["stdlib.h"],
2121
)
2222

23+
# We want to emulate the behavior of cc_binary but be able to run the target as
24+
# a test, so we use a cc_test target with linkstatic.
2325
cc_test(
2426
name = "stdlib_test",
2527
srcs = ["stdlib_test.cc"],
28+
linkstatic = True,
2629
deps = [":stdlib"],
2730
)
2831

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/bin/bash
2+
# Copyright 2021 The Bazel Authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
set -euo pipefail
17+
18+
source "$(dirname "${BASH_SOURCE[0]}")/bazel.sh"
19+
"${bazel}" version
20+
21+
binpath="$("${bazel}" info bazel-bin)/tests/stdlib_test"
22+
23+
check_with_image() {
24+
if "${CI:-false}"; then
25+
# macOS GitHub Action Runners do not have docker installed on them.
26+
return
27+
fi
28+
local image="$1"
29+
docker run --rm --mount "type=bind,source=${binpath},target=/stdlib_test" "${image}" /stdlib_test
30+
}
31+
32+
echo ""
33+
echo "Testing static linked user libraries and dynamic linked system libraries"
34+
build_args=(
35+
--incompatible_enable_cc_toolchain_resolution
36+
--platforms=//platforms:linux-x86_64
37+
--extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux
38+
--symlink_prefix=/
39+
--color=yes
40+
--show_progress_rate_limit=30
41+
)
42+
"${bazel}" --bazelrc=/dev/null build "${build_args[@]}" //tests:stdlib_test
43+
file "${binpath}" | tee /dev/stderr | grep -q ELF
44+
check_with_image "frolvlad/alpine-glibc" # Need glibc image for system libraries.
45+
46+
echo ""
47+
echo "Testing static linked user and system libraries"
48+
build_args+=(
49+
--features=fully_static_link
50+
)
51+
"${bazel}" --bazelrc=/dev/null build "${build_args[@]}" //tests:stdlib_test
52+
file "${binpath}" | tee /dev/stderr | grep -q ELF
53+
check_with_image "alpine"

toolchain/cc_toolchain_config.bzl

Lines changed: 69 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -96,87 +96,101 @@ def cc_toolchain_config(
9696

9797
is_xcompile = not (host_os == target_os and host_arch == target_arch)
9898

99+
# Default compiler flags:
100+
compile_flags = [
101+
"--target=" + target_system_name,
102+
# Security
103+
"-U_FORTIFY_SOURCE", # https://github.com/google/sanitizers/issues/247
104+
"-fstack-protector",
105+
"-fno-omit-frame-pointer",
106+
# Diagnostics
107+
"-fcolor-diagnostics",
108+
"-Wall",
109+
"-Wthread-safety",
110+
"-Wself-assign",
111+
]
112+
113+
dbg_compile_flags = ["-g", "-fstandalone-debug"]
114+
115+
opt_compile_flags = [
116+
"-g0",
117+
"-O2",
118+
"-D_FORTIFY_SOURCE=1",
119+
"-DNDEBUG",
120+
"-ffunction-sections",
121+
"-fdata-sections",
122+
]
123+
124+
link_flags = [
125+
"--target=" + target_system_name,
126+
"-lm",
127+
"-no-canonical-prefixes",
128+
]
129+
99130
# Linker flags:
100131
if host_os == "darwin" and not is_xcompile:
101132
# lld is experimental for Mach-O, so we use the native ld64 linker.
102133
use_lld = False
103-
linker_flags = [
134+
link_flags.extend([
104135
"-headerpad_max_install_names",
105136
"-undefined",
106137
"dynamic_lookup",
107-
]
138+
])
108139
else:
109140
# We prefer the lld linker.
110141
# Note that for xcompiling from darwin to linux, the native ld64 is
111142
# not an option because it is not a cross-linker, so lld is the
112143
# only option.
113144
use_lld = True
114-
linker_flags = [
145+
link_flags.extend([
115146
"-fuse-ld=lld",
116147
"-Wl,--build-id=md5",
117148
"-Wl,--hash-style=gnu",
118149
"-Wl,-z,relro,-z,now",
119-
]
150+
])
120151

152+
# Flags related to C++ standard.
121153
# The linker has no way of knowing if there are C++ objects; so we
122154
# always link C++ libraries.
123-
if host_os == "linux" and not is_xcompile:
124-
# For single-platform linux builds, we can statically link the bundled
125-
# libraries.
126-
linker_flags.extend([
127-
"-L{}lib".format(toolchain_path_prefix),
128-
"-l:libc++.a",
129-
"-l:libc++abi.a",
130-
"-l:libunwind.a",
131-
# Compiler runtime features.
132-
"-rtlib=compiler-rt",
133-
# To support libunwind.
134-
"-lpthread",
135-
"-ldl",
136-
])
155+
if not is_xcompile:
156+
cxx_flags = [
157+
"-std=c++17",
158+
"-stdlib=libc++",
159+
]
160+
if use_lld:
161+
# For single-platform builds, we can statically link the bundled
162+
# libraries.
163+
link_flags.extend([
164+
"-L{}lib".format(toolchain_path_prefix),
165+
"-l:libc++.a",
166+
"-l:libc++abi.a",
167+
"-l:libunwind.a",
168+
# Compiler runtime features.
169+
"-rtlib=compiler-rt",
170+
# To support libunwind.
171+
"-lpthread",
172+
"-ldl",
173+
])
174+
else:
175+
# TODO: Not sure how to achieve static linking of bundled libraries
176+
# with ld64; maybe we don't really need it.
177+
link_flags.extend([
178+
"-lc++",
179+
"-lc++abi",
180+
])
137181
else:
182+
cxx_flags = [
183+
"-std=c++17",
184+
"-stdlib=libstdc++",
185+
]
186+
138187
# For xcompile, we expect to pick up these libraries from the sysroot.
139-
# TODO: For single-platform darwin builds, we can statically link the
140-
# bundled libraries but I do not know the right flags to make it
141-
# happen.
142-
linker_flags.extend([
143-
"-lc++",
144-
"-lc++abi",
188+
link_flags.extend([
189+
"-l:libstdc++.a",
145190
])
146191

147-
link_flags = [
148-
"-lm",
149-
"-no-canonical-prefixes",
150-
] + linker_flags
151-
152192
opt_link_flags = ["-Wl,--gc-sections"] if target_os == "linux" else []
153193

154-
# Default compiler flags:
155-
compile_flags = [
156-
# Security
157-
"-U_FORTIFY_SOURCE", # https://github.com/google/sanitizers/issues/247
158-
"-fstack-protector",
159-
"-fno-omit-frame-pointer",
160-
# Diagnostics
161-
"-fcolor-diagnostics",
162-
"-Wall",
163-
"-Wthread-safety",
164-
"-Wself-assign",
165-
]
166-
167-
dbg_compile_flags = ["-g", "-fstandalone-debug"]
168-
169-
opt_compile_flags = [
170-
"-g0",
171-
"-O2",
172-
"-D_FORTIFY_SOURCE=1",
173-
"-DNDEBUG",
174-
"-ffunction-sections",
175-
"-fdata-sections",
176-
]
177-
178-
cxx_flags = ["-std=c++17", "-stdlib=libc++"]
179-
180194
# Coverage flags:
181195
coverage_compile_flags = ["-fprofile-instr-generate", "-fcoverage-mapping"]
182196
coverage_link_flags = ["-fprofile-instr-generate"]

0 commit comments

Comments
 (0)