Skip to content

Commit 26fca44

Browse files
committed
WiX: add custom action to copy Clang resources
1 parent a22a5bb commit 26fca44

File tree

4 files changed

+238
-2
lines changed

4 files changed

+238
-2
lines changed

Diff for: platforms/Windows/CustomActions/CustomActions.cc

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include <Windows.h>
2+
#include <msi.h>
3+
#include <msiquery.h>
4+
5+
#include <filesystem>
6+
7+
namespace msi {
8+
void log(MSIHANDLE hInstall, UINT eMessageType, std::wstring message) noexcept {
9+
PMSIHANDLE record = MsiCreateRecord(0);
10+
(void)MsiRecordSetStringW(record, 0, message.c_str());
11+
(void)MsiProcessMessage(hInstall, INSTALLMESSAGE(eMessageType), record);
12+
}
13+
14+
void log_last_error(MSIHANDLE hInstall) noexcept {
15+
PMSIHANDLE record = MsiGetLastErrorRecord();
16+
(void)MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, record);
17+
}
18+
19+
std::wstring get_action_data(MSIHANDLE hInstall, UINT &result) noexcept {
20+
DWORD size = 0;
21+
22+
result = MsiGetPropertyW(hInstall, L"CustomActionData", L"", &size);
23+
switch (result) {
24+
case ERROR_MORE_DATA:
25+
break;
26+
case ERROR_SUCCESS:
27+
result = ERROR_INSTALL_FAILURE;
28+
return nullptr;
29+
default:
30+
log_last_error(hInstall);
31+
return nullptr;
32+
}
33+
34+
std::vector<WCHAR> buffer;
35+
buffer.resize(size + 1);
36+
37+
size = buffer.capacity();
38+
result = MsiGetPropertyW(hInstall, L"CustomActionData", buffer.data(), &size);
39+
switch (result) {
40+
case ERROR_SUCCESS:
41+
break;
42+
default:
43+
log_last_error(hInstall);
44+
return nullptr;
45+
}
46+
47+
return {buffer.data(), buffer.capacity()};
48+
}
49+
}
50+
51+
extern "C" _declspec(dllexport) UINT __stdcall CopyClangResources(MSIHANDLE hInstall) {
52+
UINT result = ERROR_SUCCESS;
53+
54+
// Get the runtime resource directory path
55+
auto resourceDirectory = msi::get_action_data(hInstall, result);
56+
if (result != ERROR_SUCCESS) {
57+
return result;
58+
}
59+
msi::log(hInstall, INSTALLMESSAGE_INFO, L"Swift runtime resources: " + resourceDirectory);
60+
61+
// Get the source and destination paths
62+
std::filesystem::path resourcePath(resourceDirectory);
63+
if (resourcePath.has_filename()) {
64+
resourcePath = resourcePath.parent_path();
65+
}
66+
auto sourcePath = resourcePath.parent_path() / "clang";
67+
auto destinationPath = resourcePath / "clang";
68+
69+
msi::log(hInstall, INSTALLMESSAGE_INFO, L"Clang resources: " + sourcePath.wstring());
70+
msi::log(hInstall, INSTALLMESSAGE_INFO, L"Clang resources for Swift: " + destinationPath.wstring());
71+
72+
// Verify that Clang resources contain exactly one top-level directory
73+
{
74+
int directoryCount = 0, fileCount = 0;
75+
for (const auto& entry : std::filesystem::directory_iterator(sourcePath)) {
76+
if (entry.is_directory()) {
77+
directoryCount++;
78+
sourcePath = entry.path();
79+
} else {
80+
fileCount++;
81+
}
82+
}
83+
if (directoryCount != 1 || fileCount != 0) {
84+
msi::log(hInstall, INSTALLMESSAGE_ERROR | MB_OK, L"lib\\clang must contain exactly one directory.");
85+
return ERROR_FILE_CORRUPT;
86+
}
87+
}
88+
msi::log(hInstall, INSTALLMESSAGE_INFO, L"Detected Clang version: " + sourcePath.filename().wstring());
89+
90+
// Copy the contents of the single directory directly to the destination path
91+
std::error_code error;
92+
auto options = std::filesystem::copy_options::overwrite_existing | std::filesystem::copy_options::recursive;
93+
94+
std::filesystem::copy(sourcePath, destinationPath, options, error);
95+
if (error) {
96+
std::string errorMessage = "Error during directory copy: " + error.message();
97+
msi::log(hInstall, INSTALLMESSAGE_ERROR | MB_OK, {errorMessage.begin(), errorMessage.end()});
98+
return ERROR_DISK_OPERATION_FAILED;
99+
}
100+
101+
return result;
102+
}
103+
104+
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
105+
switch (ul_reason_for_call) {
106+
case DLL_PROCESS_ATTACH:
107+
case DLL_PROCESS_DETACH:
108+
case DLL_THREAD_ATTACH:
109+
case DLL_THREAD_DETACH:
110+
break;
111+
}
112+
return TRUE;
113+
}
+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="16.0">
2+
<ItemGroup>
3+
`<ProjectConfiguration Include="Debug|Win32">
4+
<Configuration>Debug</Configuration>
5+
<Platform>x86</Platform>
6+
</ProjectConfiguration>
7+
<ProjectConfiguration Include="Release|Win32">
8+
<Configuration>Release</Configuration>
9+
<Platform>x86</Platform>
10+
</ProjectConfiguration>
11+
<ProjectConfiguration Include="Debug|ARM64">
12+
<Configuration>Debug</Configuration>
13+
<Platform>ARM64</Platform>
14+
</ProjectConfiguration>
15+
<ProjectConfiguration Include="Release|ARM64">
16+
<Configuration>Release</Configuration>
17+
<Platform>ARM64</Platform>
18+
</ProjectConfiguration>
19+
<ProjectConfiguration Include="Debug|x64">
20+
<Configuration>Debug</Configuration>
21+
<Platform>x64</Platform>
22+
</ProjectConfiguration>
23+
<ProjectConfiguration Include="Release|x64">
24+
<Configuration>Release</Configuration>
25+
<Platform>x64</Platform>
26+
</ProjectConfiguration>
27+
</ItemGroup>
28+
29+
<PropertyGroup>
30+
<ProjectGuid>{84027311-67A4-4351-AD3A-53529767BFA0}</ProjectGuid>
31+
<RootNamespace>SwiftInstaller</RootNamespace>
32+
</PropertyGroup>
33+
34+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
35+
36+
<PropertyGroup>
37+
<ConfigurationType>DynamicLibrary</ConfigurationType>
38+
<CharacterSet>Unicode</CharacterSet>
39+
<TargetName>CustomActions</TargetName>
40+
41+
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
42+
43+
<PlatformToolset Condition="'$(PlatformToolset)' == ''">$(DefaultPlatformToolset)</PlatformToolset>
44+
<PlatformToolset>$(PlatformToolset)</PlatformToolset>
45+
46+
<IntDir>build\$(Configuration)\$(PlatformShortName)\obj\</IntDir>
47+
<OutDir>build\$(Configuration)\$(PlatformShortName)\bin\</OutDir>
48+
</PropertyGroup>
49+
50+
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
51+
<UseDebugLibraries>true</UseDebugLibraries>
52+
</PropertyGroup>
53+
54+
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
55+
<UseDebugLibraries>false</UseDebugLibraries>
56+
<WholeProgramOptimization>true</WholeProgramOptimization>
57+
</PropertyGroup>
58+
59+
<ItemDefinitionGroup>
60+
<ClCompile>
61+
<LanguageStandard>stdcpp17</LanguageStandard>
62+
<PreprocessorDefinitions>VC_EXTRALEAN;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
63+
</ClCompile>
64+
<Link>
65+
<AdditionalDependencies>msi.lib</AdditionalDependencies>
66+
</Link>
67+
</ItemDefinitionGroup>
68+
69+
<ItemDefinitionGroup Condition="'$(Configuration)' == 'Debug'">
70+
<ClCompile>
71+
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
72+
</ClCompile>
73+
<Link>
74+
<GenerateDebugInformation>true</GenerateDebugInformation>
75+
</Link>
76+
</ItemDefinitionGroup>
77+
78+
<ItemDefinitionGroup Condition="'$(Configuration)' == 'Release'">
79+
<ClCompile>
80+
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
81+
</ClCompile>
82+
</ItemDefinitionGroup>
83+
84+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
85+
86+
<ItemGroup>
87+
<ClCompile Include="CustomActions.cc" />
88+
</ItemGroup>
89+
90+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Targets"/>
91+
</Project>

Diff for: platforms/Windows/toolchain-amd64.wxs

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
1+
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
22
<Package
33
Language="1033"
44
Manufacturer="swift.org"
@@ -578,5 +578,21 @@
578578
<WixVariable Id="WixUIDialogBmp" Value="Resources\swift_dialog.png" />
579579
<WixVariable Id="WixUIBannerBmp" Value="Resources\swift_banner.png" />
580580

581+
<Binary Id="CustomActions" SourceFile="$(var.CustomActions.TargetDir)\CustomActions.dll" />
582+
583+
<CustomAction Id="CopyClangResources.SetProperty"
584+
Property="CopyClangResources"
585+
Value="[_usr_lib_swift]" />
586+
<CustomAction Id="CopyClangResources"
587+
BinaryRef="CustomActions"
588+
DllEntry="CopyClangResources"
589+
Execute="deferred"
590+
Impersonate="no"
591+
Return="check" />
592+
593+
<InstallExecuteSequence>
594+
<Custom Action="CopyClangResources.SetProperty" Before="CopyClangResources" />
595+
<Custom Action="CopyClangResources" After="InstallFiles" Condition="NOT REMOVE" />
596+
</InstallExecuteSequence>
581597
</Package>
582598
</Wix>

Diff for: platforms/Windows/toolchain-arm64.wxs

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
1+
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
22
<Package
33
Language="1033"
44
Manufacturer="swift.org"
@@ -578,5 +578,21 @@
578578
<WixVariable Id="WixUIDialogBmp" Value="Resources\swift_dialog.png" />
579579
<WixVariable Id="WixUIBannerBmp" Value="Resources\swift_banner.png" />
580580

581+
<Binary Id="CustomActions" SourceFile="$(var.CustomActions.TargetDir)\CustomActions.dll" />
582+
583+
<CustomAction Id="CopyClangResources.SetProperty"
584+
Property="CopyClangResources"
585+
Value="[_usr_lib_swift]" />
586+
<CustomAction Id="CopyClangResources"
587+
BinaryRef="CustomActions"
588+
DllEntry="CopyClangResources"
589+
Execute="deferred"
590+
Impersonate="no"
591+
Return="check" />
592+
593+
<InstallExecuteSequence>
594+
<Custom Action="CopyClangResources.SetProperty" Before="CopyClangResources" />
595+
<Custom Action="CopyClangResources" After="InstallFiles" Condition="NOT REMOVE" />
596+
</InstallExecuteSequence>
581597
</Package>
582598
</Wix>

0 commit comments

Comments
 (0)