Support for ARM64 (#257)

* Support for ARM64

* Rename environment variable

* Switch to MinGW toolchain

* Fix invalid path

* Fix error handling

* Fix error level

* Delete installer/actions/actions.def
This commit is contained in:
Gerhard Tan
2025-07-12 22:08:03 +08:00
committed by GitHub
parent 89bc3bd5ef
commit 3730c0660b
10 changed files with 97 additions and 51 deletions

View File

@ -10,7 +10,7 @@ jobs:
runs-on: windows-latest
strategy:
matrix:
architecture: [x64, x86]
architecture: [x64, x86, arm64]
steps:
- name: Checkout
uses: actions/checkout@v4
@ -49,6 +49,14 @@ jobs:
goto :eof
"@ | Out-File -Encoding ascii -FilePath safe_copy.bat
- name: Setup toolchain
shell: cmd
run: |
curl "https://github.com/mstorsjo/llvm-mingw/releases/download/20250709/llvm-mingw-20250709-msvcrt-x86_64.zip" -o llvm-mingw-20250709-msvcrt-x86_64.zip -L
tar -xf llvm-mingw-20250709-msvcrt-x86_64.zip
echo %CD%\llvm-mingw-20250709-msvcrt-x86_64\bin>>%GITHUB_PATH%
vcvarsall x64 && set WindowsSdkVerBinPath >> %GITHUB_ENV%
- name: Build main application
shell: cmd
run: build.bat -p ${{ matrix.architecture }}

View File

@ -13,7 +13,7 @@ jobs:
runs-on: windows-latest
strategy:
matrix:
architecture: [x64, x86]
architecture: [x64, x86, arm64]
steps:
- name: Checkout
uses: actions/checkout@v4
@ -27,6 +27,14 @@ jobs:
shell: powershell
run: echo "$(vswhere.exe -latest -property installationPath)\VC\Auxiliary\Build" >> $env:GITHUB_PATH
- name: Setup toolchain
shell: cmd
run: |
curl "https://github.com/mstorsjo/llvm-mingw/releases/download/20250709/llvm-mingw-20250709-msvcrt-x86_64.zip" -o llvm-mingw-20250709-msvcrt-x86_64.zip -L
tar -xf llvm-mingw-20250709-msvcrt-x86_64.zip
echo %CD%\llvm-mingw-20250709-msvcrt-x86_64\bin>>%GITHUB_PATH%
vcvarsall x64 && set WindowsSdkVerBinPath >> %GITHUB_ENV%
- name: Add commit hash to version number
shell: powershell
if: github.event_name == 'pull_request'

View File

@ -36,11 +36,11 @@ Visit the **[Wiki](https://github.com/koho/frpmgr/wiki)** for comprehensive guid
To build FRP Manager from source, you need to install the following dependencies:
- Go
- Visual Studio
- [MinGW](https://www.mingw-w64.org/)
- [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/)
- [MinGW](https://github.com/mstorsjo/llvm-mingw)
- [WiX Toolset](https://wixtoolset.org/) v3.14
Once Visual Studio is installed, add the [developer command file directory](https://learn.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-170#developer_command_file_locations) (e.g., `C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build`) to the `PATH` environment variable. Likewise, do the same for the `bin` directory of MinGW.
Once installed, the `WindowsSdkVerBinPath` environment variable should be set to tell build script where to find the specific version of Windows SDK, e.g., `set WindowsSdkVerBinPath=C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\`. You should also add the `bin` directory of MinGW to the `PATH` environment variable.
You can compile the project by opening the terminal:

View File

@ -36,11 +36,11 @@ FRP 管理器是一个多节点、图形化反向代理工具,专为 Windows
要从源代码构建 FRP 管理器,您需要安装以下依赖项:
- Go
- Visual Studio
- [MinGW](https://www.mingw-w64.org/)
- [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/)
- [MinGW](https://github.com/mstorsjo/llvm-mingw)
- [WiX Toolset](https://wixtoolset.org/) v3.14
安装 Visual Studio 后,将 [开发者命令文件目录](https://learn.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-170#developer_command_file_locations)(例如 `C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build`)添加到 `PATH` 环境变量中。同样,将 MinGW 的 `bin` 目录添加到中。
安装完成后,您需要设置 `WindowsSdkVerBinPath` 环境变量,以指示构建脚本在哪里找到特定版本的 Windows SDK例如 `set WindowsSdkVerBinPath=C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\`。您还需要将 MinGW 的 `bin` 目录添加到 `PATH` 环境变量中。
您可以通过打开终端来编译项目:

View File

@ -6,12 +6,12 @@ set BUILDDIR=%~dp0
cd /d %BUILDDIR% || exit /b 1
if "%~1" == "-p" (
set TARGET=%~2
set FRPMGR_TARGET=%~2
) else (
set TARGET=%~1
set FRPMGR_TARGET=%~1
)
if "%TARGET%" == "" set TARGET=x64 x86
if "%FRPMGR_TARGET%" == "" set FRPMGR_TARGET=x64 x86
:packages
echo [+] Downloading packages
@ -27,8 +27,12 @@ if "%TARGET%" == "" set TARGET=x64 x86
set MOD=github.com/koho/frpmgr
set GO111MODULE=on
set CGO_ENABLED=0
for %%a in (%TARGET%) do (
set GOARCH=!GOARCH_%%a!
for %%a in (%FRPMGR_TARGET%) do (
if defined GOARCH_%%a (
set GOARCH=!GOARCH_%%a!
) else (
set GOARCH=%%a
)
go build -trimpath -ldflags="-H windowsgui -s -w -X %MOD%/pkg/version.BuildDate=%BUILD_DATE%" -o bin\%%a\frpmgr.exe .\cmd\frpmgr || goto :error
)
@ -36,7 +40,7 @@ if "%~1" == "-p" goto :success
:installer
echo [+] Building installer
for %%a in (%TARGET%) do (
for %%a in (%FRPMGR_TARGET%) do (
call installer\build.bat %VERSION% %%a || goto :error
)

View File

@ -1,8 +0,0 @@
LIBRARY actions
EXPORTS
EvaluateFrpServices
KillFrpGUIProcesses
KillFrpProcesses
MoveFrpProfiles
RemoveFrpFiles
SetLangConfig

View File

@ -5,6 +5,9 @@ set ARCH=%~2
set STEP="%~3"
set BUILDDIR=%~dp0
cd /d %BUILDDIR% || exit /b 1
set TARGET_x64=x86_64
set TARGET_x86=i686
set TARGET_arm64=aarch64
if "%VERSION%" == "" (
echo ERROR: no version provided.
@ -16,25 +19,34 @@ if "%ARCH%" == "" (
exit /b 1
)
if not defined TARGET_%ARCH% (
echo ERROR: unsupported architecture.
exit /b 1
)
:build
if not exist build md build
set PLAT_DIR=build\%ARCH%
set SETUP_FILENAME=frpmgr-%VERSION%-setup-%ARCH%.exe
if %STEP% == "dist" goto :dist
call vcvarsall.bat %ARCH%
set CC=!TARGET_%ARCH%!-w64-mingw32-gcc
set WINDRES=!TARGET_%ARCH%!-w64-mingw32-windres
if not exist %PLAT_DIR% md %PLAT_DIR%
set MSI_FILE=%PLAT_DIR%\frpmgr.msi
if %STEP:"actions"=""% == "" call :build_actions
if %STEP:"msi"=""% == "" call :build_msi
if %STEP:"setup"=""% == "" call :build_setup
if %STEP:"actions"=""% == "" call :build_actions || goto :error
if %STEP:"msi"=""% == "" call :build_msi || goto :error
if %STEP:"setup"=""% == "" call :build_setup || goto :error
if %STEP% == "" goto :dist
:success
exit /b 0
:build_actions
rc /DVERSION_ARRAY=%VERSION:.=,% /DVERSION_STR=%VERSION% /Fo %PLAT_DIR%\actions.res actions\version.rc || goto :error
cl /O2 /LD /MD /DNDEBUG /Fe%PLAT_DIR%\actions.dll /Fo%PLAT_DIR%\actions.obj actions\actions.c /link /DEF:actions\actions.def %PLAT_DIR%\actions.res msi.lib shell32.lib advapi32.lib shlwapi.lib ole32.lib || goto :error
%WINDRES% -DVERSION_ARRAY=%VERSION:.=,% -DVERSION_STR=%VERSION% -o %PLAT_DIR%\actions.res.obj -i actions\version.rc -O coff -c 65001 || exit /b 1
set CFLAGS=-O3 -Wall -std=gnu11 -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -municode -DUNICODE -D_UNICODE -DNDEBUG
set LDFLAGS=-shared -s -Wl,--kill-at -Wl,--major-os-version=6 -Wl,--minor-os-version=1 -Wl,--major-subsystem-version=6 -Wl,--minor-subsystem-version=1 -Wl,--tsaware -Wl,--dynamicbase -Wl,--nxcompat -Wl,--export-all-symbols
set LDLIBS=-lmsi -lole32 -lshlwapi -lshell32 -ladvapi32
%CC% %CFLAGS% %LDFLAGS% -o %PLAT_DIR%\actions.dll actions\actions.c %PLAT_DIR%\actions.res.obj %LDLIBS% || exit /b 1
goto :eof
:build_msi
@ -45,19 +57,19 @@ if "%ARCH%" == "" (
set WIX_CANDLE_FLAGS=-dVERSION=%VERSION%
set WIX_LIGHT_FLAGS=-ext "%WIX%bin\WixUtilExtension.dll" -ext "%WIX%bin\WixUIExtension.dll" -sval
set WIX_OBJ=%PLAT_DIR%\frpmgr.wixobj
"%WIX%bin\candle" %WIX_CANDLE_FLAGS% -out %WIX_OBJ% -arch %ARCH% msi\frpmgr.wxs || goto :error
"%WIX%bin\light" %WIX_LIGHT_FLAGS% -cultures:en-US -loc msi\en-US.wxl -out %MSI_FILE% %WIX_OBJ% || goto :error
"%WIX%bin\candle" %WIX_CANDLE_FLAGS% -out %WIX_OBJ% -arch %ARCH% msi\frpmgr.wxs || exit /b 1
"%WIX%bin\light" %WIX_LIGHT_FLAGS% -cultures:en-US -loc msi\en-US.wxl -out %MSI_FILE% %WIX_OBJ% || exit /b 1
for %%l in (zh-CN zh-TW ja-JP ko-KR es-ES) do (
set WIX_LANG_MSI=%MSI_FILE:~0,-4%_%%l.msi
"%WIX%bin\light" %WIX_LIGHT_FLAGS% -cultures:%%l -loc msi\%%l.wxl -out !WIX_LANG_MSI! %WIX_OBJ% || goto :error
"%WIX%bin\light" %WIX_LIGHT_FLAGS% -cultures:%%l -loc msi\%%l.wxl -out !WIX_LANG_MSI! %WIX_OBJ% || exit /b 1
for /f "tokens=3 delims=><" %%a in ('findstr /r "Id.*=.*Language" msi\%%l.wxl') do set LANG_CODE=%%a
"%WindowsSdkVerBinPath%x86\MsiTran" -g %MSI_FILE% !WIX_LANG_MSI! %PLAT_DIR%\!LANG_CODE! || goto :error
"%WindowsSdkVerBinPath%x86\MsiDb" -d %MSI_FILE% -r %PLAT_DIR%\!LANG_CODE! || goto :error
"%WindowsSdkVerBinPath%x86\MsiTran" -g %MSI_FILE% !WIX_LANG_MSI! %PLAT_DIR%\!LANG_CODE! || exit /b 1
"%WindowsSdkVerBinPath%x86\MsiDb" -d %MSI_FILE% -r %PLAT_DIR%\!LANG_CODE! || exit /b 1
)
goto :eof
:build_setup
rc /DFILENAME=%SETUP_FILENAME% /DVERSION_ARRAY=%VERSION:.=,% /DVERSION_STR=%VERSION% /DMSI_FILE=%MSI_FILE:\=\\% /Fo %PLAT_DIR%\setup.res setup\resource.rc || goto :error
%WINDRES% -DFILENAME=%SETUP_FILENAME% -DVERSION_ARRAY=%VERSION:.=,% -DVERSION_STR=%VERSION% -DMSI_FILE=%MSI_FILE:\=\\% -o %PLAT_DIR%\setup.res.obj -i setup\resource.rc -O coff -c 65001 || exit /b 1
set ARCH_LINE=-1
for /f "tokens=1 delims=:" %%a in ('findstr /n /r ".*=.*\"%ARCH%\"" msi\frpmgr.wxs') do set ARCH_LINE=%%a
if %ARCH_LINE% lss 0 (
@ -71,7 +83,10 @@ if "%ARCH%" == "" (
echo ERROR: UpgradeCode was not found.
exit /b 1
)
cl /O2 /MD /DUPGRADE_CODE=L\"{%UPGRADE_CODE%}\" /DVERSION=L\"%VERSION%\" /DNDEBUG /Fe%PLAT_DIR%\setup.exe /Fo%PLAT_DIR%\setup.obj setup\setup.c /link /subsystem:windows %PLAT_DIR%\setup.res shlwapi.lib msi.lib user32.lib advapi32.lib ole32.lib || goto :error
set CFLAGS=-O3 -Wall -std=gnu11 -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -municode -DUNICODE -D_UNICODE -DNDEBUG -DUPGRADE_CODE=L\"{%UPGRADE_CODE%}\" -DVERSION=L\"%VERSION%\"
set LDFLAGS=-s -Wl,--major-os-version=6 -Wl,--minor-os-version=1 -Wl,--major-subsystem-version=6 -Wl,--minor-subsystem-version=1 -Wl,--tsaware -Wl,--dynamicbase -Wl,--nxcompat -mwindows
set LDLIBS=-lmsi -lole32 -lshlwapi -ladvapi32 -luser32
%CC% %CFLAGS% %LDFLAGS% -o %PLAT_DIR%\setup.exe setup\setup.c %PLAT_DIR%\setup.res.obj %LDLIBS% || exit /b 1
goto :eof
:dist

View File

@ -6,6 +6,9 @@
<?elseif $(sys.BUILDARCH) = "x86" ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?define UpgradeCode = "46E3AA36-10BB-4CD9-92E3-5F990AB5FC88" ?>
<?elseif $(sys.BUILDARCH) = "arm64" ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?define UpgradeCode = "3C3590A6-8139-482D-81F5-2FE6D21687A6" ?>
<?else?>
<?error Unknown platform ?>
<?endif?>
@ -13,7 +16,7 @@
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="!(loc.ApplicationName)" Language="!(loc.Language)" Version="$(var.VERSION)" Manufacturer="FRP Manager Project" UpgradeCode="$(var.UpgradeCode)">
<Package InstallerVersion="400" Compressed="yes" InstallScope="perMachine" Languages="1033,1041,1042,2052,1028,3082" Description="!(loc.ApplicationName)" ReadOnly="yes" />
<Package InstallerVersion="500" Compressed="yes" InstallScope="perMachine" Languages="1033,1041,1042,2052,1028,3082" Description="!(loc.ApplicationName)" ReadOnly="yes" />
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />

View File

@ -1,7 +1,4 @@
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <windows.h>
#include <msi.h>
#include <shlwapi.h>
#include <sddl.h>
@ -120,6 +117,7 @@ out:
INT_PTR CALLBACK LanguageDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
INT_PTR nResult;
switch (message) {
case WM_INITDIALOG:
for (size_t i = 0; i < _countof(languages); i++)
@ -128,7 +126,7 @@ INT_PTR CALLBACK LanguageDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM l
return (INT_PTR)TRUE;
case WM_COMMAND:
INT_PTR nResult = LOWORD(wParam);
nResult = LOWORD(wParam);
if (nResult == IDOK || nResult == IDCANCEL)
{
if (nResult == IDOK)
@ -158,7 +156,7 @@ static int cleanup(void)
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
INT langIndex = -1;
BOOL installed = FALSE, showDlg = TRUE;
@ -178,7 +176,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
MsiGetProductInfo(productCode, INSTALLPROPERTY_VERSIONSTRING, product.version, &product.versionLen);
if (MsiGetProductInfo(productCode, INSTALLPROPERTY_INSTALLLOCATION, product.path, &product.pathLen) == ERROR_SUCCESS && product.path[0])
langIndex = GetApplicationLanguage(product.path, product.pathLen);
if (MsiGetProductInfo(productCode, INSTALLPROPERTY_INSTALLEDLANGUAGE, product.lang, &product.langLen) == ERROR_SUCCESS && langIndex < 0)
if (MsiGetProductInfo(productCode, L"InstalledLanguage", product.lang, &product.langLen) == ERROR_SUCCESS && langIndex < 0)
{
for (size_t i = 0; i < _countof(languages); i++)
{

View File

@ -15,10 +15,7 @@ import (
"github.com/koho/frpmgr/pkg/version"
)
var (
versionArray = strings.ReplaceAll(version.Number, ".", ",")
archMap = map[string]string{"amd64": "pe-x86-64", "386": "pe-i386"}
)
var versionArray = strings.ReplaceAll(version.Number, ".", ",")
func main() {
rcFiles, err := filepath.Glob("cmd/*/*.rc")
@ -26,11 +23,32 @@ func main() {
println(err.Error())
os.Exit(1)
}
for _, rc := range rcFiles {
for goArch, resArch := range archMap {
arch := os.Getenv("FRPMGR_TARGET")
if arch == "" {
arch = os.Getenv("GOARCH")
}
for _, arch := range strings.Split(arch, " ") {
var args []string
var goArch string
switch strings.TrimSpace(arch) {
case "x64", "amd64":
goArch = "amd64"
args = append(args, "windres", "-F", "pe-x86-64")
case "x86", "386":
goArch = "386"
args = append(args, "windres", "-F", "pe-i386")
case "arm64":
goArch = "arm64"
args = append(args, "aarch64-w64-mingw32-windres")
default:
continue
}
for _, rc := range rcFiles {
output := strings.TrimSuffix(rc, filepath.Ext(rc)) + fmt.Sprintf("_windows_%s.syso", goArch)
res, err := exec.Command("windres", "-DVERSION_ARRAY="+versionArray, "-DVERSION_STR="+version.Number,
"-i", rc, "-o", output, "-O", "coff", "-c", "65001", "-F", resArch).CombinedOutput()
res, err := exec.Command(args[0], append([]string{
"-DVERSION_ARRAY=" + versionArray, "-DVERSION_STR=" + version.Number,
"-i", rc, "-o", output, "-O", "coff", "-c", "65001",
}, args[1:]...)...).CombinedOutput()
if err != nil {
println(err.Error(), string(res))
os.Exit(1)