-
Notifications
You must be signed in to change notification settings - Fork 510
Automatic generation of method export file for shared libraries #5154
Changes from 20 commits
9f615d8
0d17711
655be26
ea9e84c
cb11f1f
7443e76
f8106e1
0fad626
996bea2
b5050e6
99435e1
2dbde95
50b0686
7fc2d0d
3bad6d1
0c00f1a
4f80359
b46e2c0
4b7424b
7f7e1d7
9d581df
a062443
f085583
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ See the LICENSE file in the project root for more information. | |
<NativeObjectExt Condition="'$(TargetOS)' == 'Windows_NT'">.obj</NativeObjectExt> | ||
<NativeObjectExt Condition="'$(TargetOS)' != 'Windows_NT'">.o</NativeObjectExt> | ||
<NativeObjectExt Condition="'$(NativeCodeGen)' == 'wasm'">.bc</NativeObjectExt> | ||
|
||
<LibFileExt Condition="'$(TargetOS)' == 'Windows_NT'">.lib</LibFileExt> | ||
<LibFileExt Condition="'$(TargetOS)' != 'Windows_NT'">.a</LibFileExt> | ||
|
||
|
@@ -48,8 +49,12 @@ See the LICENSE file in the project root for more information. | |
<NativeBinaryExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' != 'Windows_NT' and $(NativeLib) == 'Static'">.a</NativeBinaryExt> | ||
<NativeBinaryExt Condition="'$(NativeCodeGen)' == 'wasm'">.html</NativeBinaryExt> | ||
|
||
<ExportsFiletExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' == 'Windows_NT' and '$(NativeLib)' == 'Shared'">.def</ExportsFiletExt> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: typo: Filet -> File |
||
<ExportsFiletExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' != 'Windows_NT' and '$(NativeLib)' == 'Shared'">.exports</ExportsFiletExt> | ||
|
||
<NativeObject>$(NativeIntermediateOutputPath)$(TargetName)$(NativeObjectExt)</NativeObject> | ||
<NativeBinary>$(NativeOutputPath)$(TargetName)$(NativeBinaryExt)</NativeBinary> | ||
<ExportsFile Condition="$(NativeLib) == 'Shared' and $(ExportsFile) == ''">$(NativeIntermediateOutputPath)$(TargetName)$(ExportsFiletExt)</ExportsFile> | ||
|
||
<IlcCompileOutput Condition="$(NativeCodeGen) == ''">$(NativeObject)</IlcCompileOutput> | ||
<IlcCompileOutput Condition="$(NativeCodeGen) == 'cpp'">$(NativeIntermediateOutputPath)$(TargetName).cpp</IlcCompileOutput> | ||
|
@@ -151,7 +156,8 @@ See the LICENSE file in the project root for more information. | |
<IlcArg Condition="$(DebugSymbols) == 'true'" Include="-g" /> | ||
<IlcArg Condition="$(IlcGenerateMapFile) == 'true'" Include="--map:$(NativeIntermediateOutputPath)%(ManagedBinary.Filename).map.xml" /> | ||
<IlcArg Condition="$(RdXmlFile) != ''" Include="--rdxml:$(RdXmlFile)" /> | ||
<IlcArg Condition="$(OutputType) == 'Library' and $(NativeLib) != ''" Include="--nativelib" /> | ||
<IlcArg Condition="$(OutputType) == 'Library' and $(NativeLib) != ''" Include="--nativelib" /> | ||
<IlcArg Condition="$(ExportsFile) != ''" Include="--exportsfile:$(ExportsFile)" /> | ||
<ILcArg Condition="'$(Platform)' == 'wasm'" Include="--wasm" /> | ||
</ItemGroup> | ||
|
||
|
@@ -193,6 +199,8 @@ See the LICENSE file in the project root for more information. | |
<CustomLinkerArg Include="$(NativeObject)" /> | ||
<CustomLinkerArg Include="-o $(NativeBinary)" Condition="'$(OS)' != 'Windows_NT'" /> | ||
<CustomLinkerArg Include="/OUT:$(NativeBinary)" Condition="'$(OS)' == 'Windows_NT'" /> | ||
<CustomLinkerArg Include="/DEF:$(ExportsFile)" Condition="'$(OS)' == 'Windows_NT' and $(ExportsFile) != ''" /> | ||
<CustomLinkerArg Include="-exported_symbols_list $(ExportsFile)" Condition="'$(OS)' != 'Windows_NT' and $(ExportsFile) != ''" /> | ||
<CustomLinkerArg Include="@(LinkerArg)" /> | ||
</ItemGroup> | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,9 @@ | |
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System.Collections.Generic; | ||
|
||
using Internal.TypeSystem; | ||
using Internal.TypeSystem.Ecma; | ||
|
||
namespace ILCompiler | ||
|
@@ -12,12 +15,36 @@ namespace ILCompiler | |
public class ExportedMethodsRootProvider : ICompilationRootProvider | ||
{ | ||
private EcmaModule _module; | ||
private List<EcmaMethod> _methods; | ||
|
||
public ExportedMethodsRootProvider(EcmaModule module) | ||
{ | ||
_module = module; | ||
} | ||
|
||
public IEnumerable<EcmaMethod> ExportedMethods | ||
{ | ||
get | ||
{ | ||
if (_methods != null) | ||
return _methods; | ||
|
||
_methods = new List<EcmaMethod>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: It is a better pattern to create the list in a local, and only assign it to the field once it is done. (Slightly better performance and reliability.) |
||
|
||
foreach (var type in _module.GetAllTypes()) | ||
{ | ||
foreach (var method in type.GetMethods()) | ||
{ | ||
EcmaMethod ecmaMethod = (EcmaMethod)method; | ||
if (ecmaMethod.IsNativeCallable) | ||
_methods.Add(ecmaMethod); | ||
} | ||
} | ||
|
||
return _methods; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you factor this class in a way that we can't get different results depending on when |
||
} | ||
} | ||
|
||
public void AddCompilationRoots(IRootingServiceProvider rootProvider) | ||
{ | ||
foreach (var type in _module.GetAllTypes()) | ||
|
@@ -32,15 +59,15 @@ public void AddCompilationRoots(IRootingServiceProvider rootProvider) | |
if (runtimeExportName != null) | ||
rootProvider.AddCompilationRoot(method, "Runtime export", runtimeExportName); | ||
} | ||
|
||
if (ecmaMethod.IsNativeCallable) | ||
{ | ||
string nativeCallableExportName = ecmaMethod.GetNativeCallableExportName(); | ||
if (nativeCallableExportName != null) | ||
rootProvider.AddCompilationRoot(method, "Native callable", nativeCallableExportName); | ||
} | ||
} | ||
} | ||
|
||
foreach (var ecmaMethod in ExportedMethods) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not think we need to be differentiating between NativeCallable and RuntimeExports here. They can be treated the same. |
||
{ | ||
string nativeCallableExportName = ecmaMethod.GetNativeCallableExportName(); | ||
if (nativeCallableExportName != null) | ||
rootProvider.AddCompilationRoot((MethodDesc)ecmaMethod, "Native callable", nativeCallableExportName); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
|
||
using Internal.TypeSystem; | ||
using Internal.TypeSystem.Ecma; | ||
|
||
namespace ILCompiler | ||
{ | ||
public class ExportsFileWriter | ||
{ | ||
private string _exportsFile; | ||
private List<EcmaMethod> _methods; | ||
private TypeSystemContext _context; | ||
|
||
public ExportsFileWriter(TypeSystemContext context, string exportsFile) | ||
{ | ||
_exportsFile = exportsFile; | ||
_context = context; | ||
_methods = new List<EcmaMethod>(); | ||
} | ||
|
||
public void AddExportedMethods(IEnumerable<EcmaMethod> methods) | ||
=> _methods.AddRange(methods.Where(m => m.Module != _context.SystemModule)); | ||
|
||
public void EmitExportedMethods() | ||
{ | ||
FileStream fileStream = new FileStream(_exportsFile, FileMode.Create); | ||
using (StreamWriter streamWriter = new StreamWriter(fileStream)) | ||
{ | ||
if (_context.Target.IsWindows) | ||
{ | ||
streamWriter.WriteLine("EXPORTS"); | ||
foreach (var method in _methods) | ||
streamWriter.WriteLine($" {method.GetNativeCallableExportName()}"); | ||
} | ||
else | ||
{ | ||
foreach (var method in _methods) | ||
streamWriter.WriteLine($"_{method.GetNativeCallableExportName()}"); | ||
} | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I though that
-shared
works on OSX too. Just for my education - why did you change this to-dynamiclib
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah I know it works. I guess I was just trying to be as platform accurate as possible, most Apple docs use
-dynamiclib
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, that's fine.