Skip to content
This repository has been archived by the owner on Mar 22, 2022. It is now read-only.

Commit

Permalink
Link against core PDBs when building interop DLL (#208)
Browse files Browse the repository at this point in the history
This change enables linking the interop DLL
Microsoft.MixedReality.WebRTC.Native.dll with the PDBs from the core
webrtc.lib and, on UWP platform, the UWP wrappers from
Org.WebRtc.WrapperGlue.lib, to enable a better debugging experience for
users.

Given the large size of PDBs for each build variant (~400 MB and more),
this changes uses some Universal Packages to store the PDBs in some
private Artifacts feed on Azure DevOps when compiling webrtc.lib, and
restore them when compiling Microsoft.MixedReality.WebRTC.Native.dll, as
the frequency of the former is much lower than the frequency of the
latter, and the former build is generally shared by multiple branches of
the latter (e.g. master and release/1.0 at the moment).

Additionally, because Azure build agents have a limit of 10GB per build,
this change generates on-the-fly a custom packages.config for the
current build triple (config-platform-arch) which allows restoring only
the necessary core NuGet packages (containing webrtc.lib). This has the
extra advantage of reducing the time needed to restore all platform
packages: previously 4 on Desktop and 13 on UWP, now only 1 on Desktop
and 3 on UWP. The .vcxproj is also modified on-the-fly and in-place to
import only the restored packages. Note that those steps are executed
via PowerShell scripts during the build and not stored in the committed
.vcxproj/packages.config files because it is uncertain whether the
Visual Studio IDE would understand platform- and config-dependent NuGet
restore, which are rather unusual and only required because we are
hitting the NuGet file size limit on nuget.org, therefore the files
shipped on GitHub are left untouched with the full set of NuGet packages
for all config/arch per platform, to avoid missing any NuGet restore
which would prevent the user from compiling the solution.
  • Loading branch information
djee-ms authored Mar 5, 2020
1 parent 5a1e8d2 commit f773f40
Show file tree
Hide file tree
Showing 13 changed files with 484 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@
<PropertyGroup Condition="'$(PlatformTarget)' == 'ARM'">
<UnityPluginDirectory>$(ProjectDir)..\..\..\\Microsoft.MixedReality.WebRTC.Unity\Assets\Plugins\WSA\ARM</UnityPluginDirectory>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemGroup>
<NativeUnityPluginSourceFiles Include="$(OutDir)\Microsoft.MixedReality.WebRTC.Native.dll;$(OutDir)\Microsoft.MixedReality.WebRTC.Native.pdb" />
</ItemGroup>
Expand All @@ -114,6 +120,28 @@
<AdditionalDependencies>Ole32.lib;Evr.lib;mf.lib;mfuuid.lib;mfplat.lib;webrtc.lib;WindowsApp.lib;Org.WebRtc.WrapperGlue.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>..\exports.def</ModuleDefinitionFile>
<AdditionalLibraryDirectories>$(WebRTCCoreRepoPath)webrtc\xplatform\webrtc\OUTPUT\webrtc\winuwp\$(PlatformTarget)\$(Configuration);$(WebRTCCoreRepoPath)webrtc\windows\projects\msvc\Org.WebRtc.WrapperGlue.Universal\Build\Output\Org.WebRtc.WrapperGlue\$(Configuration)\$(PlatformTarget);$(WebRTCCoreRepoPath)webrtc\windows\projects\msvc\Org.WebRtc.Universal\Build\Output\Org.WebRtc\$(Configuration)\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<ClInclude Include="../interop/interop_api.h">
<Filter>interop</Filter>
</ClInclude>
<ClInclude Include="../data_channel.h">
<ClInclude Include="../../include/data_channel.h">
<Filter>media</Filter>
</ClInclude>
<ClInclude Include="../../include/str.h" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
<ModuleDefinitionFile>..\exports.def</ModuleDefinitionFile>
<AdditionalDependencies>strmiids.lib;Msdmo.lib;dmoguids.lib;wmcodecdspuuid.lib;Secur32.lib;winmm.lib;Ole32.lib;Evr.lib;mfreadwrite.lib;mf.lib;mfuuid.lib;mfplat.lib;mfplay.lib;webrtc.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WebRTCCoreRepoPath)webrtc\xplatform\webrtc\OUTPUT\webrtc\win\$(PlatformTarget)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
Expand All @@ -104,9 +105,6 @@
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<ClInclude Include="../interop/interop_api.h">
<Filter>interop</Filter>
</ClInclude>
<ClInclude Include="../data_channel.h">
<ClInclude Include="../../include/data_channel.h">
<Filter>media</Filter>
</ClInclude>
<ClInclude Include="../../include/str.h" />
Expand Down
73 changes: 73 additions & 0 deletions tools/ci/computePdbPackageVars.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Compute the name and version of the Universal Package used for PDBs,
# and populate the relevant pipeline variables.

