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

[runtime] Infrastructure to build runtime components using NativeAOT #98565

Merged
merged 85 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from 82 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
663184e
wip: dotnet.sh build src/native/libhellomanaged/compile-native.proj w…
lambdageek Feb 14, 2024
d16749d
hide unnecesary dependencies
lambdageek Feb 15, 2024
ca01640
add compile-native.proj to runtime-prereqs.proj
lambdageek Feb 15, 2024
2ad4c85
make first builds work
lambdageek Feb 15, 2024
44ce176
add an include dir for libhellomanaged
lambdageek Feb 15, 2024
6aad355
wire in static lib support; use to call libhellomanaged from daccess
lambdageek Feb 15, 2024
eb56ef6
call hellomanaged_Hello from DAC DllMain
lambdageek Feb 15, 2024
225d05b
static linking of nativeAotFramework
lambdageek Feb 15, 2024
19d17ac
support for importing NativeAOT compiled shared libs
lambdageek Feb 16, 2024
c03b37e
build native libs as shared by default
lambdageek Feb 16, 2024
730dd07
WIP: first try at installing the native lib
lambdageek Feb 16, 2024
472ee21
relocatable linking for static libs
lambdageek Feb 16, 2024
51f56b1
cleanup shared lib version; add install_clr support
lambdageek Feb 16, 2024
b6c637c
rm TODO
lambdageek Feb 16, 2024
80c706d
don't build hellomanaged on platforms without NativeAOT
lambdageek Feb 16, 2024
1f6a9f7
fixup windows build
lambdageek Feb 16, 2024
26c33ab
fixup win implib
lambdageek Feb 16, 2024
f6dcfe8
disable more configurations
lambdageek Feb 16, 2024
b94c67a
try to workaround dotnet/msbuild#2811
lambdageek Feb 16, 2024
4c7793b
allow daccess to keep building if hellomanaged is not present
lambdageek Feb 16, 2024
ce900f1
always use lld on linux?
lambdageek Feb 16, 2024
37edeaf
put AdditionalProperties on the ProjectReference same as msbuild publish
lambdageek Feb 16, 2024
a24dc46
no x86 or riscv
lambdageek Feb 17, 2024
748a84d
linux-arm64 hack
lambdageek Feb 17, 2024
d77776e
HACK: installer
lambdageek Feb 20, 2024
e7eca1f
disable armel
lambdageek Feb 20, 2024
4149bea
remove bfd hack - it didn't work
lambdageek Feb 20, 2024
11c9d90
pass SysRoot and --gcc-toolchain to native build
lambdageek Feb 20, 2024
f664970
fix typo (RID is linux-riscv64 not linux-riscv)
lambdageek Feb 20, 2024
70bc9c7
set linker flavor if doing cross builds
lambdageek Feb 20, 2024
0f776cc
fix for cmake 3.20
lambdageek Feb 20, 2024
66f4b53
use GenerateFileFromTemplate for shared mode
lambdageek Feb 20, 2024
c32f8ac
use GenerateFileFromTemplate for static libs
lambdageek Feb 20, 2024
556d0b5
rename toplevel dir to src/native/managed
lambdageek Feb 20, 2024
fd04a07
allow csproj to specify cmake include dir for native library
lambdageek Feb 21, 2024
f6dd13f
fixup INCLUDE path for Windows
lambdageek Feb 21, 2024
b06ddeb
Use find_package to find native AOT libs
lambdageek Feb 21, 2024
533f183
Add README
lambdageek Feb 21, 2024
211d683
remove unused function
lambdageek Feb 21, 2024
70db261
libhellomanaged is optional
lambdageek Feb 21, 2024
f9b52d5
move user-facing cmake to eng/functions.cmake
lambdageek Feb 21, 2024
c3b231d
remove cruft
lambdageek Feb 21, 2024
014a674
fix windows paths
lambdageek Feb 21, 2024
0c96465
Use unix-style paths even on Windows; cmake prefers this
lambdageek Feb 21, 2024
bf6c499
dependency tracking and stripping
lambdageek Feb 21, 2024
44ba2cc
windows stripping support
lambdageek Feb 22, 2024
3184d6d
cleanup
lambdageek Feb 22, 2024
3835325
update README
lambdageek Feb 22, 2024
4b04029
remove FIXME
lambdageek Feb 22, 2024
77d9899
remove static linking support
lambdageek Feb 22, 2024
5a4be9a
use _IsPublishing for the publish target
lambdageek Feb 22, 2024
7ecdca0
set MSBuildRestoreSessionId when restoring
lambdageek Feb 22, 2024
238ee10
rename property to CLR_IMPORTED_COPY_TARGET
lambdageek Feb 22, 2024
d7a57b8
add a general purpose add_imported_library_clr cmake function
lambdageek Feb 23, 2024
bf5652f
Merge remote-tracking branch 'origin/main' into naot-runtime-lib
lambdageek Mar 4, 2024
0e05f17
move call to hellomanaged_Hello to CLRDataAccessCreateInstance
lambdageek Mar 4, 2024
481a77a
WIP: copy runtime components to final location in native-library.targets
lambdageek Mar 4, 2024
de1114b
add ::libs and ::headers imported lib targets
lambdageek Mar 5, 2024
0d21d2e
remove unused var
lambdageek Mar 5, 2024
7c409be
add TODOs for new approach
lambdageek Mar 5, 2024
2b0850a
remove import-nativeaot-library.cmake
lambdageek Mar 5, 2024
6dad61e
remove add_imported_library_clr cmake function
lambdageek Mar 5, 2024
e075acd
revert cmake changes for imported libs
lambdageek Mar 5, 2024
ce1c1c7
update README
lambdageek Mar 5, 2024
7eff8e6
just emit one cmake file
lambdageek Mar 5, 2024
182df7a
simplify the cmake template
lambdageek Mar 5, 2024
8eb8e36
rename some cmake vars
lambdageek Mar 5, 2024
dd50ff0
strip nativeoat-built componentlike coreclr does on mac/linux
lambdageek Mar 5, 2024
bdc85a0
fixup osx and linux builds
lambdageek Mar 5, 2024
6aae973
empty commit to trigger build
lambdageek Mar 6, 2024
003af6a
copy windows PDBs to final install destinations
lambdageek Mar 6, 2024
edbbe84
DRY
lambdageek Mar 6, 2024
adc9314
simplify example
lambdageek Mar 6, 2024
3a5353b
fixup comments and docs
lambdageek Mar 6, 2024
c7b6751
cleanup
lambdageek Mar 6, 2024
a07ecaa
set library name on linux and mac
lambdageek Mar 6, 2024
0cc4db4
remove example
lambdageek Mar 6, 2024
0f90a93
remove support for exporting a header target
lambdageek Mar 7, 2024
0a582c2
Revert "remove support for exporting a header target"
lambdageek Mar 7, 2024
937a173
native-library.targets: make SetupOSSpecificProps probe for objcopy
lambdageek Mar 7, 2024
0e3bed5
Remove cmake integration
lambdageek Mar 7, 2024
19724f1
fix comment
lambdageek Mar 8, 2024
0958981
rename InstallRuntimeComponentDestination
lambdageek Mar 8, 2024
f55ebcc
automatically include native-library.{props,targets}
lambdageek Mar 8, 2024
b97c391
switch compile-native.proj to the traversal sdk
lambdageek Mar 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/coreclr/runtime-prereqs.proj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
<Import Project="$(RepositoryEngineeringDir)versioning.targets" />
<Import Project="$(RepositoryEngineeringDir)nativepgo.targets" />

<ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\native\managed\compile-native.proj" ReferenceOutputAssembly="false"/>
</ItemGroup>

<Target Name="BuildPrereqs" BeforeTargets="Build" DependsOnTargets="GenerateRuntimeVersionFile;GenerateNativeSourcelinkFile;OutputPgoPathForCI" />
<Import Project="Sdk.targets" Sdk="Microsoft.Build.NoTargets" />
<!--
Expand Down
3 changes: 3 additions & 0 deletions src/native/managed/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Project>
<Import Project="..\..\..\Directory.Build.props" />
</Project>
35 changes: 35 additions & 0 deletions src/native/managed/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Native runtime component libraries using NativeAOT

This directory contains managed libraries that will be compiled using NativeAOT and can be used in runtime components.

## Adding a new managed library

Add a new subdirectory to `src/native/managed` for your library with a `src` and `inc` subdirectories:

``` console
$ mkdir -p libMyNewLibrary/src libMyNewLibrary/inc
$ dotnet new classlib -n libMyNewLibrary -o libMyNewLibrary/src
```

In `src/native/managed/compile-native.proj`, add
`src/native/managed/libMyNewLibrary/src/libMyNewLibrary.csproj` to the `NativeLibsProjectsToBuild`
item group.

In `src/native/managed/libMyNewLibrary/src/libMyNewLibrary.csproj`:
1. Near the top, add `<Import Project="..\..\native-library.props" />`
2. Near the bottom, add `<Import Project="..\..\native-library.targets" />`
lambdageek marked this conversation as resolved.
Show resolved Hide resolved
3. Define an item `@(InstallRuntimeComponentDest)` that has directory names relative to `artifacts/bin/<runtimeFlavor>/<os.arch.config>/` where the shared library should be installed. It's a good idea to have at least `.`:
```xml
<ItemGroup>
<InstallRuntimeComponentDest Include="." />
<InstallRuntimeComponentDest Include="sharedFramework" Condition="'$(RuntimeFlavor)' == 'coreclr'"/>
</ItemGroup>
```
lambdageek marked this conversation as resolved.
Show resolved Hide resolved

