wasm: init cross target

Adds pkgsCross.wasm32 and pkgsCross.wasm64. Use it to build Nixpkgs
with a WebAssembly toolchain.

stdenv/cross: use static overlay on isWasm

isWasm doesn’t make sense dynamically linked.
This commit is contained in:
Matthew Bauer 2019-01-29 21:01:24 -05:00
parent 6088a4793f
commit 9abff4af4f
19 changed files with 126 additions and 19 deletions

View File

@ -30,6 +30,7 @@ rec {
libc = libc =
/**/ if final.isDarwin then "libSystem" /**/ if final.isDarwin then "libSystem"
else if final.isMinGW then "msvcrt" else if final.isMinGW then "msvcrt"
else if final.isWasi then "wasilibc"
else if final.isMusl then "musl" else if final.isMusl then "musl"
else if final.isUClibc then "uclibc" else if final.isUClibc then "uclibc"
else if final.isAndroid then "bionic" else if final.isAndroid then "bionic"
@ -62,7 +63,7 @@ rec {
"netbsd" = "NetBSD"; "netbsd" = "NetBSD";
"freebsd" = "FreeBSD"; "freebsd" = "FreeBSD";
"openbsd" = "OpenBSD"; "openbsd" = "OpenBSD";
"wasm" = "Wasm"; "wasi" = "Wasi";
}.${final.parsed.kernel.name} or null; }.${final.parsed.kernel.name} or null;
# uname -p # uname -p

View File

@ -17,6 +17,8 @@ let
"x86_64-netbsd" "x86_64-openbsd" "x86_64-solaris" "x86_64-netbsd" "x86_64-openbsd" "x86_64-solaris"
"x86_64-windows" "i686-windows" "x86_64-windows" "i686-windows"
"wasm64-wasi" "wasm32-wasi"
]; ];
allParsed = map parse.mkSystemFromString all; allParsed = map parse.mkSystemFromString all;
@ -45,6 +47,7 @@ in rec {
netbsd = filterDoubles predicates.isNetBSD; netbsd = filterDoubles predicates.isNetBSD;
openbsd = filterDoubles predicates.isOpenBSD; openbsd = filterDoubles predicates.isOpenBSD;
unix = filterDoubles predicates.isUnix; unix = filterDoubles predicates.isUnix;
wasi = filterDoubles predicates.isWasi;
windows = filterDoubles predicates.isWindows; windows = filterDoubles predicates.isWindows;
mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "armv7a-linux" "aarch64-linux" "powerpc64le-linux"]; mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "armv7a-linux" "aarch64-linux" "powerpc64le-linux"];

View File

@ -211,4 +211,14 @@ rec {
config = "x86_64-unknown-netbsd"; config = "x86_64-unknown-netbsd";
libc = "nblibc"; libc = "nblibc";
}; };
#
# WASM
#
wasi32 = {
config = "wasm32-unknown-wasi";
useLLVM = true;
};
} }

View File

@ -32,6 +32,7 @@ in rec {
openbsd = [ patterns.isOpenBSD ]; openbsd = [ patterns.isOpenBSD ];
unix = patterns.isUnix; # Actually a list unix = patterns.isUnix; # Actually a list
windows = [ patterns.isWindows ]; windows = [ patterns.isWindows ];
wasi = [ patterns.isWasi ];
inherit (lib.systems.doubles) mesaPlatforms; inherit (lib.systems.doubles) mesaPlatforms;
} }

View File

@ -43,9 +43,10 @@ rec {
isWindows = { kernel = kernels.windows; }; isWindows = { kernel = kernels.windows; };
isCygwin = { kernel = kernels.windows; abi = abis.cygnus; }; isCygwin = { kernel = kernels.windows; abi = abis.cygnus; };
isMinGW = { kernel = kernels.windows; abi = abis.gnu; }; isMinGW = { kernel = kernels.windows; abi = abis.gnu; };
isWasi = { kernel = kernels.wasi; };
isAndroid = [ { abi = abis.android; } { abi = abis.androideabi; } ]; isAndroid = [ { abi = abis.android; } { abi = abis.androideabi; } ];
isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ]; isMusl = (with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ]) ++ [{ kernel = kernels.wasi; }];
isUClibc = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ]; isUClibc = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ];
isEfi = map (family: { cpu.family = family; }) isEfi = map (family: { cpu.family = family; })

