Improve consumption of NativeAOT linker flags (#18835)

Fixes #18819
This commit is contained in:
Filip Navara 2023-08-28 12:17:09 +02:00 коммит произвёл GitHub
Родитель cd77ecba37
Коммит 88b009288d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 5 добавлений и 70 удалений

Просмотреть файл

@ -1285,77 +1285,12 @@
<TrimmerRootAssembly Include="@(_TrimmerRootAssemblyButOnlyIntermediateAssembly->'%(Filename)')" /> <TrimmerRootAssembly Include="@(_TrimmerRootAssemblyButOnlyIntermediateAssembly->'%(Filename)')" />
</ItemGroup> </ItemGroup>
<!--
Collect all the native linker args ILC would have used and use
them ourselves when we link natively.
Unfortunately there's a major difference between LinkerArgs (as
used by ILC) and our _CustomLinkerFlags: ILC splits on space in
LinkerArg, while we quote (when necessary) the items in
_CustomLinkerFlags.
Example:
<LinkerArg Include="-framework UIKit" />
ILC will pass that as two separate arguments to the native
compiler
<_CustomLinkFlags Include="-framework UIKit" />
We'll pass that as a single argument ('-framework UIKit')
to the native compiler (which the native compiler doesn't
like)
So we need to convert the list of space-separated items in
LinkerArg to space-preserved items in _CustomLinkFlags.
How to do this in MSBuild is somewhat non-obvious: first we
convert the LinkerArg item group to a property where every item is
separated by a semi-colon, and where we've also replaced spaces by
semi-colons. This means we have a property where every flag we
want is separated by a semi-colon. Then we split on the property
string on a semi-colon and add those items to the _CustomLinkFlags
item group.
Note: this means ILC doesn't support linker flags with spaces in them.
Additionally, the LinkerArg item group are actually passed to the
native compiler by the NativeAOT build tasks, not the native
linker. This means they might contain wrapped linker arguments:
'-Wl,...', which the compiler understands, but not the linker.
Thus we need to unwrap the (compiler) arguments in LinkerArgs to
be actual linker arguments. Also note that there can be multiple
linker arguments passed using a single compiler argument, and
those are separated by a comma: "-Wl,-linkerarg1,-linkerarg2", so
we need to split those into multiple linker arguments as well. And
to make things even more complicated, there may be quotes as well:
<LinkerArg>'-Wl,-linkerarg1,-linkerarg2'</LinkerArg>.
-->
<PropertyGroup>
<_LinkerArgsSplitBySemiColon>@(LinkerArg->Replace(' ',';'))</_LinkerArgsSplitBySemiColon>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<_AllLinkerArgs Include="$(_LinkerArgsSplitBySemiColon.Split(';'))" /> <!-- Collect extra native linker flags ILC would have used -->
<_LinkerArgsWhichAreReallyCompilerArgs Include="@(_AllLinkerArgs)" Condition="$([System.String]::new('%(Identity)').StartsWith('-Wl,'))"> <_CustomLinkFlags Include="@(NativeLibrary)" />
<TransformedArgument>$([System.String]::new('%(Identity)').Substring(4))</TransformedArgument> <_CustomLinkFlags Include="@(NativeSystemLibrary->'-l%(Identity)')" />
</_LinkerArgsWhichAreReallyCompilerArgs> <_CustomLinkFlags Include="@(NativeFramework->'-Wl,-framework,%(Identity)')" />
<!-- Handle quoted arguments: <LinkerArg>'-Wl,-linkerarg'</LinkerArg> --> <_CustomLinkFlags Include="@(ExtraLinkerArg->'-Wl,%(Identity)')" />
<_LinkerArgsWhichAreReallyCompilerArgs Include="@(_AllLinkerArgs)" Condition="$([System.String]::new('%(Identity)').StartsWith('%27-Wl,')) And $([System.String]::new('%(Identity)').EndsWith('%27'))">
<TransformedArgument>$([System.String]::new('%(Identity)').Substring(5, $([MSBuild]::Subtract($([System.String]::new('%(Identity)').Length), 6))))</TransformedArgument>
</_LinkerArgsWhichAreReallyCompilerArgs>
<_CompilerArgsTransformedToLinkerArgs Include="@(_LinkerArgsWhichAreReallyCompilerArgs->'%(TransformedArgument)')" />
</ItemGroup>
<PropertyGroup>
<_CompilerArgsTransformedToLinkerArgsSplitByComma>@(_CompilerArgsTransformedToLinkerArgs->Replace(',',';'))</_CompilerArgsTransformedToLinkerArgsSplitByComma>
</PropertyGroup>
<ItemGroup>
<_AllLinkerArgs Remove="@(_LinkerArgsWhichAreReallyCompilerArgs)" />
<_AllLinkerArgs Include="$(_CompilerArgsTransformedToLinkerArgsSplitByComma.Split(';'))" />
<_CustomLinkFlags Include="@(_AllLinkerArgs)" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>