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

Allow creating static or shared native library #4718

Merged
merged 34 commits into from
Nov 21, 2017
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b7a5b0f
add bootstrapper for native libraries (#1285)
tonerdo Jul 30, 2017
e0752ec
overwrite main method when building library (#1285)
tonerdo Aug 4, 2017
a915ad9
update buildscripts to build shared library for non-windows (#1285)
tonerdo Aug 4, 2017
155a9ca
add stub for native library startup method (#1285)
tonerdo Aug 5, 2017
65b2b25
initialize runtime at start of reverse PInvoke, unix dlopen successfu…
tonerdo Aug 5, 2017
80d721b
don't run library initializers for Multi module build (#1285)
tonerdo Aug 8, 2017
79d3322
update Windows buildscripts, LoadLibrary successful (#1285)
tonerdo Aug 11, 2017
27ef3aa
tidy up native binary extension conditions (#1285)
tonerdo Sep 5, 2017
f5f71f4
update buildscript to build unix static library (#1285)
tonerdo Sep 5, 2017
0435d64
update buildscript to build Windows static library (#1285)
tonerdo Sep 15, 2017
c13edf6
fix rebase related error (#1285)
tonerdo Sep 15, 2017
c82a602
create and use NativeLibraryInitializerRootProvider (#1285)
tonerdo Oct 23, 2017
3ba221b
use "shared" linker arg on unix to build shared library (#1285)
tonerdo Oct 23, 2017
9ae9eb7
use system module to initialize NativeLibraryInitializerRootProvider …
tonerdo Oct 23, 2017
55495ee
move NativeLibraryStartupMethod ClassCode and CompareToImpl to separa…
tonerdo Oct 23, 2017
8b3f216
revert redundant changes to LibraryRootProvider (#1285)
tonerdo Oct 23, 2017
a915c73
revert redundant changes to Windows build script (#1285)
tonerdo Oct 23, 2017
bd42322
move call to InitializeRuntime to RhpReversePInvokeAttachOrTrapThread…
tonerdo Oct 24, 2017
6738e30
initialize runtime just before initializing the thread (#1285)
tonerdo Oct 24, 2017
6575a65
move InitializeRuntime call to within TSF_Attached state check (#1285)
tonerdo Oct 26, 2017
9d7df3d
use pointer to reference InitializeRuntime method (#1285)
tonerdo Oct 28, 2017
641ebd8
use Dllmain to set InitializeRuntime function pointer on Windows (#1285)
tonerdo Nov 8, 2017
079a369
use static struct constructor to set InitializeRuntime pointer (#1285)
tonerdo Nov 11, 2017
fd7b073
update method signature of native library startup method (#1285)
tonerdo Nov 11, 2017
0558e82
do not include main function in native library build (#1285)
tonerdo Nov 11, 2017
32da10e
move runtime initialization check to thread init (#1285)
tonerdo Nov 11, 2017
4a91edf
use Thread* to determine whether to initialize runtime (#1285)
tonerdo Nov 11, 2017
0c3b863
update code to match overall style of the CoreRT runtime (#1285)
tonerdo Nov 13, 2017
474dd62
update code style (#1285)
tonerdo Nov 21, 2017
426693e
handle race conditions when initializing runtime (#1285)
tonerdo Nov 21, 2017
928f04d
fix Windows build (#1285)
tonerdo Nov 21, 2017
727bcd1
some code improvements (#1285)
tonerdo Nov 21, 2017
7a2d8a0
explicitly use spaces (#1285)
tonerdo Nov 21, 2017
2c3b68c
remove unneeded usings (#1285)
tonerdo Nov 21, 2017
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: 3 additions & 1 deletion src/BuildIntegration/Microsoft.NETCore.Native.Unix.props
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ See the LICENSE file in the project root for more information.

<ItemGroup>
<NativeLibrary Condition="'$(IlcMultiModule)' == 'true' and $(NativeCodeGen) == ''" Include="$(SharedLibrary)" />
<NativeLibrary Condition="$(NativeCodeGen) == ''" Include="$(IlcPath)/sdk/libbootstrapper.a" />
<NativeLibrary Condition="$(NativeCodeGen) == '' and $(NativeLib) == ''" Include="$(IlcPath)/sdk/libbootstrapper.a" />
<NativeLibrary Condition="$(NativeCodeGen) == '' and $(NativeLib) != ''" Include="$(IlcPath)/sdk/libbootstrapperdll.a" />
<NativeLibrary Condition="$(NativeCodeGen) == ''" Include="$(IlcPath)/sdk/libRuntime.a" />
<NativeLibrary Condition="$(NativeCodeGen) == 'cpp'" Include="$(IlcPath)/sdk/libbootstrappercpp.a" />
<NativeLibrary Condition="$(NativeCodeGen) == 'cpp'" Include="$(IlcPath)/sdk/libPortableRuntime.a" />
Expand All @@ -58,5 +59,6 @@ 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'" />
</ItemGroup>
</Project>
5 changes: 4 additions & 1 deletion src/BuildIntegration/Microsoft.NETCore.Native.Windows.props
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ See the LICENSE file in the project root for more information.
</ItemGroup>

<ItemGroup>
<NativeLibrary Condition="$(NativeCodeGen) == ''" Include="$(IlcPath)\sdk\bootstrapper.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == '' and $(NativeLib) == ''" Include="$(IlcPath)\sdk\bootstrapper.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == '' and $(NativeLib) != ''" Include="$(IlcPath)\sdk\bootstrapperdll.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == ''" Include="$(IlcPath)\sdk\Runtime.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == 'cpp'" Include="$(IlcPath)\sdk\bootstrappercpp.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == 'cpp'" Include="$(IlcPath)\sdk\PortableRuntime.lib" />
Expand All @@ -57,6 +58,8 @@ See the LICENSE file in the project root for more information.
</ItemGroup>

<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
27 changes: 21 additions & 6 deletions src/BuildIntegration/Microsoft.NETCore.Native.targets
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ See the LICENSE file in the project root for more information.

<NativeBinaryExt Condition="'$(OutputType)' == 'Exe' and '$(TargetOS)' == 'Windows_NT'">.exe</NativeBinaryExt>
<NativeBinaryExt Condition="'$(OutputType)' == 'Exe' and '$(TargetOS)' != 'Windows_NT'"></NativeBinaryExt>
<NativeBinaryExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' == 'Windows_NT'">.dll</NativeBinaryExt>
<NativeBinaryExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' == 'OSX'">.dylib</NativeBinaryExt>
<NativeBinaryExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' != 'Windows_NT' and '$(TargetOS)' != 'OSX'">.so</NativeBinaryExt>
<NativeBinaryExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' == 'Windows_NT' and $(NativeLib) == 'Shared'">.dll</NativeBinaryExt>
<NativeBinaryExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' == 'OSX' and $(NativeLib) == 'Shared'">.dylib</NativeBinaryExt>
<NativeBinaryExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' != 'Windows_NT' and '$(TargetOS)' != 'OSX' and $(NativeLib) == 'Shared'">.so</NativeBinaryExt>
<NativeBinaryExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' == 'Windows_NT' and $(NativeLib) == 'Static'">.lib</NativeBinaryExt>
<NativeBinaryExt Condition="'$(OutputType)' != 'Exe' and '$(TargetOS)' != 'Windows_NT' and $(NativeLib) == 'Static'">.a</NativeBinaryExt>
<NativeBinaryExt Condition="'$(NativeCodeGen)' == 'wasm'">.html</NativeBinaryExt>

<NativeObject>$(NativeIntermediateOutputPath)$(TargetName)$(NativeObjectExt)</NativeObject>
Expand Down Expand Up @@ -119,6 +121,7 @@ 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" />
</ItemGroup>

<MakeDir Directories="$(NativeIntermediateOutputPath)" />
Expand Down Expand Up @@ -162,10 +165,22 @@ See the LICENSE file in the project root for more information.
<CustomLinkerArg Include="@(LinkerArg)" />
</ItemGroup>

<ItemGroup>
<CustomLibArg Include="-crs $(NativeBinary)" Condition="'$(OS)' != 'Windows_NT'" />
<CustomLibArg Include="/OUT:$(NativeBinary)" Condition="'$(OS)' == 'Windows_NT'" />
<CustomLibArg Include="$(NativeObject)" />
</ItemGroup>

<MakeDir Directories="$([System.IO.Path]::GetDirectoryName($(NativeBinary)))" />
<Exec Command="$(CppLinker) @(CustomLinkerArg, ' ')" Condition="'$(OS)' != 'Windows_NT'" />
<WriteLinesToFile File="$(NativeIntermediateOutputPath)link.rsp" Lines="@(CustomLinkerArg)" Overwrite="true" Condition="'$(OS)' == 'Windows_NT'" />
<Exec Command="$(CppLinker) @&quot;$(NativeIntermediateOutputPath)link.rsp&quot;" Condition="'$(OS)' == 'Windows_NT' and '$(NativeCodeGen)' != 'wasm'" />

<Exec Command="$(CppLinker) @(CustomLinkerArg, ' ')" Condition="'$(OS)' != 'Windows_NT' and '$(NativeLib)' != 'Static'" />
<Exec Command="$(CppLibCreator) @(CustomLibArg, ' ')" Condition="'$(OS)' != 'Windows_NT' and '$(NativeLib)' == 'Static'" />

<WriteLinesToFile File="$(NativeIntermediateOutputPath)link.rsp" Lines="@(CustomLinkerArg)" Overwrite="true" Condition="'$(OS)' == 'Windows_NT' and '$(NativeLib)' != 'Static'" />
<Exec Command="$(CppLinker) @&quot;$(NativeIntermediateOutputPath)link.rsp&quot;" Condition="'$(OS)' == 'Windows_NT' and '$(NativeLib)' != 'Static' and '$(NativeCodeGen)' != 'wasm'" />
<WriteLinesToFile File="$(NativeIntermediateOutputPath)lib.rsp" Lines="@(CustomLibArg)" Overwrite="true" Condition="'$(OS)' == 'Windows_NT' and '$(NativeLib)' == 'Static'" />
<Exec Command="$(CppLibCreator) @&quot;$(NativeIntermediateOutputPath)lib.rsp&quot;" Condition="'$(OS)' == 'Windows_NT' and '$(NativeLib)' == 'Static' and '$(NativeCodeGen)' != 'wasm'" />

<Exec Command="&quot;$(EMSCRIPTEN)\emcc.bat&quot; &quot;$(NativeObject)&quot; -o &quot;$(NativeBinary)&quot; -s WASM=1" Condition="'$(NativeCodeGen)' == 'wasm' and '$(EMSCRIPTEN)' != ''" />
<Message Text="Emscripten not found, not linking WebAssembly. To enable WebAssembly linking, install Emscripten and ensure the EMSCRIPTEN environment variable points to the directory containing emcc.bat"
Condition="'$(NativeCodeGen)' == 'wasm' and '$(EMSCRIPTEN)' == ''" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// 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 Internal.TypeSystem.Ecma;
using Internal.TypeSystem;
using Internal.IL.Stubs.StartupCode;

namespace ILCompiler
{
/// <summary>
/// Provides compilation group for a native library that compiles the initialize method.
/// </summary>
public class NativeLibraryInitializerRootProvider : ICompilationRootProvider
{
/// <summary>
/// Symbolic name under which the managed initializer is exported.
/// </summary>
public const string ManagedEntryPointMethodName = "__managed__Startup";

private EcmaModule _module;
private IList<MethodDesc> _libraryInitializers;

public NativeLibraryInitializerRootProvider(EcmaModule module, IList<MethodDesc> libraryInitializers)
{
_module = module;
_libraryInitializers = libraryInitializers;
}

public void AddCompilationRoots(IRootingServiceProvider rootProvider)
{
TypeDesc owningType = _module.GetGlobalModuleType();
NativeLibraryStartupMethod nativeLibStartupCode = new NativeLibraryStartupMethod(owningType, _libraryInitializers);
rootProvider.AddCompilationRoot(nativeLibStartupCode, "Startup Code Main Method", ManagedEntryPointMethodName);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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;
using System.Collections.Generic;

using Internal.TypeSystem;

using AssemblyName = System.Reflection.AssemblyName;
Copy link
Member

Choose a reason for hiding this comment

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

Nit: unneeded using

using Debug = System.Diagnostics.Debug;

namespace Internal.IL.Stubs.StartupCode
{
partial class NativeLibraryStartupMethod
{
protected override int ClassCode => -304225482;

protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
{
// Should be a singleton
Debug.Assert(this == other);
return 0;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// 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;
using System.Collections.Generic;

using Internal.TypeSystem;

using AssemblyName = System.Reflection.AssemblyName;
Copy link
Member

Choose a reason for hiding this comment

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

Nit: unneeded using

using Debug = System.Diagnostics.Debug;

namespace Internal.IL.Stubs.StartupCode
{
/// <summary>
/// Startup code that does initialization, Main invocation
/// and shutdown of the runtime.
/// </summary>
public sealed partial class NativeLibraryStartupMethod : ILStubMethod
{
private TypeDesc _owningType;
private MethodSignature _signature;
private IList<MethodDesc> _libraryInitializers;

public NativeLibraryStartupMethod(TypeDesc owningType, IList<MethodDesc> libraryInitializers)
{
_owningType = owningType;
_libraryInitializers = libraryInitializers;
}

public override TypeSystemContext Context
{
get
{
return _owningType.Context;
}
}

public override TypeDesc OwningType
{
get
{
return _owningType;
}
}

public override string Name
{
get
{
return "NativeLibraryStartup";
}
}

public override MethodIL EmitIL()
{
ILEmitter emitter = new ILEmitter();
ILCodeStream codeStream = emitter.NewCodeStream();

// Allow the class library to run explicitly ordered class constructors first thing in start-up.
if (_libraryInitializers != null)
{
foreach (MethodDesc method in _libraryInitializers)
{
codeStream.Emit(ILOpcode.call, emitter.NewToken(method));
}
}

codeStream.Emit(ILOpcode.ret);
return emitter.Link(this);
}

public override MethodSignature Signature
{
get
{
if (_signature == null)
{
_signature = new MethodSignature(MethodSignatureFlags.Static, 0,
Context.GetWellKnownType(WellKnownType.Void),
new TypeDesc[0]);
}

return _signature;
}
}

public override bool IsNativeCallable
{
get
{
return true;
}
}
}
}
3 changes: 3 additions & 0 deletions src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@
<Compile Include="Compiler\MethodExtensions.cs" />
<Compile Include="Compiler\MultiFileCompilationModuleGroup.cs" />
<Compile Include="Compiler\NameMangler.cs" />
<Compile Include="Compiler\NativeLibraryInitializerRootProvider.cs" />
<Compile Include="Compiler\NodeMangler.cs" />
<Compile Include="Compiler\ObjectDumper.cs" />
<Compile Include="Compiler\PrecomputedMetadataManager.cs" />
Expand Down Expand Up @@ -344,6 +345,8 @@
<Compile Include="IL\Stubs\PInvokeILProvider.cs" />
<Compile Include="IL\Stubs\StartupCode\StartupCodeMainMethod.cs" />
<Compile Include="IL\Stubs\StartupCode\StartupCodeMainMethod.Sorting.cs" />
<Compile Include="IL\Stubs\StartupCode\NativeLibraryStartupMethod.cs" />
<Compile Include="IL\Stubs\StartupCode\NativeLibraryStartupMethod.Sorting.cs" />
<Compile Include="Logger.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
10 changes: 9 additions & 1 deletion src/ILCompiler/src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ internal class Program
private string _ilDump;
private string _systemModuleName = "System.Private.CoreLib";
private bool _multiFile;
private bool _nativeLib;
private bool _useSharedGenerics;
private bool _useScanner;
private bool _noScanner;
Expand Down Expand Up @@ -126,6 +127,7 @@ private ArgumentSyntax ParseCommandLine(string[] args)
syntax.DefineOption("g", ref _enableDebugInfo, "Emit debugging information");
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("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 @@ -309,6 +311,12 @@ private int Run(string[] args)
compilationRoots.Add(new RawMainMethodRootProvider(entrypointModule));
}
}
else if (_nativeLib)
{
EcmaModule module = (EcmaModule)typeSystemContext.SystemModule;
LibraryInitializers libraryInitializers = new LibraryInitializers(typeSystemContext, _isCppCodegen);
compilationRoots.Add(new NativeLibraryInitializerRootProvider(module, libraryInitializers.LibraryInitializerMethods));
}

if (_multiFile)
{
Expand All @@ -330,7 +338,7 @@ private int Run(string[] args)
}
else
{
if (entrypointModule == null)
if (entrypointModule == null && !_nativeLib)
throw new Exception("No entrypoint module");

// TODO: Wasm fails to compile some of the xported methods due to missing opcodes
Expand Down
1 change: 1 addition & 0 deletions src/Native/Bootstrap/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ if(NOT CLR_CMAKE_PLATFORM_WASM)
endif(NOT CLR_CMAKE_PLATFORM_WASM)

add_subdirectory(cpp)
add_subdirectory(dll)
16 changes: 16 additions & 0 deletions src/Native/Bootstrap/dll/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
project(bootstrapperdll)

add_definitions(-DCORERT_DLL)

set(SOURCES
../main.cpp
../common.cpp
)

add_library(bootstrapperdll STATIC ${SOURCES})

# Install the static bootstrapperdll library
install (TARGETS bootstrapperdll DESTINATION sdk)
if(WIN32)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/bootstrapperdll.dir/$<CONFIG>/bootstrapperdll.pdb DESTINATION sdk)
endif()
Loading