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