Limitations:

* The project should be called `libXXXX` - currently the infrastructure expects a `lib` prefix on all platforms.

* Currently only shared library output is supported. In principle static linking is possible, but the
infrastructure is not finished yet. Additionally, mixing Debug/Release configurations with static
linking will not be supported on Windows.
67 changes: 67 additions & 0 deletions src/native/managed/compile-native.proj
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<Project Sdk="Microsoft.Build.NoTargets">
<PropertyGroup>
<!-- We always want to use release for publishing using NativeAOT -->
<NativeLibsPublishConfiguration>Release</NativeLibsPublishConfiguration>
<!-- we always want to make shared libs -->
<NativeLibKind Condition="'$(NativeLibKind)' == ''">shared</NativeLibKind>
</PropertyGroup>
lambdageek marked this conversation as resolved.
Show resolved Hide resolved

<ItemGroup>
<!-- add new projects here -->
<!-- NativeLibsProjectsToBuild Include="$(MSBuildThisFileDirectory)libhellomanaged/src/libhellomanaged.csproj" -->
</ItemGroup>

<!-- Decide if we're going to do the NativeAOT builds -->
<PropertyGroup>
<!-- disable on Mono, for now -->
<SupportsNativeAotComponents Condition="'$(SupportsNativeAotComponents)' == '' and '$(RuntimeFlavor)' == 'Mono'">false</SupportsNativeAotComponents>
<!-- NativeAOT doesn't support cross-OS compilation. disable for crossdac-->
<SupportsNativeAotComponents Condition="'$(SupportsNativeAotComponents)' == '' and '$(HostOS)' != '$(TargetOS)'">false</SupportsNativeAotComponents>
<!-- unsupported targets -->
<SupportsNativeAotComponents Condition="'$(SupportsNativeAotComponents)' == '' and ('$(TargetArchitecture)' == 'arm' or '$(TargetArchitecture)' == 'armel' or '$(TargetArchitecture)' == 'x86' or '$(TargetArchitecture)' == 'riscv64')">false</SupportsNativeAotComponents>
<SupportsNativeAotComponents Condition="'$(SupportsNativeAotComponents)' == '' and ('$(TargetsWindows)' == 'true' or '$(TargetsOSX)' == 'true' or ('$(TargetsLinux)' == 'true' and '$(TargetsAndroid)' != 'true' and '$(TargetsLinuxMusl)' != 'true'))">true</SupportsNativeAotComponents>
<SupportsNativeAotComponents Condition="'$(SupportsNativeAotComponents)' == ''">false</SupportsNativeAotComponents>
</PropertyGroup>

