1{
2 lib,
3 stdenv,
4 fetchFromGitHub,
5 nix-update-script,
6
7 cmake,
8 mimalloc,
9 ninja,
10 tbb_2022,
11 zlib,
12 zstd,
13
14 buildPackages,
15 clangStdenv,
16 gccStdenv,
17 hello,
18 mold,
19 mold-wrapped,
20 runCommandCC,
21 testers,
22 useMoldLinker,
23
24 versionCheckHook,
25}:
26
27stdenv.mkDerivation (finalAttrs: {
28 pname = "mold";
29 version = "2.40.3";
30
31 src = fetchFromGitHub {
32 owner = "rui314";
33 repo = "mold";
34 tag = "v${finalAttrs.version}";
35 hash = "sha256-zE+qve1ooCN1UY0h9tI2jo7Sw+fVdhh4DPFIU7yYKSg=";
36 };
37
38 nativeBuildInputs = [
39 cmake
40 ninja
41 ];
42
43 buildInputs = [
44 tbb_2022
45 zlib
46 zstd
47 ]
48 ++ lib.optionals (!stdenv.hostPlatform.isDarwin) [
49 mimalloc
50 ];
51
52 cmakeFlags = [
53 "-DMOLD_USE_SYSTEM_MIMALLOC:BOOL=ON"
54 "-DMOLD_USE_SYSTEM_TBB:BOOL=ON"
55 ];
56
57 doInstallCheck = true;
58 nativeInstallCheckInputs = [ versionCheckHook ];
59 versionCheckProgramArg = "--version";
60
61 passthru = {
62 updateScript = nix-update-script { };
63 tests =
64 let
65 helloTest =
66 name: helloMold:
67 let
68 command = "$READELF -p .comment ${lib.getExe helloMold}";
69 emulator = stdenv.hostPlatform.emulator buildPackages;
70 in
71 runCommandCC "mold-${name}-test" { passthru = { inherit helloMold; }; } ''
72 echo "Testing running the 'hello' binary which should be linked with 'mold'" >&2
73 ${emulator} ${lib.getExe helloMold}
74
75 echo "Checking for mold in the '.comment' section" >&2
76 if output=$(${command} 2>&1); then
77 if grep -Fw -- "mold" - <<< "$output"; then
78 touch $out
79 else
80 echo "No mention of 'mold' detected in the '.comment' section" >&2
81 echo "The command was:" >&2
82 echo "${command}" >&2
83 echo "The output was:" >&2
84 echo "$output" >&2
85 exit 1
86 fi
87 else
88 echo -n "${command}" >&2
89 echo " returned a non-zero exit code." >&2
90 echo "$output" >&2
91 exit 1
92 fi
93 '';
94 in
95 {
96 version = testers.testVersion { package = mold; };
97 }
98 // lib.optionalAttrs stdenv.hostPlatform.isLinux {
99 adapter-gcc = helloTest "adapter-gcc" (
100 hello.override (old: {
101 stdenv = useMoldLinker gccStdenv;
102 })
103 );
104 adapter-llvm = helloTest "adapter-llvm" (
105 hello.override (old: {
106 stdenv = useMoldLinker clangStdenv;
107 })
108 );
109 wrapped = helloTest "wrapped" (
110 hello.overrideAttrs (previousAttrs: {
111 nativeBuildInputs = (previousAttrs.nativeBuildInputs or [ ]) ++ [ mold-wrapped ];
112 NIX_CFLAGS_LINK = toString (previousAttrs.NIX_CFLAGS_LINK or "") + " -fuse-ld=mold";
113 })
114 );
115 };
116 };
117
118 meta = {
119 description = "Faster drop-in replacement for existing Unix linkers (unwrapped)";
120 longDescription = ''
121 mold is a faster drop-in replacement for existing Unix linkers. It is
122 several times faster than the LLVM lld linker. mold is designed to
123 increase developer productivity by reducing build time, especially in
124 rapid debug-edit-rebuild cycles.
125 '';
126 homepage = "https://github.com/rui314/mold";
127 changelog = "https://github.com/rui314/mold/releases/tag/v${finalAttrs.version}";
128 license = lib.licenses.mit;
129 platforms = lib.platforms.unix;
130 broken = stdenv.hostPlatform.isDarwin;
131 mainProgram = "mold";
132 maintainers = with lib.maintainers; [ azahi ];
133 };
134})