Skip to content

Commit

Permalink
Fix #894: Upgrade WiX from v3.14 to v4.0.5
Browse files Browse the repository at this point in the history
This commit upgrades WiX, which we rely on to build Mozc's installer
from WiX v3.14 to WiX v4.0.5 [1].

Unlike WiX v3.14, which we checked out as an xcopy deployment under

  src/third_party/wix

with our in-house script update_deps.py, WiX v4 and later will be
installed from NuGet repository with 'dotnet' command [2]. On top of
that we use local installation mode so that a specified version of WiX
can be used in our repository in a side-by-side manner rather than
asking developers to install WiX globally. The WiX version is pined in

 dotnet-tools.json

in the repository root [3]. You can run the following command

 dotnet tool restore

from any directory in the repository so that the specified version of
WiX can become available, no matter what version of WiX is globally
installed in the system.

To actually run locally installed version of WiX, you can run

 dotnet tool run wix

from any directory in the repository.

.wxs file were also converted as follows [4]

 dotnet tool run wix convert

then manually cleaned up a bit.

There must be no user observable behavior change in Mozc64.msi.
I have actually confirmed it by manually checking InstallExecuteSequence
table in Mozc64.msi by using Orca [5].

#codehealth

 [1]: https://github.com/wixtoolset/wix/releases/tag/v4.0.5
 [2]: https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet
 [3]: https://learn.microsoft.com/en-us/dotnet/core/tools/local-tools-how-to-use
 [4]: https://wixtoolset.org/docs/fourthree/
 [5]: https://learn.microsoft.com/en-us/windows/win32/msi/orca-exe

PiperOrigin-RevId: 624751431
  • Loading branch information
yukawa authored and hiroyuki-komatsu committed Apr 14, 2024
1 parent 2bc8d81 commit cbd5556
Show file tree
Hide file tree
Showing 7 changed files with 408 additions and 475 deletions.
3 changes: 2 additions & 1 deletion docs/build_mozc_in_windows.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Building Mozc on Windows requires the following software.
* Python 3.9 or later with the following pip modules.
* `six`
* `requests`
* `.NET 6` or later (for `dotnet` command).

### Install pip modules

Expand All @@ -68,7 +69,7 @@ In this step, additional build dependencies will be downloaded.

* [Ninja 1.11.0](https://github.com/ninja-build/ninja/releases/download/v1.11.0/ninja-win.zip)
* [Qt 6.7.0](https://download.qt.io/archive/qt/6.7/6.7.0/submodules/qtbase-everywhere-src-6.7.0.tar.xz)
* [WiX 3.14](https://github.com/wixtoolset/wix3/releases/download/wix314rtm/wix314-binaries.zip)
* [.NET tools](../dotnet-tools.json)
* [git submodules](../.gitmodules)

You can skip this step if you would like to manually download these libraries.
Expand Down
12 changes: 12 additions & 0 deletions dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"wix": {
"version": "4.0.5",
"commands": [
"wix"
]
}
}
}
15 changes: 1 addition & 14 deletions src/build_mozc.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,6 @@ def AddTargetPlatformOption(parser):
'should be done.'))


def GetDefaultWixPath():
"""Returns the default Wix directory.."""
possible_wix_path = pathlib.Path(ABS_SCRIPT_DIR).joinpath(
'third_party', 'wix')
if possible_wix_path.exists():
return possible_wix_path
return ''


def GetDefaultQtPath():
"""Returns the default Qt directory.."""
qtdir_env = os.getenv('QTDIR', None)
Expand Down Expand Up @@ -261,9 +252,6 @@ def ParseGypOptions(args):
parser.add_option('--msvs_version', dest='msvs_version',
default='2022',
help='Version of the Visual Studio.')
parser.add_option('--wix_dir', dest='wix_dir',
default=GetDefaultWixPath(),
help='A path to the binary directory of wix.')

if IsWindows() or IsMac():
parser.add_option('--qtdir', dest='qtdir',
Expand Down Expand Up @@ -497,9 +485,8 @@ def GypMain(options, unused_args):
gyp_options.extend(['-D', 'qt_dir=' + (qt_dir or '')])
gyp_options.extend(['-D', 'qt_ver=' + str(qt_ver or '')])

if target_platform == 'Windows' and options.wix_dir:
if target_platform == 'Windows':
gyp_options.extend(['-D', 'use_wix=YES'])
gyp_options.extend(['-D', 'wix_dir="%s"' % options.wix_dir])
else:
gyp_options.extend(['-D', 'use_wix=NO'])

Expand Down
94 changes: 31 additions & 63 deletions src/build_tools/update_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,6 @@ def __hash__(self):
sha256='11b2e29e2e52fb0e3b453ea13bbe51a10fdff36e1c192d8868c5a40233b8b254',
)

