Skip to content

Commit

Permalink
WIP: Build mozc_tip64.dll for ARM64
Browse files Browse the repository at this point in the history
  • Loading branch information
yukawa committed Nov 21, 2024
1 parent caf5d47 commit ce19f7a
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 35 deletions.
20 changes: 9 additions & 11 deletions src/base/system_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -376,24 +376,22 @@ class ProgramFilesX86Cache {
path->clear();

wchar_t program_files_path_buffer[MAX_PATH] = {};
#if defined(_M_X64)
#if defined(_M_IX86)
// In 32-bit processes (such as server, renderer, and other binaries),
// CSIDL_PROGRAM_FILES always points 32-bit Program Files directory
// even if they are running in 64-bit Windows.
const HRESULT result =
::SHGetFolderPathW(nullptr, CSIDL_PROGRAM_FILES, nullptr,
SHGFP_TYPE_CURRENT, program_files_path_buffer);
#else // !_M_IX86
// In 64-bit processes (such as Text Input Prosessor DLL for 64-bit apps),
// CSIDL_PROGRAM_FILES points 64-bit Program Files directory. In this case,
// we should use CSIDL_PROGRAM_FILESX86 to find server, renderer, and other
// binaries' path.
const HRESULT result =
::SHGetFolderPathW(nullptr, CSIDL_PROGRAM_FILESX86, nullptr,
SHGFP_TYPE_CURRENT, program_files_path_buffer);
#elif defined(_M_IX86)
// In 32-bit processes (such as server, renderer, and other binaries),
// CSIDL_PROGRAM_FILES always points 32-bit Program Files directory
// even if they are running in 64-bit Windows.
const HRESULT result =
::SHGetFolderPathW(nullptr, CSIDL_PROGRAM_FILES, nullptr,
SHGFP_TYPE_CURRENT, program_files_path_buffer);
#else // !_M_X64 && !_M_IX86
#error "Unsupported CPU architecture"
#endif // _M_X64, _M_IX86, and others
#endif // _M_IX86
if (FAILED(result)) {
return result;
}
Expand Down
68 changes: 52 additions & 16 deletions src/build_mozc.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import optparse
import os
import pathlib
import platform
import re
import subprocess
import sys
Expand Down Expand Up @@ -349,29 +350,64 @@ def ParseCleanOptions(args):
return parser.parse_args(args)


def UpdateEnvironmentFilesForWindows(out_dir):
def ReadEnvironmentFile(path):
nul = chr(0)
with open(path, 'rb') as f:
content = f.read()
entries = content.decode('utf-8').split(nul)
env = dict()
for e in entries:
if '=' in e:
key, value = e.split('=', 1)
env[key] = value
return env


def WriteEnvironmentFile(path, env):
nul = chr(0)
entries = [f'{key}={value}' for (key, value) in env.items()]
entries.extend(['', ''])
with open(path, 'wb') as f:
f.write(nul.join(entries).encode('utf-8'))


def UpdateEnvironmentFilesForWindows(out_dir, vcvarsall_path):
"""Add required environment variables for Ninja build."""
python_path_root = MOZC_ROOT
python_path = os.path.abspath(python_path_root)
original_python_paths = os.environ.get('PYTHONPATH', '')
if original_python_paths:
python_path = os.pathsep.join([original_python_paths, python_path])
nul = chr(0)
additional_content = nul.join([
'PYTHONPATH=' + python_path,
'VSLANG=1033', # 1033 == MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)
nul]).encode('utf-8')

for d in os.listdir(out_dir):
abs_dir = os.path.abspath(os.path.join(out_dir, d))
with open(os.path.join(abs_dir, 'environment.x86'), 'rb') as x86_file:
x86_content = x86_file.read()[:-1] + additional_content
with open(os.path.join(abs_dir, 'environment.x86'), 'wb') as x86_file:
x86_file.write(x86_content)
with open(os.path.join(abs_dir, 'environment.x64'), 'rb') as x64_file:
x64_content = x64_file.read()[:-1] + additional_content
with open(os.path.join(abs_dir, 'environment.x64'), 'wb') as x64_file:
x64_file.write(x64_content)

# Tweak generated build rules for ARM64
if d.endswith('arm64'):
build_ninja = os.path.join(abs_dir, 'build.ninja')
with open(build_ninja, 'r', encoding='utf-8') as f:
lines = f.readlines()
for i in range(0, 2):
lines[i] = lines[i].replace('x64\\cl.exe', 'arm64\\cl.exe')
lines[i] = lines[i].replace('x86\\cl.exe', 'arm64\\cl.exe')
with open(build_ninja, 'w', encoding='utf-8') as f:
f.writelines(lines)

for arch in ['x86', 'x64']:
env_file = os.path.join(abs_dir, f'environment.{arch}')
env = ReadEnvironmentFile(env_file)
# Tweak for ARM64
if d.endswith('arm64'):
vs_arch = platform.uname().machine
if vs_arch != 'arm64':
vs_arch = vs_arch + '_arm64'
vs_env = get_vs_env_vars(vs_arch)
env['INCLUDE'] = vs_env['INCLUDE']
env['LIB'] = vs_env['LIB']
env['LIBPATH'] = vs_env['LIBPATH']
env['PATH'] = vs_env['PATH']
env['PYTHONPATH'] = python_path
env['VSLANG'] = '1033' # == MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)
WriteEnvironmentFile(env_file, env)


def GypMain(options, unused_args):
Expand Down Expand Up @@ -548,7 +584,7 @@ def GypMain(options, unused_args):
# For internal Ninja build on Windows, set up environment files
if IsWindows():
out_dir = os.path.join(MOZC_ROOT, 'out_win')
UpdateEnvironmentFilesForWindows(out_dir)
UpdateEnvironmentFilesForWindows(out_dir, options.vcvarsall_path)

if IsWindows() and qt_dir and qt_ver:
# When Windows build is configured to use DLL version of Qt, copy Qt's DLLs
Expand Down
2 changes: 2 additions & 0 deletions src/build_tools/protoc_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ def main():
protoc_path = opts.protoc_command
if opts.protoc_dir:
protoc_path = os.path.join(os.path.abspath(opts.protoc_dir), protoc_path)
if os.name == 'nt' and protoc_path.endswith('_arm64\\protoc.exe'):
protoc_path = protoc_path.replace('_arm64\\protoc', '_x64\\protoc')

# The path of proto file should be transformed as a relative path from
# the project root so that correct relative paths should be embedded into
Expand Down
37 changes: 31 additions & 6 deletions src/gyp/common_win.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,7 @@
},
'VCLinkerTool': {
'TargetMachine': '<(win_target_machine_x86)',
'AdditionalOptions': [
'/SAFESEH',
],
'ImageHasSafeExceptionHandlers': 'true',
'EnableUAC': 'true',
'UACExecutionLevel': '0', # level="asInvoker"
'UACUIAccess': 'false', # uiAccess="false"
Expand Down Expand Up @@ -158,6 +156,30 @@
},
'VCLinkerTool': {
'TargetMachine': '<(win_target_machine_x64)',
'AdditionalOptions': [
'/CETCOMPAT',
],
},
},
},
'arm64_Base': {
'abstract': 1,
'msvs_configuration_attributes': {
'OutputDirectory': '<(build_base)/$(ConfigurationName)_arm64',
'IntermediateDirectory': '<(build_base)/$(ConfigurationName)_arm64/obj/$(ProjectName)',
},
'msvs_target_platform': 'arm64',
'msvs_settings': {
'VCCLCompilerTool': {
'AdditionalOptions': [
'/bigobj',
],
},
'VCLinkerTool': {
'ImageHasSafeExceptionHandlers': 'false',
'AdditionalOptions': [
'/MACHINE:ARM64',
],
},
},
},
Expand Down Expand Up @@ -270,6 +292,12 @@
'Release_x64': {
'inherit_from': ['x64_Base', 'Release_Base', 'Win_Static_Release_CRT_Base'],
},
'Debug_arm64': {
'inherit_from': ['arm64_Base', 'Debug_Base', 'Win_Static_Debug_CRT_Base'],
},
'Release_arm64': {
'inherit_from': ['arm64_Base', 'Release_Base', 'Win_Static_Release_CRT_Base'],
},
},
'default_configuration': 'Debug',
'defines': [
Expand Down Expand Up @@ -338,9 +366,6 @@
'user32.lib',
'uuid.lib',
],
'AdditionalOptions': [
'/CETCOMPAT',
],
'DataExecutionPrevention': '2', # /NXCOMPAT
'EnableCOMDATFolding': '2', # /OPT:ICF
'GenerateDebugInformation': 'true', # /DEBUG
Expand Down
4 changes: 2 additions & 2 deletions src/win32/tip/tip_text_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,9 @@ struct ComPtrHash {
size_t operator()(const wil::com_ptr_nothrow<T> &value) const {
// Caveats: On x86 environment, both _M_X64 and _M_IX86 are defined. So we
// need to check _M_X64 first.
#if defined(_M_X64)
#if defined(_M_X64) || defined(_M_ARM64)
constexpr size_t kUnusedBits = 3; // assuming 8-byte aligned
#elif defined(_M_IX86) // defined(_M_X64)
#elif defined(_M_IX86) // defined(_M_X64) or defined(_M_ARM64)
constexpr size_t kUnusedBits = 2; // assuming 4-byte aligned
#else // defined(_M_IX86)
#error "unsupported platform"
Expand Down

0 comments on commit ce19f7a

Please sign in to comment.