about summary refs log tree commit diff
path: root/nixpkgs/pkgs/by-name/ha
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/by-name/ha')
-rw-r--r--nixpkgs/pkgs/by-name/ha/hare/cross-compilation-tests.nix31
-rw-r--r--nixpkgs/pkgs/by-name/ha/hare/package.nix63
2 files changed, 93 insertions, 1 deletions
diff --git a/nixpkgs/pkgs/by-name/ha/hare/cross-compilation-tests.nix b/nixpkgs/pkgs/by-name/ha/hare/cross-compilation-tests.nix
new file mode 100644
index 000000000000..26611fea9d65
--- /dev/null
+++ b/nixpkgs/pkgs/by-name/ha/hare/cross-compilation-tests.nix
@@ -0,0 +1,31 @@
+{ lib
+, buildPackages
+, hare
+, runCommandNoCC
+, stdenv
+, writeText
+}:
+let
+  inherit (stdenv.hostPlatform.uname) processor;
+  inherit (stdenv.hostPlatform) emulator;
+  mainDotHare = writeText "main.ha" ''
+    use fmt;
+    use os;
+    export fn main() void = {
+        const machine = os::machine();
+        if (machine == "${processor}") {
+            fmt::println("os::machine() matches ${processor}")!;
+        } else {
+            fmt::fatalf("os::machine() does not match ${processor}: {}", machine);
+        };
+    };
+  '';
+in
+runCommandNoCC "${hare.pname}-cross-compilation-test" { meta.timeout = 60; } ''
+  HARECACHE="$(mktemp -d --tmpdir harecache.XXXXXXXX)"
+  export HARECACHE
+  outbin="test-${processor}"
+  ${lib.getExe hare} build -q -a "${processor}" -o "$outbin" ${mainDotHare}
+  ${emulator buildPackages} "./$outbin"
+  : 1>$out
+''
diff --git a/nixpkgs/pkgs/by-name/ha/hare/package.nix b/nixpkgs/pkgs/by-name/ha/hare/package.nix
index c509955c6f09..a41bcb90a513 100644
--- a/nixpkgs/pkgs/by-name/ha/hare/package.nix
+++ b/nixpkgs/pkgs/by-name/ha/hare/package.nix
@@ -8,15 +8,55 @@
 , scdoc
 , tzdata
 , substituteAll
+, callPackage
+, enableCrossCompilation ? (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.is64bit)
+, pkgsCross
+, x86_64PkgsCrossToolchain ? pkgsCross.gnu64
+, aarch64PkgsCrossToolchain ? pkgsCross.aarch64-multiplatform
+, riscv64PkgsCrossToolchain ? pkgsCross.riscv64
 }:
 
+# There's no support for `aarch64-freebsd` or `riscv64-freebsd` on nix.
+# See `lib.systems.doubles.aarch64` and `lib.systems.doubles.riscv64`.
+assert let
+  inherit (stdenv.hostPlatform) isLinux is64bit;
+  inherit (lib) intersectLists platforms concatStringsSep;
+  workingPlatforms = intersectLists platforms.linux (with platforms; x86_64 ++ aarch64 ++ riscv64);
+in
+(enableCrossCompilation -> !(isLinux && is64bit))
+  -> builtins.throw ''
+  The cross-compilation toolchains may only be enabled on the following platforms:
+  ${concatStringsSep "\n" workingPlatforms}
+'';
+
 let
   # We use harec's override of qbe until 1.2 is released, but the `qbe` argument
   # is kept to avoid breakage.
   qbe = harec.qbeUnstable;
   # https://harelang.org/platforms/
   arch = stdenv.hostPlatform.uname.processor;
-  platform = lib.strings.toLower stdenv.hostPlatform.uname.system;
+  platform = lib.toLower stdenv.hostPlatform.uname.system;
+  embeddedOnBinaryTools =
+    let
+      genToolsFromToolchain = toolchain:
+        let
+          crossTargetPrefix = toolchain.stdenv.cc.targetPrefix;
+          toolchainArch = toolchain.stdenv.hostPlatform.uname.processor;
+          absOrRelPath = toolDrv: toolBasename:
+            if arch == toolchainArch then toolBasename
+            else lib.getExe' toolDrv "${crossTargetPrefix}${toolBasename}";
+        in
+        {
+          "ld" = absOrRelPath toolchain.buildPackages.binutils "ld";
+          "as" = absOrRelPath toolchain.buildPackages.binutils "as";
+          "cc" = absOrRelPath toolchain.stdenv.cc "cc";
+        };
+    in
+    {
+      x86_64 = genToolsFromToolchain x86_64PkgsCrossToolchain;
+      aarch64 = genToolsFromToolchain aarch64PkgsCrossToolchain;
+      riscv64 = genToolsFromToolchain riscv64PkgsCrossToolchain;
+    };
 in
 stdenv.mkDerivation (finalAttrs: {
   pname = "hare";
@@ -58,6 +98,19 @@ stdenv.mkDerivation (finalAttrs: {
     "PREFIX=${builtins.placeholder "out"}"
     "PLATFORM=${platform}"
     "ARCH=${arch}"
+    # Strip the variable of an empty $(SRCDIR)/hare/third-party, since nix does
+    # not follow the FHS.
+    "HAREPATH=$(SRCDIR)/hare/stdlib"
+  ] ++ lib.optionals enableCrossCompilation [
+    "RISCV64_AS=${embeddedOnBinaryTools.riscv64.as}"
+    "RISCV64_CC=${embeddedOnBinaryTools.riscv64.cc}"
+    "RISCV64_LD=${embeddedOnBinaryTools.riscv64.ld}"
+    "AARCH64_AS=${embeddedOnBinaryTools.aarch64.as}"
+    "AARCH64_CC=${embeddedOnBinaryTools.aarch64.cc}"
+    "AARCH64_LD=${embeddedOnBinaryTools.aarch64.ld}"
+    "x86_64_AS=${embeddedOnBinaryTools.x86_64.as}"
+    "x86_64_CC=${embeddedOnBinaryTools.x86_64.cc}"
+    "x86_64_LD=${embeddedOnBinaryTools.x86_64.ld}"
   ];
 
   enableParallelBuilding = true;
@@ -80,6 +133,14 @@ stdenv.mkDerivation (finalAttrs: {
 
   setupHook = ./setup-hook.sh;
 
+  passthru = {
+    tests = lib.optionalAttrs enableCrossCompilation {
+      crossCompilation = callPackage ./cross-compilation-tests.nix {
+        hare = finalAttrs.finalPackage;
+      };
+    };
+  };
+
   meta = {
     homepage = "https://harelang.org/";
     description = "Systems programming language designed to be simple, stable, and robust";