Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows ARM64 support #836

Merged
merged 9 commits into from
Feb 24, 2024
Merged

Windows ARM64 support #836

merged 9 commits into from
Feb 24, 2024

Conversation

driver1998
Copy link
Contributor

@driver1998 driver1998 commented Feb 25, 2023

Summary

  • Only TSF and IME clients are ported to ARM, WeaselServer and other components are kept as x86.
  • Supports x86/x64/ARM32/ARM64 apps.

Notes

Pass arm64 to build.bat to build ARM support, you'll need the following Visual Studio Components:

  • C++ ARM build tools & MFC
  • C++ ARM64 build tools & MFC
  • C++ ARM64EC build tools (This is now merged into ARM64 build tools in latest VS 2022)

ARM64X redirecton DLLs are used for ARM64 to support x64 and ARM64 apps. weasel.dll and weasel.ime are wrappers that redirects to weaselARM64 or weaselx64 depending on the app calling them. And that's also why three files are needed in system32 now.

This is required since there is no WOW redirection in the case of x64 on ARM64 and they have to somehow share the same system32 directory.

Screenshots

Windows Search (ARM64)
屏幕截图 2023-02-26 040003

Mail app (ARM32)
Note: ARM32 version will not be installed on systems without ARM32 app support (Windows 11 24H2 and higher).
屏幕截图 2023-02-26 040040

QQ (x86)
屏幕截图 2023-02-26 040227

mintty (x64)
屏幕截图 2023-02-26 040103

@david50407
Copy link

Works on Windows 11 (build 22621.1265) on ARM64 (Dev Kit 2023)

@driver1998
Copy link
Contributor Author

driver1998 commented Jun 5, 2023

@fxliang 的分支合并之后变了很多东西,有空我再rebase一下,最好是等 #886 合并之后。

另外 STL 那边的问题似乎是解决了,可以研究一下怎么将TSF Client编译成一个ARM64X DLL了,这样部署可以简化很多(能删掉WeaselSetup的一坨hacky代码)

if (is_arm64_machine())
{
// On ARM64 weasel.dll(ime) is an ARM64X redirection DLL (weaselARM64X).
// When loaded, it will be redirected to weaselARM64.dll(ime) on ARM64 processes,
// and weaselx64.dll(ime) on x64 processes.
// So we need a total of three files.
std::wstring srcPathX64 = srcPath;
std::wstring destPathX64 = destPath;
ireplace_last(srcPathX64, ext, L"x64" + ext);
ireplace_last(destPathX64, ext, L"x64" + ext);
if (!copy_file(srcPathX64, destPathX64))
{
if (!silent) MessageBoxW(NULL, destPathX64.c_str(), L"安裝失敗", MB_ICONERROR | MB_OK);
return 1;
}
std::wstring srcPathARM64 = srcPath;
std::wstring destPathARM64 = destPath;
ireplace_last(srcPathARM64, ext, L"ARM64" + ext);
ireplace_last(destPathARM64, ext, L"ARM64" + ext);
if (!copy_file(srcPathARM64, destPathARM64))
{
if (!silent) MessageBoxW(NULL, destPathARM64.c_str(), L"安裝失敗", MB_ICONERROR | MB_OK);
return 1;
}
// Since weaselARM64X is just a redirector we don't have separate
// HANS and HANT variants.
srcPath = std::wstring(drive) + dir + L"weaselARM64X" + ext;
}
else
{
ireplace_last(srcPath, ext, L"x64" + ext);
}

#ifdef _M_ARM64
{
// On ARM64 we use ARM64X redirection DLL.
// When loaded, weasel.dll will be redirected to weaselARM64.dll on ARM64 processes,
// and weaselx64.dll on x64 processes.
//
// But GetModuleFileNameA will return the actual loaded DLL name aka weaselARM64.dll
// Rewrite the path to point to the redirector.
char wrapperPath[MAX_PATH];
StringCbCatA(achFileName, MAX_PATH, "\\..\\weasel.dll");
GetFullPathNameA(achFileName, MAX_PATH, wrapperPath, NULL);
memcpy(achFileName, wrapperPath, MAX_PATH);
}
#endif

