Merge pull request #217 from brthor/dotnet-compile-natives
dotnet-compile-native Thanks for getting this in!
This commit is contained in:
commit
c284a7492a
35 changed files with 1829 additions and 9 deletions
|
@ -56,6 +56,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Dotnet.Cli.Compil
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Init", "src\Microsoft.DotNet.Tools.Init\Microsoft.DotNet.Tools.Init.xproj", "{BC765FBF-AD7A-4A99-9902-5540C5A74181}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Compiler.Native", "src\Microsoft.DotNet.Tools.Compiler.Native\Microsoft.DotNet.Tools.Compiler.Native.xproj", "{172485DD-B94E-4F3E-851E-CF23908FF960}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -296,6 +298,22 @@ Global
|
|||
{BC765FBF-AD7A-4A99-9902-5540C5A74181}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{BC765FBF-AD7A-4A99-9902-5540C5A74181}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{BC765FBF-AD7A-4A99-9902-5540C5A74181}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.MinSizeRel|x64.Build.0 = Debug|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.Release|x64.Build.0 = Release|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -318,5 +336,6 @@ Global
|
|||
{1C16108C-C786-482D-BB0A-36BDAFE109ED} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
|
||||
{A16958E1-24C7-4F1E-B317-204AD91625DD} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
|
||||
{BC765FBF-AD7A-4A99-9902-5540C5A74181} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
|
||||
{172485DD-B94E-4F3E-851E-CF23908FF960} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<add key="roslyn-nightly" value="https://www.myget.org/F/roslyn-nightly/api/v3/index.json" />
|
||||
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||
<add key="corefxlab" value="https://www.myget.org/F/netcore-package-prototyping/api/v3/index.json" />
|
||||
<add key="corert" value="https://www.myget.org/F/dotnet/auth/3e4f1dbe-f43a-45a8-b029-3ad4d25605ac/api/v2" />
|
||||
</packageSources>
|
||||
<activePackageSource>
|
||||
<add key="AspNetCIDev" value="https://www.myget.org/F/aspnetcidev/api/v3/index.json" />
|
||||
|
|
|
@ -21,7 +21,8 @@ $Projects = @(
|
|||
"Microsoft.DotNet.Tools.Repl.Csi",
|
||||
"Microsoft.DotNet.Tools.Resgen",
|
||||
"Microsoft.DotNet.Tools.Run",
|
||||
"Microsoft.DotNet.Tools.Init"
|
||||
"Microsoft.DotNet.Tools.Init",
|
||||
"Microsoft.DotNet.Tools.Compiler.Native"
|
||||
)
|
||||
|
||||
$BinariesForCoreHost = @(
|
||||
|
|
|
@ -33,6 +33,7 @@ PROJECTS=( \
|
|||
Microsoft.DotNet.Tools.Repl.Csi \
|
||||
Microsoft.DotNet.Tools.Resgen \
|
||||
Microsoft.DotNet.Tools.Run \
|
||||
Microsoft.DotNet.Tools.Compiler.Native \
|
||||
)
|
||||
|
||||
BINARIES_FOR_COREHOST=( \
|
||||
|
|
21
scripts/build/build_appdeps.cmd
Normal file
21
scripts/build/build_appdeps.cmd
Normal file
|
@ -0,0 +1,21 @@
|
|||
@echo off
|
||||
|
||||
REM This file encapsulates the temporary steps to build the dotnet-compile-native command successfully
|
||||
REM The AppDepSDK package is a temporary artifact until we have CoreRT assemblies published to Nuget
|
||||
|
||||
set __ScriptDir=%~dp0
|
||||
set __RepoRoot=%__ScriptDir%\..\..
|
||||
set __AppDepsProjectDir=%__RepoRoot%\src\Microsoft.DotNet.Tools.Compiler.Native\appdep
|
||||
|
||||
REM Get absolute path
|
||||
pushd %1
|
||||
set __OutputPath=%CD%\bin
|
||||
popd
|
||||
|
||||
pushd %__AppDepsProjectDir%
|
||||
dotnet restore --packages %AppDepsProjectDir%\packages
|
||||
set __AppDepSDK=%AppDepsProjectDir%\packages\toolchain*\*\
|
||||
popd
|
||||
|
||||
mkdir %__OutputPath%\appdepsdk
|
||||
xcopy /S/E/H/Y %__AppDepSDK% %__OutputPath%\appdepsdk
|
30
scripts/build/build_appdeps.sh
Executable file
30
scripts/build/build_appdeps.sh
Executable file
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# This file encapsulates the temporary steps to build the dotnet-compile-native command successfully
|
||||
# The AppDepSDK package is a temporary artifact until we have CoreRT assemblies published to Nuget
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
source $SCRIPT_DIR/../_common.sh
|
||||
|
||||
# Dotnet-compile-native doesn't work for mac yet
|
||||
if [[ "$(uname)" != "Linux" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
REPO_ROOT="$SCRIPT_DIR/../.."
|
||||
APPDEPS_PROJECT_DIR=$REPO_ROOT/src/Microsoft.DotNet.Tools.Compiler.Native/appdep
|
||||
|
||||
# Get Absolute Output Dir
|
||||
pushd $1
|
||||
OUTPUT_DIR="$(pwd)"
|
||||
popd
|
||||
|
||||
## App Deps ##
|
||||
pushd $APPDEPS_PROJECT_DIR
|
||||
dotnet restore --packages $APPDEPS_PROJECT_DIR/packages
|
||||
APPDEP_SDK=$APPDEPS_PROJECT_DIR/packages/toolchain*/*/
|
||||
popd
|
||||
|
||||
mkdir -p $OUTPUT_DIR/appdepsdk
|
||||
cp -a $APPDEP_SDK/. $OUTPUT_DIR/appdepsdk
|
|
@ -46,7 +46,7 @@ Download it from https://www.cmake.org
|
|||
|
||||
# Restore packages
|
||||
header "Restoring packages"
|
||||
dotnet restore "$RepoRoot" --quiet --runtime "osx.10.10-x64" --runtime "ubuntu.14.04-x64" --runtime "win7-x64"
|
||||
dotnet restore "$RepoRoot" --quiet --runtime "osx.10.10-x64" --runtime "ubuntu.14.04-x64" --runtime "win7-x64" --no-cache
|
||||
|
||||
header "Building corehost"
|
||||
pushd "$RepoRoot\src\corehost"
|
||||
|
@ -94,8 +94,12 @@ Download it from https://www.cmake.org
|
|||
# Copy in the dotnet-restore script
|
||||
cp "$PSScriptRoot\dotnet-restore.cmd" "$Stage2Dir\bin\dotnet-restore.cmd"
|
||||
|
||||
# Smoke test stage2
|
||||
# Copy in AppDeps
|
||||
$env:PATH = "$Stage2Dir\bin;$StartPath"
|
||||
header "Acquiring Native App Dependencies"
|
||||
cmd /c "$PSScriptRoot\build\build_appdeps.cmd" "$Stage2Dir"
|
||||
|
||||
# Smoke test stage2
|
||||
$env:DOTNET_HOME = "$Stage2Dir"
|
||||
& "$PSScriptRoot\test\smoke-test.ps1"
|
||||
} finally {
|
||||
|
|
|
@ -51,7 +51,7 @@ if [ ! -d "$DNX_ROOT" ] || [ ! -e "$DNX_ROOT/dnx" ]; then
|
|||
fi
|
||||
|
||||
header "Restoring packages"
|
||||
dotnet restore "$REPOROOT" --quiet --runtime "osx.10.10-x64" --runtime "ubuntu.14.04-x64" --runtime "win7-x64"
|
||||
dotnet restore "$REPOROOT" --quiet --runtime "osx.10.10-x64" --runtime "ubuntu.14.04-x64" --runtime "win7-x64" --no-cache
|
||||
|
||||
header "Building corehost"
|
||||
|
||||
|
@ -106,6 +106,10 @@ cp -R $DNX_ROOT $STAGE2_DIR/bin/dnx
|
|||
cp $DIR/dotnet-restore.sh $STAGE2_DIR/bin/dotnet-restore
|
||||
chmod a+x $STAGE2_DIR/bin/dotnet-restore
|
||||
|
||||
# Copy in AppDeps
|
||||
header "Acquiring Native App Dependencies"
|
||||
DOTNET_HOME=$STAGE2_DIR DOTNET_TOOLS=$STAGE2_DIR $REPOROOT/scripts/build/build_appdeps.sh "$STAGE2_DIR/bin"
|
||||
|
||||
# Stamp the output with the commit metadata
|
||||
COMMIT_ID=$(git rev-parse HEAD)
|
||||
echo $COMMIT_ID > $STAGE2_DIR/.commit
|
||||
|
|
31
src/Microsoft.DotNet.Tools.Compiler.Native/ArgValues.cs
Normal file
31
src/Microsoft.DotNet.Tools.Compiler.Native/ArgValues.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
internal class ArgValues
|
||||
{
|
||||
public string LogPath { get; set; }
|
||||
public string InputManagedAssemblyPath { get; set; }
|
||||
public string OutputDirectory { get; set; }
|
||||
public string IntermediateDirectory { get; set; }
|
||||
public string BuildConfiguration { get; set; }
|
||||
public string Architecture { get; set; }
|
||||
public string NativeMode { get; set; }
|
||||
public List<string> ReferencePaths { get; set; }
|
||||
public string IlcArgs { get; set; }
|
||||
public List<string> LinkLibPaths { get; set; }
|
||||
public string AppDepSDKPath { get; set; }
|
||||
public string IlcPath { get; set; }
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public static class DirectoryExtensions
|
||||
{
|
||||
internal static void CleanOrCreateDirectory(string path)
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(path, recursive: true);
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("Unable to remove directory: " + path);
|
||||
Console.WriteLine(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
src/Microsoft.DotNet.Tools.Compiler.Native/EnumExtensions.cs
Normal file
23
src/Microsoft.DotNet.Tools.Compiler.Native/EnumExtensions.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public static class EnumExtensions
|
||||
{
|
||||
internal static T Parse<T>(string value)
|
||||
{
|
||||
return (T)Enum.Parse(typeof(T), value, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
106
src/Microsoft.DotNet.Tools.Compiler.Native/ILCompilerInvoker.cs
Normal file
106
src/Microsoft.DotNet.Tools.Compiler.Native/ILCompilerInvoker.cs
Normal file
|
@ -0,0 +1,106 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public class ILCompilerInvoker
|
||||
{
|
||||
private readonly string ExecutableName = "corerun" + Constants.ExeSuffix;
|
||||
private readonly string ILCompiler = "ilc.exe";
|
||||
|
||||
private static readonly Dictionary<NativeIntermediateMode, string> ModeOutputExtensionMap = new Dictionary<NativeIntermediateMode, string>
|
||||
{
|
||||
{ NativeIntermediateMode.cpp, ".cpp" },
|
||||
{ NativeIntermediateMode.ryujit, ".obj" }
|
||||
};
|
||||
|
||||
private static readonly Dictionary<OSMode, string> OSCoreLibNameMap = new Dictionary<OSMode, string>()
|
||||
{
|
||||
{OSMode.Windows, "System.Private.CoreLib.dll" },
|
||||
{OSMode.Linux, "System.Private.Corelib.dll" },
|
||||
{OSMode.Mac, "System.Private.Corelib.dll" },
|
||||
};
|
||||
|
||||
|
||||
private string ArgStr { get; set; }
|
||||
private NativeCompileSettings config;
|
||||
|
||||
public ILCompilerInvoker(NativeCompileSettings config)
|
||||
{
|
||||
this.config = config;
|
||||
InitializeArgs(config);
|
||||
}
|
||||
|
||||
private void InitializeArgs(NativeCompileSettings config)
|
||||
{
|
||||
var argsList = new List<string>();
|
||||
|
||||
var managedPath = Path.Combine(config.IlcPath, ILCompiler);
|
||||
argsList.Add(managedPath);
|
||||
|
||||
// Input File
|
||||
var inputFilePath = config.InputManagedAssemblyPath;
|
||||
argsList.Add(inputFilePath);
|
||||
|
||||
// System.Private.CoreLib Reference
|
||||
var coreLibPath = Path.Combine(config.IlcPath, OSCoreLibNameMap[config.OS]);
|
||||
argsList.Add($"-r \"{coreLibPath}\"");
|
||||
|
||||
// Dependency References
|
||||
foreach (var reference in config.ReferencePaths)
|
||||
{
|
||||
argsList.Add($"-r \"{reference}\"");
|
||||
}
|
||||
|
||||
// Set Output DetermineOutFile
|
||||
var outFile = DetermineOutputFile(config);
|
||||
argsList.Add($"-out \"{outFile}\"");
|
||||
|
||||
// Add Mode Flag TODO
|
||||
if (config.NativeMode == NativeIntermediateMode.cpp)
|
||||
{
|
||||
argsList.Add("-cpp");
|
||||
}
|
||||
|
||||
// Custom Ilc Args support
|
||||
if (! string.IsNullOrEmpty(config.IlcArgs))
|
||||
{
|
||||
argsList.Add(config.IlcArgs);
|
||||
}
|
||||
|
||||
this.ArgStr = string.Join(" ", argsList);
|
||||
}
|
||||
|
||||
public int Invoke()
|
||||
{
|
||||
var executablePath = Path.Combine(AppContext.BaseDirectory, ExecutableName);
|
||||
|
||||
var result = Command.Create(executablePath, ArgStr)
|
||||
.ForwardStdErr()
|
||||
.ForwardStdOut()
|
||||
.Execute();
|
||||
|
||||
return result.ExitCode;
|
||||
}
|
||||
|
||||
public string DetermineOutputFile(NativeCompileSettings config)
|
||||
{
|
||||
var intermediateDirectory = config.IntermediateDirectory;
|
||||
|
||||
var extension = ModeOutputExtensionMap[config.NativeMode];
|
||||
|
||||
var filename = Path.GetFileNameWithoutExtension(config.InputManagedAssemblyPath);
|
||||
|
||||
var outFile = Path.Combine(intermediateDirectory, filename + extension);
|
||||
|
||||
return outFile;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public interface IPlatformNativeStep
|
||||
{
|
||||
int Invoke();
|
||||
string DetermineOutputFile(NativeCompileSettings config);
|
||||
bool CheckPreReqs();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public class IntermediateCompiler
|
||||
{
|
||||
public static IntermediateCompiler Create(NativeCompileSettings config)
|
||||
{
|
||||
var platformStepList = CreatePlatformNativeSteps(config);
|
||||
|
||||
return new IntermediateCompiler(platformStepList);
|
||||
}
|
||||
|
||||
private static List<IPlatformNativeStep> CreatePlatformNativeSteps(NativeCompileSettings config)
|
||||
{
|
||||
if (config.NativeMode == NativeIntermediateMode.cpp)
|
||||
{
|
||||
return CreateCppSteps(config);
|
||||
}
|
||||
else if (config.NativeMode == NativeIntermediateMode.ryujit)
|
||||
{
|
||||
return CreateJitSteps(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unrecognized Mode");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<IPlatformNativeStep> CreateCppSteps(NativeCompileSettings config)
|
||||
{
|
||||
var stepList = new List<IPlatformNativeStep>();
|
||||
|
||||
if (config.OS == OSMode.Windows)
|
||||
{
|
||||
stepList.Add(new WindowsCppCompileStep(config));
|
||||
stepList.Add(new WindowsLinkStep(config));
|
||||
}
|
||||
else if (config.OS == OSMode.Linux)
|
||||
{
|
||||
stepList.Add(new LinuxCppCompileStep(config));
|
||||
}
|
||||
else if (config.OS == OSMode.Mac)
|
||||
{
|
||||
throw new NotImplementedException("Mac not yet supported.");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unrecognized Operating System. Unable to create Intermediate Compiler.");
|
||||
}
|
||||
|
||||
return stepList;
|
||||
}
|
||||
|
||||
private static List<IPlatformNativeStep> CreateJitSteps(NativeCompileSettings config)
|
||||
{
|
||||
var stepList = new List<IPlatformNativeStep>();
|
||||
|
||||
if (config.OS == OSMode.Windows)
|
||||
{
|
||||
stepList.Add(new WindowsLinkStep(config));
|
||||
}
|
||||
else if (config.OS == OSMode.Linux)
|
||||
{
|
||||
stepList.Add(new LinuxRyuJitCompileStep(config));
|
||||
}
|
||||
else if (config.OS == OSMode.Mac)
|
||||
{
|
||||
throw new NotImplementedException("Mac RyuJit not supported");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unrecognized Operating System. Unable to create Intermediate Compiler.");
|
||||
}
|
||||
|
||||
return stepList;
|
||||
}
|
||||
|
||||
private List<IPlatformNativeStep> StepList { get; set; }
|
||||
|
||||
private IntermediateCompiler(List<IPlatformNativeStep> stepList)
|
||||
{
|
||||
if (stepList == null || stepList.Count < 1)
|
||||
{
|
||||
throw new Exception("Intermediate step list must not be empty.");
|
||||
}
|
||||
|
||||
this.StepList = stepList;
|
||||
}
|
||||
|
||||
public int Invoke()
|
||||
{
|
||||
foreach(var step in StepList)
|
||||
{
|
||||
int result = step.Invoke();
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public string DetermineOutputFile(NativeCompileSettings config)
|
||||
{
|
||||
return config.DetermineFinalOutputPath();
|
||||
}
|
||||
|
||||
public bool CheckPreReqs()
|
||||
{
|
||||
var check = true;
|
||||
|
||||
foreach(var step in StepList)
|
||||
{
|
||||
check = check && step.CheckPreReqs();
|
||||
}
|
||||
|
||||
return check;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public class LinuxCppCompileStep : IPlatformNativeStep
|
||||
{
|
||||
private readonly string CompilerName = "clang-3.5";
|
||||
private readonly string InputExtension = ".cpp";
|
||||
|
||||
// TODO: debug/release support
|
||||
private readonly string cLibsFlags = "-lm -ldl";
|
||||
private readonly string cflags = "-g -lstdc++ -lrt -Wno-invalid-offsetof -pthread";
|
||||
|
||||
private readonly string[] libs = new string[]
|
||||
{
|
||||
"libbootstrappercpp.a",
|
||||
"libPortableRuntime.a",
|
||||
"libSystem.Private.CoreLib.Native.a"
|
||||
};
|
||||
|
||||
private readonly string[] appdeplibs = new string[]
|
||||
{
|
||||
"libSystem.Native.a"
|
||||
};
|
||||
|
||||
|
||||
private string CompilerArgStr { get; set; }
|
||||
private NativeCompileSettings config;
|
||||
|
||||
public LinuxCppCompileStep(NativeCompileSettings config)
|
||||
{
|
||||
this.config = config;
|
||||
InitializeArgs(config);
|
||||
}
|
||||
|
||||
public int Invoke()
|
||||
{
|
||||
var result = InvokeCompiler();
|
||||
if (result != 0)
|
||||
{
|
||||
Reporter.Error.WriteLine("Compilation of intermediate files failed.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool CheckPreReqs()
|
||||
{
|
||||
// TODO check for clang
|
||||
return true;
|
||||
}
|
||||
|
||||
private void InitializeArgs(NativeCompileSettings config)
|
||||
{
|
||||
var argsList = new List<string>();
|
||||
|
||||
// Flags
|
||||
argsList.Add(cflags);
|
||||
|
||||
// Add Includes
|
||||
argsList.Add("-I");
|
||||
argsList.Add(Path.Combine(config.AppDepSDKPath, "CPPSdk/ubuntu.14.04"));
|
||||
|
||||
argsList.Add("-I");
|
||||
argsList.Add(Path.Combine(config.AppDepSDKPath, "CPPSdk"));
|
||||
|
||||
// Input File
|
||||
var inCppFile = DetermineInFile(config);
|
||||
argsList.Add(inCppFile);
|
||||
|
||||
// Add Stubs
|
||||
argsList.Add(Path.Combine(config.AppDepSDKPath, "CPPSdk/ubuntu.14.04/lxstubs.cpp"));
|
||||
|
||||
// Libs
|
||||
foreach (var lib in libs)
|
||||
{
|
||||
var libPath = Path.Combine(config.IlcPath, lib);
|
||||
argsList.Add(libPath);
|
||||
}
|
||||
|
||||
// AppDep Libs
|
||||
foreach (var lib in appdeplibs)
|
||||
{
|
||||
var libPath = Path.Combine(config.AppDepSDKPath, lib);
|
||||
argsList.Add(libPath);
|
||||
}
|
||||
|
||||
argsList.Add(cLibsFlags);
|
||||
|
||||
// Output
|
||||
var libOut = DetermineOutputFile(config);
|
||||
argsList.Add($"-o \"{libOut}\"");
|
||||
|
||||
this.CompilerArgStr = string.Join(" ", argsList);
|
||||
}
|
||||
|
||||
private int InvokeCompiler()
|
||||
{
|
||||
var result = Command.Create(CompilerName, CompilerArgStr)
|
||||
.ForwardStdErr()
|
||||
.ForwardStdOut()
|
||||
.Execute();
|
||||
|
||||
return result.ExitCode;
|
||||
}
|
||||
|
||||
private string DetermineInFile(NativeCompileSettings config)
|
||||
{
|
||||
var intermediateDirectory = config.IntermediateDirectory;
|
||||
|
||||
var filename = Path.GetFileNameWithoutExtension(config.InputManagedAssemblyPath);
|
||||
|
||||
var infile = Path.Combine(intermediateDirectory, filename + InputExtension);
|
||||
|
||||
return infile;
|
||||
}
|
||||
|
||||
public string DetermineOutputFile(NativeCompileSettings config)
|
||||
{
|
||||
var intermediateDirectory = config.OutputDirectory;
|
||||
|
||||
var filename = Path.GetFileNameWithoutExtension(config.InputManagedAssemblyPath);
|
||||
|
||||
var outfile = Path.Combine(intermediateDirectory, filename);
|
||||
|
||||
return outfile;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public class LinuxRyuJitCompileStep : IPlatformNativeStep
|
||||
{
|
||||
private readonly string CompilerName = "clang-3.5";
|
||||
private readonly string InputExtension = ".obj";
|
||||
|
||||
private readonly string CompilerOutputExtension = "";
|
||||
|
||||
// TODO: debug/release support
|
||||
private readonly string cflags = "-lstdc++ -lpthread -ldl -lm";
|
||||
|
||||
private readonly string[] libs = new string[]
|
||||
{
|
||||
"libbootstrapper.a",
|
||||
"libRuntime.a",
|
||||
"libSystem.Private.CoreLib.Native.a"
|
||||
};
|
||||
|
||||
private readonly string[] appdeplibs = new string[]
|
||||
{
|
||||
"libSystem.Native.a"
|
||||
};
|
||||
|
||||
|
||||
private string CompilerArgStr { get; set; }
|
||||
private NativeCompileSettings config;
|
||||
|
||||
public LinuxRyuJitCompileStep(NativeCompileSettings config)
|
||||
{
|
||||
this.config = config;
|
||||
InitializeArgs(config);
|
||||
}
|
||||
|
||||
public int Invoke()
|
||||
{
|
||||
var result = InvokeCompiler();
|
||||
if (result != 0)
|
||||
{
|
||||
Reporter.Error.WriteLine("Compilation of intermediate files failed.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool CheckPreReqs()
|
||||
{
|
||||
// TODO check for clang
|
||||
return true;
|
||||
}
|
||||
|
||||
private void InitializeArgs(NativeCompileSettings config)
|
||||
{
|
||||
var argsList = new List<string>();
|
||||
|
||||
// Flags
|
||||
argsList.Add(cflags);
|
||||
|
||||
// Input File
|
||||
var inLibFile = DetermineInFile(config);
|
||||
argsList.Add(inLibFile);
|
||||
|
||||
// Libs
|
||||
foreach (var lib in libs)
|
||||
{
|
||||
var libPath = Path.Combine(config.IlcPath, lib);
|
||||
argsList.Add(libPath);
|
||||
}
|
||||
|
||||
// AppDep Libs
|
||||
foreach (var lib in appdeplibs)
|
||||
{
|
||||
var libPath = Path.Combine(config.AppDepSDKPath, lib);
|
||||
argsList.Add(libPath);
|
||||
}
|
||||
|
||||
// Output
|
||||
var libOut = DetermineOutputFile(config);
|
||||
argsList.Add($"-o \"{libOut}\"");
|
||||
|
||||
// Add Stubs
|
||||
argsList.Add(Path.Combine(config.AppDepSDKPath, "CPPSdk/ubuntu.14.04/lxstubs.cpp"));
|
||||
|
||||
this.CompilerArgStr = string.Join(" ", argsList);
|
||||
}
|
||||
|
||||
private int InvokeCompiler()
|
||||
{
|
||||
var result = Command.Create(CompilerName, CompilerArgStr)
|
||||
.ForwardStdErr()
|
||||
.ForwardStdOut()
|
||||
.Execute();
|
||||
|
||||
// Needs System.Native.so in output
|
||||
var sharedLibPath = Path.Combine(config.IlcPath, "System.Native.so");
|
||||
var outputSharedLibPath = Path.Combine(config.OutputDirectory, "System.Native.so");
|
||||
try
|
||||
{
|
||||
File.Copy(sharedLibPath, outputSharedLibPath);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Reporter.Error.WriteLine("Unable to copy System.Native.so to output");
|
||||
}
|
||||
|
||||
return result.ExitCode;
|
||||
}
|
||||
|
||||
private string DetermineInFile(NativeCompileSettings config)
|
||||
{
|
||||
var intermediateDirectory = config.IntermediateDirectory;
|
||||
|
||||
var filename = Path.GetFileNameWithoutExtension(config.InputManagedAssemblyPath);
|
||||
|
||||
var infile = Path.Combine(intermediateDirectory, filename + InputExtension);
|
||||
|
||||
return infile;
|
||||
}
|
||||
|
||||
public string DetermineOutputFile(NativeCompileSettings config)
|
||||
{
|
||||
var intermediateDirectory = config.OutputDirectory;
|
||||
|
||||
var filename = Path.GetFileNameWithoutExtension(config.InputManagedAssemblyPath);
|
||||
|
||||
var outfile = Path.Combine(intermediateDirectory, filename + CompilerOutputExtension);
|
||||
|
||||
return outfile;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public class MacCppCompileStep : IPlatformNativeStep
|
||||
{
|
||||
public MacCppCompileStep(NativeCompileSettings config)
|
||||
{
|
||||
throw new NotImplementedException("Mac Cpp Not Supported Yet");
|
||||
}
|
||||
|
||||
public int Invoke()
|
||||
{
|
||||
throw new NotImplementedException("mac cpp Not supported yet.");
|
||||
}
|
||||
|
||||
public bool CheckPreReqs()
|
||||
{
|
||||
throw new NotImplementedException("mac cpp Not supported yet.");
|
||||
}
|
||||
|
||||
public string DetermineOutputFile(NativeCompileSettings config)
|
||||
{
|
||||
throw new NotImplementedException("Mac cpp Not supported yet.");
|
||||
}
|
||||
|
||||
public bool RequiresLinkStep()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public class MacLinkStep : IPlatformNativeStep
|
||||
{
|
||||
public int Invoke()
|
||||
{
|
||||
throw new NotImplementedException("Mac linker Not supported yet.");
|
||||
}
|
||||
|
||||
public bool CheckPreReqs()
|
||||
{
|
||||
throw new NotImplementedException("Mac linker Not supported yet.");
|
||||
}
|
||||
|
||||
public string DetermineOutputFile(NativeCompileSettings config)
|
||||
{
|
||||
throw new NotImplementedException("Mac linker Not supported yet.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
class WindowsCommon
|
||||
{
|
||||
internal static int SetVCVars()
|
||||
{
|
||||
// TODO: This is not working because it sets the environment variables in a child process
|
||||
// For now get around this by using x86_amd64 cross tools
|
||||
|
||||
// var commonToolsPath = Environment.GetEnvironmentVariable("VS140COMNTOOLS");
|
||||
|
||||
// var scriptPath = Path.Combine(commonToolsPath, "..\\..\\VC\\vcvarsall.bat");
|
||||
// var scriptArgs = "x86_amd64";
|
||||
|
||||
// var result = Command.Create(scriptPath, scriptArgs)
|
||||
// .ForwardStdErr()
|
||||
// .ForwardStdOut()
|
||||
// .Execute();
|
||||
|
||||
// return result.ExitCode;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public class WindowsCppCompileStep : IPlatformNativeStep
|
||||
{
|
||||
//TODO support x86
|
||||
private readonly string CompilerName = "cl.exe";
|
||||
|
||||
private readonly string VSBin = "..\\..\\VC\\bin\\amd64";
|
||||
private readonly string InputExtension = ".cpp";
|
||||
|
||||
private readonly string CompilerOutputExtension = ".obj";
|
||||
|
||||
private static readonly Dictionary<BuildConfiguration, string> ConfigurationCompilerOptionsMap = new Dictionary<BuildConfiguration, string>
|
||||
{
|
||||
{ BuildConfiguration.debug, "/ZI /nologo /W3 /WX- /sdl /Od /D CPPCODEGEN /D WIN32 /D _DEBUG /D _CONSOLE /D _LIB /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Gd /TP /wd4477 /errorReport:prompt" },
|
||||
{ BuildConfiguration.release, "/Zi /nologo /W3 /WX- /sdl /O2 /Oi /GL /D CPPCODEGEN /D WIN32 /D NDEBUG /D _CONSOLE /D _LIB /D _UNICODE /D UNICODE /Gm- /EHsc /MD /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Gd /TP /wd4477 /errorReport:prompt" }
|
||||
};
|
||||
|
||||
private string CompilerArgStr { get; set; }
|
||||
|
||||
private NativeCompileSettings config;
|
||||
|
||||
public WindowsCppCompileStep(NativeCompileSettings config)
|
||||
{
|
||||
this.config = config;
|
||||
InitializeArgs(config);
|
||||
}
|
||||
|
||||
public int Invoke()
|
||||
{
|
||||
var result = WindowsCommon.SetVCVars();
|
||||
if (result != 0)
|
||||
{
|
||||
Reporter.Error.WriteLine("vcvarsall.bat invocation failed.");
|
||||
return result;
|
||||
}
|
||||
|
||||
result = InvokeCompiler();
|
||||
if (result != 0)
|
||||
{
|
||||
Reporter.Error.WriteLine("Compilation of intermediate files failed.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool CheckPreReqs()
|
||||
{
|
||||
var vcInstallDir = Environment.GetEnvironmentVariable("VS140COMNTOOLS");
|
||||
return !string.IsNullOrEmpty(vcInstallDir);
|
||||
}
|
||||
|
||||
private void InitializeArgs(NativeCompileSettings config)
|
||||
{
|
||||
var argsList = new List<string>();
|
||||
|
||||
// Use a Custom Link Step
|
||||
argsList.Add("/c");
|
||||
|
||||
// Add Includes
|
||||
argsList.Add("/I");
|
||||
argsList.Add(Path.Combine(config.AppDepSDKPath, "CPPSdk\\Windows_NT"));
|
||||
|
||||
argsList.Add("/I");
|
||||
argsList.Add(Path.Combine(config.AppDepSDKPath, "CPPSdk"));
|
||||
|
||||
// Configuration Based Compiler Options
|
||||
argsList.Add(ConfigurationCompilerOptionsMap[config.BuildType]);
|
||||
|
||||
// Output
|
||||
var objOut = DetermineOutputFile(config);
|
||||
argsList.Add($"/Fo\"{objOut}\"");
|
||||
|
||||
// Input File
|
||||
var inCppFile = DetermineInFile(config);
|
||||
argsList.Add(inCppFile);
|
||||
|
||||
this.CompilerArgStr = string.Join(" ", argsList);
|
||||
}
|
||||
|
||||
private int InvokeCompiler()
|
||||
{
|
||||
var vcInstallDir = Environment.GetEnvironmentVariable("VS140COMNTOOLS");
|
||||
var compilerPath = Path.Combine(vcInstallDir, VSBin, CompilerName);
|
||||
|
||||
var result = Command.Create(compilerPath, CompilerArgStr)
|
||||
.ForwardStdErr()
|
||||
.ForwardStdOut()
|
||||
.Execute();
|
||||
|
||||
return result.ExitCode;
|
||||
}
|
||||
|
||||
private string DetermineInFile(NativeCompileSettings config)
|
||||
{
|
||||
var intermediateDirectory = config.IntermediateDirectory;
|
||||
|
||||
var filename = Path.GetFileNameWithoutExtension(config.InputManagedAssemblyPath);
|
||||
|
||||
var infile = Path.Combine(intermediateDirectory, filename + InputExtension);
|
||||
|
||||
return infile;
|
||||
}
|
||||
|
||||
public string DetermineOutputFile(NativeCompileSettings config)
|
||||
{
|
||||
var intermediateDirectory = config.IntermediateDirectory;
|
||||
|
||||
var filename = Path.GetFileNameWithoutExtension(config.InputManagedAssemblyPath);
|
||||
|
||||
var outfile = Path.Combine(intermediateDirectory, filename + CompilerOutputExtension);
|
||||
|
||||
return outfile;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public class WindowsLinkStep : IPlatformNativeStep
|
||||
{
|
||||
private readonly string LinkerName = "link.exe";
|
||||
private readonly string LinkerOutputExtension = ".exe";
|
||||
private readonly string VSBin = "..\\..\\VC\\bin\\amd64";
|
||||
|
||||
private readonly string InputExtension = ".obj";
|
||||
|
||||
private static readonly Dictionary<BuildConfiguration, string> ConfigurationLinkerOptionsMap = new Dictionary<BuildConfiguration, string>
|
||||
{
|
||||
{ BuildConfiguration.debug, "/NOLOGO /ERRORREPORT:PROMPT /MANIFEST /MANIFESTUAC:\"level='asInvoker' uiAccess='false'\" /manifest:embed /Debug /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT" },
|
||||
{ BuildConfiguration.release, "/NOLOGO /ERRORREPORT:PROMPT /INCREMENTAL:NO /OPT:REF /OPT:ICF /LTCG:incremental /MANIFEST /MANIFESTUAC:\"level='asInvoker' uiAccess='false'\" /manifest:embed /Debug /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT" }
|
||||
};
|
||||
|
||||
private static readonly Dictionary<NativeIntermediateMode, string[]> ModeLibMap = new Dictionary<NativeIntermediateMode, string[]>
|
||||
{
|
||||
{ NativeIntermediateMode.cpp, new string[] { "PortableRuntime.lib", "bootstrappercpp.lib" } },
|
||||
{ NativeIntermediateMode.ryujit, new string[] { "Runtime.lib", "bootstrapper.lib" } }
|
||||
};
|
||||
|
||||
private static readonly string[] ConstantLinkLibs = new string[]
|
||||
{
|
||||
"kernel32.lib",
|
||||
"user32.lib",
|
||||
"gdi32.lib",
|
||||
"winspool.lib",
|
||||
"comdlg32.lib",
|
||||
"advapi32.lib",
|
||||
"shell32.lib",
|
||||
"ole32.lib",
|
||||
"oleaut32.lib",
|
||||
"uuid.lib",
|
||||
"odbc32.lib",
|
||||
"odbccp32.lib"
|
||||
};
|
||||
|
||||
private string ArgStr { get; set; }
|
||||
private NativeCompileSettings config;
|
||||
|
||||
public WindowsLinkStep(NativeCompileSettings config)
|
||||
{
|
||||
this.config = config;
|
||||
InitializeArgs(config);
|
||||
}
|
||||
|
||||
public int Invoke()
|
||||
{
|
||||
var result = WindowsCommon.SetVCVars();
|
||||
if (result != 0)
|
||||
{
|
||||
Reporter.Error.WriteLine("vcvarsall.bat invocation failed.");
|
||||
return result;
|
||||
}
|
||||
|
||||
result = InvokeLinker();
|
||||
if (result != 0)
|
||||
{
|
||||
Reporter.Error.WriteLine("Linking of intermediate files failed.");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool CheckPreReqs()
|
||||
{
|
||||
var vcInstallDir = Environment.GetEnvironmentVariable("VS140COMNTOOLS");
|
||||
return !string.IsNullOrEmpty(vcInstallDir);
|
||||
}
|
||||
|
||||
private void InitializeArgs(NativeCompileSettings config)
|
||||
{
|
||||
var argsList = new List<string>();
|
||||
|
||||
// Configuration Based Linker Options
|
||||
argsList.Add(ConfigurationLinkerOptionsMap[config.BuildType]);
|
||||
|
||||
//Output
|
||||
var outFile = DetermineOutputFile(config);
|
||||
argsList.Add($"/out:\"{outFile}\"");
|
||||
|
||||
// Constant Libs
|
||||
argsList.Add(string.Join(" ", ConstantLinkLibs));
|
||||
|
||||
// SDK Libs
|
||||
var SDKLibs = ModeLibMap[config.NativeMode];
|
||||
foreach (var lib in SDKLibs)
|
||||
{
|
||||
argsList.Add(Path.Combine(config.IlcPath, lib));
|
||||
}
|
||||
|
||||
// Link Libs
|
||||
foreach(var path in config.LinkLibPaths){
|
||||
argsList.Add($"\"{path}\"");
|
||||
}
|
||||
|
||||
//arch
|
||||
argsList.Add($"/MACHINE:{config.Architecture}");
|
||||
|
||||
//Input Obj file
|
||||
var inputFile = DetermineInputFile(config);
|
||||
argsList.Add($"\"{inputFile}\"");
|
||||
|
||||
this.ArgStr = string.Join(" ", argsList);
|
||||
}
|
||||
|
||||
private int InvokeLinker()
|
||||
{
|
||||
var vcInstallDir = Environment.GetEnvironmentVariable("VS140COMNTOOLS");
|
||||
var linkerPath = Path.Combine(vcInstallDir, VSBin, LinkerName);
|
||||
|
||||
var result = Command.Create(linkerPath, ArgStr)
|
||||
.ForwardStdErr()
|
||||
.ForwardStdOut()
|
||||
.Execute();
|
||||
|
||||
return result.ExitCode;
|
||||
}
|
||||
|
||||
public string DetermineOutputFile(NativeCompileSettings config)
|
||||
{
|
||||
var outputDirectory = config.OutputDirectory;
|
||||
|
||||
var filename = Path.GetFileNameWithoutExtension(config.InputManagedAssemblyPath);
|
||||
|
||||
var outFile = Path.Combine(outputDirectory, filename + LinkerOutputExtension);
|
||||
|
||||
return outFile;
|
||||
}
|
||||
|
||||
private string DetermineInputFile(NativeCompileSettings config)
|
||||
{
|
||||
var intermediateDirectory = config.IntermediateDirectory;
|
||||
|
||||
var filename = Path.GetFileNameWithoutExtension(config.InputManagedAssemblyPath);
|
||||
|
||||
var infile = Path.Combine(intermediateDirectory, filename + InputExtension);
|
||||
|
||||
return infile;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>172485dd-b94e-4f3e-851e-cf23908ff960</ProjectGuid>
|
||||
<RootNamespace>Microsoft.DotNet.Tools.Compiler.Native</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public class NativeCompileSettings
|
||||
{
|
||||
public string LogPath { get; set; }
|
||||
public string InputManagedAssemblyPath { get; set; }
|
||||
|
||||
public string OutputDirectory { get; set; }
|
||||
public string IntermediateDirectory { get; set; }
|
||||
|
||||
public BuildConfiguration BuildType { get; set; }
|
||||
public ArchitectureMode Architecture { get; set; }
|
||||
public NativeIntermediateMode NativeMode { get; set; }
|
||||
public OSMode OS { get; set; }
|
||||
|
||||
public List<string> ReferencePaths { get; set; }
|
||||
|
||||
// Optional Customization Points (Can be null)
|
||||
public string IlcArgs { get; set; }
|
||||
public List<string> LinkLibPaths { get; set; }
|
||||
|
||||
// Required Customization Points (Must have default)
|
||||
public string AppDepSDKPath { get; set; }
|
||||
public string IlcPath { get; set; }
|
||||
|
||||
public NativeCompileSettings()
|
||||
{
|
||||
LinkLibPaths = new List<string>();
|
||||
ReferencePaths = new List<string>();
|
||||
}
|
||||
|
||||
public string DetermineFinalOutputPath()
|
||||
{
|
||||
var outputDirectory = this.OutputDirectory;
|
||||
|
||||
var filename = Path.GetFileNameWithoutExtension(this.InputManagedAssemblyPath);
|
||||
|
||||
var outFile = Path.Combine(outputDirectory, filename + Constants.ExeSuffix);
|
||||
|
||||
return outFile;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
41
src/Microsoft.DotNet.Tools.Compiler.Native/NativeCompiler.cs
Normal file
41
src/Microsoft.DotNet.Tools.Compiler.Native/NativeCompiler.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public class NativeCompiler
|
||||
{
|
||||
public static NativeCompiler Create(NativeCompileSettings config)
|
||||
{
|
||||
var invoker = new ILCompilerInvoker(config);
|
||||
var intCompiler = IntermediateCompiler.Create(config);
|
||||
|
||||
var nc = new NativeCompiler()
|
||||
{
|
||||
invoker = invoker,
|
||||
intermediateCompiler = intCompiler
|
||||
};
|
||||
|
||||
return nc;
|
||||
}
|
||||
|
||||
private ILCompilerInvoker invoker;
|
||||
private IntermediateCompiler intermediateCompiler;
|
||||
|
||||
public bool CompileToNative(NativeCompileSettings config)
|
||||
{
|
||||
int result = invoker.Invoke();
|
||||
if(result != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
result = intermediateCompiler.Invoke();
|
||||
if (result != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
330
src/Microsoft.DotNet.Tools.Compiler.Native/Program.cs
Normal file
330
src/Microsoft.DotNet.Tools.Compiler.Native/Program.cs
Normal file
|
@ -0,0 +1,330 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
DebugHelper.HandleDebugSwitch(ref args);
|
||||
|
||||
var app = SetupApp();
|
||||
|
||||
return ExecuteApp(app, args);
|
||||
}
|
||||
|
||||
private static int ExecuteApp(CommandLineApplication app, string[] args)
|
||||
{
|
||||
// Support Response File
|
||||
foreach(var arg in args)
|
||||
{
|
||||
if(arg.Contains(".rsp"))
|
||||
{
|
||||
args = ParseResponseFile(arg);
|
||||
|
||||
if (args == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return app.Execute(args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
#if DEBUG
|
||||
System.Console.WriteLine(ex);
|
||||
#else
|
||||
Reporter.Error.WriteLine(ex.Message);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] ParseResponseFile(string rspPath)
|
||||
{
|
||||
if (!File.Exists(rspPath))
|
||||
{
|
||||
Reporter.Error.WriteLine("Invalid Response File Path");
|
||||
return null;
|
||||
}
|
||||
|
||||
string content = null;
|
||||
try
|
||||
{
|
||||
content = File.ReadAllText(rspPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Reporter.Error.WriteLine("Unable to Read Response File");
|
||||
return null;
|
||||
}
|
||||
|
||||
string[] nArgs = content.Split('\n');
|
||||
return nArgs;
|
||||
}
|
||||
|
||||
private static CommandLineApplication SetupApp()
|
||||
{
|
||||
var app = new CommandLineApplication
|
||||
{
|
||||
Name = "dotnet compile native",
|
||||
FullName = "IL to Native compiler",
|
||||
Description = "IL to Native compiler Compiler for the .NET Platform"
|
||||
};
|
||||
|
||||
app.HelpOption("-h|--help");
|
||||
|
||||
var managedInputArg = app.Argument("<INPUT_ASSEMBLY>", "The managed input assembly to compile to native.");
|
||||
var outputArg = app.Option("-o|--out <OUTPUT_DIR>", "Output Directory for native executable.", CommandOptionType.SingleValue);
|
||||
var intermediateArg = app.Option("-t|--temp-output <OUTPUT_DIR>", "Directory for intermediate files.", CommandOptionType.SingleValue);
|
||||
var buildConfigArg = app.Option("-c|--configuration <TYPE>", "debug/release build configuration. Defaults to debug.", CommandOptionType.SingleValue);
|
||||
var modeArg = app.Option("-m|--mode <MODE>", "Code Generation mode. Defaults to ryujit. ", CommandOptionType.SingleValue);
|
||||
|
||||
var referencesArg = app.Option("-r|--reference <REF_PATH>", "Use to specify Managed DLL references of the app.", CommandOptionType.MultipleValue);
|
||||
|
||||
// Custom Extensibility Points to support CoreRT workflow TODO better descriptions
|
||||
var ilcArgs = app.Option("--ilcargs <CODEGEN>", "Use to specify custom arguments for the IL Compiler.", CommandOptionType.SingleValue);
|
||||
var ilcPathArg = app.Option("--ilcpath <ILC_PATH>", "Use to plug in a custom built ilc.exe", CommandOptionType.SingleValue);
|
||||
var linklibArg = app.Option("--linklib <LINKLIB>", "Use to link in additional static libs", CommandOptionType.MultipleValue);
|
||||
|
||||
// TEMPORARY Hack until CoreRT compatible Framework Libs are available
|
||||
var appdepSdkPathArg = app.Option("--appdepsdk <SDK>", "Use to plug in custom appdepsdk path", CommandOptionType.SingleValue);
|
||||
|
||||
// Optional Log Path
|
||||
var logpathArg = app.Option("--logpath <LOG_PATH>", "Use to dump Native Compilation Logs to a file.", CommandOptionType.SingleValue);
|
||||
|
||||
app.OnExecute(() =>
|
||||
{
|
||||
var cmdLineArgs = new ArgValues()
|
||||
{
|
||||
InputManagedAssemblyPath = managedInputArg.Value,
|
||||
OutputDirectory = outputArg.Value(),
|
||||
IntermediateDirectory = intermediateArg.Value(),
|
||||
Architecture = "x64",
|
||||
BuildConfiguration = buildConfigArg.Value(),
|
||||
NativeMode = modeArg.Value(),
|
||||
ReferencePaths = referencesArg.Values,
|
||||
IlcArgs = ilcArgs.Value(),
|
||||
IlcPath = ilcPathArg.Value(),
|
||||
LinkLibPaths = linklibArg.Values,
|
||||
AppDepSDKPath = appdepSdkPathArg.Value(),
|
||||
LogPath = logpathArg.Value()
|
||||
};
|
||||
|
||||
var config = ParseAndValidateArgs(cmdLineArgs);
|
||||
|
||||
DirectoryExtensions.CleanOrCreateDirectory(config.OutputDirectory);
|
||||
DirectoryExtensions.CleanOrCreateDirectory(config.IntermediateDirectory);
|
||||
|
||||
var nativeCompiler = NativeCompiler.Create(config);
|
||||
|
||||
var result = nativeCompiler.CompileToNative(config);
|
||||
|
||||
return result ? 0 : 1;
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
private static NativeCompileSettings ParseAndValidateArgs(ArgValues args)
|
||||
{
|
||||
var config = new NativeCompileSettings();
|
||||
|
||||
// Managed Input
|
||||
if (string.IsNullOrEmpty(args.InputManagedAssemblyPath) || !File.Exists(args.InputManagedAssemblyPath))
|
||||
{
|
||||
//TODO make this message good
|
||||
throw new Exception("Invalid Managed Assembly Argument.");
|
||||
}
|
||||
|
||||
config.InputManagedAssemblyPath = Path.GetFullPath(args.InputManagedAssemblyPath);
|
||||
|
||||
// Architecture
|
||||
if(string.IsNullOrEmpty(args.Architecture))
|
||||
{
|
||||
config.Architecture = RuntimeExtensions.GetCurrentArchitecture();
|
||||
|
||||
// CoreRT does not support x86 yet
|
||||
if (config.Architecture != ArchitectureMode.x64)
|
||||
{
|
||||
throw new Exception("Native Compilation currently only supported for x64.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
config.Architecture = EnumExtensions.Parse<ArchitectureMode>(args.Architecture.ToLower());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Invalid Architecture Option.");
|
||||
}
|
||||
}
|
||||
|
||||
// BuildConfiguration
|
||||
if(string.IsNullOrEmpty(args.BuildConfiguration))
|
||||
{
|
||||
config.BuildType = GetDefaultBuildType();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
config.BuildType = EnumExtensions.Parse<BuildConfiguration>(args.BuildConfiguration.ToLower());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Invalid Configuration Option.");
|
||||
}
|
||||
}
|
||||
|
||||
// Output
|
||||
if(string.IsNullOrEmpty(args.OutputDirectory))
|
||||
{
|
||||
config.OutputDirectory = GetDefaultOutputDir(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.OutputDirectory = args.OutputDirectory;
|
||||
}
|
||||
|
||||
// Intermediate
|
||||
if(string.IsNullOrEmpty(args.IntermediateDirectory))
|
||||
{
|
||||
config.IntermediateDirectory = GetDefaultIntermediateDir(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.IntermediateDirectory = args.IntermediateDirectory;
|
||||
}
|
||||
|
||||
// Mode
|
||||
if (string.IsNullOrEmpty(args.NativeMode))
|
||||
{
|
||||
config.NativeMode = GetDefaultNativeMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
config.NativeMode = EnumExtensions.Parse<NativeIntermediateMode>(args.NativeMode.ToLower());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Invalid Mode Option.");
|
||||
}
|
||||
}
|
||||
|
||||
// AppDeps (TEMP)
|
||||
if(!string.IsNullOrEmpty(args.AppDepSDKPath))
|
||||
{
|
||||
if (!Directory.Exists(args.AppDepSDKPath))
|
||||
{
|
||||
throw new Exception("AppDepSDK Directory does not exist.");
|
||||
}
|
||||
|
||||
config.AppDepSDKPath = args.AppDepSDKPath;
|
||||
|
||||
var reference = Path.Combine(config.AppDepSDKPath, "*.dll");
|
||||
config.ReferencePaths.Add(reference);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.AppDepSDKPath = GetDefaultAppDepSDKPath();
|
||||
|
||||
var reference = Path.Combine(config.AppDepSDKPath, "*.dll");
|
||||
config.ReferencePaths.Add(reference);
|
||||
}
|
||||
|
||||
// IlcPath
|
||||
if (!string.IsNullOrEmpty(args.IlcPath))
|
||||
{
|
||||
if (!Directory.Exists(args.IlcPath))
|
||||
{
|
||||
throw new Exception("ILC Directory does not exist.");
|
||||
}
|
||||
|
||||
config.IlcPath = args.IlcPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
config.IlcPath = GetDefaultIlcPath();
|
||||
}
|
||||
|
||||
// logpath
|
||||
if (!string.IsNullOrEmpty(args.LogPath))
|
||||
{
|
||||
config.LogPath = Path.GetFullPath(args.LogPath);
|
||||
}
|
||||
|
||||
// CodeGenPath
|
||||
if (!string.IsNullOrEmpty(args.IlcArgs))
|
||||
{
|
||||
config.IlcArgs = Path.GetFullPath(args.IlcArgs);
|
||||
}
|
||||
|
||||
// Reference Paths
|
||||
foreach (var reference in args.ReferencePaths)
|
||||
{
|
||||
config.ReferencePaths.Add(Path.GetFullPath(reference));
|
||||
}
|
||||
|
||||
// Link Libs
|
||||
foreach (var lib in args.LinkLibPaths)
|
||||
{
|
||||
config.LinkLibPaths.Add(lib);
|
||||
}
|
||||
|
||||
// OS
|
||||
config.OS = RuntimeInformationExtensions.GetCurrentOS();
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
private static string GetDefaultOutputDir(NativeCompileSettings config)
|
||||
{
|
||||
var dir = Path.Combine(Constants.BinDirectoryName, config.Architecture.ToString(), config.BuildType.ToString(), "native");
|
||||
|
||||
return Path.GetFullPath(dir);
|
||||
}
|
||||
|
||||
private static string GetDefaultIntermediateDir(NativeCompileSettings config)
|
||||
{
|
||||
var dir = Path.Combine(Constants.ObjDirectoryName, config.Architecture.ToString(), config.BuildType.ToString(), "native");
|
||||
|
||||
return Path.GetFullPath(dir);
|
||||
}
|
||||
|
||||
private static BuildConfiguration GetDefaultBuildType()
|
||||
{
|
||||
return BuildConfiguration.debug;
|
||||
}
|
||||
|
||||
private static NativeIntermediateMode GetDefaultNativeMode()
|
||||
{
|
||||
return NativeIntermediateMode.ryujit;
|
||||
}
|
||||
|
||||
private static string GetDefaultAppDepSDKPath()
|
||||
{
|
||||
var appRoot = AppContext.BaseDirectory;
|
||||
|
||||
var dir = Path.Combine(appRoot, "appdepsdk");
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
private static string GetDefaultIlcPath()
|
||||
{
|
||||
return AppContext.BaseDirectory;
|
||||
}
|
||||
}
|
||||
}
|
50
src/Microsoft.DotNet.Tools.Compiler.Native/README.md
Normal file
50
src/Microsoft.DotNet.Tools.Compiler.Native/README.md
Normal file
|
@ -0,0 +1,50 @@
|
|||
dotnet-compile
|
||||
===========
|
||||
|
||||
**NAME**
|
||||
dotnet-compile-native -- Compiles IL binaries to native binaries.
|
||||
|
||||
**SYNOPSIS**
|
||||
dotnet compile [options]
|
||||
|
||||
**DESCRIPTION**
|
||||
The `compile-native` command compiles IL assemblies to native machine code. It is used by `dotnet-compile --native`.
|
||||
|
||||
The output is a native exe that conforms to the architecture of the underlying operating system (i.e. running on 64-bit OS will produce a native 64-bit exe). This can be overriden via the --arch switch and specifying the wanted architecture. The executable has a default extension of "" on Linux and OS X and ".exe" on Windows. The source must include a `static void Main(string[] args) entry point and specify compilerOptions.emitEntryPoint in the project.json.
|
||||
|
||||
Output files are written to the child `bin` folder, which will be created if it doesn't exist. Files will be overwritten as needed.
|
||||
|
||||
**Options**
|
||||
|
||||
--appdepsdk <SDK_PATH>
|
||||
Path to custom AppDepSDK
|
||||
|
||||
-c, --configuration [debug|release]
|
||||
Build configuration. Defaults to `debug`.
|
||||
|
||||
--ilcargs <args>
|
||||
Custom arguments for the IL Compiler.
|
||||
|
||||
--ilcpath <ILC_PATH>
|
||||
Path to a custom ilc.exe
|
||||
|
||||
--linklib <LIB_PATH>
|
||||
Path to static lib to link
|
||||
|
||||
--logpath <LOG_PATH>
|
||||
Enables logging and writes native compilation logs to the given path.
|
||||
|
||||
-m, --mode [cpp|ryujit|custom]
|
||||
Code generation mode. Defaults to ryujit.
|
||||
|
||||
-o, --out directoryname
|
||||
Output directory for the native executable.
|
||||
|
||||
-r, --reference
|
||||
Path to a managed dll reference for the app.
|
||||
|
||||
-t, --temp-out
|
||||
Specifies temporary directory for intermediate files.
|
||||
|
||||
-v, --verbose
|
||||
Prints verbose logging information, to follow the flow of execution of the command.
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
static class RuntimeExtensions
|
||||
{
|
||||
internal static ArchitectureMode GetCurrentArchitecture()
|
||||
{
|
||||
#if NET451
|
||||
return Environment.Is64BitProcess ? ArchitectureMode.x64 : ArchitectureMode.x86;
|
||||
#else
|
||||
return IntPtr.Size == 8 ? ArchitectureMode.x64 : ArchitectureMode.x86;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
static class RuntimeInformationExtensions
|
||||
{
|
||||
internal static OSMode GetCurrentOS()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return OSMode.Windows;
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
return OSMode.Mac;
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
return OSMode.Linux;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unrecognized OS. dotnet-compile-native is compatible with Windows, OSX, and Linux");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "appdepsdk",
|
||||
"version": "1.0.0-*",
|
||||
"compilationOptions": {
|
||||
"emitEntryPoint": true
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.DotNet.AppDep":"1.0.1-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"dnxcore50": { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public enum ArchitectureMode
|
||||
{
|
||||
x86,
|
||||
x64
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public enum BuildConfiguration
|
||||
{
|
||||
debug,
|
||||
release
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public enum NativeIntermediateMode
|
||||
{
|
||||
cpp,
|
||||
ryujit,
|
||||
custom
|
||||
}
|
||||
}
|
12
src/Microsoft.DotNet.Tools.Compiler.Native/enums/OSMode.cs
Normal file
12
src/Microsoft.DotNet.Tools.Compiler.Native/enums/OSMode.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Native
|
||||
{
|
||||
public enum OSMode
|
||||
{
|
||||
Linux,
|
||||
Windows,
|
||||
Mac
|
||||
}
|
||||
}
|
33
src/Microsoft.DotNet.Tools.Compiler.Native/project.json
Normal file
33
src/Microsoft.DotNet.Tools.Compiler.Native/project.json
Normal file
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "dotnet-compile-native",
|
||||
"version": "1.0.0-*",
|
||||
"compilationOptions": {
|
||||
"emitEntryPoint": true
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms":"1.0.1-beta-23504",
|
||||
"Microsoft.NETCore.Runtime": "1.0.1-beta-23504",
|
||||
"System.Console": "4.0.0-beta-23504",
|
||||
"System.Collections": "4.0.11-beta-23504",
|
||||
"System.Linq": "4.0.1-beta-23504",
|
||||
"Microsoft.NETCore.TestHost": "1.0.0-beta-23504",
|
||||
"System.Diagnostics.Process": "4.1.0-beta-23504",
|
||||
"System.IO": "4.0.11-beta-23504",
|
||||
"System.IO.FileSystem": "4.0.1-beta-23504",
|
||||
"System.AppContext": "4.0.1-beta-23504",
|
||||
"Microsoft.DotNet.Cli.Utils": {
|
||||
"type": "build",
|
||||
"version": "1.0.0-*"
|
||||
},
|
||||
"Microsoft.Extensions.CommandLineUtils.Sources": {
|
||||
"type": "build",
|
||||
"version": "1.0.0-*"
|
||||
},
|
||||
"Microsoft.DotNet.ILCompiler": "1.0.1-*",
|
||||
"Microsoft.DotNet.ObjectWriter": "1.0.2-*",
|
||||
"Microsoft.DotNet.RyuJit": "1.0.0-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"dnxcore50": { }
|
||||
}
|
||||
}
|
|
@ -35,7 +35,12 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
var configuration = app.Option("-c|--configuration <CONFIGURATION>", "Configuration under which to build", CommandOptionType.SingleValue);
|
||||
var noProjectDependencies = app.Option("--no-project-dependencies", "Skips building project references.", CommandOptionType.NoValue);
|
||||
var project = app.Argument("<PROJECT>", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory");
|
||||
|
||||
// Native Args
|
||||
var native = app.Option("-n|--native", "Compiles source to native machine code.", CommandOptionType.NoValue);
|
||||
var arch = app.Option("-a|--arch <ARCH>", "The architecture for which to compile. x64 only currently supported.", CommandOptionType.SingleValue);
|
||||
var ilcArgs = app.Option("--ilc-args <ARGS>", "String to pass directory to ilc in native compilation.", CommandOptionType.SingleValue);
|
||||
var cppMode = app.Option("--cpp", "Flag to do native compilation with C++ code generator.", CommandOptionType.NoValue);
|
||||
|
||||
app.OnExecute(() =>
|
||||
{
|
||||
|
@ -48,8 +53,12 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
var buildProjectReferences = !noProjectDependencies.HasValue();
|
||||
var isNative = native.HasValue();
|
||||
var isCppMode = cppMode.HasValue();
|
||||
var archValue = arch.Value();
|
||||
var ilcArgsValue = ilcArgs.Value();
|
||||
var configValue = configuration.Value() ?? Constants.DefaultConfiguration;
|
||||
var outputValue = output.Value();
|
||||
var intermediateValue = intermediateOutput.Value();
|
||||
|
||||
// Load project contexts for each framework and compile them
|
||||
bool success = true;
|
||||
|
@ -61,7 +70,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
success &= Compile(context, configValue, outputValue, intermediateOutput.Value(), buildProjectReferences);
|
||||
if (isNative && success)
|
||||
{
|
||||
success &= CompileNative(context, configValue, outputValue, buildProjectReferences);
|
||||
success &= CompileNative(context, configValue, outputValue, buildProjectReferences, intermediateValue, archValue, ilcArgsValue, isCppMode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,15 +92,90 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
}
|
||||
}
|
||||
|
||||
private static bool CompileNative(ProjectContext context, string configuration, string outputOptionValue, bool buildProjectReferences)
|
||||
private static bool CompileNative(ProjectContext context, string configuration, string outputOptionValue, bool buildProjectReferences, string intermediateOutputValue, string archValue, string ilcArgsValue, bool isCppMode)
|
||||
{
|
||||
string outputPath = Path.Combine(GetOutputPath(context, configuration, outputOptionValue), "native");
|
||||
var outputPath = Path.Combine(GetOutputPath(context, configuration, outputOptionValue), "native");
|
||||
var intermediateOutputPath = GetIntermediateOutputPath(context, configuration, intermediateOutputValue, outputOptionValue);
|
||||
|
||||
Directory.CreateDirectory(outputPath);
|
||||
Directory.CreateDirectory(intermediateOutputPath);
|
||||
|
||||
var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration);
|
||||
var managedBinaryPath = Path.Combine(outputPath, context.ProjectFile.Name + (compilationOptions.EmitEntryPoint.GetValueOrDefault() ? ".exe" : ".dll"));
|
||||
var managedOutput = GetProjectOutput(context.ProjectFile, context.TargetFramework, configuration, outputPath);
|
||||
|
||||
var nativeArgs = new List<string>();
|
||||
|
||||
// Input Assembly
|
||||
nativeArgs.Add($"\"{managedOutput}\"");
|
||||
|
||||
// ILC Args
|
||||
nativeArgs.Add("--ilcargs");
|
||||
nativeArgs.Add($"\"{ilcArgsValue}\"");
|
||||
|
||||
// CodeGen Mode
|
||||
if(isCppMode)
|
||||
{
|
||||
nativeArgs.Add("--mode");
|
||||
nativeArgs.Add("cpp");
|
||||
}
|
||||
|
||||
// Configuration
|
||||
if (configuration != null)
|
||||
{
|
||||
nativeArgs.Add("--configuration");
|
||||
nativeArgs.Add(configuration);
|
||||
}
|
||||
|
||||
// Architecture
|
||||
if (archValue != null)
|
||||
{
|
||||
nativeArgs.Add("--arch");
|
||||
nativeArgs.Add(archValue);
|
||||
}
|
||||
|
||||
// Intermediate Path
|
||||
nativeArgs.Add("--temp-output");
|
||||
nativeArgs.Add($"\"{intermediateOutputPath}\"");
|
||||
|
||||
// Output Path
|
||||
nativeArgs.Add("--output");
|
||||
nativeArgs.Add($"\"{outputPath}\"");
|
||||
|
||||
// Dependencies
|
||||
var exporter = context.CreateExporter(configuration);
|
||||
var dependencies = exporter.GetDependencies().ToList();
|
||||
foreach (var dependency in dependencies)
|
||||
{
|
||||
var projectDependency = dependency.Library as ProjectDescription;
|
||||
|
||||
if (projectDependency != null)
|
||||
{
|
||||
if (projectDependency.Project.Files.SourceFiles.Any())
|
||||
{
|
||||
var projectOutputPath = GetProjectOutput(projectDependency.Project, projectDependency.Framework, configuration, outputPath);
|
||||
nativeArgs.Add("-r");
|
||||
nativeArgs.Add($"\"{projectOutputPath}\"");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach(var dep in dependency.RuntimeAssemblies)
|
||||
{
|
||||
nativeArgs.Add("-r");
|
||||
nativeArgs.Add($"\"{dep.ResolvedPath}\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write Response File
|
||||
var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile-native.{context.ProjectFile.Name}.rsp");
|
||||
File.WriteAllLines(rsp, nativeArgs);
|
||||
|
||||
// TODO Add -r assembly.dll for all Nuget References
|
||||
// Need CoreRT Framework published to nuget
|
||||
|
||||
// Do Native Compilation
|
||||
var result = Command.Create($"dotnet-compile-native", $"\"{managedBinaryPath}\" \"{outputPath}\"")
|
||||
var result = Command.Create($"dotnet-compile-native", $"--rsp \"{rsp}\"")
|
||||
.ForwardStdErr()
|
||||
.ForwardStdOut()
|
||||
.Execute();
|
||||
|
|
Loading…
Add table
Reference in a new issue