1{
2 lib,
3 stdenv,
4 fetchurl,
5 autoPatchelfHook,
6 unzip,
7 zstd,
8 libedit,
9 zlib,
10 curl,
11 libbsd,
12 python3,
13}: let
14 mblackPythonEnv = python3.withPackages (ps:
15 with ps; [
16 click
17 mypy-extensions
18 packaging
19 pathspec
20 platformdirs
21 tomli
22 typing-extensions
23 ]);
24in
25 stdenv.mkDerivation rec {
26 pname = "mojo";
27 version = "26.1.0";
28
29 srcs = [
30 (fetchurl {
31 url = "https://conda.modular.com/max/linux-64/mojo-compiler-0.${version}-release.conda";
32 sha256 = "sha256-qtbPnlWCStoRR6yu6LN8aO8Zc7IIpKQYL3rIW8IOaQw=";
33 })
34 (fetchurl {
35 url = "https://conda.modular.com/max/linux-64/mojo-0.${version}-release.conda";
36 sha256 = "sha256-6UXo+/8P3SBk6hk7JvtLqVq3gjZ8/SosRSI1AGZDRJQ=";
37 })
38 # Using nixpkgs ncurses, mojo fails with error:
39 # version `NCURSES6_5.0.19991023' not found (required by <NIX-STORE-PATH>/lib/liblldb20.0.0git.so)
40 # So let's use the ncurses from Conda
41 (fetchurl {
42 url = "https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda";
43 sha256 = "sha256-P94pMjL6P8qYY14RZ95rfH/ag8ryS51skeye77T01YY=";
44 })
45 (fetchurl {
46 url = "https://repo.prefix.dev/max/noarch/mblack-${version}-release.conda";
47 sha256 = "sha256-bM7FL+c1T0S+k6QaEi0iFOzbAw5jYq/o54duqzVHLmI=";
48 })
49 ];
50
51 sourceRoot = ".";
52 preferLocalBuild = true;
53
54 nativeBuildInputs = [
55 autoPatchelfHook
56 unzip
57 zstd
58 ];
59
60 buildInputs = [
61 stdenv.cc.cc.lib
62 libedit
63 zlib
64 curl
65 libbsd
66 ];
67
68 unpackPhase = ''
69 for src in $srcs; do
70 unzip -o $src
71 tar --zstd -xf pkg-*.tar.zst
72 rm pkg-*.tar.zst
73 done
74 '';
75
76 installPhase = ''
77 mkdir -p $out
78 cp -r lib/ $out/lib/
79 cp -r bin/ $out/bin/
80 cp -r share/ $out/share
81
82 # Install mblack (Mojo formatter)
83 siteDir=$out/lib/${mblackPythonEnv.python.libPrefix}/site-packages
84 mkdir -p $siteDir
85 cp -r site-packages/* $siteDir/
86 cat > $out/bin/mblack << EOF
87 #!${stdenv.shell}
88 export PYTHONPATH=$siteDir:$PYTHONPATH
89 exec ${mblackPythonEnv}/bin/python -m mblack "\$@"
90 EOF
91 chmod +x $out/bin/mblack
92
93 ln -s ${libedit}/lib/libedit.so.0 $out/lib/libedit.so.2
94
95 # /etc/modular/modular.cfg contains hardcoded paths to libs
96 mkdir -p $out/etc/modular
97 cat > $out/etc/modular/modular.cfg << EOF
98 [max]
99 cache_dir = $out/share/max/.max_cache
100 driver_lib = $out/lib/libDeviceDriver.so
101 enable_compile_progress = true
102 enable_model_ir_cache = true
103 engine_lib = $out/lib/libmodular-framework-common.so
104 graph_lib = $out/lib/libmof.so
105 name = MAX Platform
106 path = $out
107 serve_lib = $out/lib/libServeRTCAPI.so
108 torch_ext_lib = $out/lib/libmodular-framework-torch-ext.so
109 version = ${version}
110
111 [mojo-max]
112 compilerrt_path = $out/lib/libKGENCompilerRTShared.so
113 mgprt_path = $out/lib/libMGPRT.so
114 atenrt_path = $out/lib/libATenRT.so
115 shared_libs = $out/lib/libAsyncRTMojoBindings.so,$out/lib/libAsyncRTRuntimeGlobals.so,$out/lib/libMSupportGlobals.so,-Xlinker,-rpath,-Xlinker,$out/lib
116 driver_path = $out/bin/mojo
117 import_path = $out/lib/mojo
118 jupyter_path = $out/lib/libMojoJupyter.so
119 lldb_path = $out/bin/mojo-lldb
120 lldb_plugin_path = $out/lib/libMojoLLDB.so
121 lldb_visualizers_path = $out/lib/lldb-visualizers
122 lldb_vscode_path = $out/bin/mojo-lldb-dap
123 lsp_server_path = $out/bin/mojo-lsp-server
124 mblack_path = $out/bin/mblack
125 orcrt_path = $out/lib/liborc_rt.a
126 repl_entry_point = $out/lib/mojo-repl-entry-point
127 system_libs = -lrt,-ldl,-lpthread,-lm,-lz,-ltinfo
128 test_executor_path = $out/lib/mojo-test-executor
129 EOF
130
131 # Create mojo wrapper that uses generated modular.cfg
132 mkdir -p $out/bin
133 mv $out/bin/mojo $out/bin/mojo-unwrapped
134 cat > $out/bin/mojo << EOF
135 #!${stdenv.shell}
136 export MODULAR_HOME=$out/etc/modular
137 export TERMINFO_DIRS=$out/share/terminfo
138 exec $out/bin/mojo-unwrapped "\$@"
139 EOF
140 chmod +x $out/bin/mojo
141
142 # Create mojo-lldb wrapper that uses generated modular.cfg
143 mkdir -p $out/bin
144 mv $out/bin/mojo-lldb $out/bin/mojo-lldb-unwrapped
145 cat > $out/bin/mojo-lldb << EOF
146 #!${stdenv.shell}
147 export MODULAR_HOME=$out/etc/modular
148 export TERMINFO_DIRS=$out/share/terminfo
149 exec $out/bin/mojo-lldb-unwrapped "\$@"
150 EOF
151 chmod +x $out/bin/mojo-lldb
152
153 # Create mojo-lsp-server wrapper that uses generated modular.cfg
154 mv $out/bin/mojo-lsp-server $out/bin/mojo-lsp-server-unwrapped
155 cat > $out/bin/mojo-lsp-server << EOF
156 #!${stdenv.shell}
157 export MODULAR_HOME=$out/etc/modular
158 exec $out/bin/mojo-lsp-server-unwrapped -I $out/lib/mojo "\$@"
159 EOF
160 chmod +x $out/bin/mojo-lsp-server
161
162 # /etc/modular/crashdb needs to be mutable
163 ln -s /tmp/ $out/etc/modular/crashdb
164
165 # /etc/modular/cache needs to be mutable
166 ln -s /tmp/ $out/etc/modular/cache
167 '';
168
169 doInstallCheck = true;
170 installCheckPhase = ''
171 $out/bin/mojo --version
172 $out/bin/mojo-lldb --version
173 $out/bin/mojo-lsp-server --version
174 '';
175
176 meta = with lib; {
177 description = "Mojo Programming Language";
178 homepage = "https://www.modular.com/mojo";
179 platforms = platforms.linux;
180 maintainers = with lib.maintainers; [noverby];
181 license = licenses.unfree;
182 };
183 }