diff options
author | Toni Solarin-Sodara <toni.edward@outlook.com> | 2018-01-03 00:28:06 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2018-01-03 00:28:06 +0300 |
commit | d5a016638e10051bc0847fe5214a3c4ccd7ae50e (patch) | |
tree | 6f59e798046ec9f03ba515dd51254cb6aa6708e6 /src | |
parent | a60adb8cdab4b496a6310e32d64880f4a1aaf2d0 (diff) |
Automatic generation of method export file for shared libraries (#5154)
Diffstat (limited to 'src')
7 files changed, 102 insertions, 18 deletions
diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.Unix.props b/src/BuildIntegration/Microsoft.NETCore.Native.Unix.props index 17f6d2e46..4c72de1d8 100644 --- a/src/BuildIntegration/Microsoft.NETCore.Native.Unix.props +++ b/src/BuildIntegration/Microsoft.NETCore.Native.Unix.props @@ -77,7 +77,8 @@ See the LICENSE file in the project root for more information. <LinkerArg Include="-luuid" Condition="'$(TargetOS)' != 'OSX'" /> <LinkerArg Include="-lrt" Condition="'$(TargetOS)' != 'OSX'" /> <LinkerArg Include="-licucore" Condition="'$(TargetOS)' == 'OSX'" /> - <LinkerArg Include="-shared" Condition="'$(NativeLib)' == 'Shared'" /> + <LinkerArg Include="-dynamiclib" Condition="'$(TargetOS)' == 'OSX' and '$(NativeLib)' == 'Shared'" /> + <LinkerArg Include="-shared" Condition="'$(TargetOS)' != 'OSX' and '$(NativeLib)' == 'Shared'" /> </ItemGroup> </Target> </Project> diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props b/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props index 2214b3423..9949a24ec 100644 --- a/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props +++ b/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props @@ -61,7 +61,6 @@ See the LICENSE file in the project root for more information. <ItemGroup> <LinkerArg Condition="$(NativeLib) == 'Shared'" Include="/DLL" /> - <LinkerArg Condition="$(DefFile) != ''" Include="/DEF:$(DefFile)" /> <LinkerArg Include="@(NativeLibrary)" /> <LinkerArg Include="@(AdditionalNativeLibrary)" /> <LinkerArg Include="/NOLOGO /DEBUG /MANIFEST:NO" /> diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.targets b/src/BuildIntegration/Microsoft.NETCore.Native.targets index 03b5366cb..4a334e624 100644 --- a/src/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/BuildIntegration/Microsoft.NETCore.Native.targets @@ -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> + <ExportsFileExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' == 'Windows_NT' and '$(NativeLib)' == 'Shared'">.def</ExportsFileExt> + <ExportsFileExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' != 'Windows_NT' and '$(NativeLib)' == 'Shared'">.exports</ExportsFileExt> + <NativeObject>$(NativeIntermediateOutputPath)$(TargetName)$(NativeObjectExt)</NativeObject> <NativeBinary>$(NativeOutputPath)$(TargetName)$(NativeBinaryExt)</NativeBinary> + <ExportsFile Condition="$(NativeLib) == 'Shared' and $(ExportsFile) == ''">$(NativeIntermediateOutputPath)$(TargetName)$(ExportsFileExt)</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> diff --git a/src/ILCompiler.Compiler/src/Compiler/ExportedMethodsRootProvider.cs b/src/ILCompiler.Compiler/src/Compiler/ExportedMethodsRootProvider.cs index 11fa9c01f..fcedbe255 100644 --- a/src/ILCompiler.Compiler/src/Compiler/ExportedMethodsRootProvider.cs +++ b/src/ILCompiler.Compiler/src/Compiler/ExportedMethodsRootProvider.cs @@ -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 @@ -18,27 +21,37 @@ namespace ILCompiler _module = module; } - public void AddCompilationRoots(IRootingServiceProvider rootProvider) + public IEnumerable<EcmaMethod> ExportedMethods { - foreach (var type in _module.GetAllTypes()) + get { - foreach (var method in type.GetMethods()) + foreach (var type in _module.GetAllTypes()) { - EcmaMethod ecmaMethod = (EcmaMethod)method; - - if (ecmaMethod.IsRuntimeExport) + foreach (var method in type.GetMethods()) { - string runtimeExportName = ecmaMethod.GetRuntimeExportName(); - if (runtimeExportName != null) - rootProvider.AddCompilationRoot(method, "Runtime export", runtimeExportName); + EcmaMethod ecmaMethod = (EcmaMethod)method; + if (ecmaMethod.IsRuntimeExport || ecmaMethod.IsNativeCallable) + yield return ecmaMethod; } + } + } + } - if (ecmaMethod.IsNativeCallable) - { - string nativeCallableExportName = ecmaMethod.GetNativeCallableExportName(); - if (nativeCallableExportName != null) - rootProvider.AddCompilationRoot(method, "Native callable", nativeCallableExportName); - } + public void AddCompilationRoots(IRootingServiceProvider rootProvider) + { + foreach (var ecmaMethod in ExportedMethods) + { + if (ecmaMethod.IsRuntimeExport) + { + string runtimeExportName = ecmaMethod.GetRuntimeExportName(); + if (runtimeExportName != null) + rootProvider.AddCompilationRoot((MethodDesc)ecmaMethod, "Runtime export", runtimeExportName); + } + else if (ecmaMethod.IsNativeCallable) + { + string nativeCallableExportName = ecmaMethod.GetNativeCallableExportName(); + if (nativeCallableExportName != null) + rootProvider.AddCompilationRoot((MethodDesc)ecmaMethod, "Native callable", nativeCallableExportName); } } } diff --git a/src/ILCompiler.Compiler/src/Compiler/ExportsFileWriter.cs b/src/ILCompiler.Compiler/src/Compiler/ExportsFileWriter.cs new file mode 100644 index 000000000..9935a4dbe --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/ExportsFileWriter.cs @@ -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()}"); + } + } + } + } +}
\ No newline at end of file diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj index 7df0a8e4d..a29a5cd10 100644 --- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj +++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj @@ -332,6 +332,7 @@ <Compile Include="Compiler\NativeLibraryInitializerRootProvider.cs" /> <Compile Include="Compiler\NodeMangler.cs" /> <Compile Include="Compiler\ObjectDumper.cs" /> + <Compile Include="Compiler\ExportsFileWriter.cs" /> <Compile Include="Compiler\PrecomputedMetadataManager.cs" /> <Compile Include="Compiler\ReadyToRun.cs" /> <Compile Include="Compiler\RyuJitCompilation.cs" /> diff --git a/src/ILCompiler/src/Program.cs b/src/ILCompiler/src/Program.cs index 0599756d5..e869f7540 100644 --- a/src/ILCompiler/src/Program.cs +++ b/src/ILCompiler/src/Program.cs @@ -40,6 +40,7 @@ namespace ILCompiler private string _systemModuleName = "System.Private.CoreLib"; private bool _multiFile; private bool _nativeLib; + private string _exportsFile; private bool _useSharedGenerics; private bool _useScanner; private bool _noScanner; @@ -134,6 +135,7 @@ namespace ILCompiler syntax.DefineOption("cpp", ref _isCppCodegen, "Compile for C++ code-generation"); syntax.DefineOption("wasm", ref _isWasmCodegen, "Compile for WebAssembly code-generation"); syntax.DefineOption("nativelib", ref _nativeLib, "Compile as static or shared library"); + syntax.DefineOption("exportsfile", ref _exportsFile, "File to write exported method definitions"); syntax.DefineOption("dgmllog", ref _dgmlLogFileName, "Save result of dependency analysis as DGML"); syntax.DefineOption("fulllog", ref _generateFullDgmlLog, "Save detailed log of dependency analysis"); syntax.DefineOption("scandgmllog", ref _scanDgmlLogFileName, "Save result of scanner dependency analysis as DGML"); @@ -446,6 +448,17 @@ namespace ILCompiler ObjectDumper dumper = _mapFileName != null ? new ObjectDumper(_mapFileName) : null; CompilationResults compilationResults = compilation.Compile(_outputFilePath, dumper); + if (_exportsFile != null) + { + ExportsFileWriter defFileWriter = new ExportsFileWriter(typeSystemContext, _exportsFile); + foreach (var compilationRoot in compilationRoots) + { + if (compilationRoot is ExportedMethodsRootProvider provider) + defFileWriter.AddExportedMethods(provider.ExportedMethods); + } + + defFileWriter.EmitExportedMethods(); + } if (_dgmlLogFileName != null) compilationResults.WriteDependencyLog(_dgmlLogFileName); |