@fxliang
Copy link
Contributor

fxliang commented Jun 5, 2023

@fxliang 的分支合并之后变了很多东西,有空我再rebase一下,最好是等 #886 合并之后。

另外 STL 那边的问题似乎是解决了,可以研究一下怎么将TSF Client编译成一个ARM64X DLL了,这样部署可以简化很多(能删掉WeaselSetup的一坨hacky代码)

if (is_arm64_machine())
{
// On ARM64 weasel.dll(ime) is an ARM64X redirection DLL (weaselARM64X).
// When loaded, it will be redirected to weaselARM64.dll(ime) on ARM64 processes,
// and weaselx64.dll(ime) on x64 processes.
// So we need a total of three files.
std::wstring srcPathX64 = srcPath;
std::wstring destPathX64 = destPath;
ireplace_last(srcPathX64, ext, L"x64" + ext);
ireplace_last(destPathX64, ext, L"x64" + ext);
if (!copy_file(srcPathX64, destPathX64))
{
if (!silent) MessageBoxW(NULL, destPathX64.c_str(), L"安裝失敗", MB_ICONERROR | MB_OK);
return 1;
}
std::wstring srcPathARM64 = srcPath;
std::wstring destPathARM64 = destPath;
ireplace_last(srcPathARM64, ext, L"ARM64" + ext);
ireplace_last(destPathARM64, ext, L"ARM64" + ext);
if (!copy_file(srcPathARM64, destPathARM64))
{
if (!silent) MessageBoxW(NULL, destPathARM64.c_str(), L"安裝失敗", MB_ICONERROR | MB_OK);
return 1;
}
// Since weaselARM64X is just a redirector we don't have separate
// HANS and HANT variants.
srcPath = std::wstring(drive) + dir + L"weaselARM64X" + ext;
}
else
{
ireplace_last(srcPath, ext, L"x64" + ext);
}

#ifdef _M_ARM64
{
// On ARM64 we use ARM64X redirection DLL.
// When loaded, weasel.dll will be redirected to weaselARM64.dll on ARM64 processes,
// and weaselx64.dll on x64 processes.
//
// But GetModuleFileNameA will return the actual loaded DLL name aka weaselARM64.dll
// Rewrite the path to point to the redirector.
char wrapperPath[MAX_PATH];
StringCbCatA(achFileName, MAX_PATH, "\\..\\weasel.dll");
GetFullPathNameA(achFileName, MAX_PATH, wrapperPath, NULL);
memcpy(achFileName, wrapperPath, MAX_PATH);
}
#endif

我是没有测试条件,没有办法测试确认的,之前有看了下,修改也不算多,新增参数建议改成默认参数放到最后,这样非ARM的调用可以不用改,其余暂时未看细

@driver1998
Copy link
Contributor Author

新增参数建议改成默认参数放到最后,这样非ARM的调用可以不用改

noarm64 现在就是放最后的
不过跟x64一样现在也是默认开了编译,因为NSIS脚本写了ARM64的文件,不编译出来我怕打不了安装包

@driver1998
Copy link
Contributor Author

Rebase 到最新 master,变化如下:

  • boost 1.83 在 MSVC ARM64 下编译不过:Fix use of intrinsics on windows ARM platforms boostorg/json#928 ,1.84 没有问题。看到 librime 已经在用 1.84 了,这里顺带更新。
  • STL 的问题解决之后单个 ARM64X DLL 确实能链接成功,但加载输入法时会崩(然后崩完之后能正常工作,狗头),先继续用重定向
  • ARM64 支持改为默认不编译,build.bat arm64 开启

@lotem lotem merged commit e040ab4 into rime:master Feb 24, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants