Skip to content

Commit

Permalink
Enable armv8 build using clang (#527)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ionut Victor Anghelcovici authored Jan 31, 2020
1 parent 2aa373a commit 7978a6e
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 53 deletions.
31 changes: 29 additions & 2 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,38 @@ build:wasm32 --symlink_prefix=bazel-wasm-
build:clang --crosstool_top=//toolchain:clang
build:clang --host_crosstool_top=@bazel_tools//tools/cpp:toolchain
build:clang --cpu=k8
build:clang --copt=-Wno-error=sign-compare

# Force the usage of stack protectors for all functions.
build:clang --cxxopt="-fstack-protector-all"
# Pretty colours.
build:clang --cxxopt="-fcolor-diagnostics"
# Don't omit the frame pointer, useful for debug.
build:clang --cxxopt="-fno-omit-frame-pointer"
# Enable all warnings.
build:clang --cxxopt="-Wall"
# Enable extra warnings.
build:clang --cxxopt="-Wextra"
# Simple but useful static checking to detect potential race conditions.
build:clang --cxxopt="-Wthread-safety"
# Treat warnings as errors.
build:clang --cxxopt="-Werror"
# Disable some warnings:
# protobuf generates unused parameters, so skip this for now.
build:clang --cxxopt="-Wno-unused-parameter"
# https://stackoverflow.com/questions/1538943
build:clang --cxxopt="-Wno-missing-field-initializers"
# Latest Asylo update
build:clang --cxxopt="-Wno-error=sign-compare"
# Use a different symlink prefix for clang-based artifacts.
build:clang --symlink_prefix=bazel-clang-

# armv8 build
build:armv8 --crosstool_top=//toolchain:clang
build:armv8 --host_crosstool_top=@bazel_tools//tools/cpp:toolchain
build:armv8 --cpu=armv8

# Use a different symlink prefix for armv8-based artifacts.
build:armv8 --symlink_prefix=bazel-armv8-

# Emscripten toolchain for Wasm.
build:emscripten --crosstool_top=//toolchain:emscripten
build:emscripten --cpu=wasm
Expand Down
14 changes: 13 additions & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,24 @@ go_rules_compat(
# clang + llvm 8.0
http_archive(
name = "clang",
build_file = "//toolchain:clang.BUILD",
build_file = "//toolchain:all_files.BUILD",
sha256 = "0f5c314f375ebd5c35b8c1d5e5b161d9efaeff0523bac287f8b4e5b751272f51",
strip_prefix = "clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-18.04",
url = "http://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz",
)

# Gcc compiler for Arm
# We need the compiler in order to get the sysroot for aarch64_linux to crosscompile + all the
# needed libraries to link agaisnt.
# NB: we are not usign gcc to build, clang is still the default compiler.
http_archive(
name = "gcc_arm",
build_file = "//toolchain:all_files.BUILD",
sha256 = "8ce3e7688a47d8cd2d8e8323f147104ae1c8139520eca50ccf8a7fa933002731",
strip_prefix = "gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu",
url = "https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz",
)

load("//toolchain:emcc_toolchain_config.bzl", "emsdk_configure")

# Should be configured after loading `clang`.
Expand Down
5 changes: 5 additions & 0 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ steps:
timeout: 30m
entrypoint: 'bash'
args: ['./scripts/build_server_dev']
- name: 'gcr.io/oak-ci/oak:latest'
id: build_server_dev_arm
timeout: 30m
entrypoint: 'bash'
args: ['./scripts/build_server_dev_arm']
- name: 'gcr.io/oak-ci/oak:latest'
id: build_server_docker
waitFor: ['build_server_dev']
Expand Down
1 change: 0 additions & 1 deletion oak/server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ cc_library(
":base_runtime",
":oak_grpc_node",
":wasm_node",
"//oak/asylo_rust:asylo_rust_wrapper",
"//oak/common:app_config",
"//oak/proto:enclave_cc_proto",
"//oak/proto:oak_api_cc_proto",
Expand Down
16 changes: 0 additions & 16 deletions oak/server/oak_runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
#include "oak/common/app_config.h"
#include "oak/server/wasm_node.h"

#include "oak/asylo_rust/rust_check.h"

namespace oak {

namespace {
Expand Down Expand Up @@ -158,20 +156,6 @@ bool OakRuntime::CreateAndRunNode(const std::string& config_name,
}

grpc::Status OakRuntime::Start() {
// We call into the Rust runtime to verify that bindings between C++ and Rust are working
// correctly.
{
LOG(INFO) << "Calling Rust runtime";
int32_t rust_check = add_magic_number(1000);

if (rust_check != 1042) {
LOG(ERROR) << "failed rust magic number" << rust_check;
return grpc::Status::CANCELLED;
}

LOG(INFO) << "Rust runtime called, result: " << rust_check;
}

LOG(INFO) << "Starting runtime";
absl::MutexLock lock(&mu_);

Expand Down
15 changes: 15 additions & 0 deletions scripts/build_server_dev_arm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash

readonly SCRIPTS_DIR="$(dirname "$(readlink -f "$0")")"
# shellcheck source=scripts/common
source "$SCRIPTS_DIR/common"

CONFIG='armv8'

bazel_build_flags+=(
"--config=${CONFIG}"
)

# Use a different output_base so that we don't lose incremental state.
# See https://docs.bazel.build/versions/master/command-line-reference.html#flag--output_base.
bazel --output_base="$CACHE_DIR/$CONFIG" build "${bazel_build_flags[@]}" //oak/server/dev:oak
39 changes: 36 additions & 3 deletions toolchain/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@
#

load("@rules_cc//cc:defs.bzl", "cc_toolchain", "cc_toolchain_suite")
load(":cc_toolchain_config.bzl", "cc_toolchain_config")
load(":emcc_toolchain_config.bzl", "emcc_toolchain_config")

package(
default_visibility = ["//visibility:public"],
licenses = ["notice"],
)

load(":cc_toolchain_config.bzl", "cc_toolchain_config")
load(":emcc_toolchain_config.bzl", "emcc_toolchain_config")

cc_toolchain_config(
name = "clang_toolchain_config_wasm32",
cpu = "wasm32",
Expand All @@ -34,11 +33,17 @@ cc_toolchain_config(
cpu = "k8",
)

cc_toolchain_config(
name = "clang_toolchain_config_armv8",
cpu = "armv8",
)

cc_toolchain_suite(
name = "clang",
toolchains = {
"wasm32": ":clang_toolchain_wasm32",
"k8": ":clang_toolchain_k8",
"armv8": ":clang_toolchain_armv8",
},
)

Expand All @@ -53,6 +58,7 @@ cc_toolchain_suite(
},
)

# Include all the files that we install for clang plus the scrips to call into it.
filegroup(
name = "clang_files",
srcs = [
Expand All @@ -62,6 +68,19 @@ filegroup(
],
)

# Include all clang files plus the gcc_arm sysroot and libraries.
# We keep this separated to avoid downloading gcc_arm unless needed.
filegroup(
name = "clang_with_arm_sysroot_files",
srcs = [
"ar.sh",
"clang.sh",
"@clang//:all_files",
"@gcc_arm//:all_files",
],
)

# Include all the files that we install for emscripten.
filegroup(
name = "emscripten_files",
srcs = [
Expand Down Expand Up @@ -99,6 +118,20 @@ cc_toolchain(
toolchain_identifier = "clang-toolchain_k8",
)

cc_toolchain(
name = "clang_toolchain_armv8",
all_files = ":clang_with_arm_sysroot_files",
ar_files = ":clang_with_arm_sysroot_files",
compiler_files = ":clang_with_arm_sysroot_files",
dwp_files = ":empty",
linker_files = ":clang_with_arm_sysroot_files",
objcopy_files = ":empty",
strip_files = ":empty",
supports_param_files = 0,
toolchain_config = ":clang_toolchain_config_armv8",
toolchain_identifier = "clang-toolchain_armv8",
)

cc_toolchain(
name = "emscripten_toolchain_wasm",
all_files = ":emscripten_files",
Expand Down
File renamed without changes.
94 changes: 64 additions & 30 deletions toolchain/cc_toolchain_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -103,19 +103,25 @@ def _impl(ctx):
),
]

# System include path we need to setup for the downloaded clang
isystem_flags = feature(
name = "isystem_flags",
# aarch64 linux gnu cross compile flags
arm_compile_flags = feature(
name = "arm_compile_flags",
enabled = True,
flag_sets = [
flag_set(
actions = all_compile_actions,
flag_groups = [
flag_group(
flags = [
# Bazel require explicit include paths for system headers
"-isystem",
"external/clang/lib/clang/8.0.0/include",
# sysroot that has all the includes.
"--sysroot=external/gcc_arm/aarch64-linux-gnu/libc",
# Path to get all the .so files we needed.
"--gcc-toolchain=external/gcc_arm",
# Compile for aarch64 linux.
"--target=aarch64-linux-gnu",
# Use armv8a architecture.
"-march=armv8a",
# Make the include paths absolute, not relative to clang binary
"-no-canonical-prefixes",
],
),
Expand All @@ -124,8 +130,35 @@ def _impl(ctx):
],
)

# Because we use clang to build everything (instead of clang++), we need to remind it to
# link the correct stdc++ library
arm_link_flags = feature(
name = "arm_link_flags",
enabled = True,
flag_sets = [
flag_set(
actions = [ACTION_NAMES.cpp_link_executable],
flag_groups = [
flag_group(
flags = [
# Use lld as the linker as it is faster and shows better error messages.
"-fuse-ld=lld",
# sysroot that has all the includes.
"--sysroot=external/gcc_arm/aarch64-linux-gnu/libc",
# Path to get all the .so files we needed.
"--gcc-toolchain=external/gcc_arm",
# Compile for aarch64 linux.
"--target=aarch64-linux-gnu",
# Use armv8a architecture.
"-march=armv8a",
# Because we use clang to build everything (instead of clang++), we need
# to remind it to link the correct stdc++ library.
"-lstdc++",
],
),
],
),
],
)

k8_link_flags = feature(
name = "k8_link_flags",
enabled = True,
Expand All @@ -135,6 +168,10 @@ def _impl(ctx):
flag_groups = [
flag_group(
flags = [
# Use lld as the linker as it is faster and shows better error messages.
"-fuse-ld=lld",
# Because we use clang to build everything (instead of clang++), we need
# to remind it to link the correct stdc++ library.
"-lstdc++",
],
),
Expand All @@ -152,25 +189,8 @@ def _impl(ctx):
flag_groups = [
flag_group(
flags = [
# Force the usage of stack protectors for all functions.
"-fstack-protector-all",
# Pretty colours.
"-fcolor-diagnostics",
# Don't omit the frame pointer, useful for debug.
"-fno-omit-frame-pointer",
# Enable all warnings.
"-Wall",
# Enable extra warnings.
"-Wextra",
# Simple but useful static checking to detect potential race conditions.
"-Wthread-safety",
# Treat warnings as errors.
"-Werror",
# Disable some warnings:
# protobuf generates unusused parameters, so skip this for now.
"-Wno-unused-parameter",
# https://stackoverflow.com/questions/1538943
"-Wno-missing-field-initializers",
# Make the include paths absolute, not relative to clang binary
"-no-canonical-prefixes",
],
),
],
Expand All @@ -194,6 +214,11 @@ def _impl(ctx):
# Do not try to use any standard includes for C or C++
"-nostdinc",
"-nostdinc++",
# Make the include paths absolute, not relative to clang binary
"-no-canonical-prefixes",
# Bazel require explicit include paths for system headers
"-isystem",
"external/clang/lib/clang/8.0.0/include",
],
),
],
Expand Down Expand Up @@ -244,19 +269,28 @@ def _impl(ctx):
"/usr/include",
]
features = [
isystem_flags,
k8_compile_flags,
k8_link_flags,
]
toolchain_identifier = "clang-toolchain_k8"
elif (ctx.attr.cpu == "armv8"):
target_cpu = "armv8a"
target_system_name = "aarch64"
abi_version = "aarch64-linux-gnu"
abi_libc_version = "aarch64-linux-gnu"
cxx_builtin_include_directories = []
features = [
arm_compile_flags,
arm_link_flags,
]
toolchain_identifier = "clang-toolchain_armv8"
elif (ctx.attr.cpu == "wasm32"):
target_cpu = "wasm32"
target_system_name = "wasm32-unknown-unknown"
abi_version = "unknown"
abi_libc_version = "unknown"
cxx_builtin_include_directories = []
features = [
isystem_flags,
wasm_compile_flags,
wasm_link_flags,
]
Expand All @@ -283,7 +317,7 @@ def _impl(ctx):
cc_toolchain_config = rule(
implementation = _impl,
attrs = {
"cpu": attr.string(mandatory = True, values = ["k8", "wasm32"]),
"cpu": attr.string(mandatory = True, values = ["k8", "wasm32", "armv8"]),
},
provides = [CcToolchainConfigInfo],
)

0 comments on commit 7978a6e

Please sign in to comment.