vlang /
	
1@setlocal EnableDelayedExpansion EnableExtensions
2
3IF NOT DEFINED VERBOSE_MAKE @echo off
4
5REM Option flags
6set /a shift_counter=0
7set /a flag_local=0
8
9REM Option variables
10set compiler=
11set subcmd=
12set target=build
13
14REM TCC variables
15set "tcc_url=https://github.com/vlang/tccbin"
16set "tcc_dir=thirdparty\tcc"
17set "tcc_exe=thirdparty\tcc\tcc.exe"
18if "%PROCESSOR_ARCHITECTURE%" == "x86" ( set "tcc_branch=thirdparty-windows-i386" ) else ( set "tcc_branch=thirdparty-windows-amd64" )
19if "%~1" == "-tcc32" set "tcc_branch=thirdparty-windows-i386"
20
21REM VC settings
22set "vc_url=https://github.com/vlang/vc"
23set "vc_dir=%~dp0vc"
24
25REM Let a particular environment specify their own TCC and VC repos (to help mirrors)
26if /I not ["%TCC_GIT%"] == [""] set "tcc_url=%TCC_GIT%"
27if /I not ["%TCC_BRANCH%"] == [""] set "tcc_branch=%TCC_BRANCH%"
28
29if /I not ["%VC_GIT%"] == [""] set "vc_url=%VC_GIT%"
30
31pushd %~dp0
32
33:verifyopt
34REM Read stdin EOF
35if ["%~1"] == [""] goto :init
36
37REM Target options
38if !shift_counter! LSS 1 (
39 if "%~1" == "help" (
40 if not ["%~2"] == [""] set "subcmd=%~2"& shift& set /a shift_counter+=1
41 )
42 for %%z in (build clean cleanall help) do (
43 if "%~1" == "%%z" set target=%1& shift& set /a shift_counter+=1& goto :verifyopt
44 )
45)
46
47REM Compiler option
48for %%g in (-gcc -msvc -tcc -tcc32 -clang) do (
49 if "%~1" == "%%g" set compiler=%~1& set compiler=!compiler:~1!& shift& set /a shift_counter+=1& goto :verifyopt
50)
51
52REM Standard options
53if "%~1" == "--local" (
54 if !flag_local! NEQ 0 (
55 echo The flag %~1 has already been specified. 1>&2
56 exit /b 2
57 )
58 set /a flag_local=1
59 set /a shift_counter+=1
60 shift
61 goto :verifyopt
62)
63
64echo Undefined option: %~1
65exit /b 2
66
67:init
68goto :!target!
69
70:cleanall
71call :clean
72if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
73echo.
74echo Cleanup vc
75echo ^> Purge TCC binaries
76rmdir /s /q "%tcc_dir%"
77echo ^> Purge vc repository
78rmdir /s /q "%vc_dir%"
79exit /b 0
80
81:clean
82echo Cleanup build artifacts
83echo ^> Purge debug symbols
84del *.pdb *.lib *.bak *.out *.ilk *.exp *.obj *.o *.a *.so
85
86echo ^> Delete old V executable
87del v_old.exe v*.exe
88exit /b 0
89
90:help
91if [!subcmd!] == [] (
92 call :usage
93) else (
94 call :help_!subcmd!
95)
96if %ERRORLEVEL% NEQ 0 echo Invalid subcommand: !subcmd!
97exit /b %ERRORLEVEL%
98
99:build
100if !flag_local! NEQ 1 (
101 call :download_tcc
102 if %ERRORLEVEL% NEQ 0 goto :error
103 pushd "%vc_dir%" && (
104 echo Updating vc...
105 echo ^> Sync with remote !vc_url!
106 cd "%vc_dir%"
107 git pull --quiet
108 cd ..
109 popd
110 ) || call :cloning_vc
111 echo.
112)
113
114echo Building V...
115if not [!compiler!] == [] goto :!compiler!_strap
116
117
118REM By default, use tcc, since we have it prebuilt:
119:tcc_strap
120:tcc32_strap
121echo ^> Attempting to build v_win.c with "!tcc_exe!"
122"!tcc_exe!" -Bthirdparty/tcc -bt10 -g -w -o v.exe vc\v_win.c -ladvapi32
123if %ERRORLEVEL% NEQ 0 goto :compile_error
124echo ^> Compiling .\v.exe with itself
125v.exe -keepc -g -showcc -cc "!tcc_exe!" -cflags -Bthirdparty/tcc -o v2.exe cmd/v
126if %ERRORLEVEL% NEQ 0 goto :clang_strap
127del v.exe
128move v2.exe v.exe
129goto :success
130
131:clang_strap
132where /q clang
133if %ERRORLEVEL% NEQ 0 (
134 echo ^> Clang not found
135 if not [!compiler!] == [] goto :error
136 goto :gcc_strap
137)
138
139echo ^> Attempting to build v_win.c with Clang
140clang -std=c99 -municode -g -w -o v.exe .\vc\v_win.c -ladvapi32
141if %ERRORLEVEL% NEQ 0 (
142 echo In most cases, compile errors happen because the version of Clang installed is too old
143 clang --version
144 goto :compile_error
145)
146
147echo ^> Compiling .\v.exe with itself
148v.exe -keepc -g -showcc -cc clang -o v2.exe cmd/v
149if %ERRORLEVEL% NEQ 0 goto :compile_error
150del v.exe
151move v2.exe v.exe
152goto :success
153
154:gcc_strap
155where /q gcc
156if %ERRORLEVEL% NEQ 0 (
157 echo ^> GCC not found
158 if not [!compiler!] == [] goto :error
159 goto :msvc_strap
160)
161
162echo ^> Attempting to build v_win.c with GCC
163gcc -std=c99 -municode -g -w -o v.exe .\vc\v_win.c -ladvapi32
164if %ERRORLEVEL% NEQ 0 (
165 echo In most cases, compile errors happen because the version of GCC installed is too old
166 gcc --version
167 goto :compile_error
168)
169
170echo ^> Compiling .\v.exe with itself
171v.exe -keepc -g -showcc -cc gcc -o v2.exe cmd/v
172if %ERRORLEVEL% NEQ 0 goto :compile_error
173del v.exe
174move v2.exe v.exe
175goto :success
176
177:msvc_strap
178set VsWhereDir=%ProgramFiles(x86)%
179set HostArch=x64
180if "%PROCESSOR_ARCHITECTURE%" == "x86" (
181 echo Using x86 Build Tools...
182 set VsWhereDir=%ProgramFiles%
183 set HostArch=x86
184)
185
186if not exist "%VsWhereDir%\Microsoft Visual Studio\Installer\vswhere.exe" (
187 echo ^> MSVC not found
188 if not [!compiler!] == [] goto :error
189 goto :compile_error
190)
191
192for /f "usebackq tokens=*" %%i in (`"%VsWhereDir%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do (
193 set InstallDir=%%i
194)
195
196if exist "%InstallDir%\Common7\Tools\vsdevcmd.bat" (
197 call "%InstallDir%\Common7\Tools\vsdevcmd.bat" -arch=%HostArch% -host_arch=%HostArch% -no_logo
198) else if exist "%VsWhereDir%\Microsoft Visual Studio 14.0\Common7\Tools\vsdevcmd.bat" (
199 call "%VsWhereDir%\Microsoft Visual Studio 14.0\Common7\Tools\vsdevcmd.bat" -arch=%HostArch% -host_arch=%HostArch% -no_logo
200)
201
202set ObjFile=.v.c.obj
203
204echo ^> Attempting to build v_win.c with MSVC
205cl.exe /volatile:ms /Fo%ObjFile% /O2 /MD /D_VBOOTSTRAP vc\v_win.c user32.lib kernel32.lib advapi32.lib shell32.lib /link /nologo /out:v.exe /incremental:no
206if %ERRORLEVEL% NEQ 0 (
207 echo In some cases, compile errors happen because of the MSVC compiler version
208 cl.exe
209 goto :compile_error
210)
211
212echo ^> Compiling .\v.exe with itself
213v.exe -keepc -g -showcc -cc msvc -o v2.exe cmd/v
214del %ObjFile%
215if %ERRORLEVEL% NEQ 0 goto :compile_error
216del v.exe
217move v2.exe v.exe
218goto :success
219
220:download_tcc
221pushd %tcc_dir% && (
222 echo Updating TCC
223 echo ^> Syncing TCC from !tcc_url!
224 git pull --quiet
225 popd
226) || call :bootstrap_tcc
227
228if [!tcc_exe!] == [] echo ^> TCC not found, even after cloning& goto :error
229echo.
230exit /b 0
231
232:compile_error
233echo.
234echo Backend compiler error
235goto :error
236
237:error
238echo.
239echo Exiting from error
240echo ERROR: please follow the instructions in https://github.com/vlang/v/wiki/Installing-a-C-compiler-on-Windows
241exit /b 1
242
243:success
244.\v.exe run cmd\tools\detect_tcc.v
245echo ^> V built successfully!
246echo ^> To add V to your PATH, run `.\v.exe symlink`.
247
248:version
249echo.
250echo | set /p="V version: "
251.\v.exe version
252goto :eof
253
254:usage
255echo Usage:
256echo make.bat [target] [compiler] [options]
257echo.
258echo Compiler:
259echo -msvc ^| -gcc ^| -tcc ^| -tcc32 ^| -clang Set C compiler
260echo.
261echo Target:
262echo build[default] Compiles V using the given C compiler
263echo clean Clean build artifacts and debugging symbols
264echo cleanall Cleanup entire ALL build artifacts and vc repository
265echo help Display usage help for the given target
266echo.
267echo Examples:
268echo make.bat -msvc
269echo make.bat -gcc --local
270echo make.bat build -tcc --local
271echo make.bat -tcc32
272echo make.bat help clean
273echo.
274echo Use "make help <target>" for more information about a target, for instance: "make help clean"
275echo.
276echo Note: Any undefined/unsupported options will be ignored
277exit /b 0
278
279:help_help
280echo Usage:
281echo make.bat help [target]
282echo.
283echo Target:
284echo build ^| clean ^| cleanall ^| help Query given target
285exit /b 0
286
287:help_clean
288echo Usage:
289echo make.bat clean
290echo.
291exit /b 0
292
293:help_cleanall
294echo Usage:
295echo make.bat cleanall
296echo.
297exit /b 0
298
299:help_build
300echo Usage:
301echo make.bat build [compiler] [options]
302echo.
303echo Compiler:
304echo -msvc ^| -gcc ^| -tcc ^| -tcc32 ^| -clang Set C compiler
305echo.
306echo Options:
307echo --local Use the local vc repository without
308echo syncing with remote
309exit /b 0
310
311:bootstrap_tcc
312echo Bootstraping TCC...
313echo ^> TCC not found
314if "!tcc_branch!" == "thirdparty-windows-i386" ( echo ^> Downloading TCC32 from !tcc_url! , branch !tcc_branch! ) else ( echo ^> Downloading TCC64 from !tcc_url! , branch !tcc_branch! )
315git clone --depth 1 --quiet --single-branch --branch !tcc_branch! !tcc_url! "%tcc_dir%"
316git -C "%tcc_dir%" log -n3
317exit /b 0
318
319:cloning_vc
320echo Cloning vc...
321echo ^> Cloning from remote !vc_url!
322git clone --depth 1 --quiet "%vc_url%"
323exit /b 0
324
325:eof
326popd
327endlocal
328exit /b 0