@echo off

REM ---------------[ PREFACE ]---------------------------------------------
REM This script will build both the 32- and 64-bit version of both Vim
REM and GVim in their latest upstream versions (if possible). It can and
REM probably will break sometimes. Just wait for repository updates - they
REM will fix it. Also, remember to keep track of your local changes (e.g.
REM by using "git diff" and "git status".)
REM ----------------------------------------------------------------------


REM ---------------[ PREREQUISITES ]--------------------------------------
REM * 7-zip (for packing the archives and SFXs).
REM * A local clone of the Vim repository (here: /vim). I take mine from
REM   GitHub: https://github.com/vim/vim
REM * A Git client.
REM * Visual Studio 2019 or higher (Community Edition would work) with
REM   the Windows 10 SDK.
REM * libsodium (the MSVC prebuilt libraries should do). Note that you might
REM   need to adjust the path in Make_mvc.mak - the library version (e.g.
REM   142 for Visual Studio 14.2 = 2019) needs to fit your MSVC version.
REM * Strawberry (or Active) Perl, IronTcl (both x86 and x64), Lua for Windows,
REM   Python2 and Python3. Note that Tcl needs to be compiled with the same MSVC
REM   version. (You might want to compile it yourself.)
REM * Racket, compiled with the same MSVC version.
REM * Depending on your Perl distribution, you might have to fix Perl's
REM   config file (CORE/config.h) by commenting out symbols you don't have
REM   (like STDBOOL).
REM * Also you'll need to grab Ruby from the RubyInstaller:
REM   http://rubyinstaller.org/. You will have to generate your own
REM   config.h file for it to work though. Please refer to Vim's docs in
REM   src\INSTALLpc.txt (paragraph 11).
REM * TERMINAL support is compiled in with winpty. You'll need winpty-agent
REM   and winpty.dll in the appropriate binary directories. winpty can be
REM   obtained from https://github.com/rprichard/winpty/releases (use the
REM   MSVC version, just in case).
REM * gettext (for the src/po folder). You will probably have to adjust
REM   the gettext path in src/po/Make_mvc.mak for your system.
REM * diff.exe and patch.exe from the official Vim releases. (Can be left
REM   out if you wish.)
REM ----------------------------------------------------------------------


REM update the sources ...
REM ------------------------------------

cd vim
git pull


REM set vars ...
REM ------------------------------------

REM LIBPYTHON2 = short (2-digit) version of Python 2.x
REM LIBPYTHON3 = short (2-digit) version of Python 3.x
REM LIBTCLSHRT = short (2-digit) version of Tcl
REM LIBTCLLONG = long (x.y) version of Tcl
REM LIBRBYSHRT = short (2-digit) version of Ruby
REM LIBRBYLIB  = Ruby version (x.y.z) in the library folder name
REM LIBLUASHRT = short (2-digit) version of Lua
REM LIBLUALONG = long (x.y) version of Lua
REM LIBPERLVER = 3-digit version of Perl
REM LIBRACKET  = current version of your libracket.lib (part of its file name)

REM LUA_DIR     = Lua installation directory
REM PERL_DIR    = Perl installation directory
REM PYTHON2_DIR = Python 2 installation directory
REM PYTHON3_DIR = Python 3 installation directory
REM RACKET_DIR  = Racket installation directory
REM RUBY_DIR    = Ruby installation directory
REM TCL32DIR    = Tcl installation directory (x86)
REM TCL64DIR    = Tcl installation directory (x64)
REM SODIUMDIR   = libsodium extraction directory
REM SODIUMx86DIR = The directory containing libsodium.dll for x86.
REM SODIUMx64DIR = The directory containing libsodium.dll for x64.

REM PATCHDIFF = the directory where patch.exe and diff.exe reside
REM MSVCDIR   = the directory where Visual Studio resides, containing the vcvarsall.bat file
REM WINPTYDIR = the root directory of your winpty folder (see the intro for details)

set LIBPYTHON2=27
set LIBPYTHON3=310
set LIBTCLSHRT=86
set LIBTCLLONG=8.6
set LIBRBYSHRT=31
set LIBRBYLIB=3.1.0
set LIBLUASHRT=54
set LIBLUALONG=5.4
set LIBPERLVER=532
set LIBRACKET=xxxxxxx

