-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
crosscompile: Add an example for cross compiling
This adds an example for cross compiling on an ARM M1 Mac to x86_64 Linux. There are rough edges around this example like it will *only* compile for Linux and won't work for OSX, but I think that this problem should be discussed in the better API issue. Also I realized I missed a bug in the previous cross compilation PR, where when cross compiling, we probably want to use the linux_wrapper for building otherwise we end up trying to `install_name_tool` the final Linux binaries, which doesn't work. ``` [nix-shell:~/code/rules_nixpkgs/examples/toolchains/cc_cross_osx_to_linux_amd64]$ bazel build --config=cross :hello INFO: Invocation ID: f10b420f-2dca-42d3-ab4b-1179862791ff INFO: Analyzed target //:hello (3 packages loaded, 19 targets configured). INFO: Found 1 target... Target //:hello up-to-date: bazel-bin/hello INFO: Elapsed time: 8.212s, Critical Path: 5.59s INFO: 4 processes: 2 internal, 2 processwrapper-sandbox. INFO: Build completed successfully, 4 total actions [nix-shell:~/code/rules_nixpkgs/examples/toolchains/cc_cross_osx_to_linux_amd64]$ file bazel-bin/hello bazel-bin/hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /nix/store/jvjrf7rqflfx4nf65yrkk697sxggffki-glibc-x86_64-linux-2.35-224/lib/ld-linux-x86-64.so.2, for GNU/Linux 3.10.0, not stripped ``` note that when compiling for the first time, it'll build clang and gcc a bunch of times for cross compilations so the initial build will take a few hours...
- Loading branch information
1 parent
89626d0
commit ada90a3
Showing
13 changed files
with
316 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
USE_BAZEL_VERSION=6.x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
load("@rules_cc//cc:defs.bzl", "cc_binary") | ||
|
||
cc_binary( | ||
name = "hello", | ||
srcs = ["hello.cc"], | ||
deps = [ | ||
"@boost.dev//:boost", | ||
"@zlib.dev//:zlib", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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=nix :hello' | ||
``` |
111 changes: 111 additions & 0 deletions
111
examples/toolchains/cc_cross_osx_to_linux_amd64/WORKSPACE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
# 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", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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=" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ pkgs ? import ./nixpkgs.nix { } }: | ||
|
||
pkgs.mkShellNoCC { nativeBuildInputs = [ pkgs.bazel_6 ]; } |
9 changes: 9 additions & 0 deletions
9
examples/toolchains/cc_cross_osx_to_linux_amd64/toolchains/BUILD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
72
examples/toolchains/cc_cross_osx_to_linux_amd64/toolchains/cc.nix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}; | ||
} | ||
) |
67 changes: 67 additions & 0 deletions
67
examples/toolchains/cc_cross_osx_to_linux_amd64/toolchains/osxcross_cc.nix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# This will take many hours to build. Caching this somewhere is recommended. | ||
let | ||
targetSystem = "x86_64-linux"; | ||
og = import <nixpkgs> {}; | ||
nixpkgs = import <nixpkgs> { | ||
buildSystem = builtins.currentSystem; | ||
hostSystem = targetSystem; | ||
crossSystem = { | ||
config = targetSystem; | ||
}; | ||
crossOverlays = [ | ||
(self: super: { | ||
# Apparently this is a hacky way to extend llvmPackages, but whatever | ||
llvmPackages_11 = super.llvmPackages_11.extend (final: prev: rec { | ||
libllvm = prev.libllvm.overrideAttrs (old: { | ||
# We need to override LDFLAGS because it puts non-Darwin compatible flags, | ||
# so remove the old flags, and also explicitly tell the compiler where to | ||
# find libcxxabi. Not sure why we need to do this. | ||
LDFLAGS = "-L ${super.llvmPackages_11.libcxxabi}/lib"; | ||
# We need to make sure cctools is available because darwin code signing needs it | ||
# in your $PATH. | ||
nativeBuildInputs = (old.nativeBuildInputs or []) ++ [og.darwin.cctools]; | ||
}); | ||
libclang = prev.libclang.override { | ||
inherit libllvm; | ||
}; | ||
libraries = super.llvmPackages_11.libraries; | ||
}); | ||
}) | ||
]; | ||
}; | ||
# this will use linux binaries from binary cache, so no need to build those | ||
pkgsLinux = import <nixpkgs> { | ||
config = {}; | ||
overlays = []; | ||
system = targetSystem; | ||
}; | ||
in let | ||
pkgs = builtins.trace nixpkgs.stdenv.name nixpkgs.buildPackages; | ||
linuxCC = pkgs.wrapCCWith rec { | ||
cc = pkgs.llvmPackages_11.clang-unwrapped; | ||
bintools = pkgs.llvmPackages_11.bintools; | ||
extraPackages = [pkgsLinux.glibc.static pkgs.llvmPackages_11.libraries.libcxxabi pkgs.llvmPackages_11.libraries.libcxx]; | ||
extraBuildCommands = '' | ||
echo "-isystem ${pkgs.llvmPackages_11.clang-unwrapped.lib}/lib/clang/${cc.version}/include" >> $out/nix-support/cc-cflags | ||
echo "-isystem ${pkgsLinux.glibc.dev}/include" >> $out/nix-support/cc-cflags | ||
echo "-L ${pkgs.llvmPackages_11.libraries.libcxxabi}/lib" >> $out/nix-support/cc-ldflags | ||
echo "-L ${pkgsLinux.glibc.static}/lib" >> $out/nix-support/cc-ldflags | ||
echo "-resource-dir=${cc}/resource-root" >> $out/nix-support/cc-cflags | ||
''; | ||
}; | ||
in | ||
pkgs.buildEnv ( | ||
let | ||
cc = linuxCC; | ||
in { | ||
name = "bazel-${cc.name}-cc"; | ||
# XXX: `gcov` is missing in `/bin`. | ||
# It exists in `stdenv.cc.cc` but that collides with `stdenv.cc`. | ||
paths = [cc cc.bintools]; | ||
pathsToLink = ["/bin"]; | ||
passthru = { | ||
inherit (cc) isClang targetPrefix; | ||
orignalName = cc.name; | ||
}; | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters