2 :: Copyright (C) 1996-2022 Free Software Foundation, Inc.
\r
3 :: This file is part of GNU Make.
\r
5 :: GNU Make is free software; you can redistribute it and/or modify it under
\r
6 :: the terms of the GNU General Public License as published by the Free
\r
7 :: Software Foundation; either version 3 of the License, or (at your option)
\r
8 :: any later version.
\r
10 :: GNU Make is distributed in the hope that it will be useful, but WITHOUT
\r
11 :: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
12 :: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for.
\r
15 :: You should have received a copy of the GNU General Public License along
\r
16 :: with this program. If not, see <https://www.gnu.org/licenses/>.
\r
19 if not "%RECURSEME%"=="%~0" (
\r
21 %ComSpec% /s /c ""%~0" %*"
\r
27 if "%1" == "-h" goto Usage
\r
28 if "%1" == "--help" goto Usage
\r
31 echo Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8/10
\r
43 if exist maintMakefile (
\r
50 if "%1" == "--verbose" goto SetVerbose
\r
51 if "%1" == "--debug" goto SetDebug
\r
52 if "%1" == "--without-guile" goto NoGuile
\r
53 if "%1" == "--x86" goto Set32Bit
\r
54 if "%1" == "gcc" goto SetCC
\r
55 if "%1" == "tcc" goto SetTCC
\r
56 if "%1" == "" goto DoneSW
\r
66 echo - Building without compiler optimizations
\r
72 echo - Building without Guile
\r
78 echo - Building 32bit GNU Make
\r
85 echo - Building with GCC
\r
92 echo - Building with TinyC
\r
97 if "%MAINT%" == "Y" echo - Enabling maintainer mode
\r
99 if "%COMPILER%" == "gcc" goto FindGcc
\r
100 if "%COMPILER%" == "tcc" goto FindTcc
\r
102 :: Find a compiler. Visual Studio requires a lot of effort to locate :-/.
\r
103 call %COMPILER% >nul 2>&1
\r
104 if not ERRORLEVEL 1 goto FoundMSVC
\r
106 :: Visual Studio 17 and above provides the "vswhere" tool
\r
108 if ERRORLEVEL 1 goto LegacyVS
\r
110 for /f "tokens=* usebackq" %%i in (`"%VSWHERE%" -latest -property installationPath`) do (
\r
111 set InstallPath=%%i
\r
113 set "VSVARS=%InstallPath%\VC\Auxiliary\Build\vcvarsall.bat"
\r
115 if not ERRORLEVEL 1 goto FoundMSVC
\r
117 :: No "vswhere" or it can't find a compiler. Go old-school.
\r
119 set "VSVARS=%VS150COMNTOOLS%\..\..\VC\vcvarsall.bat"
\r
121 if not ERRORLEVEL 1 goto FoundMSVC
\r
123 set "VSVARS=%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat"
\r
125 if not ERRORLEVEL 1 goto FoundMSVC
\r
127 set "VSVARS=%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat"
\r
129 if not ERRORLEVEL 1 goto FoundMSVC
\r
131 set "VSVARS=%VS110COMNTOOLS%\..\..\VC\vcvarsall.bat"
\r
133 if not ERRORLEVEL 1 goto FoundMSVC
\r
135 set "VSVARS=%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat"
\r
137 if not ERRORLEVEL 1 goto FoundMSVC
\r
139 set "VSVARS=%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat"
\r
141 if not ERRORLEVEL 1 goto FoundMSVC
\r
143 set "VSVARS=%VS80COMNTOOLS%\..\..\VC\vcvarsall.bat"
\r
145 if not ERRORLEVEL 1 goto FoundMSVC
\r
147 set "VSVARS=%VS71COMNTOOLS%\..\..\VC\vcvarsall.bat"
\r
149 if not ERRORLEVEL 1 goto FoundMSVC
\r
151 set "VSVARS=%VS70COMNTOOLS%\..\..\VC\vcvarsall.bat"
\r
153 if not ERRORLEVEL 1 goto FoundMSVC
\r
155 set "VSVARS=%V6TOOLS%\VC98\Bin\vcvars32.bat"
\r
157 if not ERRORLEVEL 1 goto FoundMSVC
\r
159 set "VSVARS=%V6TOOLS%\VC97\Bin\vcvars32.bat"
\r
161 if not ERRORLEVEL 1 goto FoundMSVC
\r
163 set "VSVARS=%V5TOOLS%\VC\Bin\vcvars32.bat"
\r
165 if not ERRORLEVEL 1 goto FoundMSVC
\r
167 :: We did not find anything--fail
\r
168 echo No MSVC compiler available.
\r
169 echo Please run vcvarsall.bat and/or configure your Path.
\r
173 set OUTDIR=.\WinRel
\r
174 set LNKOUT=./WinRel
\r
175 set "OPTS=/O2 /D NDEBUG"
\r
177 if "%DEBUG%" == "Y" set OUTDIR=.\WinDebug
\r
178 if "%DEBUG%" == "Y" set LNKOUT=./WinDebug
\r
179 if "%DEBUG%" == "Y" set "OPTS=/Zi /Od /D _DEBUG"
\r
180 if "%DEBUG%" == "Y" set LINKOPTS=/DEBUG
\r
181 if "%MAINT%" == "Y" set "OPTS=%OPTS% /D MAKE_MAINTAINER_MODE"
\r
182 :: Show the compiler version that we found
\r
183 :: Unfortunately this also shows a "usage" note; I can't find anything better.
\r
189 set OUTDIR=.\GccRel
\r
190 set LNKOUT=./GccRel
\r
193 if "%DEBUG%" == "Y" set OPTS=-O0
\r
194 if "%DEBUG%" == "Y" set OUTDIR=.\GccDebug
\r
195 if "%DEBUG%" == "Y" set LNKOUT=./GccDebug
\r
196 if "%MAINT%" == "Y" set "OPTS=%OPTS% -DMAKE_MAINTAINER_MODE"
\r
197 :: Show the compiler version that we found
\r
199 call %COMPILER% --version
\r
200 if not ERRORLEVEL 1 goto Build
\r
201 echo No %COMPILER% found.
\r
205 set OUTDIR=.\TccRel
\r
206 set LNKOUT=./TccRel
\r
208 if "%DEBUG%" == "Y" set OPTS=-O0
\r
209 if "%DEBUG%" == "Y" set OUTDIR=.\TccDebug
\r
210 if "%DEBUG%" == "Y" set LNKOUT=./TccDebug
\r
211 if "%MAINT%" == "Y" set "OPTS=%OPTS% -DMAKE_MAINTAINER_MODE"
\r
212 :: Show the compiler version that we found
\r
215 if not ERRORLEVEL 1 goto Build
\r
216 echo No %COMPILER% found.
\r
220 :: Clean the directory if it exists
\r
221 if exist %OUTDIR%\nul rmdir /S /Q %OUTDIR%
\r
226 mkdir %OUTDIR%\src\w32
\r
227 mkdir %OUTDIR%\src\w32\compat
\r
228 mkdir %OUTDIR%\src\w32\subproc
\r
231 if "%GUILE%" == "Y" call :ChkGuile
\r
233 if not exist src\config.h.W32 goto NotConfig
\r
236 echo Compiling %OUTDIR% version
\r
238 copy src\config.h.W32 %OUTDIR%\src\config.h
\r
240 copy lib\glob.in.h %OUTDIR%\lib\glob.h
\r
241 copy lib\fnmatch.in.h %OUTDIR%\lib\fnmatch.h
\r
243 if exist %OUTDIR%\link.sc del %OUTDIR%\link.sc
\r
245 call :Compile src/ar
\r
246 call :Compile src/arscan
\r
247 call :Compile src/commands
\r
248 call :Compile src/default
\r
249 call :Compile src/dir
\r
250 call :Compile src/expand
\r
251 call :Compile src/file
\r
252 call :Compile src/function
\r
253 call :Compile src/getopt
\r
254 call :Compile src/getopt1
\r
255 call :Compile src/guile GUILE
\r
256 call :Compile src/hash
\r
257 call :Compile src/implicit
\r
258 call :Compile src/job
\r
259 call :Compile src/load
\r
260 call :Compile src/loadapi
\r
261 call :Compile src/main GUILE
\r
262 call :Compile src/misc
\r
263 call :Compile src/output
\r
264 call :Compile src/read
\r
265 call :Compile src/remake
\r
266 call :Compile src/remote-stub
\r
267 call :Compile src/rule
\r
268 call :Compile src/shuffle
\r
269 call :Compile src/signame
\r
270 call :Compile src/strcache
\r
271 call :Compile src/variable
\r
272 call :Compile src/version
\r
273 call :Compile src/vpath
\r
274 call :Compile src/w32/pathstuff
\r
275 call :Compile src/w32/w32os
\r
276 call :Compile src/w32/compat/posixfcn
\r
277 call :Compile src/w32/subproc/misc
\r
278 call :Compile src/w32/subproc/sub_proc
\r
279 call :Compile src/w32/subproc/w32err
\r
280 call :Compile lib/fnmatch
\r
281 call :Compile lib/glob
\r
282 call :Compile lib/getloadavg
\r
284 :: Compile dirent unless it is supported by compiler library (like with gcc).
\r
285 if "%DIRENT%" == "Y" call :Compile src\w32\compat\dirent
\r
290 if exist %OUTDIR%\%MAKE%.exe goto Success
\r
291 echo %OUTDIR% build FAILED!
\r
295 echo %OUTDIR% build succeeded.
\r
296 if exist Basic.mk copy /Y Basic.mk Makefile
\r
297 if not exist tests\config-flags.pm copy /Y tests\config-flags.pm.W32 tests\config-flags.pm
\r
306 if "%VERBOSE%" == "N" echo - Compiling %1.c
\r
307 echo %LNKOUT%/%1.%O% >>%OUTDIR%\link.sc
\r
309 if "%2" == "GUILE" set "EXTRAS=%GUILECFLAGS%"
\r
310 if exist "%OUTDIR%\%1.%O%" del "%OUTDIR%\%1.%O%"
\r
311 if "%COMPILER%" == "gcc" goto GccCompile
\r
312 if "%COMPILER%" == "tcc" goto TccCompile
\r
315 if "%VERBOSE%" == "Y" echo on
\r
316 call %COMPILER% /nologo /MT /W4 /EHsc %OPTS% /I %OUTDIR%/src /I src /I %OUTDIR%/lib /I lib /I src/w32/include /D _CONSOLE /D HAVE_CONFIG_H /FR%OUTDIR% /Fp%OUTDIR%\%MAKE%.pch /Fo%OUTDIR%\%1.%O% /Fd%OUTDIR%\%MAKE%.pdb %EXTRAS% /c %1.c
\r
322 if "%VERBOSE%" == "Y" echo on
\r
323 call %COMPILER% -mthreads -Wall -std=gnu99 -gdwarf-2 -g3 %OPTS% -I%OUTDIR%/src -I./src -I%OUTDIR%/lib -I./lib -I./src/w32/include -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%/%1.%O% -c %1.c
\r
329 if "%VERBOSE%" == "Y" echo on
\r
330 call %COMPILER% -mthreads -Wall -std=c11 %OPTS% -I%OUTDIR%/src -I./src -I%OUTDIR%/lib -I./lib -I./src/w32/include -D_cdecl= -D_MSC_VER -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%/%1.%O% -c %1.c
\r
335 if not exist "%OUTDIR%\%1.%O%" exit 1
\r
340 echo - Linking %LNKOUT%/%MAKE%.exe
\r
341 if "%COMPILER%" == "gcc" goto GccLink
\r
342 if "%COMPILER%" == "tcc" goto TccLink
\r
345 echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib >>%OUTDIR%\link.sc
\r
346 if "%VERBOSE%" == "Y" echo on
\r
347 call link.exe /NOLOGO /SUBSYSTEM:console /PDB:%LNKOUT%\%MAKE%.pdb %LINKOPTS% /OUT:%LNKOUT%\%MAKE%.exe @%LNKOUT%\link.sc
\r
353 if "%VERBOSE%" == "Y" echo on
\r
354 echo %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 >>%OUTDIR%\link.sc
\r
355 call %COMPILER% -mthreads -gdwarf-2 -g3 %OPTS% -o %LNKOUT%/%MAKE%.exe @%LNKOUT%/link.sc -Wl,--out-implib=%LNKOUT%/libgnumake-1.dll.a
\r
361 if "%VERBOSE%" == "Y" echo on
\r
362 echo %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lodbc32 -lodbccp32 >>%OUTDIR%\link.sc
\r
363 call %COMPILER% -mthreads %OPTS% -o %LNKOUT%/%MAKE%.exe @%LNKOUT%/link.sc
\r
368 :: Build with Guile is supported only on NT and later versions
\r
369 if not "%OS%" == "Windows_NT" goto NoGuile
\r
370 call pkg-config --help > %OUTDIR%\guile.tmp 2> NUL
\r
371 if ERRORLEVEL 1 goto NoPkgCfg
\r
374 if not "%COMPILER%" == "gcc" set PKGMSC=--msvc-syntax
\r
376 echo Checking for Guile 2.0
\r
377 call pkg-config --cflags --short-errors "guile-2.0" > %OUTDIR%\gl-c2.tmp 2> NUL
\r
378 if not ERRORLEVEL 1 set /P GUILECFLAGS= < %OUTDIR%\gl-c2.tmp
\r
380 call pkg-config --libs --static --short-errors %PKGMSC% "guile-2.0" > %OUTDIR%\gl-l2.tmp 2> NUL
\r
381 if not ERRORLEVEL 1 set /P GUILELIBS= < %OUTDIR%\gl-l2.tmp
\r
383 if not "%GUILECFLAGS%" == "" goto GuileDone
\r
385 echo Checking for Guile 1.8
\r
386 call pkg-config --cflags --short-errors "guile-1.8" > %OUTDIR%\gl-c18.tmp 2> NUL
\r
387 if not ERRORLEVEL 1 set /P GUILECFLAGS= < %OUTDIR%\gl-c18.tmp
\r
389 call pkg-config --libs --static --short-errors %PKGMSC% "guile-1.8" > %OUTDIR%\gl-l18.tmp 2> NUL
\r
390 if not ERRORLEVEL 1 set /P GUILELIBS= < %OUTDIR%\gl-l18.tmp
\r
392 if not "%GUILECFLAGS%" == "" goto GuileDone
\r
394 echo - No Guile found, building without Guile
\r
398 echo - pkg-config not found, building without Guile
\r
401 if "%GUILECFLAGS%" == "" goto :EOF
\r
403 echo - Guile found: building with Guile
\r
404 set "GUILECFLAGS=%GUILECFLAGS% -DHAVE_GUILE"
\r
408 set VSWHERE=vswhere
\r
409 call "%VSWHERE%" -help >nul 2>&1
\r
410 if not ERRORLEVEL 1 exit /b 0
\r
411 set "VSWHERE=C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere"
\r
412 call "%VSWHERE%" -help >nul 2>&1
\r
413 if ERRORLEVEL 1 exit /b 1
\r
417 if not exist "%VSVARS%" exit /b 1
\r
418 call "%VSVARS%" %ARCH%
\r
419 if ERRORLEVEL 1 exit /b 1
\r
420 call %COMPILER% >nul 2>&1
\r
421 if ERRORLEVEL 1 exit /b 1
\r
426 echo *** This workspace is not configured.
\r
427 echo Either retrieve the configured source in the release tarball
\r
428 echo or, if building from Git, run the .\bootstrap.bat script first.
\r
432 echo Usage: %0 [options] [gcc] OR [tcc]
\r
434 echo. --without-guile Do not compile Guile support even if found
\r
435 echo. --debug Make a Debug build--default is Release
\r
436 echo. --x86 Make a 32bit binary--default is 64bit
\r
437 echo. --help Display these instructions and exit
\r
439 echo. "gcc" means compile with GCC, "tcc" means compile with Tiny C's TCC
\r