# Compute package name
# Note the restrictions on a Universal Package name (from error message):
# Universal package names must be one or more lowercase alphanumeric
# segments separated by a dash, dot or underscore. The package name
# must be under 256 characters.
if (!$env:BUILDTRIPLE)
{
$err = "Invalid build triple '$env:BUILDTRIPLE'"
Write-Error $err
Write-Host "##vso[task.complete result=Failed;]$err"
exit 1
}
$PackageName = "mr-webrtc-core_pdbs_$env:BUILDTRIPLE".ToLowerInvariant()
if ($PackageName.Length -ge 256) {
$err = "Package name too long: '$PackageName'"
Write-Error $err
Write-Host "##vso[task.complete result=Failed;]$err"
exit 1
}
Write-Host "PDB package name : $PackageName"
Write-Host "##vso[task.setvariable variable=MRWebRTC_PdbPackageName]$PackageName"

# Compute version if needed, or check existing version
if ($env:WRITE_VERSION -eq 'true')
{
# Compute package version based on build variables
if ($env:MRWEBRTC_PDBPACKAGEVERSION)
{
# Normally this should compute $(MRWebRTC_PdbPackageVersion) based on the build's version
# and optional release tag and build number. But the variable has also been already assigned
# in the build pipelines variables, which generally indicates a misconfigured pipeline.
$err = "Pipeline variable MRWebRTC_PdbPackageVersion is already set : '$env:MRWEBRTC_PDBPACKAGEVERSION'."
Write-Error $err
Write-Host "##vso[task.complete result=Failed;]$err"
exit 1
}
if (!$env:MRWEBRTCVERSION)
{
$err = "Invalid build version '$env:MRWEBRTCVERSION'"
Write-Error $err
Write-Host "##vso[task.complete result=Failed;]$err"
exit 1
}
if ($env:MRWEBRTCRELEASETAG)
{
$PackageVersion = "$env:MRWEBRTCVERSION-$env:MRWEBRTCRELEASETAG"
}
else
{
$PackageVersion = "$env:MRWEBRTCVERSION"
}
if ($env:MRWEBRTCWITHBUILDNUMBER -eq "true")
{
$PackageVersion = "$PackageVersion-$env:BUILD_BUILDNUMBER"
}
Write-Host "PDB package version (generated) : $PackageVersion"
Write-Host "##vso[task.setvariable variable=MRWebRTC_PdbPackageVersion]$PackageVersion"
}
else
{
# Read and check version from pipeline variables, but do not modify
if (!$env:MRWEBRTC_PDBPACKAGEVERSION)
{
$err = "Invalid PDB package version '$env:MRWEBRTC_PDBPACKAGEVERSION'"
Write-Error $err
Write-Host "##vso[task.complete result=Failed;]$err"
exit 1
}
Write-Host "PDB package version (from pipeline) : $env:MRWEBRTC_PDBPACKAGEVERSION"
}
20 changes: 20 additions & 0 deletions tools/ci/copyPdbsForBuilding.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copy all PDBs from their packaging folder back next to webrtc.lib
# Note that this is not their original location, but this is where
# the linker currently looks for them.

param(
[string]$SourcePath,
[string]$OutputPath
)

# Move all PDBs
Write-Host "Moving PDBs..."
mkdir -Force $OutputPath | out-null
Move-Item -Path $(Join-Path $SourcePath "*") -Destination $OutputPath -Include "*.pdb"