View File

@ -226,6 +226,7 @@ rec {
elf = {}; elf = {};
macho = {}; macho = {};
pe = {}; pe = {};
wasm = {};
unknown = {}; unknown = {};
}; };
@ -268,6 +269,7 @@ rec {
none = { execFormat = unknown; families = { }; }; none = { execFormat = unknown; families = { }; };
openbsd = { execFormat = elf; families = { inherit bsd; }; }; openbsd = { execFormat = elf; families = { inherit bsd; }; };
solaris = { execFormat = elf; families = { }; }; solaris = { execFormat = elf; families = { }; };
wasi = { execFormat = wasm; families = { }; };
windows = { execFormat = pe; families = { }; }; windows = { execFormat = pe; families = { }; };
} // { # aliases } // { # aliases
# 'darwin' is the kernel for all of them. We choose macOS by default. # 'darwin' is the kernel for all of them. We choose macOS by default.
@ -376,6 +378,8 @@ rec {
then { cpu = elemAt l 0; kernel = elemAt l 1; abi = elemAt l 2; } then { cpu = elemAt l 0; kernel = elemAt l 1; abi = elemAt l 2; }
else if (elemAt l 2 == "mingw32") # autotools breaks on -gnu for window else if (elemAt l 2 == "mingw32") # autotools breaks on -gnu for window
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; } then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; }
else if (elemAt l 2 == "wasi")
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "wasi"; }
else if hasPrefix "netbsd" (elemAt l 2) else if hasPrefix "netbsd" (elemAt l 2)
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; } then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; }
else if (elem (elemAt l 2) ["eabi" "eabihf" "elf"]) else if (elem (elemAt l 2) ["eabi" "eabihf" "elf"])

View File

