Fix cross build of Perl bindings #259

Open
opened 2024-05-01 11:20:57 +00:00 by ma27 · 0 comments
Member

So, in theory it's just (1) moving the .pm files to the appropriate place and doing a cross-build after the .xs-part was compiled down to C.
I even got that to work locally with the following (hacky) patch:

diff --git a/flake.nix b/flake.nix
index e8526f5c4..d01873967 100644
--- a/flake.nix
+++ b/flake.nix
@@ -55,6 +55,7 @@
       crossSystems = [
         "armv6l-linux"
         "armv7l-linux"
+        "aarch64-multiplatform"
         "x86_64-freebsd13"
         "x86_64-netbsd"
       ];
diff --git a/perl/default.nix b/perl/default.nix
index af700eabe..b685d9a02 100644
--- a/perl/default.nix
+++ b/perl/default.nix
@@ -46,7 +46,7 @@ perl.pkgs.toPerlModule (
     };
 
     nativeBuildInputs =
-      [ pkg-config ]
+      [ pkg-config perl ]
       ++ lib.optionals (!buildWithMeson) [
         autoconf-archive
         autoreconfHook
diff --git a/perl/meson.build b/perl/meson.build
index 75c7c2c79..322616a6a 100644
--- a/perl/meson.build
+++ b/perl/meson.build
@@ -34,13 +34,8 @@ perl_version = run_command(
   capture : true,
   check : true,
 ).stdout()
-perl_arch_name = run_command(
-  perl,
-  '-e',
-  'use Config; print $Config{archname};',
-  capture : true,
-  check : true,
-).stdout()
+
+perl_arch_name = host_machine.cpu_family() + '-' + host_machine.system()
 
 perl_libdir = f'@libdir@/perl5/site_perl/@perl_version@/@perl_arch_name@'
 

I used the following test expression, the resulting file executes fine with binfmt running:

let pkgsBase = import <nixpkgs> { }; in
with pkgsBase.pkgsCross.aarch64-multiplatform;
writeShellScriptBin "test" ''
  exec ${perl.withPackages (p: [
    (callPackage ./package.nix {
      build-release-notes = null;
    }).perl-bindings
  ])}/bin/perl ${pkgs.writeText "test.pl" ''
    use Nix::Store;
    if (isValidPath "/nix/store/8xnd1i8m9grv9ybdpbs080vxzvkdzway-home-manager-files") {
        print STDERR "yay\n";
    }
  ''}
''

Now to the problems with that:

  • this doesn't take into account the suffixes of Perl's archname (e.g. x86_64-linux-thread-multi). These are set by Perl's ./Configure script. I haven't found something where this got exposed (short of reading from pkgs.perl's $out)[1].
  • this doesn't take into account the version of the Perl interpreter. Same issue as above.

I'm a little bit out of ideas here. Sure, I could write more cursed code, but I got nerd-sniped into it by accident, so it's not sufficiently important for me to mess around. I figured I'd share how far I got and ask for ideas on how to fix this properly. Not too experienced with cross builds in the end.

[1] this is what nixpkgs seems to be doing: bcd44e224f/pkgs/development/interpreters/perl/interpreter.nix (L215)

So, in theory it's just (1) moving the `.pm` files to the appropriate place and doing a cross-build after the `.xs`-part was compiled down to C. I even got that to work locally with the following (hacky) patch: ```diff diff --git a/flake.nix b/flake.nix index e8526f5c4..d01873967 100644 --- a/flake.nix +++ b/flake.nix @@ -55,6 +55,7 @@ crossSystems = [ "armv6l-linux" "armv7l-linux" + "aarch64-multiplatform" "x86_64-freebsd13" "x86_64-netbsd" ]; diff --git a/perl/default.nix b/perl/default.nix index af700eabe..b685d9a02 100644 --- a/perl/default.nix +++ b/perl/default.nix @@ -46,7 +46,7 @@ perl.pkgs.toPerlModule ( }; nativeBuildInputs = - [ pkg-config ] + [ pkg-config perl ] ++ lib.optionals (!buildWithMeson) [ autoconf-archive autoreconfHook diff --git a/perl/meson.build b/perl/meson.build index 75c7c2c79..322616a6a 100644 --- a/perl/meson.build +++ b/perl/meson.build @@ -34,13 +34,8 @@ perl_version = run_command( capture : true, check : true, ).stdout() -perl_arch_name = run_command( - perl, - '-e', - 'use Config; print $Config{archname};', - capture : true, - check : true, -).stdout() + +perl_arch_name = host_machine.cpu_family() + '-' + host_machine.system() perl_libdir = f'@libdir@/perl5/site_perl/@perl_version@/@perl_arch_name@' ``` I used the following test expression, the resulting file executes fine with binfmt running: ```nix let pkgsBase = import <nixpkgs> { }; in with pkgsBase.pkgsCross.aarch64-multiplatform; writeShellScriptBin "test" '' exec ${perl.withPackages (p: [ (callPackage ./package.nix { build-release-notes = null; }).perl-bindings ])}/bin/perl ${pkgs.writeText "test.pl" '' use Nix::Store; if (isValidPath "/nix/store/8xnd1i8m9grv9ybdpbs080vxzvkdzway-home-manager-files") { print STDERR "yay\n"; } ''} '' ``` Now to the problems with that: * this doesn't take into account the suffixes of Perl's archname (e.g. `x86_64-linux-thread-multi`). These are set by Perl's `./Configure` script. I haven't found something where this got exposed (short of reading from `pkgs.perl`'s `$out`)[1]. * this doesn't take into account the version of the Perl interpreter. Same issue as above. I'm a little bit out of ideas here. Sure, I could write more cursed code, but I got nerd-sniped into it by accident, so it's not sufficiently important for me to mess around. I figured I'd share how far I got and ask for ideas on how to fix this properly. Not too experienced with cross builds in the end. [1] this is what nixpkgs seems to be doing: https://github.com/NixOS/nixpkgs/blob/bcd44e224fd68ce7d269b4f44d24c2220fd821e7/pkgs/development/interpreters/perl/interpreter.nix#L215
ma27 added the
bug
label 2024-05-01 11:20:57 +00:00
qyriad added the
Area/build-packaging
Cross Compilation
labels 2024-05-02 00:02:12 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lix-project/lix#259
No description provided.