Build Windows ARM64 (experimental) #7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Windows ARM64 (experimental) | |
| # Experimental native Windows ARM64 build. | |
| # - Runner: windows-11-arm (GitHub-hosted, public preview). | |
| # - Harbour libs and Scintilla DLLs are built from source for ARM64. | |
| # - Trigger is manual only until the pipeline stabilises; it is NOT | |
| # wired to "release: published" to avoid breaking the release flow. | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| upload_to_release: | |
| description: 'Upload artifact to a release tag (leave blank to skip)' | |
| required: false | |
| default: '' | |
| permissions: | |
| contents: write | |
| env: | |
| ASSET: HbBuilder-1.0.0-windows-arm64.zip | |
| jobs: | |
| build: | |
| name: Build (arm64, experimental) | |
| runs-on: windows-11-arm | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up MSVC (arm64) | |
| uses: ilammy/msvc-dev-cmd@v1 | |
| with: | |
| arch: arm64 | |
| - name: Show toolchain | |
| shell: cmd | |
| run: | | |
| where cl.exe | |
| where link.exe | |
| where nmake.exe | |
| cl.exe 2>&1 | findstr /C:"Version" /C:"ARM" | |
| - name: Cache Harbour (ARM64) | |
| id: cache-harbour | |
| uses: actions/cache@v4 | |
| with: | |
| path: C:\harbour | |
| key: harbour-win-arm64-v2-contribs | |
| save-always: true | |
| - name: Locate GNU make on runner | |
| id: findmake | |
| shell: cmd | |
| run: | | |
| where mingw32-make 2>nul && (echo MAKE=mingw32-make>>%GITHUB_ENV%& goto :done) | |
| where make 2>nul && (echo MAKE=make>>%GITHUB_ENV%& goto :done) | |
| if exist "C:\Program Files\Git\usr\bin\make.exe" ( | |
| echo MAKE="C:\Program Files\Git\usr\bin\make.exe">>%GITHUB_ENV% | |
| goto :done | |
| ) | |
| if exist "C:\msys64\usr\bin\make.exe" ( | |
| echo MAKE=C:\msys64\usr\bin\make.exe>>%GITHUB_ENV% | |
| goto :done | |
| ) | |
| echo ERROR: no GNU make found on runner | |
| exit /b 1 | |
| :done | |
| echo MAKE found | |
| - name: Build Harbour (ARM64) if cache miss | |
| if: steps.cache-harbour.outputs.cache-hit != 'true' | |
| shell: cmd | |
| run: | | |
| git clone --depth 1 https://github.com/harbour/core C:\harbour-src | |
| cd /d C:\harbour-src | |
| set HB_COMPILER=msvcarm64 | |
| set HB_PLATFORM=win | |
| set HB_INSTALL_PREFIX=C:\harbour | |
| set HB_BUILD_SHARED=no | |
| REM Enable contribs — hbct, hbsqlit3 are linked by HbBuilder. | |
| REM Contribs add ~3-5 min but provide hbct.lib / hbsqlit3.lib. | |
| echo Using make: %MAKE% | |
| REM Serialise (-j1) so harbour.exe in src/main is fully linked | |
| REM before any sub-tree (src/vm, src/rtl, ...) tries to invoke it | |
| REM to process .prg sources. | |
| %MAKE% -j1 install | |
| if errorlevel 1 ( | |
| echo Harbour build failed | |
| exit /b 1 | |
| ) | |
| REM Diagnostic listings — do NOT let their exit code fail the step | |
| echo === C:\harbour\lib\win\msvcarm64 === | |
| dir C:\harbour\lib\win\msvcarm64 1>nul 2>nul | |
| dir C:\harbour\lib\win\msvcarm64 2>&1 & rem | |
| echo === C:\harbour\bin === | |
| dir C:\harbour\bin /S /B 2>&1 & rem | |
| exit /b 0 | |
| - name: Build Scintilla + Lexilla (ARM64) | |
| shell: pwsh | |
| run: | | |
| New-Item -ItemType Directory -Force -Path resources\scintilla_src | Out-Null | |
| Push-Location resources\scintilla_src | |
| if (-not (Test-Path scintilla\cocoa\ScintillaView.h)) { | |
| curl.exe -L -o scintilla556.tgz https://www.scintilla.org/scintilla556.tgz | |
| curl.exe -L -o lexilla520.tgz https://www.scintilla.org/lexilla520.tgz | |
| tar xzf scintilla556.tgz | |
| tar xzf lexilla520.tgz | |
| Remove-Item scintilla556.tgz, lexilla520.tgz | |
| } | |
| # /CETCOMPAT is x86/x64-only (Intel CET) — strip from .mak files | |
| # before nmake. Scintilla/Lexilla hardcode it in LDFLAGS. | |
| $maks = @('lexilla\src\lexilla.mak', 'scintilla\win32\scintilla.mak') | |
| foreach ($m in $maks) { | |
| # Match the flag plus only horizontal whitespace (no newlines) | |
| # so !IF / !ENDIF block structure is preserved. | |
| (Get-Content $m -Raw) -replace '[ \t]*-CETCOMPAT', '' | Set-Content $m -NoNewline | |
| Select-String -Path $m -Pattern 'CETCOMPAT' | ForEach-Object { Write-Host "STILL PRESENT: $_" } | |
| } | |
| # Lexilla | |
| Push-Location lexilla\src | |
| nmake -f lexilla.mak DIR_O=..\bin DIR_BIN=..\bin | |
| if ($LASTEXITCODE -ne 0) { throw "Lexilla build failed" } | |
| Pop-Location | |
| # Scintilla | |
| Push-Location scintilla\win32 | |
| nmake -f scintilla.mak DIR_O=..\bin DIR_BIN=..\bin | |
| if ($LASTEXITCODE -ne 0) { throw "Scintilla build failed" } | |
| Pop-Location | |
| Get-ChildItem scintilla\bin | |
| Get-ChildItem lexilla\bin | |
| # Stage DLLs where the loader expects them | |
| New-Item -ItemType Directory -Force -Path ..\arm64 | Out-Null | |
| $sci = Get-ChildItem -Recurse -Path scintilla\bin -Include 'Scintilla.dll','SciLexer.dll' | Select-Object -First 1 | |
| $lex = Get-ChildItem -Recurse -Path lexilla\bin -Include 'Lexilla.dll','lexilla.dll' | Select-Object -First 1 | |
| Copy-Item $sci.FullName ..\arm64\Scintilla.dll | |
| Copy-Item $lex.FullName ..\arm64\Lexilla.dll | |
| Pop-Location | |
| - name: Build HbBuilder (ARM64) | |
| shell: cmd | |
| run: | | |
| set HBDIR=C:\harbour | |
| set HBBIN=%HBDIR%\bin\win\msvcarm64 | |
| if not exist "%HBBIN%\harbour.exe" set HBBIN=%HBDIR%\bin | |
| set HBLIB=%HBDIR%\lib\win\msvcarm64 | |
| set HBINC=%HBDIR%\include | |
| set SRCDIR=%CD%\source | |
| set CPPDIR=%CD%\source\cpp | |
| set INCDIR=%CD%\include | |
| set OUTDIR=%CD%\bin | |
| if not exist "%OUTDIR%" mkdir "%OUTDIR%" | |
| echo === Step 1: Harbour PRG -> C === | |
| cd /d "%SRCDIR%" | |
| "%HBBIN%\harbour.exe" hbbuilder_win.prg -n -w -es2 -q -I%HBINC% -I%INCDIR% | |
| if errorlevel 1 ( echo HARBOUR FAILED & exit /b 1 ) | |
| echo === Step 2: cl.exe (arm64 host already set up by msvc-dev-cmd) === | |
| set CL_BASE=/c /O2 /W0 /EHsc /I"%HBINC%" /I"%INCDIR%" | |
| cl.exe %CL_BASE% hbbuilder_win.c /Fohbbuilder_win.obj | |
| if not exist hbbuilder_win.obj ( echo CL FAILED hbbuilder_win.c & exit /b 1 ) | |
| for %%f in (tform hbbridge tcontrol tcontrols hb_db_real) do ( | |
| if exist "%CPPDIR%\%%f.cpp" ( | |
| cl.exe %CL_BASE% "%CPPDIR%\%%f.cpp" /Fo%%f.obj | |
| if not exist %%f.obj ( echo CL FAILED %%f.cpp & exit /b 1 ) | |
| ) | |
| ) | |
| echo === Step 2b: Resources === | |
| rc.exe /nologo /fohbbuilder_win.res hbbuilder_win.rc | |
| set RES_OBJ= | |
| if exist hbbuilder_win.res set RES_OBJ=hbbuilder_win.res | |
| echo === Step 3: Link (arm64) === | |
| set OBJS=hbbuilder_win.obj tform.obj hbbridge.obj tcontrol.obj tcontrols.obj hb_db_real.obj %RES_OBJ% | |
| link.exe /NOLOGO /SUBSYSTEM:WINDOWS /MACHINE:ARM64 /NODEFAULTLIB:LIBCMT ^ | |
| /OUT:"%OUTDIR%\hbbuilder_win_arm64.exe" ^ | |
| /LIBPATH:"%HBLIB%" ^ | |
| %OBJS% ^ | |
| hbrtl.lib hbvm.lib hbcpage.lib hblang.lib hbrdd.lib hbmacro.lib hbpp.lib ^ | |
| hbcommon.lib hbcplr.lib hbct.lib hbhsx.lib hbsix.lib hbusrrdd.lib ^ | |
| rddntx.lib rddnsx.lib rddcdx.lib rddfpt.lib hbdebug.lib hbpcre.lib ^ | |
| hbzlib.lib hbsqlit3.lib sqlite3.lib ^ | |
| gtwin.lib gtwvt.lib gtgui.lib ^ | |
| user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib ole32.lib ^ | |
| oleaut32.lib advapi32.lib ws2_32.lib winmm.lib msimg32.lib gdiplus.lib ^ | |
| winspool.lib ucrt.lib vcruntime.lib msvcrt.lib | |
| if errorlevel 1 ( echo LINK FAILED & exit /b 1 ) | |
| dir "%OUTDIR%\hbbuilder_win_arm64.exe" | |
| - name: Package | |
| shell: pwsh | |
| run: | | |
| $stage = "HbBuilder-1.0.0-windows-arm64" | |
| New-Item -ItemType Directory -Force -Path "$stage\bin","$stage\resources\arm64" | Out-Null | |
| Copy-Item "bin\hbbuilder_win_arm64.exe" "$stage\bin\" | |
| Copy-Item "resources\arm64\Scintilla.dll" "$stage\resources\arm64\" | |
| Copy-Item "resources\arm64\Lexilla.dll" "$stage\resources\arm64\" | |
| if (Test-Path "resources\icons") { Copy-Item -Recurse "resources\icons" "$stage\resources\" } | |
| if (Test-Path "resources\harbour_logo.png") { Copy-Item "resources\harbour_logo.png" "$stage\resources\" } | |
| @" | |
| HbBuilder v1.0.0 — Windows ARM64 (experimental) | |
| =============================================== | |
| Native Windows 11 ARM64 build. Requires an ARM64 PC | |
| (Surface Pro X / 9 / 11, Snapdragon X, etc). | |
| Run: bin\hbbuilder_win_arm64.exe | |
| DLLs in resources\arm64\ must remain alongside the exe. | |
| https://github.com/FiveTechSoft/HarbourBuilder | |
| "@ | Set-Content "$stage\README.txt" | |
| Compress-Archive -Path $stage -DestinationPath $env:ASSET -Force | |
| Get-Item $env:ASSET | Select-Object Name,Length | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.ASSET }} | |
| path: ${{ env.ASSET }} | |
| - name: Upload to release | |
| if: github.event_name == 'workflow_dispatch' && inputs.upload_to_release != '' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ inputs.upload_to_release }} | |
| files: ${{ env.ASSET }} |