1{ lib
2, stdenv
3, fetchFromGitHub
4, runCommand
5, ncurses
6, gettext
7, pkg-config
8, cscope
9, ruby
10, tcl
11, perl
12, luajit
13, darwin
14, python3
15}:
16
17let
18 # Building requires a few system tools to be in PATH.
19 # Some of these we could patch into the relevant source files (such as xcodebuild and
20 # qlmanage) but some are used by Xcode itself and we have no choice but to put them in PATH.
21 # Symlinking them in this way is better than just putting all of /usr/bin in there.
22 buildSymlinks = runCommand "macvim-build-symlinks" {} ''
23 mkdir -p $out/bin
24 ln -s /usr/bin/xcrun /usr/bin/xcodebuild /usr/bin/tiffutil /usr/bin/qlmanage $out/bin
25 '';
26in
27
28stdenv.mkDerivation {
29 pname = "macvim";
30
31 version = "8.2.3455";
32
33 src = fetchFromGitHub {
34 owner = "macvim-dev";
35 repo = "macvim";
36 rev = "snapshot-172";
37 sha256 = "sha256-LLLQ/V1vyKTuSXzHW3SOlOejZD5AV16NthEdMoTnfko=";
38 };
39
40 enableParallelBuilding = true;
41
42 nativeBuildInputs = [ pkg-config buildSymlinks ];
43 buildInputs = [
44 gettext ncurses cscope luajit ruby tcl perl python3
45 ];
46
47 patches = [ ./macvim.patch ];
48
49 configureFlags = [
50 "--enable-cscope"
51 "--enable-fail-if-missing"
52 "--with-features=huge"
53 "--enable-gui=macvim"
54 "--enable-multibyte"
55 "--enable-nls"
56 "--enable-luainterp=dynamic"
57 "--enable-python3interp=dynamic"
58 "--enable-perlinterp=dynamic"
59 "--enable-rubyinterp=dynamic"
60 "--enable-tclinterp=yes"
61 "--without-local-dir"
62 "--with-luajit"
63 "--with-lua-prefix=${luajit}"
64 "--with-python3-command=${python3}/bin/python3"
65 "--with-ruby-command=${ruby}/bin/ruby"
66 "--with-tclsh=${tcl}/bin/tclsh"
67 "--with-tlib=ncurses"
68 "--with-compiledby=Nix"
69 "--disable-sparkle"
70 ];
71
72 # Remove references to Sparkle.framework from the project.
73 # It's unused (we disabled it with --disable-sparkle) and this avoids
74 # copying the unnecessary several-megabyte framework into the result.
75 postPatch = ''
76 echo "Patching file src/MacVim/MacVim.xcodeproj/project.pbxproj"
77 sed -e '/Sparkle\.framework/d' -i src/MacVim/MacVim.xcodeproj/project.pbxproj
78 '';
79
80 # This is unfortunate, but we need to use the same compiler as Xcode,
81 # but Xcode doesn't provide a way to configure the compiler.
82 preConfigure = ''
83 CC=/usr/bin/clang
84
85 DEV_DIR=$(/usr/bin/xcode-select -print-path)/Platforms/MacOSX.platform/Developer
86 configureFlagsArray+=(
87 --with-developer-dir="$DEV_DIR"
88 LDFLAGS="-L${ncurses}/lib"
89 CPPFLAGS="-isystem ${ncurses.dev}/include"
90 CFLAGS="-Wno-error=implicit-function-declaration"
91 )
92 ''
93 # For some reason having LD defined causes PSMTabBarControl to fail at link-time as it
94 # passes arguments to ld that it meant for clang.
95 + ''
96 unset LD
97 ''
98 # When building with nix-daemon, we need to pass -derivedDataPath or else it tries to use
99 # a folder rooted in /var/empty and fails. Unfortunately we can't just pass -derivedDataPath
100 # by itself as this flag requires the use of -scheme or -xctestrun (not sure why), but MacVim
101 # by default just runs `xcodebuild -project src/MacVim/MacVim.xcodeproj`, relying on the default
102 # behavior to build the first target in the project. Experimentally, there seems to be a scheme
103 # called MacVim, so we'll explicitly select that. We also need to specify the configuration too
104 # as the scheme seems to have the wrong default.
105 + ''
106 configureFlagsArray+=(
107 XCODEFLAGS="-scheme MacVim -derivedDataPath $NIX_BUILD_TOP/derivedData"
108 --with-xcodecfg="Release"
109 )
110 ''
111 ;
112
113 # Because we're building with system clang, this means we're building against Xcode's SDK and
114 # linking against system libraries. The configure script is picking up Nix Libsystem (via ruby)
115 # so we need to patch that out or we'll get linker issues. The MacVim binary built by Xcode links
116 # against the system anyway so it doesn't really matter that the Vim binary will too. If we
117 # decide that matters, we can always patch it back to the Nix libsystem post-build.
118 # It also picks up libiconv, libunwind, and objc4 from Nix. These seem relatively harmless but
119 # let's strip them out too.
120 #
121 # Note: If we do add a post-build install_name_tool patch, we need to add the
122 # "LDFLAGS=-headerpad_max_install_names" flag to configureFlags and either patch it into the
123 # Xcode project or pass it as a flag to xcodebuild as well.
124 postConfigure = ''
125 substituteInPlace src/auto/config.mk \
126 --replace "PERL_CFLAGS =" "PERL_CFLAGS = -I${darwin.libutil}/include" \
127 --replace " -L${stdenv.cc.libc}/lib" "" \
128 --replace " -L${darwin.libobjc}/lib" "" \
129 --replace " -L${darwin.libunwind}/lib" "" \
130 --replace " -L${darwin.libiconv}/lib" ""
131
132 # All the libraries we stripped have -osx- in their name as of this time.
133 # Assert now that this pattern no longer appears in config.mk.
134 ( # scope variable
135 while IFS="" read -r line; do
136 if [[ "$line" == LDFLAGS*-osx-* ]]; then
137 echo "WARNING: src/auto/config.mk contains reference to Nix osx library" >&2
138 fi
139 done <src/auto/config.mk
140 )
141
142 substituteInPlace src/MacVim/vimrc --subst-var-by CSCOPE ${cscope}/bin/cscope
143 '';
144
145 postInstall = ''
146 mkdir -p $out/Applications
147 cp -r src/MacVim/build/Release/MacVim.app $out/Applications
148 rm -rf $out/MacVim.app
149
150 rm $out/bin/*
151
152 cp src/vimtutor $out/bin
153 for prog in mvim ex vi vim vimdiff view rvim rvimdiff rview; do
154 ln -s $out/Applications/MacVim.app/Contents/bin/mvim $out/bin/$prog
155 done
156
157 # Fix rpaths
158 exe="$out/Applications/MacVim.app/Contents/MacOS/Vim"
159 libperl=$(dirname $(find ${perl} -name "libperl.dylib"))
160 install_name_tool -add_rpath ${luajit}/lib $exe
161 install_name_tool -add_rpath ${tcl}/lib $exe
162 install_name_tool -add_rpath ${python3}/lib $exe
163 install_name_tool -add_rpath $libperl $exe
164 install_name_tool -add_rpath ${ruby}/lib $exe
165
166 # Remove manpages from tools we aren't providing
167 find $out/share/man \( -name eVim.1 -or -name xxd.1 \) -delete
168 '';
169
170 # We rely on the user's Xcode install to build. It may be located in an arbitrary place, and
171 # it's not clear what system-level components it may require, so for now we'll just allow full
172 # filesystem access. This way the package still can't access the network.
173 sandboxProfile = ''
174 (allow file-read* file-write* process-exec mach-lookup)
175 ; block homebrew dependencies
176 (deny file-read* file-write* process-exec mach-lookup (subpath "/usr/local") (with no-log))
177 '';
178
179 meta = with lib; {
180 description = "Vim - the text editor - for macOS";
181 homepage = "https://github.com/macvim-dev/macvim";
182 license = licenses.vim;
183 maintainers = with maintainers; [ cstrahan lilyball ];
184 platforms = platforms.darwin;
185 hydraPlatforms = []; # hydra can't build this as long as we rely on Xcode and sandboxProfile
186 };
187}