set LUA_DIR=..\..\libs\lua
set PERL_DIR=C:\strawberry\perl
set PYTHON2_DIR=C:\Python%LIBPYTHON2%
set PYTHON3_DIR=C:\Python%LIBPYTHON3%
set RACKET_DIR=..\..\libs\racket-8.5
set RUBY_DIR=C:\tools\ruby%LIBRBYSHRT%
set TCL32DIR=C:\Tcl
set TCL64DIR=C:\tcl-64
set SODIUMDIR=..\..\libs\libsodium-1.0.18
set SODIUMx86DIR=%SODIUMDIR%\Win32\Release\v142\dynamic
set SODIUMx64DIR=%SODIUMDIR%\x64\Release\v142\dynamic

set PATCHDIFF=..\..
set MSVCDIR=%PROGRAMFILES(X86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build
set WINPTYDIR=..\..\libs\winpty-0.4.3-msvc2015


REM -----------------------------------------------------
REM you probably won't have to edit anything below this.
REM -----------------------------------------------------

REM Flags for all build types:
set NMAKE_COMMON_FLAGS=DEBUG=no GUI=yes DIRECTX=yes USE_MSVCRT=yes FEATURES=HUGE CHANNEL=yes MBYTE=yes CSCOPE=yes TERMINAL=yes IME=yes GIME=yes SODIUM=%SODIUMDIR%

REM Flags for nmake clean:
set NMAKE_CLEAN_FLAGS_32=CPU=i386 PERL="%PERL_DIR%" LUA="%LUA_DIR%" TCL="%TCL32DIR%" RUBY=%RUBY_DIR% PYTHON=%PYTHON2_DIR% PYTHON3=%PYTHON3_DIR% MZSCHEME="%RACKET_DIR%"
set NMAKE_CLEAN_FLAGS_64=CPU=AMD64 PERL="%PERL_DIR%" LUA="%LUA_DIR%" TCL="%TCL64DIR%" RUBY=%RUBY_DIR% PYTHON=%PYTHON2_DIR% PYTHON3=%PYTHON3_DIR% MZSCHEME="%RACKET_DIR%"

REM Flags for nmake build:
set NMAKE_LUA_FLAGS=LUA="%LUA_DIR%" DYNAMIC_LUA=yes LUA_VER=%LIBLUASHRT%
set NMAKE_PERL_FLAGS=PERL=%PERL_DIR% DYNAMIC_PERL=yes PERL_VER=%LIBPERLVER%
set NMAKE_PYTHON_FLAGS=PYTHON=%PYTHON2_DIR% DYNAMIC_PYTHON=yes PYTHON_VER=%LIBPYTHON2% PYTHON3=%PYTHON3_DIR% DYNAMIC_PYTHON3=yes PYTHON3_VER=%LIBPYTHON3%
set NMAKE_RACKET_FLAGS=MZSCHEME="%RACKET_DIR%" DYNAMIC_MZSCHEME=yes MZSCHEME_MAIN_LIB=racket MZSCHEME_VER=%LIBRACKET%
set NMAKE_RUBY_FLAGS=RUBY=%RUBY_DIR% DYNAMIC_RUBY=yes RUBY_VER=%LIBRBYSHRT% RUBY_API_VER_LONG=%LIBRBYLIB% RUBY_MSVCRT_NAME=msvcrt
set NMAKE_TCL_FLAGS_32=TCL=%TCL32DIR% TCL_VER=%LIBTCLSHRT% TCL_VER_LONG=%LIBTCLLONG% DYNAMIC_TCL=yes TCL_DLL=tcl%LIBTCLSHRT%t.dll
set NMAKE_TCL_FLAGS_64=TCL=%TCL64DIR% TCL_VER=%LIBTCLSHRT% TCL_VER_LONG=%LIBTCLLONG% DYNAMIC_TCL=yes TCL_DLL=tcl%LIBTCLSHRT%t.dll

set NMAKE_LIB_FLAGS_32=%NMAKE_LUA_FLAGS% %NMAKE_PERL_FLAGS% %NMAKE_PYTHON_FLAGS% %NMAKE_RACKET_FLAGS% %NMAKE_RUBY_FLAGS% %NMAKE_TCL_FLAGS_32%
set NMAKE_LIB_FLAGS_64=%NMAKE_LUA_FLAGS% %NMAKE_PERL_FLAGS% %NMAKE_PYTHON_FLAGS% %NMAKE_RACKET_FLAGS% %NMAKE_RUBY_FLAGS% %NMAKE_TCL_FLAGS_64%

set NMAKE_BUILD_FLAGS_32=CPU=i386 %NMAKE_COMMON_FLAGS% XPM=.\xpm\x86 %NMAKE_LIB_FLAGS_32%
set NMAKE_BUILD_FLAGS_64=CPU=AMD64 %NMAKE_COMMON_FLAGS% XPM=.\xpm\x64 %NMAKE_LIB_FLAGS_64%


REM create output directory ...
REM ------------------------------------

if not exist src\tempoutput mkdir src\tempoutput
if not exist src\tempoutput mkdir src\tempoutput\x86
if not exist src\tempoutput mkdir src\tempoutput\x64


REM make clean (manually)
REM -------------------------------------

cd src
if exist del /Q ObjCULYHTRZVAMD64\*.*
if exist del /Q ObjCULYHTRZVi386\*.*
if exist del /Q ObjDXOULYHTRZVAMD64\*.*
if exist del /Q ObjDXOULYHTRZVi386\*.*
if exist del /Q ObjDXULYHTRZVAMD64\*.*
if exist del /Q ObjDXULYHTRZVi386\*.*
if exist del /Q ObjGXULYHTRZVAMD64\*.*
if exist del /Q ObjGXULYHTRZVi386\*.*


REM delete archive files
REM -------------------------------------

if exist tempoutput\complete*.7z del tempoutput\complete*.7z
if exist tempoutput\complete*.exe del tempoutput\complete*.exe


REM prepare the environment ...
REM ------------------------------------

if exist gvim_noOLE.exe del gvim_noOLE.exe
call "%MSVCDIR%\vcvarsall.bat" x86


REM Build GVim without OLE (x86).
REM -------------------------------------

nmake /C /S /f Make_mvc.mak VIMDLL=no OLE=no %NMAKE_COMMON_FLAGS% %NMAKE_CLEAN_FLAGS_32% clean
nmake /C /S /f Make_mvc.mak VIMDLL=no OLE=no %NMAKE_COMMON_FLAGS% %NMAKE_BUILD_FLAGS_32%


REM Keep it for the release:
REM -------------------------------------

ren gvim.exe gvim_noOLE.exe

REM Build GVim and Vim with OLE (x86).
REM -------------------------------------
REM Vim 8.1.1230 and higher automatically
REM build both versions with "VIMDLL=yes"
REM by using a shared library.
REM -------------------------------------

nmake /C /S /f Make_mvc.mak VIMDLL=yes OLE=yes %NMAKE_COMMON_FLAGS% %NMAKE_CLEAN_FLAGS_32% clean
nmake /C /S /f Make_mvc.mak VIMDLL=yes OLE=yes %NMAKE_COMMON_FLAGS% %NMAKE_BUILD_FLAGS_32%


REM generate the .mo files
REM ----------------------

cd po
nmake -f Make_mvc.mak install-all
cd ..


REM keep up the right directory structure
REM -------------------------------------

robocopy ..\runtime\ tempoutput\x86\ /MIR /NP /NJH /NJS /NFL /NDL
copy ..\vimtutor.* tempoutput\x86\
xcopy xxd\xxd.exe tempoutput\x86\ /K
xcopy tee\tee.exe tempoutput\x86\ /K
xcopy *.exe tempoutput\x86\ /K
copy vim32.dll tempoutput\x86\

copy %SODIUMx86DIR%\libsodium.dll tempoutput\x86\

if exist gvim_noOLE.exe del gvim_noOLE.exe

if not exist tempoutput\x86\GVimExt32 mkdir tempoutput\x86\GVimExt32
if not exist tempoutput\x86\VisVim mkdir tempoutput\x86\VisVim

copy gvimext\*.dll tempoutput\x86\gvimext32\
copy gvimext\*.inf tempoutput\x86\gvimext32\
copy gvimext\*.reg tempoutput\x86\gvimext32\
copy gvimext\README.txt tempoutput\x86\gvimext32\

copy %WINPTYDIR%\ia32\bin\winpty.dll tempoutput\x86\
copy %WINPTYDIR%\ia32\bin\winpty-agent.exe tempoutput\x86\

if exist %PATCHDIFF%\patch.exe copy %PATCHDIFF%\patch.exe tempoutput\x86\
if exist %PATCHDIFF%\diff.exe copy %PATCHDIFF%\diff.exe tempoutput\x86\


REM cleanup
REM ------------------------------------

del tempoutput\x86\vimlogo.*
del tempoutput\x86\*.png
del tempoutput\x86\vim??x??.*


REM pack it!
REM (remove install.exe first - triggers 
REM  false warnings from AVs)
REM ------------------------------------

cd tempoutput\x86
del *instal*.exe
7z a -mx=9 -r -bd ..\complete-x86.7z *
7z a -mx=9 -r -bd -sfx7z.sfx ..\complete-x86.exe *

cd ..\..


REM prepare the environment ...
REM ------------------------------------

if exist gvim_noOLE.exe del gvim_noOLE.exe
call "%MSVCDIR%\vcvarsall.bat" x64


REM Build GVim without OLE (x64).
REM -------------------------------------

nmake /C /S /f Make_mvc.mak VIMDLL=no OLE=no %NMAKE_COMMON_FLAGS% %NMAKE_CLEAN_FLAGS_64% clean
nmake /C /S /f Make_mvc.mak VIMDLL=no OLE=no %NMAKE_COMMON_FLAGS% %NMAKE_BUILD_FLAGS_64%

REM Keep it for the release:
REM -------------------------------------

ren gvim.exe gvim_noOLE.exe

REM Build GVim and Vim with OLE (x64).
REM -------------------------------------
REM Vim 8.1.1230 and higher automatically
REM build both versions with "VIMDLL=yes"
REM by using a shared library.
REM -------------------------------------

nmake /C /S /f Make_mvc.mak VIMDLL=yes OLE=yes %NMAKE_COMMON_FLAGS% %NMAKE_CLEAN_FLAGS_64% clean
nmake /C /S /f Make_mvc.mak VIMDLL=yes OLE=yes %NMAKE_COMMON_FLAGS% %NMAKE_BUILD_FLAGS_64%


REM generate the .mo files
REM ----------------------

cd po
nmake -f Make_mvc.mak install-all
cd ..


REM keep up the right directory structure
REM -------------------------------------

robocopy ..\runtime\ tempoutput\x64\ /MIR /NP /NJH /NJS /NFL /NDL
copy ..\vimtutor.* tempoutput\x64\
xcopy xxd\xxd.exe tempoutput\x64\ /K
xcopy tee\tee.exe tempoutput\x64\ /K
xcopy *.exe tempoutput\x64\ /K
copy vim64.dll tempoutput\x64\

copy %SODIUMx64DIR%\libsodium.dll tempoutput\x64\

if not exist tempoutput\x64\GVimExt64 mkdir tempoutput\x64\GVimExt64
if not exist tempoutput\x64\VisVim mkdir tempoutput\x64\VisVim

copy gvimext\*.dll tempoutput\x64\gvimext64\
copy gvimext\*.inf tempoutput\x64\gvimext64\
copy gvimext\*.reg tempoutput\x64\gvimext64\
copy gvimext\README.txt tempoutput\x64\gvimext64\

copy %WINPTYDIR%\x64\bin\winpty.dll tempoutput\x64\
copy %WINPTYDIR%\x64\bin\winpty-agent.exe tempoutput\x64\

if exist %PATCHDIFF%\patch.exe copy %PATCHDIFF%\patch.exe tempoutput\x64\
if exist %PATCHDIFF%\diff.exe copy %PATCHDIFF%\diff.exe tempoutput\x64\


REM cleanup
REM ------------------------------------

del tempoutput\x64\vimlogo.*
del tempoutput\x64\*.png
del tempoutput\x64\vim??x??.*


REM pack it!
REM (remove install.exe first - triggers
REM  false warnings from AVs)
REM ------------------------------------

cd tempoutput\x64
del *instal*.exe
7z a -mx=9 -r -bd ..\complete-x64.7z *
7z a -mx=9 -r -bd -sfx7z.sfx ..\complete-x64.exe *


REM ------------------------------------------------ DONE!


cd ..
cd ..
cd ..
cd ..


REM copy today's files into /upload
REM ------------------------------------

rd /S /Q upload
mkdir upload
robocopy vim\src\tempoutput\ upload\ /MAXAGE:1 /NP /NJH /NJS /NFL /NDL /SL /S
For this site, I also generate a file named _versioninfo.txt which is the list of compiled features, using ripgrep:
vim\src\tempoutput\x64\vim.exe --version | rg -e "^(Huge|[+-])" > upload/_versioninfo.txt
Using a POSIX shell, generate the version file like this:
cd $VIMDIR
major=`grep -E 'VIM_VERSION_MAJOR\s{2,}' vim/src/version.h | awk '{ printf "%d.",$3 }'`
minor=`grep -E 'VIM_VERSION_MINOR\s{2,}' vim/src/version.h | awk '{ printf "%d.",$3 }'`
build=`awk '/number below this line/,/,/' vim/src/version.c | awk 'NR == 3 { printf "%04d",$1 }' | sed -e 's/[ ,]//g'`


# Store a version file in the upload folder:
echo $major$minor$build > upload/_version.php
Finally, scp everything in the "upload" folder to the server and that's it.

Back to the site