Merge pull request #319153 from Kranzes/buildRustCrate-wasm
buildRustCrate: add support for compiling to wasm32-unknown-unknown
This commit is contained in:
commit
641b2f29b6
@ -84,20 +84,21 @@ let
|
||||
useLLVM = final.isFreeBSD || final.isOpenBSD;
|
||||
|
||||
libc =
|
||||
/**/ if final.isDarwin then "libSystem"
|
||||
else if final.isMinGW then "msvcrt"
|
||||
else if final.isWasi then "wasilibc"
|
||||
else if final.isRedox then "relibc"
|
||||
else if final.isMusl then "musl"
|
||||
else if final.isUClibc then "uclibc"
|
||||
else if final.isAndroid then "bionic"
|
||||
else if final.isLinux /* default */ then "glibc"
|
||||
else if final.isFreeBSD then "fblibc"
|
||||
else if final.isOpenBSD then "oblibc"
|
||||
else if final.isNetBSD then "nblibc"
|
||||
else if final.isAvr then "avrlibc"
|
||||
else if final.isGhcjs then null
|
||||
else if final.isNone then "newlib"
|
||||
/**/ if final.isDarwin then "libSystem"
|
||||
else if final.isMinGW then "msvcrt"
|
||||
else if final.isWasi then "wasilibc"
|
||||
else if final.isWasm && !final.isWasi then null
|
||||
else if final.isRedox then "relibc"
|
||||
else if final.isMusl then "musl"
|
||||
else if final.isUClibc then "uclibc"
|
||||
else if final.isAndroid then "bionic"
|
||||
else if final.isLinux /* default */ then "glibc"
|
||||
else if final.isFreeBSD then "fblibc"
|
||||
else if final.isOpenBSD then "oblibc"
|
||||
else if final.isNetBSD then "nblibc"
|
||||
else if final.isAvr then "avrlibc"
|
||||
else if final.isGhcjs then null
|
||||
else if final.isNone then "newlib"
|
||||
# TODO(@Ericson2314) think more about other operating systems
|
||||
else "native/impure";
|
||||
# Choose what linker we wish to use by default. Someday we might also
|
||||
@ -179,6 +180,7 @@ let
|
||||
(isAndroid || isGnu || isMusl # Linux (allows multiple libcs)
|
||||
|| isDarwin || isSunOS || isOpenBSD || isFreeBSD || isNetBSD # BSDs
|
||||
|| isCygwin || isMinGW # Windows
|
||||
|| isWasm # WASM
|
||||
) && !isStatic;
|
||||
|
||||
# The difference between `isStatic` and `hasSharedLibraries` is mainly the
|
||||
@ -187,7 +189,7 @@ let
|
||||
# don't support dynamic linking, but don't get the `staticMarker`.
|
||||
# `pkgsStatic` sets `isStatic=true`, so `pkgsStatic.hostPlatform` always
|
||||
# has the `staticMarker`.
|
||||
isStatic = final.isWasm || final.isRedox;
|
||||
isStatic = final.isWasi || final.isRedox;
|
||||
|
||||
# Just a guess, based on `system`
|
||||
inherit
|
||||
@ -337,7 +339,8 @@ let
|
||||
if isList f then f else [ f ]
|
||||
)
|
||||
else optional final.isUnix "unix"
|
||||
++ optional final.isWindows "windows";
|
||||
++ optional final.isWindows "windows"
|
||||
++ optional final.isWasm "wasm";
|
||||
|
||||
# https://doc.rust-lang.org/reference/conditional-compilation.html#target_vendor
|
||||
vendor = let
|
||||
|
@ -356,6 +356,12 @@ rec {
|
||||
useLLVM = true;
|
||||
};
|
||||
|
||||
wasm32-unknown-none = {
|
||||
config = "wasm32-unknown-none";
|
||||
rust.rustcTarget = "wasm32-unknown-unknown";
|
||||
useLLVM = true;
|
||||
};
|
||||
|
||||
# Ghcjs
|
||||
ghcjs = {
|
||||
# This triple is special to GHC/Cabal/GHCJS and not recognized by autotools
|
||||
|
@ -466,11 +466,12 @@ rec {
|
||||
}
|
||||
# cpu-vendor-os
|
||||
else if elemAt l 1 == "apple" ||
|
||||
elem (elemAt l 2) [ "wasi" "redox" "mmixware" "ghcjs" "mingw32" ] ||
|
||||
elem (elemAt l 2) [ "redox" "mmixware" "ghcjs" "mingw32" ] ||
|
||||
hasPrefix "freebsd" (elemAt l 2) ||
|
||||
hasPrefix "netbsd" (elemAt l 2) ||
|
||||
hasPrefix "openbsd" (elemAt l 2) ||
|
||||
hasPrefix "genode" (elemAt l 2)
|
||||
hasPrefix "genode" (elemAt l 2) ||
|
||||
hasPrefix "wasm32" (elemAt l 0)
|
||||
then {
|
||||
cpu = elemAt l 0;
|
||||
vendor = elemAt l 1;
|
||||
|
@ -1,5 +1,5 @@
|
||||
{ lib, stdenv
|
||||
, mkRustcDepArgs, mkRustcFeatureArgs, needUnstableCLI
|
||||
, mkRustcDepArgs, mkRustcFeatureArgs, needUnstableCLI, rustc
|
||||
}:
|
||||
|
||||
{ crateName,
|
||||
@ -27,6 +27,10 @@
|
||||
# since rustc 1.42 the "proc_macro" crate is part of the default crate prelude
|
||||
# https://github.com/rust-lang/cargo/commit/4d64eb99a4#diff-7f98585dbf9d30aa100c8318e2c77e79R1021-R1022
|
||||
++ lib.optional (lib.elem "proc-macro" crateType) "--extern proc_macro"
|
||||
++ lib.optional (stdenv.hostPlatform.linker == "lld") # Needed when building for targets that use lld. e.g. 'wasm32-unknown-unknown'
|
||||
"-C linker=${rustc.llvmPackages.lld}/bin/lld"
|
||||
++ lib.optional (stdenv.hasCC && stdenv.hostPlatform.linker != "lld")
|
||||
"-C linker=${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc"
|
||||
;
|
||||
rustcMeta = "-C metadata=${metadata} -C extra-filename=-${metadata}";
|
||||
|
||||
@ -39,10 +43,7 @@
|
||||
++ (map (x: "--crate-type ${x}") crateType)
|
||||
);
|
||||
|
||||
binRustcOpts = lib.concatStringsSep " " (
|
||||
[ "-C linker=${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc" ] ++
|
||||
baseRustcOpts
|
||||
);
|
||||
binRustcOpts = lib.concatStringsSep " " baseRustcOpts;
|
||||
|
||||
build_bin = if buildTests then "build_bin_test" else "build_bin";
|
||||
in ''
|
||||
|
@ -16,6 +16,16 @@
|
||||
}:
|
||||
|
||||
let
|
||||
# Returns a true if the builder's rustc was built with support for the target.
|
||||
targetAlreadyIncluded = lib.elem stdenv.hostPlatform.rust.rustcTarget
|
||||
(lib.splitString "," (lib.removePrefix "--target=" (
|
||||
lib.elemAt (lib.filter (f: lib.hasPrefix "--target=" f) pkgsBuildBuild.rustc.unwrapped.configureFlags) 0)
|
||||
));
|
||||
|
||||
# If the build's rustc was built with support for the target then reuse it. (Avoids uneeded compilation for targets like `wasm32-unknown-unknown`)
|
||||
rustc' = if targetAlreadyIncluded then pkgsBuildBuild.rustc else rustc;
|
||||
cargo' = if targetAlreadyIncluded then pkgsBuildBuild.cargo else cargo;
|
||||
|
||||
# Create rustc arguments to link against the given list of dependencies
|
||||
# and renames.
|
||||
#
|
||||
@ -77,6 +87,7 @@ let
|
||||
|
||||
buildCrate = import ./build-crate.nix {
|
||||
inherit lib stdenv mkRustcDepArgs mkRustcFeatureArgs needUnstableCLI;
|
||||
rustc = rustc';
|
||||
};
|
||||
|
||||
installCrate = import ./install-crate.nix { inherit stdenv; };
|
||||
@ -274,7 +285,8 @@ crate_: lib.makeOverridable
|
||||
name = "rust_${crate.crateName}-${crate.version}${lib.optionalString buildTests_ "-test"}";
|
||||
version = crate.version;
|
||||
depsBuildBuild = [ pkgsBuildBuild.stdenv.cc ];
|
||||
nativeBuildInputs = [ rust stdenv.cc cargo jq ]
|
||||
nativeBuildInputs = [ rustc' cargo' jq ]
|
||||
++ lib.optionals stdenv.hasCC [ stdenv.cc ]
|
||||
++ lib.optionals stdenv.buildPlatform.isDarwin [ libiconv ]
|
||||
++ (crate.nativeBuildInputs or [ ]) ++ nativeBuildInputs_;
|
||||
buildInputs = lib.optionals stdenv.isDarwin [ libiconv ] ++ (crate.buildInputs or [ ]) ++ buildInputs_;
|
||||
@ -380,7 +392,7 @@ crate_: lib.makeOverridable
|
||||
)
|
||||
)
|
||||
{
|
||||
rust = rustc;
|
||||
rust = rustc';
|
||||
release = crate_.release or true;
|
||||
verbose = crate_.verbose or true;
|
||||
extraRustcOpts = [ ];
|
||||
|
@ -8,6 +8,7 @@
|
||||
, stdenv
|
||||
, symlinkJoin
|
||||
, writeTextFile
|
||||
, pkgsCross
|
||||
}:
|
||||
|
||||
let
|
||||
@ -120,7 +121,10 @@ let
|
||||
|
||||
`name` is used as part of the derivation name that performs the checking.
|
||||
|
||||
`crateArgs` is passed to `mkHostCrate` to build the crate with `buildRustCrate`.
|
||||
`mkCrate` can be used to override the `mkCrate` call/implementation to use to
|
||||
override the `buildRustCrate`, useful for cross compilation. Uses `mkHostCrate` by default.
|
||||
|
||||
`crateArgs` is passed to `mkCrate` to build the crate with `buildRustCrate`
|
||||
|
||||
`expectedFiles` contains a list of expected file paths in the output. E.g.
|
||||
`[ "./bin/my_binary" ]`.
|
||||
@ -129,13 +133,13 @@ let
|
||||
output is used but e.g. `output = "lib";` will cause the lib output
|
||||
to be checked instead. You do not need to specify any directories.
|
||||
*/
|
||||
assertOutputs = { name, crateArgs, expectedFiles, output? null }:
|
||||
assertOutputs = { name, mkCrate ? mkHostCrate, crateArgs, expectedFiles, output? null, }:
|
||||
assert (builtins.isString name);
|
||||
assert (builtins.isAttrs crateArgs);
|
||||
assert (builtins.isList expectedFiles);
|
||||
|
||||
let
|
||||
crate = mkHostCrate (builtins.removeAttrs crateArgs ["expectedTestOutput"]);
|
||||
crate = mkCrate (builtins.removeAttrs crateArgs ["expectedTestOutput"]);
|
||||
crateOutput = if output == null then crate else crate."${output}";
|
||||
expectedFilesFile = writeTextFile {
|
||||
name = "expected-files-${name}";
|
||||
@ -155,7 +159,7 @@ let
|
||||
''
|
||||
# sed out the hash because it differs per platform
|
||||
+ ''
|
||||
| sed -E -e 's/-[0-9a-fA-F]{10}\.rlib/-HASH.rlib/g' \
|
||||
| sed 's/-${crate.metadata}//g' \
|
||||
> "$actualFiles"
|
||||
diff -q ${expectedFilesFile} "$actualFiles" > /dev/null || {
|
||||
echo -e "\033[0;1;31mERROR: Difference in expected output files in ${crateOutput} \033[0m" >&2
|
||||
@ -651,7 +655,7 @@ let
|
||||
};
|
||||
expectedFiles = [
|
||||
"./nix-support/propagated-build-inputs"
|
||||
"./lib/libtest_lib-HASH.rlib"
|
||||
"./lib/libtest_lib.rlib"
|
||||
"./lib/link"
|
||||
];
|
||||
};
|
||||
@ -668,7 +672,24 @@ let
|
||||
};
|
||||
expectedFiles = [
|
||||
"./nix-support/propagated-build-inputs"
|
||||
"./lib/libtest_lib-HASH.rlib"
|
||||
"./lib/libtest_lib.rlib"
|
||||
"./lib/link"
|
||||
];
|
||||
};
|
||||
|
||||
crateLibOutputsWasm32 = assertOutputs {
|
||||
name = "wasm32-crate-lib";
|
||||
output = "lib";
|
||||
mkCrate = mkCrate pkgsCross.wasm32-unknown-none.buildRustCrate;
|
||||
crateArgs = {
|
||||
libName = "test_lib";
|
||||
type = [ "cdylib" ];
|
||||
libPath = "src/lib.rs";
|
||||
src = mkLib "src/lib.rs";
|
||||
};
|
||||
expectedFiles = [
|
||||
"./nix-support/propagated-build-inputs"
|
||||
"./lib/test_lib.wasm"
|
||||
"./lib/link"
|
||||
];
|
||||
};
|
||||
|
@ -16443,7 +16443,9 @@ with pkgs;
|
||||
|
||||
makeRustPlatform = callPackage ../development/compilers/rust/make-rust-platform.nix { };
|
||||
|
||||
buildRustCrate = callPackage ../build-support/rust/build-rust-crate { };
|
||||
buildRustCrate = callPackage ../build-support/rust/build-rust-crate ({ } // lib.optionalAttrs (stdenv.hostPlatform.libc == null) {
|
||||
stdenv = stdenvNoCC; # Some build targets without libc will fail to evaluate with a normal stdenv.
|
||||
});
|
||||
buildRustCrateHelpers = callPackage ../build-support/rust/build-rust-crate/helpers.nix { };
|
||||
|
||||
cargo2junit = callPackage ../development/tools/rust/cargo2junit { };
|
||||
|
Loading…
Reference in New Issue
Block a user