diff options
25 files changed, 186 insertions, 40 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..46d40ef7b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,27 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "", + "osx": { + "program": "${workspaceRoot}/bin/Product/OSX.x64.Debug/packaging/publish1/ilc.dll" + }, + "linux": { + "program": "${workspaceRoot}/bin/Product/Linux.x64.Debug/packaging/publish1/ilc.dll" + }, + "args": [], + "cwd": "${workspaceRoot}", + "stopAtEntry": false, + "externalConsole": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command.pickProcess}" + } + ] +}
\ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..3420cc476 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,18 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "0.1.0", + "command": "${workspaceRoot}/build.sh", + "isShellCommand": false, + "args": [], + "tasks": [ + { + "taskName": "build", + "args": [ ], + "isBuildCommand": true, + "showOutput": "silent", + "suppressTaskName" : true, + "problemMatcher": "$msCompile" + } + ] +} diff --git a/Documentation/README.md b/Documentation/README.md index bcca1faeb..1f099ff2c 100644 --- a/Documentation/README.md +++ b/Documentation/README.md @@ -12,5 +12,6 @@ This is the repo for CoreRT, the .NET Core runtime optimized for AOT (Ahead of T - [Prerequisites for building](prerequisites-for-building.md) - [How to build and run from the Command Line](how-to-build-and-run-ilcompiler-in-console-shell-prompt.md) - [How to build and run from Visual Studio](how-to-build-and-run-ilcompiler-in-visual-studio-2015.md) +- [How to build and run from VSCode](how-to-build-and-run-ilcompiler-in-vscode.md) - [How to run tests](how-to-run-tests.md) - [Cross Compilation for ARM on Linux](cross-building.md) diff --git a/Documentation/how-to-build-and-run-ilcompiler-in-vscode.md b/Documentation/how-to-build-and-run-ilcompiler-in-vscode.md new file mode 100644 index 000000000..df1f3fe9b --- /dev/null +++ b/Documentation/how-to-build-and-run-ilcompiler-in-vscode.md @@ -0,0 +1,54 @@ +_Please ensure that [pre-requisites](prerequisites-for-building.md) are installed for a successful build of the repo._ + +_Note_: + +* Instructions below assume ```~/corert``` is the repo root. + +# Setting up # + +Please make sure you have latest VS Code, C# extension, and .NET Core available. This guide is tested under C# 1.6.2 + VS Code 1.8.1 + CLI 1.0.0-preview4-004233. + +This guide assumes that your VS code workspace is set to the root of the repo. + +# Running VS Code + +We've checked-in reasonable default ```launch.json``` and ```tasks.json``` under ```corert/.vscode``` directory. You only need to run vscode form corert root: + +``` +code ~/corert +``` + +And then press SHIFT+COMMAND+B to start the build. + +# Debugging ILC.exe using .NET Core Debugger # + +Go to the debug pane and click Debug, choose .NET Core as the environment. If needed, you can change program property in launch.json (the gear button) to point to a different flavor of ilc: + +```json + "osx": { + "program": "${workspaceRoot}/bin/Product/OSX.x64.Debug/packaging/publish1/ilc.dll" + }, + "linux": { + "program": "${workspaceRoot}/bin/Product/Linux.x64.Debug/packaging/publish1/ilc.dll" + }, +``` + +By default we've disabled automatic build before debug. If you want to change that, you can change the ```preLaunchTask``` property to ```"build"```. But this is not currently recommended. + +# Getting ILC response files + +A ```.ilc.rsp``` file path can be easily obtained from a .NET core project that you want to debug by following command: + +``` +dotnet build /t:LinkNative /t:Rebuild /v:Detailed | grep ".ilc.rsp" +``` + +Once you have the ilc path, you can change ```launch.json``` accordingly: + +```json + "args": ["@obj/Debug/netcoreapp1.0/native/<netcore_app_name>.ilc.rsp"], + "cwd": "<netcore_app_root_folder>", +``` + +* ```args``` - the argument to ILC +* ```cwd``` - the current directory where ILC is running. You can set it to the .NET Core project root. diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.targets b/src/BuildIntegration/Microsoft.NETCore.Native.targets index 9d1325eff..c45f6636f 100644 --- a/src/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/BuildIntegration/Microsoft.NETCore.Native.targets @@ -91,7 +91,7 @@ See the LICENSE file in the project root for more information. <TestHost Condition="'$(OS)' != 'Windows_NT'">corerun</TestHost> </PropertyGroup> - <Exec Command=""$(IlcPath)\$(TestHost)" "$(IlcPath)\ilc.exe" @"$(NativeIntermediateOutputPath)%(ManagedBinary.Filename).ilc.rsp""> + <Exec Command=""$(IlcPath)\$(TestHost)" "$(IlcPath)\ilc.dll" @"$(NativeIntermediateOutputPath)%(ManagedBinary.Filename).ilc.rsp""> </Exec> </Target> diff --git a/src/Common/src/Interop/Windows/Interop.Libraries.cs b/src/Common/src/Interop/Windows/Interop.Libraries.cs index 6740c2cb2..0c1679ed2 100644 --- a/src/Common/src/Interop/Windows/Interop.Libraries.cs +++ b/src/Common/src/Interop/Windows/Interop.Libraries.cs @@ -15,6 +15,7 @@ internal static partial class Interop internal const string IO = "api-ms-win-core-io-l1-1-0.dll"; internal const string Memory = "api-ms-win-core-memory-l1-1-0.dll"; internal const string ProcessEnvironment = "api-ms-win-core-processenvironment-l1-1-0.dll"; + internal const string ProcessThreads = "api-ms-win-core-processthreads-l1-1-0.dll"; internal const string RealTime = "api-ms-win-core-realtime-l1-1-0.dll"; internal const string SysInfo = "api-ms-win-core-sysinfo-l1-2-0.dll"; internal const string Kernel32 = "api-ms-win-core-kernel32-legacy-l1-1-0.dll"; diff --git a/src/Common/src/Interop/Windows/mincore/Interop.GetCurrentThreadId.cs b/src/Common/src/Interop/Windows/mincore/Interop.GetCurrentThreadId.cs new file mode 100644 index 000000000..10e850f03 --- /dev/null +++ b/src/Common/src/Interop/Windows/mincore/Interop.GetCurrentThreadId.cs @@ -0,0 +1,14 @@ +// 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.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class mincore + { + [DllImport(Libraries.ProcessThreads)] + internal extern static uint GetCurrentThreadId(); + } +} diff --git a/src/ILCompiler/src/ILCompiler.csproj b/src/ILCompiler/src/ILCompiler.csproj index 1121a50ee..3ffc7651a 100644 --- a/src/ILCompiler/src/ILCompiler.csproj +++ b/src/ILCompiler/src/ILCompiler.csproj @@ -7,6 +7,10 @@ <ProjectGuid>{DD5B6BAA-D41A-4A6E-9E7D-83060F394B10}</ProjectGuid> <OutputType>Exe</OutputType> <RootNamespace>ILCompiler</RootNamespace> + <!-- This is needed for VS Code debugging for ILC - it only likes DLL extension --> + <!-- This also aligns with .NET Core applications model --> + <!-- Note that we can't change the OutputType to be library - there is no entry point --> + <TargetExt>.dll</TargetExt> <AssemblyName>ilc</AssemblyName> <DefaultLanguage>en-US</DefaultLanguage> <FileAlignment>512</FileAlignment> @@ -44,6 +48,10 @@ </ItemGroup> <ItemGroup> <None Include="project.json" /> + <!-- This is needed for VS Code debugging for ILC --> + <Content Include="ilc.runtimeconfig.json"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\ILCompiler.Compiler\src\ILCompiler.Compiler.csproj"> diff --git a/src/ILCompiler/src/ilc.runtimeconfig.json b/src/ILCompiler/src/ilc.runtimeconfig.json new file mode 100755 index 000000000..d0437745b --- /dev/null +++ b/src/ILCompiler/src/ilc.runtimeconfig.json @@ -0,0 +1,8 @@ +{ + "runtimeOptions": { + "framework": { + "name": "Microsoft.NETCore.App", + "version": "1.0.1" + } + } +}
\ No newline at end of file diff --git a/src/System.Private.CoreLib/src/Interop/Interop.manual.cs b/src/System.Private.CoreLib/src/Interop/Interop.manual.cs index 08b9a91e5..ffc17b236 100644 --- a/src/System.Private.CoreLib/src/Interop/Interop.manual.cs +++ b/src/System.Private.CoreLib/src/Interop/Interop.manual.cs @@ -86,9 +86,6 @@ internal partial class Interop [DllImport("api-ms-win-core-synch-l1-1-0.dll", EntryPoint = "CreateSemaphoreExW", CharSet = CharSet.Unicode)] internal static extern IntPtr CreateSemaphoreEx(IntPtr lpSemaphoreAttributes, int lInitialCount, int lMaximumCount, string lpName, uint dwFlags, uint dwDesiredAccess); - [DllImport("api-ms-win-core-processthreads-l1-1-0.dll")] - internal extern static uint GetCurrentThreadId(); - [DllImport("api-ms-win-core-debug-l1-1-0.dll", EntryPoint = "IsDebuggerPresent", CharSet = CharSet.Unicode)] internal extern static bool IsDebuggerPresent(); diff --git a/src/System.Private.CoreLib/src/Resources/System.Private.CoreLib.rd.xml b/src/System.Private.CoreLib/src/Resources/System.Private.CoreLib.rd.xml index f33a654d6..8e7f7ead1 100644 --- a/src/System.Private.CoreLib/src/Resources/System.Private.CoreLib.rd.xml +++ b/src/System.Private.CoreLib/src/Resources/System.Private.CoreLib.rd.xml @@ -87,7 +87,13 @@ <!-- System.TimeSpan is well known to the serializers and must not be explicitly specified to sg.exe --> <Type Name="TimeSpan" DataContractJsonSerializer="Excluded" DataContractSerializer="Excluded"/> </Namespace> + <Namespace Name="System.Reflection"> + <Type Name="MethodInfo"> + <Method Name="CreateDelegate"> + <TypeParameter Name="delegateType" Activate="Public"/> + </Method> + </Type> + </Namespace> </Assembly> </Library> </Directives> - diff --git a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 4998a45c6..41cce6086 100644 --- a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -752,6 +752,9 @@ <Compile Include="..\..\Common\src\Interop\Windows\Interop.BOOL.cs"> <Link>Interop\Windows\Interop.BOOL.cs</Link> </Compile> + <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.GetCurrentThreadId.cs"> + <Link>Interop\Windows\mincore\Interop.GetCurrentThreadId.cs</Link> + </Compile> <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.SetLastError.cs"> <Link>Interop\Windows\mincore\Interop.SetLastError.cs</Link> </Compile> diff --git a/src/System.Private.CoreLib/src/System/Environment.Unix.cs b/src/System.Private.CoreLib/src/System/Environment.Unix.cs index bcfdbe4f6..84ce40165 100644 --- a/src/System.Private.CoreLib/src/System/Environment.Unix.cs +++ b/src/System.Private.CoreLib/src/System/Environment.Unix.cs @@ -4,11 +4,14 @@ using System.Text; using System.Runtime.InteropServices; +using System.Threading; namespace System { public static partial class Environment { + internal static int CurrentNativeThreadId => ManagedThreadId.Current; + internal static long TickCount64 { get diff --git a/src/System.Private.CoreLib/src/System/Environment.Windows.cs b/src/System.Private.CoreLib/src/System/Environment.Windows.cs index 7576857a9..3c35f0f7a 100644 --- a/src/System.Private.CoreLib/src/System/Environment.Windows.cs +++ b/src/System.Private.CoreLib/src/System/Environment.Windows.cs @@ -6,6 +6,8 @@ namespace System { public static partial class Environment { + internal static int CurrentNativeThreadId => unchecked((int)Interop.mincore.GetCurrentThreadId()); + internal static long TickCount64 => (long)Interop.mincore.GetTickCount64(); public static int ProcessorCount diff --git a/src/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Win32.cs b/src/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Win32.cs index 55e78f5d5..a83c4fad9 100644 --- a/src/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Win32.cs +++ b/src/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Win32.cs @@ -171,7 +171,7 @@ namespace System.Globalization // Get Strings // // Needs to be a certain length e_a_E_A at least (7 chars, exactly 4 groups) - String[] names = data.Split(new char[] { '_' }); + String[] names = data.Split('_'); // Should have exactly 4 parts // 0 - Era Name diff --git a/src/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs b/src/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs index 1a47b20a7..ca62a64b6 100644 --- a/src/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs +++ b/src/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs @@ -402,7 +402,7 @@ namespace System LowLevelList<Exception> exceptions = new LowLevelList<Exception>(curThreadExceptions); LowLevelList<Exception> nonThrownInnerExceptions = new LowLevelList<Exception>(); - uint currentThreadId = Interop.mincore.GetCurrentThreadId(); + uint currentThreadId = (uint)Environment.CurrentNativeThreadId; // Reset nesting levels for exceptions on this thread that might not be currently in flight foreach (ExceptionData exceptionData in s_exceptionDataTable.GetValues()) diff --git a/src/System.Private.CoreLib/src/System/Threading/Lock.cs b/src/System.Private.CoreLib/src/System/Threading/Lock.cs index e81d5c3cf..1a122c21b 100644 --- a/src/System.Private.CoreLib/src/System/Threading/Lock.cs +++ b/src/System.Private.CoreLib/src/System/Threading/Lock.cs @@ -2,9 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#pragma warning disable 0420 //passing volatile field by reference - - using System.Diagnostics; using System.Runtime.CompilerServices; @@ -57,12 +54,14 @@ namespace System.Threading } } - /// <remarks>Inlined version of Lock.Acquire has CurrentManagedThreadId not inlined, non-inlined version has it inlined. - /// So it saves code to keep this function non inlining while keep the same runtime cost</remarks> + // On platforms where CurrentNativeThreadId redirects to ManagedThreadId.Current the inlined + // version of Lock.Acquire has the ManagedThreadId.Current call not inlined, while the non-inlined + // version has it inlined. So it saves code to keep this function not inlined while having + // the same runtime cost. [MethodImpl(MethodImplOptions.NoInlining)] public void Acquire() { - int currentThreadId = Environment.CurrentManagedThreadId; + int currentThreadId = Environment.CurrentNativeThreadId; // // Make one quick attempt to acquire an uncontended lock @@ -95,7 +94,7 @@ namespace System.Threading if (millisecondsTimeout < -1) throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); - int currentThreadId = Environment.CurrentManagedThreadId; + int currentThreadId = Environment.CurrentNativeThreadId; // // Make one quick attempt to acquire an uncontended lock @@ -231,13 +230,16 @@ namespace System.Threading get { // + // The comment below is for platforms where CurrentNativeThreadId redirects to + // ManagedThreadId.Current instead of being a compiler intrinsic. + // // Compare the current owning thread ID with the current thread ID. We need // to read the current thread's ID before we read m_owningThreadId. Otherwise, // the following might happen: // // 1) We read m_owningThreadId, and get, say 42, which belongs to another thread. // 2) Thread 42 releases the lock, and exits. - // 3) We call CurrentManagedThreadId. If this is the first time it's been called + // 3) We call ManagedThreadId.Current. If this is the first time it's been called // on this thread, we'll go get a new ID. We may reuse thread 42's ID, since // that thread is dead. // 4) Now we're thread 42, and it looks like we own the lock, even though we don't. @@ -246,8 +248,8 @@ namespace System.Threading // because while we're doing this check the current thread is definitely still // alive. // - int currentManagedThreadId = Environment.CurrentManagedThreadId; - bool acquired = (currentManagedThreadId == _owningThreadId); + int currentThreadId = Environment.CurrentNativeThreadId; + bool acquired = (currentThreadId == _owningThreadId); if (acquired) Debug.Assert((_state & Locked) != 0); return acquired; diff --git a/src/System.Private.CoreLib/src/System/TimeZoneInfo.Win32.cs b/src/System.Private.CoreLib/src/System/TimeZoneInfo.Win32.cs index 7c7711906..326f1718d 100644 --- a/src/System.Private.CoreLib/src/System/TimeZoneInfo.Win32.cs +++ b/src/System.Private.CoreLib/src/System/TimeZoneInfo.Win32.cs @@ -830,7 +830,7 @@ namespace System // filePath = "C:\Windows\System32\tzres.dll" // resourceId = -100 // - string[] resources = resource.Split(new char[] { ',' }, StringSplitOptions.None); + string[] resources = resource.Split(','); if (resources.Length != 2) { return String.Empty; diff --git a/src/System.Private.CoreLib/src/System/Type.cs b/src/System.Private.CoreLib/src/System/Type.cs index 8a9197464..4c54744a6 100644 --- a/src/System.Private.CoreLib/src/System/Type.cs +++ b/src/System.Private.CoreLib/src/System/Type.cs @@ -105,7 +105,7 @@ namespace System public bool IsContextful => IsContextfulImpl(); protected virtual bool IsContextfulImpl() => typeof(ContextBoundObject).IsAssignableFrom(this); - public bool IsEnum => IsSubclassOf(typeof(Enum)); + public virtual bool IsEnum => IsSubclassOf(typeof(Enum)); public bool IsMarshalByRef => IsMarshalByRefImpl(); protected virtual bool IsMarshalByRefImpl() => typeof(MarshalByRefObject).IsAssignableFrom(this); public bool IsPrimitive => IsPrimitiveImpl(); @@ -351,7 +351,7 @@ namespace System return systemType.GetHashCode(); return base.GetHashCode(); } - public bool Equals(Type o) => o == null ? false : object.ReferenceEquals(this.UnderlyingSystemType, o.UnderlyingSystemType); + public virtual bool Equals(Type o) => o == null ? false : object.ReferenceEquals(this.UnderlyingSystemType, o.UnderlyingSystemType); public static bool operator ==(Type left, Type right) { diff --git a/src/System.Private.CoreLib/src/System/Version.cs b/src/System.Private.CoreLib/src/System/Version.cs index 31f062c82..13404bfd7 100644 --- a/src/System.Private.CoreLib/src/System/Version.cs +++ b/src/System.Private.CoreLib/src/System/Version.cs @@ -256,7 +256,7 @@ namespace System return false; } - String[] parsedComponents = version.Split(new char[] { '.' }); + String[] parsedComponents = version.Split('.'); int parsedComponentsLength = parsedComponents.Length; if ((parsedComponentsLength < 2) || (parsedComponentsLength > 4)) { diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs index 83cd7a4fc..58635acca 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs @@ -141,6 +141,11 @@ namespace System.Reflection.Runtime.TypeInfos return object.ReferenceEquals(this, obj); } + public sealed override bool Equals(Type o) + { + return object.ReferenceEquals(this, o); + } + public sealed override int GetHashCode() { return InternalGetHashCode(); @@ -302,6 +307,14 @@ namespace System.Reflection.Runtime.TypeInfos } } + public sealed override bool IsEnum + { + get + { + return 0 != (Classification & TypeClassification.IsEnum); + } + } + // // Left unsealed as generic parameter types must override. // diff --git a/src/System.Private.Reflection/src/Resources/System.Private.Reflection.rd.xml b/src/System.Private.Reflection/src/Resources/System.Private.Reflection.rd.xml deleted file mode 100644 index 7d964d890..000000000 --- a/src/System.Private.Reflection/src/Resources/System.Private.Reflection.rd.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata"> - <Library Name="*System.Private.Reflection*"> - <Assembly Name="System.Private.Reflection"> - <Namespace Name="System.Reflection"> - <Type Name="MethodInfo"> - <Method Name="CreateDelegate"> - <TypeParameter Name="delegateType" Activate="Public"/> - </Method> - </Type> - </Namespace> - </Assembly> - </Library> -</Directives> diff --git a/src/System.Private.Reflection/src/System.Private.Reflection.csproj b/src/System.Private.Reflection/src/System.Private.Reflection.csproj index 645c7e84c..e2e74005a 100644 --- a/src/System.Private.Reflection/src/System.Private.Reflection.csproj +++ b/src/System.Private.Reflection/src/System.Private.Reflection.csproj @@ -24,8 +24,5 @@ <Compile Include="Internal\Reflection\Augments\TypeForwarders.cs" /> <Compile Include="System\Reflection\TypeForwarders.cs" /> </ItemGroup> - <ItemGroup> - <EmbeddedResource Include="Resources\$(AssemblyName).rd.xml" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project> diff --git a/src/Test.CoreLib/readme.md b/src/Test.CoreLib/readme.md index d05eca4ff..878302f80 100644 --- a/src/Test.CoreLib/readme.md +++ b/src/Test.CoreLib/readme.md @@ -14,7 +14,7 @@ csc /noconfig /nostdlib Program.cs /r:<repo_root>\bin\Product\Windows_NT.x64.Deb 2. Compile the IL with ILC -Use ilc.exe that was built with the repo to compile the program. +Use ilc.dll that was built with the repo to compile the program. ``` ilc repro.exe -o:repro.obj -r:<repo_root>\bin\Product\Windows_NT.x64.Debug\Test.CoreLib\Test.CoreLib.dll --systemmodule Test.CoreLib diff --git a/src/packaging/packages.targets b/src/packaging/packages.targets index f362e52cd..00b505047 100644 --- a/src/packaging/packages.targets +++ b/src/packaging/packages.targets @@ -33,7 +33,7 @@ </PropertyGroup> <ItemGroup> <!-- IL.Compiler target files --> - <ILCompilerFiles Include="ilc.exe" /> + <ILCompilerFiles Include="ilc.dll" /> <ILCompilerFiles Include="ILCompiler.Compiler.dll" /> <ILCompilerFiles Include="ILCompiler.DependencyAnalysisFramework.dll" /> <ILCompilerFiles Include="ILCompiler.MetadataTransform.dll" /> @@ -74,6 +74,12 @@ <ILCompilerBinPlace Include="@(ILCompilerContentFiles)"> <Text><![CDATA[ <file src="src/%(Identity)" target="runtimes/$(NuPkgRid)/native/%(Filename)%(Extension)" /> ]]></Text> </ILCompilerBinPlace> + + <!-- This is needed for VS Code debugging for ILC --> + <ILCompilerJsonContentFiles Include="ilc.runtimeconfig.json" /> + <ILCompilerBinPlace Include="@(ILCompilerJsonContentFiles)"> + <Text><![CDATA[ <file src="src/ILCompiler/src/%(Identity)" target="runtimes/$(NuPkgRid)/native/%(Filename)%(Extension)" /> ]]></Text> + </ILCompilerBinPlace> <!-- IL.Compiler.SDK target files --> <ILCompilerSdkFiles Include="Runtime" /> |