<!-- some special kinds of runtime builds need extra NativeAOT flags -->
<PropertyGroup>
<SysRoot Condition="'$(CrossBuild)' == 'true' and '$(HostOS)' != 'windows'">$(ROOTFS_DIR)</SysRoot>
<LinkerFlavor Condition="'$(CrossBuild)' == 'true' and '$(TargetsLinux)' == 'true'">lld</LinkerFlavor>
<CustomLinkerArgToolchainArg Condition="'$(CrossBuild)' == 'true' and '$(_hostArchitecture)' == '$(_targetArchitecture)' and '$(_hostOS)' != 'windows'">--gcc-toolchain=$(ROOTFS_DIR)/usr</CustomLinkerArgToolchainArg>
</PropertyGroup>

<!-- properties to pass down to the subproject builds -->
<ItemGroup>
<SubprojectProps Include="Configuration" Value="$(NativeLibsPublishConfiguration)" />
<SubprojectProps Include="RuntimeConfiguration" Value="$(RuntimeConfiguration)" />
<SubprojectProps Include="LibrariesConfiguration" Value="$(LibrariesConfiguration)" />
<SubprojectProps Include="RuntimeIdentifier" Value="$(OutputRID)" />

<SubprojectProps Include="NativeLib" Value="$(NativeLibKind)" />

<SubprojectProps Condition="'$(SysRoot)' != ''" Include="SysRoot" Value="$(SysRoot)" />
<SubprojectProps Condition="'$(LinkerFlavor)' != ''" Include="LinkerFlavor" Value="$(LinkerFlavor)" />
<SubprojectProps Condition="'$(CustomLinkerArgToolchainArg)' != ''" Include="CustomLinkerArgToolchainArg" Value="$(CustomLinkerArgToolchainArg)" />
</ItemGroup>

<ItemGroup Condition="$(SupportsNativeAotComponents)">
<ProjectReference Include="@(NativeLibsProjectsToBuild)"
ReferenceOutputAssembly="false"
AdditionalProperties="%(AdditionalProperties);@(SubprojectProps->'%(Identity)=%(Value)', ';')"/>
</ItemGroup>

<Target Name="BuildNativeLibs" BeforeTargets="Build" Condition="$(SupportsNativeAotComponents)">
<PropertyGroup>
<SplitSubprojectProps>@(SubprojectProps->'%(Identity)=%(Value)', ';')</SplitSubprojectProps>
</PropertyGroup>

<!-- workaround https://github.com/dotnet/msbuild/issues/2811 - Restore has to be a separate exectution with a different evaluation -->
<MSBuild Projects="@(NativeLibsProjectsToBuild)"
Properties="MSBuildRestoreSessionId=$([System.Guid]::NewGuid());$(SplitSubprojectProps)"
Targets="Restore" />

<MSBuild Projects="@(NativeLibsProjectsToBuild)"
Properties="_IsPublishing=true;$(SplitSubprojectProps)"
Targets="Build;Publish" />
</Target>
lambdageek marked this conversation as resolved.
Show resolved Hide resolved
</Project>
35 changes: 35 additions & 0 deletions src/native/managed/native-library.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Project>
<PropertyGroup>
<PublishAot>true</PublishAot>
<SelfContained>true</SelfContained>
<!-- Don't strip symbols NativeAOT's default way. We will strip and save the symbols ourselves,
the same way as eng/native/functions.cmake strip_symbols
-->
<StripSymbols>false</StripSymbols>
</PropertyGroup>

<!-- set the shared library name. this helps the native linker correctly reference this shared
library in dependents -->
<PropertyGroup>
<!-- in net9.0 we can do this, but only on mobile apple platforms, not OSX -->
<SharedLibraryInstallName>@rpath/$(MSBuildProjectName).dylib</SharedLibraryInstallName>
</PropertyGroup>
<ItemGroup Condition="'$(TargetsOSX)' == 'true'">
<LinkerArg Include="-Wl,-install_name,@rpath/$(MSBuildProjectName).dylib" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsUnix)' == 'true' and ! ('$(TargetsAppleMobile)' == 'true' or '$(TargetsOSX)' == 'true')">
<!-- If there is no soname, ld on Linux and some other Unixes will embed the full (build-time!)
path to this shared library into any binary that links against it. We don't want that. -->
<LinkerArg Include="-Wl,-soname=$(MSBuildProjectName).so" />
</ItemGroup>