WIX = ArchiveInfo(
url='https://github.com/wixtoolset/wix3/releases/download/wix314rtm/wix314-binaries.zip',
size=41282726,
sha256='13f067f38969faf163d93a804b48ea0576790a202c8f10291f2000f0e356e934',
)

NINJA_MAC = ArchiveInfo(
url='https://github.com/ninja-build/ninja/releases/download/v1.11.0/ninja-mac.zip',
size=277298,
Expand Down Expand Up @@ -232,59 +226,6 @@ def __exit__(self, *exc):
self.cleaner.cleanup()


def wix_extract_filter(
members: Iterator[zipfile.ZipInfo],
) -> Iterator[zipfile.ZipInfo]:
"""Custom extract filter for the WiX Zip archive.
This custom filter can be used to adjust directory structure and drop
unnecessary files/directories to save disk space.
Args:
members: an iterator of ZipInfo from the Zip archive.
Yields:
an iterator of ZipInfo to be extracted.
"""
with ProgressPrinter() as printer:
for info in members:
paths = info.filename.split('/')
if '..' in paths:
continue
if len(paths) >= 2:
printer.print_line('skipping ' + info.filename)
continue
else:
printer.print_line('extracting ' + info.filename)
yield info


def extract_wix(dryrun: bool = False) -> None:
"""Extract WiX archive.
Args:
dryrun: True if this is a dry-run.
"""
dest = ABS_THIRD_PARTY_DIR.joinpath('wix').absolute()
src = CACHE_DIR.joinpath(WIX.filename)

if dryrun:
if dest.exists():
print(f"dryrun: shutil.rmtree(r'{dest}')")
print(f'dryrun: Extracting {src}')
return

def filename(members: Iterator[zipfile.ZipInfo]):
if dest.exists():
shutil.rmtree(dest)
for info in members:
yield info.filename
with zipfile.ZipFile(src) as z:
z.extractall(
path=dest, members=filename(wix_extract_filter(z.infolist()))
)


def extract_ninja(dryrun: bool = False) -> None:
"""Extract ninja-win archive.
Expand Down Expand Up @@ -339,6 +280,35 @@ def update_submodules(dryrun: bool = False) -> None:
subprocess.run(command, shell=True, check=True)


def exec_command(args: list[str], cwd: os.PathLike) -> None:
"""Runs the given command then returns the output.
Args:
args: The command to be executed.
Raises:
ChildProcessError: When the given command cannot be executed.
"""
process = subprocess.Popen(args, stdout=subprocess.PIPE, shell=False, cwd=cwd)
_, _ = process.communicate()
exitcode = process.wait()
if exitcode != 0:
raise ChildProcessError(f'Failed to execute {args}')


def restore_dotnet_tools(dryrun: bool = False) -> None:
"""Run 'dotnet tool restore'.
Args:
dryrun: true to perform dryrun.
"""
args = ['dotnet', 'tool', 'restore']
if dryrun:
print(f'dryrun: exec_command({args}, cwd={ABS_MOZC_SRC_DIR})')
else:
exec_command(args, cwd=ABS_MOZC_SRC_DIR)


def main():
parser = argparse.ArgumentParser()
parser.add_argument('--dryrun', action='store_true', default=False)
Expand All @@ -358,17 +328,15 @@ def main():
archives.append(NINJA_MAC)
elif is_windows():
archives.append(NINJA_WIN)
if (not args.nowix) and is_windows():
archives.append(WIX)

for archive in archives:
download(archive, args.dryrun)

if args.cache_only:
return

if WIX in archives:
extract_wix(args.dryrun)
if (not args.nowix) and is_windows():
restore_dotnet_tools(args.dryrun)

if (NINJA_WIN in archives) or (NINJA_MAC in archives):
extract_ninja(args.dryrun)
Expand Down
77 changes: 29 additions & 48 deletions src/win32/installer/installer.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,11 @@
'type': 'none',
'variables': {
'wxs_file': '<(wxs_64bit_file)',
'wixobj_file': '<(mozc_64bit_wixobj)',
'msi_file': '<(mozc_64bit_msi)',
},
'actions': [
{
'action_name': 'candle',
'action_name': 'generate_msi',
'conditions': [
['channel_dev==1', {
'variables': {
Expand All @@ -131,65 +130,47 @@
'icon_path': '<(mozc_content_dir)/images/win/product_icon.ico',
'document_dir': '<(mozc_content_dir)/installer',
},
'inputs': [
'<(wxs_file)',
],
'outputs': [
'<(wixobj_file)',
],
'action': [
'<(wix_dir)/candle.exe',
'-nologo',
'-dMozcVersion=<(version)',
'-dUpgradeCode=<(upgrade_code)',
'-dOmahaGuid=<(omaha_guid)',
'-dOmahaClientKey=<(omaha_client_key)',
'-dOmahaClientStateKey=<(omaha_clientstate_key)',
'-dOmahaChannelType=<(omaha_channel_type)',
'-dVSConfigurationName=<(CONFIGURATION_NAME)',
'-dReleaseRedistCrt32Dir=<(release_redist_32bit_crt_dir)',
'-dReleaseRedistCrt64Dir=<(release_redist_64bit_crt_dir)',
'-dAddRemoveProgramIconPath=<(icon_path)',
'-dMozcTIP32Path=<(mozc_tip32_path)',
'-dMozcTIP64Path=<(mozc_tip64_path)',
'-dMozcBroker64Path=<(mozc_broker64_path)',
'-dMozcServer64Path=<(mozc_server64_path)',
'-dMozcCacheService64Path=<(mozc_cache_service64_path)',
'-dMozcRenderer64Path=<(mozc_renderer64_path)',
'-dMozcToolPath=<(mozc_tool_path)',
'-dCustomActions64Path=<(mozc_ca64_path)',
'-dDocumentsDir=<(document_dir)',
'-dQtDir=<(qt_dir)',
'-dQtVer=<(qt_ver)',
'-o', '<@(_outputs)',
# We do not use '<@(_inputs)' here because it contains some
# input files just for peoper rebiuld condition.
'<(wxs_file)',
],
'message': 'candle is generating <@(_outputs)',
},
{
'action_name': 'generate_msi',
'inputs': [
# ninja.exe will invoke this action if any file listed here is
# newer than files in 'outputs'.
'<(wixobj_file)',
'<(wxs_file)',
'<@(mozc_64bit_installer_inputs)',
],
'outputs': [
'<(msi_file)',
],
'action': [
'<(wix_dir)/light.exe',
'dotnet', 'tool', 'run', 'wix',
'build',
'-nologo',
# Suppress the validation to address the LGHT0217 error.
'-sval',
'-o', '<@(_outputs)',
'-arch', 'x64',
'-define', 'MozcVersion=<(version)',
'-define', 'UpgradeCode=<(upgrade_code)',
'-define', 'OmahaGuid=<(omaha_guid)',
'-define', 'OmahaClientKey=<(omaha_client_key)',
'-define', 'OmahaClientStateKey=<(omaha_clientstate_key)',
'-define', 'OmahaChannelType=<(omaha_channel_type)',
'-define', 'VSConfigurationName=<(CONFIGURATION_NAME)',
'-define', 'ReleaseRedistCrt32Dir=<(release_redist_32bit_crt_dir)',
'-define', 'ReleaseRedistCrt64Dir=<(release_redist_64bit_crt_dir)',
'-define', 'AddRemoveProgramIconPath=<(icon_path)',
'-define', 'MozcTIP32Path=<(mozc_tip32_path)',
'-define', 'MozcTIP64Path=<(mozc_tip64_path)',
'-define', 'MozcBroker64Path=<(mozc_broker64_path)',
'-define', 'MozcServer64Path=<(mozc_server64_path)',
'-define', 'MozcCacheService64Path=<(mozc_cache_service64_path)',
'-define', 'MozcRenderer64Path=<(mozc_renderer64_path)',
'-define', 'MozcToolPath=<(mozc_tool_path)',
'-define', 'CustomActions64Path=<(mozc_ca64_path)',
'-define', 'DocumentsDir=<(document_dir)',
'-define', 'QtDir=<(qt_dir)',
'-define', 'QtVer=<(qt_ver)',
'-out', '<@(_outputs)',
# We do not use '<@(_inputs)' here because it contains some
# input files just for peoper rebiuld condition.
'<(wixobj_file)',
'-src', '<(wxs_file)',
],
'message': 'light is generating <@(_outputs)',
'message': 'WiX is generating <@(_outputs)',
},
],
},
Expand Down
Loading

0 comments on commit cbd5556

Please sign in to comment.