18 # Try to match MacVim's documented script interface compatibility
24 # Building requires a few system tools to be in PATH.
25 # Some of these we could patch into the relevant source files (such as xcodebuild and
26 # qlmanage) but some are used by Xcode itself and we have no choice but to put them in PATH.
27 # Symlinking them in this way is better than just putting all of /usr/bin in there.
28 buildSymlinks = runCommand "macvim-build-symlinks" {} ''
30 ln -s /usr/bin/xcrun /usr/bin/xcodebuild /usr/bin/tiffutil /usr/bin/qlmanage $out/bin
34 stdenv.mkDerivation (finalAttrs: {
39 src = fetchFromGitHub {
42 rev = "release-${finalAttrs.version}";
43 hash = "sha256-L9LVXyeA09aMtNf+b/Oo+eLpeVEKTD1/oNWCiFn5FbU=";
46 enableParallelBuilding = true;
48 nativeBuildInputs = [ pkg-config buildSymlinks ];
50 gettext ncurses cscope luajit ruby tcl perl python3
53 patches = [ ./macvim.patch ];
57 "--enable-fail-if-missing"
58 "--with-features=huge"
62 "--enable-luainterp=dynamic"
63 "--enable-python3interp=dynamic"
64 "--enable-perlinterp=dynamic"
65 "--enable-rubyinterp=dynamic"
66 "--enable-tclinterp=yes"
69 "--with-lua-prefix=${luajit}"
70 "--with-python3-command=${python3}/bin/python3"
71 "--with-ruby-command=${ruby}/bin/ruby"
72 "--with-tclsh=${tcl}/bin/tclsh"
74 "--with-compiledby=Nix"
78 # Remove references to Sparkle.framework from the project.
79 # It's unused (we disabled it with --disable-sparkle) and this avoids
80 # copying the unnecessary several-megabyte framework into the result.
82 echo "Patching file src/MacVim/MacVim.xcodeproj/project.pbxproj"
83 sed -e '/Sparkle\.framework/d' -i src/MacVim/MacVim.xcodeproj/project.pbxproj
86 # This is unfortunate, but we need to use the same compiler as Xcode, but Xcode doesn't provide a
87 # way to configure the compiler. We also need to pull in lib/include paths for some of our build
88 # inputs since we don't have cc-wrapper to do that for us.
91 # ideally we'd recurse, but we don't need that right now
92 inputs = [ ncurses ] ++ perl.propagatedBuildInputs;
93 ldflags = map (drv: "-L${lib.getLib drv}/lib") inputs;
94 cppflags = map (drv: "-isystem ${lib.getDev drv}/include") inputs;
97 unset DEVELOPER_DIR # Use the system Xcode not the nixpkgs SDK.
101 DEV_DIR=$(/usr/bin/xcode-select -print-path)/Platforms/MacOSX.platform/Developer
102 configureFlagsArray+=(
103 --with-developer-dir="$DEV_DIR"
104 LDFLAGS=${lib.escapeShellArg ldflags}
105 CPPFLAGS=${lib.escapeShellArg cppflags}
106 CFLAGS="-Wno-error=implicit-function-declaration"
109 # For some reason having LD defined causes PSMTabBarControl to fail at link-time as it
110 # passes arguments to ld that it meant for clang.
114 # When building with nix-daemon, we need to pass -derivedDataPath or else it tries to use
115 # a folder rooted in /var/empty and fails. Unfortunately we can't just pass -derivedDataPath
116 # by itself as this flag requires the use of -scheme or -xctestrun (not sure why), but MacVim
117 # by default just runs `xcodebuild -project src/MacVim/MacVim.xcodeproj`, relying on the default
118 # behavior to build the first target in the project. Experimentally, there seems to be a scheme
119 # called MacVim, so we'll explicitly select that. We also need to specify the configuration too
120 # as the scheme seems to have the wrong default.
122 configureFlagsArray+=(
123 XCODEFLAGS="-scheme MacVim -derivedDataPath $NIX_BUILD_TOP/derivedData"
124 --with-xcodecfg="Release"
129 # Because we're building with system clang, this means we're building against Xcode's SDK and
130 # linking against system libraries. The configure script is picking up Nix Libsystem (via ruby)
131 # so we need to patch that out or we'll get linker issues. The MacVim binary built by Xcode links
132 # against the system anyway so it doesn't really matter that the Vim binary will too. If we
133 # decide that matters, we can always patch it back to the Nix libsystem post-build.
134 # It also picks up libiconv, libunwind, and objc4 from Nix. These seem relatively harmless but
135 # let's strip them out too.
137 # Note: If we do add a post-build install_name_tool patch, we need to add the
138 # "LDFLAGS=-headerpad_max_install_names" flag to configureFlags and either patch it into the
139 # Xcode project or pass it as a flag to xcodebuild as well.
141 substituteInPlace src/auto/config.mk \
142 --replace "PERL_CFLAGS${"\t"}=" "PERL_CFLAGS${"\t"}= -I${darwin.libutil}/include" \
143 --replace " -L${stdenv.cc.libc}/lib" "" \
144 --replace " -L${darwin.libobjc}/lib" "" \
145 --replace " -L${darwin.libunwind}/lib" "" \
146 --replace " -L${libiconv}/lib" ""
148 # All the libraries we stripped have -osx- in their name as of this time.
149 # Assert now that this pattern no longer appears in config.mk.
151 while IFS="" read -r line; do
152 if [[ "$line" == LDFLAGS*-osx-* ]]; then
153 echo "WARNING: src/auto/config.mk contains reference to Nix osx library" >&2
155 done <src/auto/config.mk
158 substituteInPlace src/MacVim/vimrc --subst-var-by CSCOPE ${cscope}/bin/cscope
161 # Note that $out/MacVim.app has a misnamed set of binaries in the Contents/bin folder (the V is
162 # capitalized) and is missing a bunch of them. This is why we're grabbing the version from the
165 mkdir -p $out/Applications
166 cp -r src/MacVim/build/Release/MacVim.app $out/Applications
167 rm -rf $out/MacVim.app
170 for prog in ex vi {,g,m,r}vi{m,mdiff,ew}; do
171 ln -s $out/Applications/MacVim.app/Contents/bin/mvim $out/bin/$prog
173 for prog in {,g}vimtutor xxd; do
174 ln -s $out/Applications/MacVim.app/Contents/bin/$prog $out/bin/$prog
176 ln -s $out/Applications/MacVim.app/Contents/bin/gvimtutor $out/bin/mvimtutor
179 ln -s $out/Applications/MacVim.app/Contents/man $out/share/man
182 exe="$out/Applications/MacVim.app/Contents/MacOS/Vim"
183 libperl=$(dirname $(find ${perl} -name "libperl.dylib"))
184 install_name_tool -add_rpath ${luajit}/lib $exe
185 install_name_tool -add_rpath ${tcl}/lib $exe
186 install_name_tool -add_rpath ${python3}/lib $exe
187 install_name_tool -add_rpath $libperl $exe
188 install_name_tool -add_rpath ${ruby}/lib $exe
190 # Remove manpages from tools we aren't providing
191 find $out/Applications/MacVim.app/Contents/man -name evim.1 -delete
194 # We rely on the user's Xcode install to build. It may be located in an arbitrary place, and
195 # it's not clear what system-level components it may require, so for now we'll just allow full
196 # filesystem access. This way the package still can't access the network.
198 (allow file-read* file-write* process-exec mach-lookup)
199 ; block homebrew dependencies
200 (deny file-read* file-write* process-exec mach-lookup (subpath "/usr/local") (with no-log))
204 description = "Vim - the text editor - for macOS";
205 homepage = "https://macvim.org/";
206 license = licenses.vim;
208 platforms = platforms.darwin;
209 hydraPlatforms = []; # hydra can't build this as long as we rely on Xcode and sandboxProfile