Skip to content

Commit

Permalink
Merge pull request #402 from DolceTriade/cross_ex
Browse files Browse the repository at this point in the history
crosscompile: Add an example for cross compiling
  • Loading branch information
benradf authored Aug 25, 2023
2 parents e3e1b1a + b102265 commit 6691c54
Show file tree
Hide file tree
Showing 17 changed files with 591 additions and 4 deletions.
13 changes: 10 additions & 3 deletions .github/workflows/workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,16 @@ jobs:
for dir in "${with_nix[@]}"; do
pushd "$dir"
echo
echo "::group::Running $(head -n1 README.md) with Nix"
nix-shell --command 'bazel run --config=nix :hello'
# TODO: all toolchains should run without Nixpkgs
example_name="$(head -n1 README.md) with Nix"
if [[ -f skip-on-ci ]]; then
echo "Skipping $example_name"
popd
continue
else
echo "::group::Running $example_name"
nix-shell --command 'bazel run --config=nix :hello'
# TODO: all toolchains should run without Nixpkgs
fi
popd
done
for dir in "${without_nix[@]}"; do
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
USE_BAZEL_VERSION=6.x
6 changes: 6 additions & 0 deletions examples/toolchains/cc_cross_osx_to_linux_amd64/.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
build --incompatible_enable_cc_toolchain_resolution
build:nix --host_platform=@io_tweag_rules_nixpkgs//nixpkgs/platforms:host
build:nix --crosstool_top=@nixpkgs_config_cc//:toolchain
build:cross --host_platform=@io_tweag_rules_nixpkgs//nixpkgs/platforms:host
build:cross --host_crosstool_top=@nixpkgs_config_cc//:toolchain
build:cross --cpu=k8 --crosstool_top=@nixpkgs_cross_cc//:toolchain --platforms=//toolchains:linux_x86_64
40 changes: 40 additions & 0 deletions examples/toolchains/cc_cross_osx_to_linux_amd64/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
load("@rules_cc//cc:defs.bzl", "cc_binary")
load("@rules_oci//oci:defs.bzl", "oci_image", "oci_tarball")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("//toolchains:runfiles.bzl", "runfiles")

cc_binary(
name = "hello",
srcs = ["hello.cc"],
deps = [
"@boost.dev//:boost",
"@zlib.dev//:zlib",
],
)

runfiles(
name = "hello_runfiles",
binary = ":hello",
root = "/app"
)

pkg_tar(
name = "hello_tar",
srcs = [":hello_runfiles"],
)

oci_image(
name = "hello_image",
base = "@alpine",
tars = [
":hello_tar",
"@nixdeps//:closure.tar",
],
entrypoint = ["/app/hello"],
)

oci_tarball(
name = "hello_image_tarball",
image = ":hello_image",
repo_tags = ["cross_example:latest"],
)
13 changes: 13 additions & 0 deletions examples/toolchains/cc_cross_osx_to_linux_amd64/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
C++ With Dependencies Toolchain Example
=======================================

This is an example C++ project with dependencies that uses `rules_cc`.

This example uses the Nix package manager to provide C++ dependencies, and as such only works with Nix installed. Demonstrating other methods of providing C++ dependencies is out of scope of this example.

# Usage

To run the example with Nix, issue the following command:
```
nix-shell --command 'bazel run --config=cross:hello'
```
180 changes: 180 additions & 0 deletions examples/toolchains/cc_cross_osx_to_linux_amd64/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# Replace with http_archive: https://github.com/tweag/rules_nixpkgs/#setup
local_repository(
name = "io_tweag_rules_nixpkgs",
path = "../../../",
)

load("@io_tweag_rules_nixpkgs//nixpkgs:repositories.bzl", "rules_nixpkgs_dependencies")

rules_nixpkgs_dependencies()

load(
"@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl",
"nixpkgs_cc_configure",
"nixpkgs_local_repository",
)

nixpkgs_local_repository(
name = "nixpkgs",
nix_file = "//:nixpkgs.nix",
nix_file_deps = ["//:nixpkgs.json"],
)

nixpkgs_cc_configure(
name = "nixpkgs_config_cc",
nix_file = "//toolchains:cc.nix",
repository = "@nixpkgs",
)

nixpkgs_cc_configure(
name = "nixpkgs_cross_cc",
cross_cpu = "k8",
exec_constraints = [
"@platforms//os:osx",
"@platforms//cpu:arm64",
],
nix_file = "//toolchains:osxcross_cc.nix",
nixopts = [
"--arg",
"ccPkgs",
"import <nixpkgs> { crossSystem = \"x86_64-linux\";}",
"--show-trace",
],
repository = "@nixpkgs",
target_constraints = [
"@platforms//cpu:x86_64",
"@platforms//os:linux",
"@rules_nixpkgs_core//constraints:support_nix",
],
)

load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_package")