# List content of output folder
Write-Host "Content of output folder $OutputPath"
foreach ($f in $(Get-ChildItem -Path $OutputPath -Recurse))
{
Write-Host $f.FullName
}
47 changes: 47 additions & 0 deletions tools/ci/copyPdbsForPackaging.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copy all PDBs into a single folder for packaging as Universal Package

param(
[string]$CorePath,
[string]$WrapperPath,
[string]$WrapperGluePath,
[string]$OutputPath,
[ValidateSet('Debug','Release')]
[string]$BuildConfig,
[switch]$WithUwpWrapper
)

# Copied from https://github.com/microsoft/MixedReality-Sharing/blob/master/tools/ci/utils.ps1
function Ensure-Empty($DirectoryPath) {
mkdir -Force "$DirectoryPath" | out-null
Remove-Item "$DirectoryPath\*" -Force -Recurse
}

# Ensure the output path exists and is empty
Ensure-Empty $OutputPath

# Copy core PDBs
Write-Host "Copying PDBs for core webrtc.lib..."
Copy-Item -Path $(Join-Path $CorePath "*") -Destination $OutputPath -Include "*.pdb"

if ($WithUwpWrapper)
{
# Copy wrapper PDB (Org.WebRtc.pdb)
Write-Host "Copying PDB for Org.WebRtc.dll..."
Copy-Item -Path $(Join-Path $WrapperPath "Org.WebRtc.pdb") -Destination $OutputPath

# Copy wrapper glue PDB (Org.WebRtc.WrapperGlue.pdb)
# In Release there is no PDB; the project does not specify /DEBUG so defaults to Debug-only PDBs.
if ($BuildConfig -eq "Release") {
Write-Host "Skipping PDB for Org.WebRtc.WrapperGlue.lib (not generated in Release)"
} else {
Write-Host "Copying PDB for Org.WebRtc.WrapperGlue.lib..."
Copy-Item -Path $(Join-Path $WrapperGluePath "Org.WebRtc.WrapperGlue.pdb") -Destination $OutputPath
}
}

# List content of output folder
Write-Host "Content of output folder $OutputPath"
foreach ($f in $(Get-ChildItem -Path $OutputPath -Recurse))
{
Write-Host $f.FullName
}
66 changes: 66 additions & 0 deletions tools/ci/generateCppPackagesConfig.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Generate a custom packages.config to restore only the necessary Core
# NuGet packages for the given build triple, to save on disk space

param(
[ValidateSet('Win32','UWP')]
[string]$BuildPlatform,
[ValidateSet('x86','x64','ARM')]
[string]$BuildArch,
[ValidateSet('Debug','Release')]
[string]$BuildConfig,
[string]$InputFile,
[string]$OutputFile
)

Write-Host "Generating packages.config for build triple $BuildPlatform-$BuildArch-$BuildConfig..."

$reader = [System.IO.File]::OpenText($InputFile)
$content = ""
try {
for() {
$line = $reader.ReadLine()
if ($line -eq $null) { break }
# Check if the package is arch/config dependent.
# Note that this will *not* match the generic UWP package containing the generated headers,
# "Microsoft.MixedReality.WebRTC.Native.Core.UWP" (without '.' after 'UWP'), which should
# always be restored on all UWP variants independent of the arch/config.
if ($line -match "Microsoft\.MixedReality\.WebRTC\.Native\.Core\.(Desktop|UWP|WinRT)\.")
{
# Once the package is known to be config/arch-dependent, validate that this is the
# correct arch and config for the current build.
if ($line -match "Microsoft\.MixedReality\.WebRTC\.Native\.Core\.(Desktop|UWP|WinRT)\.$BuildArch\.$BuildConfig")
{
$linePlatform = $Matches.1 # Desktop|UWP|WinRT
if ((($linePlatform -eq 'Desktop') -and ($BuildPlatform -eq 'Win32')) -or (($linePlatform -ne 'Desktop') -and ($BuildPlatform -eq 'UWP')))
{
# Copy line for matching build triple as is
$content += $line + "`n";
}
else
{
# Discard line - mismatching platform
}
}
else
{
# Discard line - mismatching arch/config
}
}
else
{
# Copy any other line as is, including "Microsoft.MixedReality.WebRTC.Native.Core.UWP"
$content += $line + "`n";
}
}
}
finally {
$reader.Close()
}
Write-Output $content | Set-Content -Path $OutputFile -Encoding UTF8