@ -191,7 +191,8 @@ stdenv.mkDerivation {
else if targetPlatform.isAvr then "avr" else if targetPlatform.isAvr then "avr"
else if targetPlatform.isAlpha then "alpha" else if targetPlatform.isAlpha then "alpha"
else throw "unknown emulation for platform: ${targetPlatform.config}"; else throw "unknown emulation for platform: ${targetPlatform.config}";
in targetPlatform.platform.bfdEmulation or (fmt + sep + arch); in if targetPlatform.useLLVM or false then ""
else targetPlatform.platform.bfdEmulation or (fmt + sep + arch);
strictDeps = true; strictDeps = true;
depsTargetTargetPropagated = extraPackages; depsTargetTargetPropagated = extraPackages;

View File

@ -299,6 +299,12 @@ stdenv.mkDerivation {
hardening_unsupported_flags+=" stackprotector fortify pie pic" hardening_unsupported_flags+=" stackprotector fortify pie pic"
'' ''
+ optionalString targetPlatform.isWasm ''
hardening_unsupported_flags+=" stackprotector fortify pie pic"
'' + optionalString (targetPlatform.isWasm && libc != null) ''
echo "--allow-undefined-file=${libc}/share/wasm32-wasi/undefined-symbols.txt" >> $out/nix-support/cc-ldflags
''
+ optionalString (libc != null && targetPlatform.isAvr) '' + optionalString (libc != null && targetPlatform.isAvr) ''
for isa in avr5 avr3 avr4 avr6 avr25 avr31 avr35 avr51 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 tiny-stack; do for isa in avr5 avr3 avr4 avr6 avr25 avr31 avr35 avr51 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 tiny-stack; do
echo "-B${getLib libc}/avr/lib/$isa" >> $out/nix-support/libc-cflags echo "-B${getLib libc}/avr/lib/$isa" >> $out/nix-support/libc-cflags

View File

@ -60,7 +60,11 @@ stdenv.mkDerivation rec {
ln -s $out/lib/*/clang_rt.crtend-*.o $out/lib/crtend.o ln -s $out/lib/*/clang_rt.crtend-*.o $out/lib/crtend.o
ln -s $out/lib/*/clang_rt.crtbegin_shared-*.o $out/lib/crtbeginS.o ln -s $out/lib/*/clang_rt.crtbegin_shared-*.o $out/lib/crtbeginS.o
ln -s $out/lib/*/clang_rt.crtend_shared-*.o $out/lib/crtendS.o ln -s $out/lib/*/clang_rt.crtend_shared-*.o $out/lib/crtendS.o
'' + stdenv.lib.optionalString stdenv.hostPlatform.isWasm ''
ln -s $out/lib/*/* $out/lib
''; '';
NIX_LDFLAGS = stdenv.lib.optionalString stdenv.hostPlatform.isWasm "--allow-undefined --no-entry";
enableParallelBuilding = true; enableParallelBuilding = true;
} }

View File

@ -97,12 +97,14 @@ let
targetLlvmLibraries.libcxx targetLlvmLibraries.libcxx
targetLlvmLibraries.libcxxabi targetLlvmLibraries.libcxxabi
targetLlvmLibraries.compiler-rt targetLlvmLibraries.compiler-rt
] ++ stdenv.lib.optionals (!stdenv.targetPlatform.isWasm) [
targetLlvmLibraries.libunwind targetLlvmLibraries.libunwind
]; ];
extraBuildCommands = '' extraBuildCommands = ''
echo "-target ${stdenv.targetPlatform.config}" >> $out/nix-support/cc-cflags echo "-target ${stdenv.targetPlatform.config}" >> $out/nix-support/cc-cflags
echo "-rtlib=compiler-rt -Wno-unused-command-line-argument" >> $out/nix-support/cc-cflags echo "-rtlib=compiler-rt -Wno-unused-command-line-argument" >> $out/nix-support/cc-cflags
echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags
'' + stdenv.lib.optionalString (!stdenv.targetPlatform.isWasm) ''
echo "--unwindlib=libunwind" >> $out/nix-support/cc-cflags echo "--unwindlib=libunwind" >> $out/nix-support/cc-cflags
'' + mkExtraBuildCommands cc; '' + mkExtraBuildCommands cc;
}; };

View File

@ -1,4 +1,5 @@
{ lib, stdenv, fetch, cmake, python, libcxxabi, fixDarwinDylibNames, version }: { lib, stdenv, fetch, cmake, python, libcxxabi, fixDarwinDylibNames, version
, enableShared ? true }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "libc++-${version}"; name = "libc++-${version}";
@ -31,7 +32,11 @@ stdenv.mkDerivation rec {
"-DLIBCXX_LIBCPPABI_VERSION=2" "-DLIBCXX_LIBCPPABI_VERSION=2"
"-DLIBCXX_CXX_ABI=libcxxabi" "-DLIBCXX_CXX_ABI=libcxxabi"
] ++ stdenv.lib.optional stdenv.hostPlatform.isMusl "-DLIBCXX_HAS_MUSL_LIBC=1" ] ++ stdenv.lib.optional stdenv.hostPlatform.isMusl "-DLIBCXX_HAS_MUSL_LIBC=1"
++ stdenv.lib.optional (stdenv.hostPlatform.useLLVM or false) "-DLIBCXX_USE_COMPILER_RT=ON"; ++ stdenv.lib.optional (stdenv.hostPlatform.useLLVM or false) "-DLIBCXX_USE_COMPILER_RT=ON"
++ stdenv.lib.optional stdenv.hostPlatform.isWasm [
"-DLIBCXX_ENABLE_THREADS=OFF"
"-DLIBCXX_ENABLE_FILESYSTEM=OFF"
] ++ stdenv.lib.optional (!enableShared) "-DLIBCXX_ENABLE_SHARED=OFF";
enableParallelBuilding = true; enableParallelBuilding = true;
@ -46,6 +51,6 @@ stdenv.mkDerivation rec {
homepage = http://libcxx.llvm.org/; homepage = http://libcxx.llvm.org/;
description = "A new implementation of the C++ standard library, targeting C++11"; description = "A new implementation of the C++ standard library, targeting C++11";
license = with stdenv.lib.licenses; [ ncsa mit ]; license = with stdenv.lib.licenses; [ ncsa mit ];
platforms = stdenv.lib.platforms.unix; platforms = stdenv.lib.platforms.all;
}; };
} }

View File

@ -1,4 +1,5 @@
{ stdenv, cmake, fetch, libcxx, libunwind, llvm, version }: { stdenv, cmake, fetch, libcxx, libunwind, llvm, version
, enableShared ? true }:
stdenv.mkDerivation { stdenv.mkDerivation {
name = "libc++abi-${version}"; name = "libc++abi-${version}";
@ -6,13 +7,20 @@ stdenv.mkDerivation {
src = fetch "libcxxabi" "1k875f977ybdkpdnr9105wa6hccy9qvpd9xd42n75h7p56bdxmn2"; src = fetch "libcxxabi" "1k875f977ybdkpdnr9105wa6hccy9qvpd9xd42n75h7p56bdxmn2";
nativeBuildInputs = [ cmake ]; nativeBuildInputs = [ cmake ];
buildInputs = stdenv.lib.optional (!stdenv.isDarwin && !stdenv.isFreeBSD) libunwind; buildInputs = stdenv.lib.optional (!stdenv.isDarwin && !stdenv.isFreeBSD && !stdenv.hostPlatform.isWasm) libunwind;
cmakeFlags = stdenv.lib.optionals (stdenv.hostPlatform.useLLVM or false) [ cmakeFlags = stdenv.lib.optionals (stdenv.hostPlatform.useLLVM or false) [
"-DLLVM_ENABLE_LIBCXX=ON" "-DLLVM_ENABLE_LIBCXX=ON"
"-DLIBCXXABI_USE_LLVM_UNWINDER=ON" "-DLIBCXXABI_USE_LLVM_UNWINDER=ON"
] ++ stdenv.lib.optionals stdenv.hostPlatform.isWasm [
"-DUNIX=ON"
"-DLIBCXXABI_ENABLE_THREADS=OFF"
] ++ stdenv.lib.optionals (!enableShared) [
"-DLIBCXXABI_ENABLE_SHARED=OFF"
]; ];
patches = [ ./libcxxabi-no-threads.patch ];
postUnpack = '' postUnpack = ''
unpackFile ${libcxx.src} unpackFile ${libcxx.src}
unpackFile ${llvm.src} unpackFile ${llvm.src}
@ -39,8 +47,9 @@ stdenv.mkDerivation {
else '' else ''
install -d -m 755 $out/include $out/lib install -d -m 755 $out/include $out/lib
install -m 644 lib/libc++abi.a $out/lib install -m 644 lib/libc++abi.a $out/lib
install -m 644 lib/libc++abi.so.1.0 $out/lib
install -m 644 ../include/cxxabi.h $out/include install -m 644 ../include/cxxabi.h $out/include
'' + stdenv.lib.optionalString enableShared ''
install -m 644 lib/libc++abi.so.1.0 $out/lib
ln -s libc++abi.so.1.0 $out/lib/libc++abi.so ln -s libc++abi.so.1.0 $out/lib/libc++abi.so
ln -s libc++abi.so.1.0 $out/lib/libc++abi.so.1 ln -s libc++abi.so.1.0 $out/lib/libc++abi.so.1
''; '';
@ -50,6 +59,6 @@ stdenv.mkDerivation {
description = "A new implementation of low level support for a standard C++ library"; description = "A new implementation of low level support for a standard C++ library";
license = with stdenv.lib.licenses; [ ncsa mit ]; license = with stdenv.lib.licenses; [ ncsa mit ];
maintainers = with stdenv.lib.maintainers; [ vlstill ]; maintainers = with stdenv.lib.maintainers; [ vlstill ];
platforms = stdenv.lib.platforms.unix; platforms = stdenv.lib.platforms.all;
}; };
} }

View File

@ -0,0 +1,12 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4138acf..41b4763 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -362,6 +362,7 @@ if (NOT LIBCXXABI_ENABLE_THREADS)
" is also set to ON.")
endif()
add_definitions(-D_LIBCXXABI_HAS_NO_THREADS)
+ add_definitions(-D_LIBCPP_HAS_NO_THREADS)
endif()
if (LIBCXXABI_HAS_EXTERNAL_THREAD_API)

View File

@ -0,0 +1,28 @@
{ stdenv, fetchFromGitHub, lib }:
stdenv.mkDerivation {
name = "wasilibc-20190413";
src = fetchFromGitHub {
owner = "CraneStation";
repo = "wasi-sysroot";
rev = "079d7bda78bc0ad8f69c1594444b54786545ce57";
sha256 = "09s906bc9485wzkgibnpfh0mii7jkldzr1a6g8k7ch0si8rshi5r";
};
makeFlags = [
"WASM_CC=${stdenv.cc.targetPrefix}cc"
"WASM_NM=${stdenv.cc.targetPrefix}nm"
"WASM_AR=${stdenv.cc.targetPrefix}ar"
"INSTALL_DIR=${placeholder "out"}"
];
postInstall = ''
mv $out/lib/*/* $out/lib
'';
meta = {
description = "WASI libc implementation for WebAssembly";
homepage = "https://wasi.dev";
platforms = lib.platforms.wasi;
maintainers = [ lib.maintainers.matthewbauer ];
};
}

View File

@ -37,7 +37,8 @@ in lib.init bootStages ++ [
# Run Packages # Run Packages
(buildPackages: { (buildPackages: {
inherit config; inherit config;
overlays = overlays ++ crossOverlays; overlays = overlays ++ crossOverlays
++ (if crossSystem.isWasm then [(import ../../top-level/static.nix)] else []);
selfBuild = false; selfBuild = false;
stdenv = buildPackages.stdenv.override (old: rec { stdenv = buildPackages.stdenv.override (old: rec {
buildPlatform = localSystem; buildPlatform = localSystem;

View File

@ -91,6 +91,9 @@ let
'' + lib.optionalString hostPlatform.isDarwin '' '' + lib.optionalString hostPlatform.isDarwin ''
export NIX_DONT_SET_RPATH=1 export NIX_DONT_SET_RPATH=1
export NIX_NO_SELF_RPATH=1 export NIX_NO_SELF_RPATH=1
'' + lib.optionalString (hostPlatform.parsed.kernel.execFormat != lib.systems.parse.execFormats.elf && hostPlatform.parsed.kernel.execFormat != lib.systems.parse.execFormats.macho) ''
export NIX_DONT_SET_RPATH=1
export NIX_NO_SELF_RPATH=1
'' ''
# TODO this should be uncommented, but it causes stupid mass rebuilds. I # TODO this should be uncommented, but it causes stupid mass rebuilds. I
# think the best solution would just be to fixup linux RPATHs so we don't # think the best solution would just be to fixup linux RPATHs so we don't

View File

@ -93,8 +93,7 @@ let
}; };
in (lib.mapAttrs (_: mapMultiPlatformTest builtins.id) tests) in {
// (lib.mapAttrs' (name: test: { gcc = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = false;})) tests);
name = "${name}-llvm"; llvm = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = true;})) tests);
value = mapMultiPlatformTest (system: system // {useLLVM = true;}) test; }
}) tests)

View File

@ -10311,10 +10311,15 @@ in
else if stdenv.targetPlatform.useiOSPrebuilt then targetPackages.darwin.iosSdkPkgs.libraries or darwin.iosSdkPkgs.libraries else if stdenv.targetPlatform.useiOSPrebuilt then targetPackages.darwin.iosSdkPkgs.libraries or darwin.iosSdkPkgs.libraries
else if name == "libSystem" then targetPackages.darwin.xcode else if name == "libSystem" then targetPackages.darwin.xcode
else if name == "nblibc" then targetPackages.netbsdCross.libc else if name == "nblibc" then targetPackages.netbsdCross.libc
else throw "Unknown libc"; else if name == "wasilibc" then targetPackages.wasilibc
else throw "Unknown libc ${name}";
libcCross = assert stdenv.targetPlatform != stdenv.buildPlatform; libcCrossChooser stdenv.targetPlatform.libc; libcCross = assert stdenv.targetPlatform != stdenv.buildPlatform; libcCrossChooser stdenv.targetPlatform.libc;
wasilibc = callPackages ../development/libraries/wasilibc {
stdenv = crossLibcStdenv;
};
# Only supported on Linux, using glibc # Only supported on Linux, using glibc
glibcLocales = if stdenv.hostPlatform.libc == "glibc" then callPackage ../development/libraries/glibc/locales.nix { } else null; glibcLocales = if stdenv.hostPlatform.libc == "glibc" then callPackage ../development/libraries/glibc/locales.nix { } else null;

View File

@ -148,4 +148,16 @@ in {
}; };
}; };
llvmPackages_8 = super.llvmPackages_8 // {
libraries = super.llvmPackages_8.libraries // rec {
libcxxabi = super.llvmPackages_8.libraries.libcxxabi.override {
enableShared = false;
};
libcxx = super.llvmPackages_8.libraries.libcxx.override {
enableShared = false;
inherit libcxxabi;
};
};
};
} }