# We would probably want a select or something to make this work with OSX as well, for a more
# production set up.
nixpkgs_package(
name = "boost",
attribute_path = "boost175",
nix_file_content = """import <nixpkgs> { config = {}; overlays = []; system = "x86_64-linux"; }""",
repository = "@nixpkgs",
)

nixpkgs_package(
name = "boost.dev",
attribute_path = "boost175.dev",
build_file_content = """\
load("@rules_cc//cc:defs.bzl", "cc_library")
filegroup(
name = "include",
srcs = glob(["include/**/*.h", "include/**/*.hpp"]),
visibility = ["//visibility:public"],
)
cc_library(
name = "boost",
srcs = ["@boost//:lib"],
hdrs = [":include"],
strip_include_prefix = "include",
visibility = ["//visibility:public"],
)
""",
nix_file_content = """import <nixpkgs> { config = {}; overlays = []; system = "x86_64-linux"; }""",
repository = "@nixpkgs",
)

nixpkgs_package(
name = "zlib",
attribute_path = "zlib",
nix_file_content = """import <nixpkgs> { config = {}; overlays = []; system = "x86_64-linux"; }""",
repository = "@nixpkgs",
)

nixpkgs_package(
name = "zlib.dev",
attribute_path = "zlib.dev",
build_file_content = """\
load("@rules_cc//cc:defs.bzl", "cc_library")
filegroup(
name = "include",
srcs = glob(["include/**/*.h"]),
visibility = ["//visibility:public"],
)
cc_library(
name = "zlib",
srcs = ["@zlib//:lib"],
hdrs = [":include"],
strip_include_prefix = "include",
visibility = ["//visibility:public"],
)
""",
nix_file_content = """import <nixpkgs> { config = {}; overlays = []; system = "x86_64-linux"; }""",
repository = "@nixpkgs",
)

nixpkgs_package(
name = "nixdeps",
build_file_content = """\
exports_files(["closure.tar"])
""",
nix_file = "//toolchains:tarenv.nix",
repository = "@nixpkgs",
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "rules_oci",
sha256 = "a3b6f4c0051938940ccf251a7bdcdf7ac5a93ae00e63ad107c9c6d3bfe20885b",
strip_prefix = "rules_oci-1.3.1",
url = "https://github.com/bazel-contrib/rules_oci/releases/download/v1.3.1/rules_oci-v1.3.1.tar.gz",
)

load("@rules_oci//oci:dependencies.bzl", "rules_oci_dependencies")

rules_oci_dependencies()

load("@rules_oci//oci:repositories.bzl", "LATEST_CRANE_VERSION", "LATEST_ZOT_VERSION", "oci_register_toolchains")

oci_register_toolchains(
name = "oci",
crane_version = LATEST_CRANE_VERSION,
# Uncommenting the zot toolchain will cause it to be used instead of crane for some tasks.
# Note that it does not support docker-format images.
# zot_version = LATEST_ZOT_VERSION,
)

# You can pull your base images using oci_pull like this:
load("@rules_oci//oci:pull.bzl", "oci_pull")

oci_pull(
name = "distroless_base",
digest = "sha256:ccaef5ee2f1850270d453fdf700a5392534f8d1a8ca2acda391fbb6a06b81c86",
image = "gcr.io/distroless/base",
platforms = [
"linux/amd64",
"linux/arm64",
],
)

oci_pull(
name = "alpine",
digest = "sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a",
image = "https://index.docker.io/library/alpine",
platforms = [
"linux/amd64",
],
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "rules_pkg",
sha256 = "8f9ee2dc10c1ae514ee599a8b42ed99fa262b757058f65ad3c384289ff70c4b8",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.9.1/rules_pkg-0.9.1.tar.gz",
"https://github.com/bazelbuild/rules_pkg/releases/download/0.9.1/rules_pkg-0.9.1.tar.gz",
],
)

load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")

rules_pkg_dependencies()
8 changes: 8 additions & 0 deletions examples/toolchains/cc_cross_osx_to_linux_amd64/hello.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <iostream>
#include <boost/filesystem/operations.hpp>
#include <zlib.h>

int main()
{
std::cout << "Hello world!\n";
}
7 changes: 7 additions & 0 deletions examples/toolchains/cc_cross_osx_to_linux_amd64/nixpkgs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"owner": "NixOS",
"repo": "nixpkgs",
"branch": "23.05",
"rev": "3ad64d9e2d5bf80c877286102355b1625891ae9a",
"sha256": "sha256-PuZSAHeq4/9pP/uYH1FcagQ3nLm/DrDrvKi/xC9glvw="
}
8 changes: 8 additions & 0 deletions examples/toolchains/cc_cross_osx_to_linux_amd64/nixpkgs.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
let
spec = builtins.fromJSON (builtins.readFile ./nixpkgs.json);
nixpkgs = fetchTarball {
url = "https://github.com/${spec.owner}/${spec.repo}/archive/${spec.rev}.tar.gz";
sha256 = spec.sha256;
};
in
import nixpkgs
3 changes: 3 additions & 0 deletions examples/toolchains/cc_cross_osx_to_linux_amd64/shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{ pkgs ? import ./nixpkgs.nix { } }:

pkgs.mkShellNoCC { nativeBuildInputs = [ pkgs.bazel_6 ]; }
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
platform(
name = "linux_x86_64",
constraint_values = [
"@platforms//cpu:x86_64",
"@platforms//os:linux",
"@rules_nixpkgs_core//constraints:support_nix",
],
visibility = ["//visibility:public"],
)
72 changes: 72 additions & 0 deletions examples/toolchains/cc_cross_osx_to_linux_amd64/toolchains/cc.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# We need to write a fancy nix file to handle the CC compiler due to OSX: https://github.com/tweag/rules_nixpkgs/issues/368
# What this file is basically saying is: if OSX, change the CXX compiler to use a bunch of Apple frameworks, LLVM libs,
# libc++ instead of libstdc++, and some additional compiler flags to ignore some warnings, otherwise, just use clang11
let
pkgs = import <nixpkgs> {};
in let
clang = pkgs.clang_11;
# The original `postLinkSignHook` from nixpkgs assumes `codesign_allocate` is
# in the PATH which is not the case when using our cc_wrapper. Set
# `CODESIGN_ALLOCATE` to an absolute path here and override the hook for
# `darwinCC` below.
postLinkSignHook = with pkgs;
writeTextFile {
name = "post-link-sign-hook";
executable = true;

text = ''
CODESIGN_ALLOCATE=${darwin.cctools}/bin/codesign_allocate \
${darwin.sigtool}/bin/codesign -f -s - "$linkerOutput"
'';
};
darwinCC =
# Work around https://github.com/NixOS/nixpkgs/issues/42059.
# See also https://github.com/NixOS/nixpkgs/pull/41589.
pkgs.wrapCCWith rec {
cc = clang;
bintools = pkgs.stdenv.cc.bintools.override {inherit postLinkSignHook;};
extraBuildCommands = with pkgs.darwin.apple_sdk.frameworks; ''
echo "-Wno-unused-command-line-argument" >> $out/nix-support/cc-cflags
echo "-Wno-elaborated-enum-base" >> $out/nix-support/cc-cflags
echo "-isystem ${pkgs.llvmPackages_11.libcxx.dev}/include/c++/v1" >> $out/nix-support/cc-cflags
echo "-isystem ${pkgs.llvmPackages_11.clang-unwrapped.lib}/lib/clang/${cc.version}/include" >> $out/nix-support/cc-cflags
echo "-F${CoreFoundation}/Library/Frameworks" >> $out/nix-support/cc-cflags
echo "-F${CoreServices}/Library/Frameworks" >> $out/nix-support/cc-cflags
echo "-F${Security}/Library/Frameworks" >> $out/nix-support/cc-cflags
echo "-F${Foundation}/Library/Frameworks" >> $out/nix-support/cc-cflags
echo "-L${pkgs.llvmPackages_11.libcxx}/lib" >> $out/nix-support/cc-cflags
echo "-L${pkgs.llvmPackages_11.libcxxabi}/lib" >> $out/nix-support/cc-cflags
echo "-L${pkgs.libiconv}/lib" >> $out/nix-support/cc-cflags
echo "-L${pkgs.darwin.libobjc}/lib" >> $out/nix-support/cc-cflags
echo "-resource-dir=${pkgs.stdenv.cc}/resource-root" >> $out/nix-support/cc-cflags
'';
};
linuxCC = pkgs.wrapCCWith rec {
cc = clang;
bintools = pkgs.stdenv.cc.bintools;
extraPackages = [pkgs.glibc.static];
extraBuildCommands = ''
echo "-isystem ${pkgs.llvmPackages_11.clang-unwrapped.lib}/lib/clang/${cc.version}/include" >> $out/nix-support/cc-cflags
echo "-L ${pkgs.glibc.static}/lib" >> $out/nix-support/cc-ldflags
echo "-resource-dir=${cc}/resource-root" >> $out/nix-support/cc-cflags
'';
};
in
pkgs.buildEnv (
let
cc =
if pkgs.stdenv.isDarwin
then darwinCC
else linuxCC;
in {
name = "bazel-nixpkgs-cc";
# XXX: `gcov` is missing in `/bin`.
# It exists in `stdenv.cc.cc` but that collides with `stdenv.cc`.
paths = [cc cc.bintools] ++ pkgs.lib.optional pkgs.stdenv.isDarwin pkgs.darwin.cctools;
pathsToLink = ["/bin"];
passthru = {
inherit (cc) isClang targetPrefix;
orignalName = cc.name;
};
}
)
Loading

0 comments on commit 6691c54

Please sign in to comment.