Write-Host "== $OutputFile ======================================="
Get-Content -Encoding UTF8 -Path "$OutputFile"
Write-Host "=========================================================="

# Write the filename of the new packages.config file to $(PackagesConfigFile) for later use
Write-Host "##vso[task.setvariable variable=PackagesConfigFile]$OutputFile"
88 changes: 88 additions & 0 deletions tools/ci/modifyCppProject.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Modify the .vcxproj project file to only import the NuGet packages for
# the current build triple, which are the only ones restored.

param(
[ValidateSet('Win32','UWP')]
[string]$BuildPlatform,
[ValidateSet('x86','x64','ARM')]
[string]$BuildArch,
[ValidateSet('Debug','Release')]
[string]$BuildConfig,
[string]$ProjectFile
)

Write-Host "Modifying .vcxproj for build triple $BuildPlatform-$BuildArch-$BuildConfig..."

$reader = [System.IO.File]::OpenText($ProjectFile)
$content = ""
try {
for() {
$line = $reader.ReadLine()
if ($line -eq $null) { break }
if ($line -match "Import Project=")
{
if ($line -match "packages\\Microsoft\.MixedReality\.WebRTC\.Native\.Core\.(Desktop|UWP|WinRT)\.(x86|x64|ARM)\.(Debug|Release)")
{
$linePlatform = $Matches.1 # Desktop|UWP|WinRT
$lineArch = $Matches.2 # x86|x64|ARM
$lineConfig = $Matches.3 #Debug|Release
$matchPlatform = (($linePlatform -eq 'Desktop') -and ($BuildPlatform -eq 'Win32')) -or (($linePlatform -ne 'Desktop') -and ($BuildPlatform -eq 'UWP'))
$matchArch = ($lineArch -eq $BuildArch)
$matchConfig = ($lineConfig -eq $BuildConfig)
if ($matchPlatform -and $matchArch -and $matchConfig)
{
# Copy line for matching build triple as is
$content += $line + "`n";
}
else
{
# Discard line - mismatching platform or arch or config
}
}
else
{
# Copy any other line as is
$content += $line + "`n";
}
}
elseif ($line -match "Error Condition=")
{
if ($line -match "packages\\Microsoft\.MixedReality\.WebRTC\.Native\.Core\.(Desktop|UWP|WinRT)\.(x86|x64|ARM)\.(Debug|Release)")
{
$linePlatform = $Matches.1 # Desktop|UWP|WinRT
$lineArch = $Matches.2 # x86|x64|ARM
$lineConfig = $Matches.3 #Debug|Release
$matchPlatform = (($linePlatform -eq 'Desktop') -and ($BuildPlatform -eq 'Win32')) -or (($linePlatform -ne 'Desktop') -and ($BuildPlatform -eq 'UWP'))
$matchArch = ($lineArch -eq $BuildArch)
$matchConfig = ($lineConfig -eq $BuildConfig)
if ($matchPlatform -and $matchArch -and $matchConfig)
{
# Copy line for matching build triple as is
$content += $line + "`n";
}
else
{
# Discard line - mismatching platform or arch or config
}
}
else
{
# Copy any other line as is
$content += $line + "`n";
}
}
else
{
# Copy any other line as is
$content += $line + "`n";
}
}
}
finally {
$reader.Close()
}
Write-Output $content | Set-Content -Path $ProjectFile -Encoding UTF8

Write-Host "== $ProjectFile ======================================="
Get-Content -Encoding UTF8 -Path "$ProjectFile"
Write-Host "=========================================================="
5 changes: 0 additions & 5 deletions tools/ci/release-core-nosign.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ pr: none
# Give a unique name to the build each time it runs
name: $(Date:yyyyMMdd)-$(Rev:r)

variables:
# Version string is "$(MRWebRTCVersion)-$(MRWebRTCReleaseTag)-$(Build.BuildId)"
MRWebRTCVersion: 0.0.1 # Major.Minor.Patch
MRWebRTCReleaseTag: 'alpha' # Optional, without '-'

stages:

# Compile all platform/architecture/config variants as separate jobs
Expand Down
Loading

0 comments on commit f773f40

Please sign in to comment.