<PropertyGroup>
<!-- if IsRuntimeComponent is true, we will put the native library into the specified locations under `artifacts/bin/$(RuntimeFlavor)/os.arch.config/` -->
<IsRuntimeComponent Condition="'$(IsRuntimeComponent)' == ''">true</IsRuntimeComponent>
</PropertyGroup>

<ItemGroup>
<!-- passed by compile-native.proj to set - -gcc-toolchain=$(ROOTFS_DIR)/usr -->
<CustomLinkerArg Condition="'$(CustomLinkerArgToolchainArg)' != ''" Include="$(CustomLinkerArgToolchainArg)" />
</ItemGroup>
</Project>
107 changes: 107 additions & 0 deletions src/native/managed/native-library.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<Project>

<!-- strip the library the same way as the cmake build for coreclr does it:
- on mac, leave a .dylib.dwarf file next to the library.
- on linux leave a .so.dbg file next to to the library
-->
<Target Name="StripLibraryLikeCoreCLRSetupPaths"
DependsOnTargets="CopyNativeBinary"
Condition="'$(IsRuntimeComponent)' == 'true' and '$(TargetsWindows)' != 'true'">
<PropertyGroup>
<StrippedOutputPath>$(OutputPath)stripped\</StrippedOutputPath>
<StripSourceFile>$(StrippedOutputPath)$(TargetName)$(NativeBinaryExt)</StripSourceFile>
<StrippedExt Condition="'$(StrippedExt)' == '' and ('$(TargetsOSX)' == 'true' or '$(TargetsAppleMobile)' == 'true')">.dylib.dwarf</StrippedExt>
<StrippedExt Condition="'$(TargetsUnix)' == 'true' and '$(StrippedExt)' == ''">.so.dbg</StrippedExt>
<StripDestinationFile>$(StrippedOutputPath)$(TargetName)$(StrippedExt)</StripDestinationFile>
</PropertyGroup>
</Target>

<!--
Hack: temporarily turn on StripSymbols whlie SetupOSSpecificProps runs, then turn it off
again before LinkNative runs. The problem is that SetupOSSpecificProps only probes for
$(ObjCopyName) and $(ObjCopyNameAlternative) if symbol stripping is turned on. But we don't
want LinkNative to actually do any stripping since we have our own way that we'd like it to
work.
-->
<Target Name="TempStripSymbolsOn"
BeforeTargets="SetupOSSpecificProps">
<PropertyGroup>
<StripSymbols>true</StripSymbols>
</PropertyGroup>
</Target>

<Target Name="TempStripSymbolsOff"
AfterTargets="SetupOSSpecificProps"
BeforeTargets="LinkNative">
<PropertyGroup>
<StripSymbols>false</StripSymbols>
</PropertyGroup>
</Target>

<Target Name="StripLibraryLikeCoreCLRBuild"
DependsOnTargets="SetupOSSpecificProps;CopyNativeBinary;StripLibraryLikeCoreCLRSetupPaths"
Condition="'$(IsRuntimeComponent)' == 'true' and '$(TargetsWindows)' != 'true'"
Inputs="$(PublishDir)$(TargetName)$(NativeBinaryExt)"
Outputs="$(StripSourceFile);$(StripDestinationFile)">
<Error Text="Do not set StripSymbols to true - runtime components stripping is controlled by native-library.targets" Condition="'$(StripSymbols)' == 'true'" />

<Message Importance="Normal" Text="Stripping $(PublishDir)$(TargetName)$(NativeBinaryExt) into $(StripSourceFile) and $(StripDestinationFile)" />

