Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Automatic generation of method export file for shared libraries #5154

Merged
merged 23 commits into from
Jan 2, 2018
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9f615d8
add ExportedDefinitionsWriter (#4986)
tonerdo Dec 20, 2017
0d17711
add automatic location of auto-generated definition file to build scr…
tonerdo Dec 20, 2017
655be26
add support for generating OSX symbol export files (#4986)
tonerdo Dec 24, 2017
ea9e84c
rename ExportedDefinitionsWriter to ExportsWriter (#4986)
tonerdo Dec 24, 2017
cb11f1f
update buildscripts for OSX exports file location (#4986)
tonerdo Dec 24, 2017
7443e76
rename ExportsWriter to ExportedMethodsWriter (#4986)
tonerdo Dec 25, 2017
f8106e1
restructure ExportedMethodsWriter class (#4986)
tonerdo Dec 25, 2017
0fad626
remove exporting of internal nativecallable methods (#4986)
tonerdo Dec 25, 2017
996bea2
only generate exports file during native library build (#4986)
tonerdo Dec 25, 2017
b5050e6
add generation and location of version-script on linux (#4986)
tonerdo Dec 26, 2017
99435e1
make linux version script generation the default case (#4986)
tonerdo Dec 26, 2017
2dbde95
move exported methods emission to ExportedMethodsRootProvider class (…
tonerdo Dec 26, 2017
50b0686
set ExportsFile variable if not user defined and it's a shared lib bu…
tonerdo Dec 27, 2017
7fc2d0d
make optimizations to exports file emission code (#4986)
tonerdo Dec 27, 2017
3bad6d1
remove redundant info from exported definition files (#4986)
tonerdo Dec 27, 2017
0c00f1a
ensure definition file is overwritten (#4986)
tonerdo Dec 27, 2017
4f80359
add DefFileWriter class (#4986)
tonerdo Dec 27, 2017
b46e2c0
fix wasm build error caused by merge (#4986)
tonerdo Dec 28, 2017
4b7424b
rename DefFileWriter to ExportsFileWriter (#4986)
tonerdo Dec 28, 2017
7f7e1d7
restructure ExportedMethodsRootProvider class (#4986)
tonerdo Dec 31, 2017
9d581df
refactor ExportedMethodsRootProvider class (#4986)
tonerdo Dec 31, 2017
a062443
improve performance of ExportedMethods property (#4986)
tonerdo Dec 31, 2017
f085583
fix typo (#4986)
tonerdo Jan 2, 2018
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
3 changes: 2 additions & 1 deletion src/BuildIntegration/Microsoft.NETCore.Native.Unix.props
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,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'" />
Copy link
Member

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?

Copy link
Contributor Author

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that's fine.

<LinkerArg Include="-shared" Condition="'$(TargetOS)' != 'OSX' and '$(NativeLib)' == 'Shared'" />
</ItemGroup>
</Target>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
10 changes: 9 additions & 1 deletion src/BuildIntegration/Microsoft.NETCore.Native.targets
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -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>
Copy link
Member

Choose a reason for hiding this comment

The 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>
Expand Down Expand Up @@ -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>

Expand Down Expand Up @@ -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>

Expand Down
43 changes: 28 additions & 15 deletions src/ILCompiler.Compiler/src/Compiler/ExportedMethodsRootProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -18,27 +21,37 @@ public ExportedMethodsRootProvider(EcmaModule module)
_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);
}
}
}
Expand Down
49 changes: 49 additions & 0 deletions src/ILCompiler.Compiler/src/Compiler/ExportsFileWriter.cs
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()}");
}
}
}
}
}
1 change: 1 addition & 0 deletions src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
13 changes: 13 additions & 0 deletions src/ILCompiler/src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ internal class Program
private string _systemModuleName = "System.Private.CoreLib";
private bool _multiFile;
private bool _nativeLib;
private string _exportsFile;
private bool _useSharedGenerics;
private bool _useScanner;
private bool _noScanner;
Expand Down Expand Up @@ -134,6 +135,7 @@ private ArgumentSyntax ParseCommandLine(string[] args)
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");
Expand Down Expand Up @@ -446,6 +448,17 @@ private int Run(string[] args)
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);
Expand Down