@echo off setlocal enabledelayedexpansion set ROOT=%~dp0. set SRC=%ROOT%\code set PUBLIC=%SRC%\public set COMMON=%SRC%\common set KERNEL=%SRC%\kernel set HAL=%KERNEL%\hal set USER=%SRC%\user set DRIVERS=%SRC%\drivers set THIRD_PARTY=%SRC%\third_party set VHD=%~dp0disk.vhd if not exist "%VHD%" ( call mkimage.bat ) if exist "obj" rd /s /q "obj" if exist "bin" rd /s /q "bin" mkdir "obj\boot" 2>nul mkdir "obj\kernel" 2>nul mkdir "obj\lwip" 2>nul mkdir "obj\hal" 2>nul mkdir "obj\syscall" 2>nul mkdir "obj\win32" 2>nul mkdir "obj\posix" 2>nul mkdir "obj\drivers" 2>nul mkdir "obj\init" 2>nul mkdir "obj\shell_win32" 2>nul mkdir "obj\shell_posix" 2>nul mkdir "obj\shell_native" 2>nul mkdir "obj\async_apc" 2>nul mkdir "obj\async_cancel" 2>nul mkdir "obj\edit" 2>nul mkdir "obj\httpget" 2>nul mkdir "obj\tcpserve" 2>nul mkdir "obj\udp" 2>nul mkdir "obj\resolve" 2>nul mkdir "obj\ping" 2>nul mkdir "obj\doom" 2>nul mkdir "obj\video" 2>nul mkdir "bin" 2>nul set INCLUDES=/I"%PUBLIC%" /I"%COMMON%\include" /I"%KERNEL%\include" set CFLAGS=/nologo /W3 /WX /Od /GS- /Gs999999 /Gz /Gy /EHsc- /GR- /Oi /Zi /std:c17 /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS %INCLUDES% set KERNEL_CFLAGS=%CFLAGS% rem lwIP is third-party freestanding C. Compile it into lwip.sys without /WX, rem and silence expected MSVC warnings from packed protocol headers and macros. set LWIP_ROOT=%DRIVERS%\net\lwip set LWIP_DRIVER_CFLAGS=%CFLAGS:/WX =% /I"%LWIP_ROOT%\include" /I"%THIRD_PARTY%\lwip\src\include" /wd4005 /wd4100 /wd4103 /wd4127 /wd4244 /wd4267 /wd4706 set LFLAGS=/nologo /NODEFAULTLIB /DEBUG :: ---- Assemble ASM files ---- echo Assembling... ml64 /nologo /c /Fo"obj\kernel\ke_switch.obj" "%KERNEL%\ke_switch.asm" || exit /b 1 ml64 /nologo /c /Fo"obj\kernel\ke_syscall_asm.obj" "%KERNEL%\ke_syscall.asm" || exit /b 1 ml64 /nologo /c /Fo"obj\kernel\ke_gdt_reload.obj" "%KERNEL%\ke_gdt_reload.asm" || exit /b 1 for %%f in (%SRC%\boot\uefi\*.asm) do ( ml64 /nologo /c /Fo"obj\boot\%%~nf.obj" "%%f" || exit /b 1 ) ml64 /nologo /c /Fo"obj\syscall\stubs.obj" "%USER%\syscall\syscall_stubs.asm" || exit /b 1 :: ---- Compile shared freestanding support ---- cl /nologo /c /Fo"obj\libc.obj" "%COMMON%\libc.c" || exit /b 1 cl %CFLAGS% /c /Fo"obj\printf.obj" "%COMMON%\printf.c" || exit /b 1 cl %CFLAGS% /c /Fo"obj\ini_parser.obj" "%COMMON%\ini_parser.c" || exit /b 1 :: ---- Compile bootloader ---- echo Compiling bootloader... for %%f in (%SRC%\boot\uefi\*.c) do ( cl %CFLAGS% /c /I"%SRC%\boot\uefi\include" /Fo"obj\boot\%%~nf.obj" "%%f" || exit /b 1 ) :: ---- Link bootloader ---- echo Linking bootx64.efi... link %LFLAGS% /SUBSYSTEM:EFI_APPLICATION /ENTRY:UefiMain /OUT:"bin\bootx64.efi" ^ /PDB:"bin\bootx64.pdb" %SRC%\boot\uefi\efilib.lib obj\ini_parser.obj obj\libc.obj obj\boot\*.obj || exit /b 1 :: ---- Compile HAL ---- echo Compiling hal... for %%f in (%HAL%\*.c) do ( cl %CFLAGS% /c /Fo"obj\hal\%%~nf.obj" "%%f" || exit /b 1 ) :: ---- Link hal.dll ---- echo Linking hal.dll... link %LFLAGS% /DLL /OUT:"bin\hal.dll" /ENTRY:HalInitialize /IGNORE:4216 obj\printf.obj obj\libc.obj obj\hal\*.obj || exit /b 1 :: ---- Compile kernel ---- echo Compiling kernel... for %%f in (%KERNEL%\*.c) do ( cl %KERNEL_CFLAGS% /c /Fo"obj\kernel\%%~nf.obj" "%%f" || exit /b 1 ) :: ---- Link kernel.exe ---- echo Linking kernel.exe... link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:KernelMain /OUT:"bin\kernel.exe" /PDB:"bin\kernel.pdb" ^ bin\hal.lib obj\ini_parser.obj obj\printf.obj obj\libc.obj obj\kernel\*.obj || exit /b 1 :: ---- Compile syscall.dll ---- echo Compiling syscall.dll... link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL ^ /OUT:"bin\syscall.dll" obj\syscall\stubs.obj || exit /b 1 :: ---- Compile win32.dll ---- echo Compiling win32.dll... for %%f in (%USER%\personalities\win32\*.c) do ( cl %CFLAGS% /c /Fo"obj\win32\%%~nf.obj" "%%f" || exit /b 1 ) link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL ^ /OUT:"bin\win32.dll" bin\syscall.lib obj\libc.obj obj\win32\*.obj || exit /b 1 :: ---- Compile posix.dll ---- echo Compiling posix.dll... for %%f in (%USER%\personalities\posix\*.c) do ( cl %CFLAGS% /c /Fo"obj\posix\%%~nf.obj" "%%f" || exit /b 1 ) link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL ^ /OUT:"bin\posix.dll" bin\syscall.lib obj\libc.obj obj\posix\*.obj || exit /b 1 :: ---- Compile drivers ---- echo Compiling drivers... echo Compiling ide.sys... cl %CFLAGS% /c /Fo"obj\drivers\ide.obj" "%DRIVERS%\storage\ide\ide.c" || exit /b 1 link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:"bin\ide.sys" /ENTRY:DriverEntry ^ bin\hal.lib bin\kernel.lib obj\libc.obj obj\drivers\ide.obj || exit /b 1 echo Compiling ahci.sys... cl %CFLAGS% /c /Fo"obj\drivers\ahci.obj" "%DRIVERS%\storage\ahci\ahci.c" || exit /b 1 link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:"bin\ahci.sys" /ENTRY:DriverEntry ^ bin\hal.lib bin\kernel.lib obj\libc.obj obj\drivers\ahci.obj || exit /b 1 echo Compiling fat32.sys... cl %CFLAGS% /c /Fo"obj\drivers\fat32.obj" "%DRIVERS%\fs\fat32\fat32.c" || exit /b 1 link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:"bin\fat32.sys" /ENTRY:DriverEntry ^ bin\hal.lib bin\kernel.lib obj\libc.obj obj\drivers\fat32.obj || exit /b 1 echo Compiling lwip.sys... for /f "usebackq tokens=* delims=" %%f in ("%LWIP_ROOT%\lwip_sources.txt") do ( set "LWIP_FILE=%%f" if not "!LWIP_FILE!"=="" if not "!LWIP_FILE:~0,1!"=="#" ( set "LWIP_WIN_FILE=!LWIP_FILE:/=\!" for %%g in ("!LWIP_WIN_FILE!") do ( cl %LWIP_DRIVER_CFLAGS% /c /Fo"obj\lwip\%%~ng.obj" "%SRC%\!LWIP_WIN_FILE!" || exit /b 1 ) ) ) link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:"bin\lwip.sys" /ENTRY:DriverEntry ^ bin\hal.lib bin\kernel.lib obj\libc.obj obj\lwip\*.obj || exit /b 1 echo Compiling usb.sys... cl %CFLAGS% /c /Fo"obj\drivers\usb.obj" "%DRIVERS%\bus\usb\usb.c" || exit /b 1 link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:"bin\usb.sys" /ENTRY:DriverEntry ^ bin\hal.lib bin\kernel.lib obj\libc.obj obj\drivers\usb.obj || exit /b 1 echo Compiling rtl816x.sys... cl %CFLAGS% /c /Fo"obj\drivers\rtl816x.obj" "%DRIVERS%\net\rtl816x\rtl816x.c" || exit /b 1 link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:"bin\rtl816x.sys" /ENTRY:DriverEntry ^ bin\hal.lib bin\kernel.lib obj\libc.obj obj\drivers\rtl816x.obj || exit /b 1 echo Compiling rtl8139.sys... cl %CFLAGS% /c /Fo"obj\drivers\rtl8139.obj" "%DRIVERS%\net\rtl8139\rtl8139.c" || exit /b 1 link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:"bin\rtl8139.sys" /ENTRY:DriverEntry ^ bin\hal.lib bin\kernel.lib obj\libc.obj obj\drivers\rtl8139.obj || exit /b 1 :: ---- Compile init ---- echo Compiling init... for %%f in (%USER%\system\init\*.c) do ( cl %CFLAGS% /c /Fo"obj\init\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:_start ^ /OUT:"bin\init.exe" /PDB:"bin\init.pdb" bin\syscall.lib obj\libc.obj obj\init\init.obj || exit /b 1 :: ---- Compile shell_win32 ---- echo Compiling shell_win32... for %%f in (%USER%\apps\shell_win32\*.c) do ( cl %CFLAGS% /c /Fo"obj\shell_win32\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\shell_win32.exe" /PDB:"bin\shell_win32.pdb" bin\win32.lib obj\libc.obj obj\shell_win32\*.obj || exit /b 1 :: ---- Compile shell_posix ---- echo Compiling shell_posix... for %%f in (%USER%\apps\shell_posix\*.c) do ( cl %CFLAGS% /c /Fo"obj\shell_posix\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\shell_posix.exe" /PDB:"bin\shell_posix.pdb" bin\posix.lib obj\libc.obj obj\shell_posix\*.obj || exit /b 1 :: ---- Compile shell_native ---- echo Compiling shell_native... for %%f in (%USER%\apps\shell_native\*.c) do ( cl %CFLAGS% /c /Fo"obj\shell_native\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\shell_native.exe" /PDB:"bin\shell_native.pdb" bin\syscall.lib obj\libc.obj obj\shell_native\*.obj || exit /b 1 :: ---- Compile async_apc ---- echo Compiling async_apc... for %%f in (%USER%\tests\async_apc\*.c) do ( cl %CFLAGS% /c /Fo"obj\async_apc\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\async_apc.exe" /PDB:"bin\async_apc.pdb" bin\syscall.lib obj\libc.obj obj\async_apc\*.obj || exit /b 1 :: ---- Compile async_cancel ---- echo Compiling async_cancel... for %%f in (%USER%\tests\async_cancel\*.c) do ( cl %CFLAGS% /c /Fo"obj\async_cancel\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\async_cancel.exe" /PDB:"bin\async_cancel.pdb" bin\syscall.lib obj\libc.obj obj\async_cancel\*.obj || exit /b 1 :: ---- Compile edit ---- echo Compiling edit... for %%f in (%USER%\apps\edit\*.c) do ( cl %CFLAGS% /c /Fo"obj\edit\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\edit.exe" /PDB:"bin\edit.pdb" bin\syscall.lib obj\libc.obj obj\edit\*.obj || exit /b 1 :: ---- Compile httpget ---- echo Compiling httpget... for %%f in (%USER%\apps\httpget\*.c) do ( cl %CFLAGS% /c /Fo"obj\httpget\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\httpget.exe" /PDB:"bin\httpget.pdb" bin\syscall.lib obj\libc.obj obj\httpget\*.obj || exit /b 1 :: ---- Compile tcpserve ---- echo Compiling tcpserve... for %%f in (%USER%\apps\tcpserve\*.c) do ( cl %CFLAGS% /c /Fo"obj\tcpserve\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\tcpserve.exe" /PDB:"bin\tcpserve.pdb" bin\syscall.lib obj\libc.obj obj\tcpserve\*.obj || exit /b 1 :: ---- Compile udp ---- echo Compiling udp... for %%f in (%USER%\apps\udp\*.c) do ( cl %CFLAGS% /c /Fo"obj\udp\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\udp.exe" /PDB:"bin\udp.pdb" bin\syscall.lib obj\libc.obj obj\udp\*.obj || exit /b 1 :: ---- Compile resolve ---- echo Compiling resolve... for %%f in (%USER%\apps\resolve\*.c) do ( cl %CFLAGS% /c /Fo"obj\resolve\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\resolve.exe" /PDB:"bin\resolve.pdb" bin\syscall.lib obj\libc.obj obj\resolve\*.obj || exit /b 1 :: ---- Compile ping ---- echo Compiling ping... for %%f in (%USER%\apps\ping\*.c) do ( cl %CFLAGS% /c /Fo"obj\ping\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\ping.exe" /PDB:"bin\ping.pdb" bin\syscall.lib obj\libc.obj obj\ping\*.obj || exit /b 1 :: ---- Compile doom ---- echo Compiling doom... for %%f in (%USER%\apps\doom\*.c) do ( cl %CFLAGS% /c /Fo"obj\doom\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\doom.exe" /PDB:"bin\doom.pdb" bin\syscall.lib obj\libc.obj obj\doom\*.obj || exit /b 1 :: ---- Compile video player ---- echo Compiling video... for %%f in (%USER%\apps\video\*.c) do ( cl %CFLAGS% /c /Fo"obj\video\%%~nf.obj" "%%f" || exit /b 1 ) link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:main ^ /OUT:"bin\video.exe" /PDB:"bin\video.pdb" bin\win32.lib obj\libc.obj %USER%\apps\video\bink2w64.lib obj\video\*.obj || exit /b 1 :: ---- Mount disk image ---- echo Mounting disk.vhd... set DPS=%TEMP%\ntlite_mnt_%RANDOM%.txt ( echo select vdisk file="%VHD%" echo attach vdisk echo select partition 1 echo format fs=fat32 quick echo assign letter=Z echo select partition 2 echo format fs=fat32 quick echo assign letter=Y echo exit ) > "%DPS%" diskpart /s "%DPS%" del "%DPS%" if not exist "Z:\" ( echo ERROR: Could not mount disk.vhd as Z: echo If Z: is already in use, change the letter in build.bat and mkimage.bat. exit /b 1 ) set DEST=Z: set DEST2=Y: :: ---- Copy to ESP layout ---- echo Assembling ESP... mkdir "%DEST%\apps" 2>nul mkdir "%DEST2%\apps" 2>nul mkdir "%DEST%\system" 2>nul mkdir "%DEST%\drivers" 2>nul mkdir "%DEST%\EFI\BOOT" 2>nul copy /y "bin\bootx64.efi" "%DEST%\EFI\BOOT\" copy /y "bin\kernel.exe" "%DEST%\system\colonel.exe" copy /y "bin\hal.dll" "%DEST%\system\" copy /y "bin\syscall.dll" "%DEST%\system\" copy /y "bin\win32.dll" "%DEST%\system\" copy /y "bin\posix.dll" "%DEST%\system\" copy /y "%SRC%\settings.ini" "%DEST%\system\" copy /y "bin\ide.sys" "%DEST%\drivers\" copy /y "bin\ahci.sys" "%DEST%\drivers\" copy /y "bin\fat32.sys" "%DEST%\drivers\" copy /y "bin\lwip.sys" "%DEST%\drivers\" copy /y "bin\usb.sys" "%DEST%\drivers\" copy /y "bin\rtl816x.sys" "%DEST%\drivers\" copy /y "bin\rtl8139.sys" "%DEST%\drivers\" copy /y "bin\init.exe" "%DEST%\system\" copy /y "bin\shell_win32.exe" "%DEST%\apps\" copy /y "bin\shell_posix.exe" "%DEST%\apps\" copy /y "bin\shell_native.exe" "%DEST%\apps\" copy /y "bin\async_apc.exe" "%DEST2%\apps\" copy /y "bin\async_cancel.exe" "%DEST2%\apps\" copy /y "bin\edit.exe" "%DEST%\apps\" copy /y "bin\httpget.exe" "%DEST%\apps\" copy /y "bin\tcpserve.exe" "%DEST%\apps\" copy /y "bin\udp.exe" "%DEST%\apps\" copy /y "bin\resolve.exe" "%DEST%\apps\" copy /y "bin\ping.exe" "%DEST%\apps\" copy /y "bin\doom.exe" "%DEST%\apps\" copy /y "bin\video.exe" "%DEST%\apps\" copy /y "%SRC%\boot.ini" "%DEST%\" copy /y "%DRIVERS%\drivers.ini" "%DEST%\drivers\" if exist "%USER%\apps\video\bink2w64.dll" copy /y "%USER%\apps\video\bink2w64.dll" "%DEST%\apps\" if exist "%USER%\apps\video\video.bk2" copy /y "%USER%\apps\video\video.bk2" "%DEST%\apps\" if exist "%USER%\apps\doom\doom1.wad" copy /y "%USER%\apps\doom\doom1.wad" "%DEST%\apps\" :: ---- Unmount disk image ---- echo Unmounting disk.vhd... set DPS=%TEMP%\ntlite_umnt_%RANDOM%.txt ( echo select vdisk file="%VHD%" echo detach vdisk echo exit ) > "%DPS%" diskpart /s "%DPS%" del "%DPS%" echo. echo Build complete.