<!-- copy from the published/ subfolder to the stripped/ subfolder -->
<Copy SourceFiles="$(PublishDir)$(TargetName)$(NativeBinaryExt)"
DestinationFolder="$(StrippedOutputPath)"
SkipUnchangedFiles="true" />

<PropertyGroup>
<_StripLike Condition="'$(TargetsOSX)' == 'true' or '$(TargetsAppleMobile)' == 'true'">apple</_StripLike>
<_StripLike Condition="'$(_StripLike)' == ''">gnu</_StripLike>
</PropertyGroup>

<Exec Command="dsymutil --flat $(LikeCoreCLRDSymUtilMinimizeOpt) $(StripSourceFile)" Condition="'$(_StripLike)' == 'apple'"/> <!-- produces the .dylib.dwarf file -->
<Exec Command="strip -no_code_signature_warning -S $(StripSourceFile)" Condition="'$(_StripLike)' == 'apple'"/>
<!-- runtime build runs "codesign -f -s - libWhatever.dylib" in release configurations -->
<Exec Command="codesign -f -s - $(StripSourceFile)" Condition="'$(RuntimeConfiguration)' == 'Release' and '$(_StripLike)' == 'apple'" />

<Exec Command="$(ObjCopyName) --only-keep-debug $(StripSourceFile) $(StripDestinationFile)" Condition="'$(_StripLike)' == 'gnu'"/>
<Exec Command="$(ObjCopyName) --strip-debug --strip-unneeded $(StripSourceFile)" Condition="'$(_StripLike)' == 'gnu'"/>
<Exec Command="$(ObjCopyName) --add-gnu-debuglink=$(StripDestinationFile) $(StripSourceFile)" Condition="'$(_StripLike)' == 'gnu'"/>
</Target>

<Target Name="InstallRuntimeComponentToFinalDest"
AfterTargets="CopyNativeBinary"
DependsOnTargets="CopyNativeBinary;StripLibraryLikeCoreCLRBuild" Condition="'$(IsRuntimeComponent)' == 'true'">
<Error Text="Set at least one @InstallRuntimeComponentDest item" Condition="@(InstallRuntimeComponentDest->Count()) == 0" />

<PropertyGroup>
<!-- FIXME: this is the same as CoreCLRToolPath - but that doesn't seem like a good name -->
<FinalRuntimeComponentDestinationBase>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', '$(RuntimeFlavor.ToLower())', '$(TargetOS).$(TargetArchitecture).$(RuntimeConfiguration)'))</FinalRuntimeComponentDestinationBase>
</PropertyGroup>

<ItemGroup>
<_NormalizedInstallRuntimeComponentDest Include="$([MSBuild]::NormalizeDirectory('$(FinalRuntimeComponentDestinationBase)', '%(InstallRuntimeComponentDest.Identity)'))" />
</ItemGroup>

<ItemGroup Condition="'$(TargetsWindows)' != 'true'">
<CopyFinalFiles Include="$(StripSourceFile)" />
<CopyFinalFiles Include="$(StripDestinationFile)" />
</ItemGroup>

<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
<CopyFinalFiles Include="$(PublishDir)$(TargetName)$(NativeBinaryExt)" />
<CopyFinalFilesPDB Include="$(PublishDir)$(TargetName).pdb" />
</ItemGroup>

<Message Importance="Normal" Text="Installing @(CopyFinalFiles) into %(_NormalizedInstallRuntimeComponentDest.Identity)"/>
<Message Importance="Normal" Text="Installing @(CopyFinalFilesPDB) into %(_NormalizedInstallRuntimeComponentDest.Identity)PDB\" Condition="'$(TargetsWindows)' == 'true'"/>

<Copy SourceFiles="@(CopyFinalFiles)"
DestinationFolder="%(_NormalizedInstallRuntimeComponentDest.Identity)"
SkipUnchangedFiles="true"/>
<Copy SourceFiles="@(CopyFinalFilesPDB)"
DestinationFolder="%(_NormalizedInstallRuntimeComponentDest.Identity)PDB\"
SkipUnchangedFiles="true"
Condition="'$(TargetsWindows)' == 'true'"/>
</Target>


</Project>