1{
2 lib,
3 stdenv,
4 fetchFromGitHub,
5 gitUpdater,
6 cmake,
7 python3,
8 withDynarec ? (
9 stdenv.hostPlatform.isAarch64 || stdenv.hostPlatform.isRiscV64 || stdenv.hostPlatform.isLoongArch64
10 ),
11 runCommand,
12 hello-x86_64,
13}:
14
15# Currently only supported on specific archs
16assert
17 withDynarec
18 -> (
19 stdenv.hostPlatform.isAarch64 || stdenv.hostPlatform.isRiscV64 || stdenv.hostPlatform.isLoongArch64
20 );
21
22stdenv.mkDerivation (finalAttrs: {
23 pname = "box64";
24 version = "0.3.6";
25
26 src = fetchFromGitHub {
27 owner = "ptitSeb";
28 repo = "box64";
29 rev = "v${finalAttrs.version}";
30 hash = "sha256-Z8r7aonVj7VSifgLKx/L7VRdGNnQtTvS4mjI+2+uPxY=";
31 };
32
33 # Setting cpu doesn't seem to work (or maybe isn't enough / gets overwritten by the wrapper's arch flag?), errors about unsupported instructions for target
34 # (this is for code that gets executed conditionally if the cpu at runtime supports their features, so setting this should be fine)
35 postPatch = ''
36 substituteInPlace CMakeLists.txt \
37 --replace-fail 'ASMFLAGS -pipe -mcpu=cortex-a76' 'ASMFLAGS -pipe -march=armv8.2-a+fp16+dotprod'
38 '';
39
40 nativeBuildInputs = [
41 cmake
42 python3
43 ];
44
45 cmakeFlags = [
46 (lib.cmakeBool "NOGIT" true)
47
48 # Arch mega-option
49 (lib.cmakeBool "ARM64" stdenv.hostPlatform.isAarch64)
50 (lib.cmakeBool "RV64" stdenv.hostPlatform.isRiscV64)
51 (lib.cmakeBool "PPC64LE" (stdenv.hostPlatform.isPower64 && stdenv.hostPlatform.isLittleEndian))
52 (lib.cmakeBool "LARCH64" stdenv.hostPlatform.isLoongArch64)
53 ]
54 ++ lib.optionals stdenv.hostPlatform.isx86_64 [
55 # x86_64 has no arch-specific mega-option, manually enable the options that apply to it
56 (lib.cmakeBool "LD80BITS" true)
57 (lib.cmakeBool "NOALIGN" true)
58 ]
59 ++ [
60 # Arch dynarec
61 (lib.cmakeBool "ARM_DYNAREC" (withDynarec && stdenv.hostPlatform.isAarch64))
62 (lib.cmakeBool "RV64_DYNAREC" (withDynarec && stdenv.hostPlatform.isRiscV64))
63 (lib.cmakeBool "LARCH64_DYNAREC" (withDynarec && stdenv.hostPlatform.isLoongArch64))
64 ];
65
66 installPhase = ''
67 runHook preInstall
68
69 install -Dm 0755 box64 "$out/bin/box64"
70
71 runHook postInstall
72 '';
73
74 doCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
75
76 doInstallCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
77
78 installCheckPhase = ''
79 runHook preInstallCheck
80
81 echo Checking if it works
82 $out/bin/box64 -v
83
84 echo Checking if Dynarec option was respected
85 $out/bin/box64 -v | grep ${lib.optionalString (!withDynarec) "-v"} Dynarec
86
87 runHook postInstallCheck
88 '';
89
90 passthru = {
91 updateScript = gitUpdater { rev-prefix = "v"; };
92 tests.hello =
93 runCommand "box64-test-hello" { nativeBuildInputs = [ finalAttrs.finalPackage ]; }
94 # There is no actual "Hello, world!" with any of the logging enabled, and with all logging disabled it's hard to
95 # tell what problems the emulator has run into.
96 ''
97 BOX64_NOBANNER=0 BOX64_LOG=1 box64 ${lib.getExe hello-x86_64} --version | tee $out
98 '';
99 };
100
101 meta = {
102 homepage = "https://box86.org/";
103 description = "Lets you run x86_64 Linux programs on non-x86_64 Linux systems";
104 changelog = "https://github.com/ptitSeb/box64/releases/tag/v${finalAttrs.version}";
105 license = lib.licenses.mit;
106 maintainers = with lib.maintainers; [
107 gador
108 OPNA2608
109 ];
110 mainProgram = "box64";
111 platforms = [
112 "x86_64-linux"
113 "aarch64-linux"
114 "riscv64-linux"
115 "powerpc64le-linux"
116 "loongarch64-linux"
117 "mips64el-linux"
118 ];
119 };
120})