From 907cf006549e85a30d53c99bbe40199cc6a57acf Mon Sep 17 00:00:00 2001 From: schellap Date: Sat, 9 Jan 2016 23:33:22 -0800 Subject: [PATCH] Split corehost into serviceable DLL and EXE --- scripts/compile/compile-stage.ps1 | 3 +- scripts/compile/compile-stage.sh | 8 +++- .../CommandResolver.cs | 2 +- src/Microsoft.DotNet.Cli.Utils/Constants.cs | 14 ++++++- src/Microsoft.DotNet.Cli.Utils/CoreHost.cs | 41 ++++++++++++++----- .../ProjectContextExtensions.cs | 2 +- .../PublishCommand.cs | 21 ++++++---- src/corehost/cli/CMakeLists.txt | 8 +--- src/corehost/cli/clihost.cpp | 2 - src/corehost/cli/libhost.h | 4 ++ src/corehost/corehost.cpp | 17 +++----- 11 files changed, 77 insertions(+), 45 deletions(-) create mode 100644 src/corehost/cli/libhost.h diff --git a/scripts/compile/compile-stage.ps1 b/scripts/compile/compile-stage.ps1 index 7f565d578..8683a7d77 100644 --- a/scripts/compile/compile-stage.ps1 +++ b/scripts/compile/compile-stage.ps1 @@ -79,6 +79,7 @@ cp -rec "$RuntimeOutputDir\*" "$OutputDir\bin" # Deploy the CLR host to the output cp "$HostDir\corehost.exe" "$OutputDir\bin" +cp "$HostDir\clihost.dll" "$OutputDir\bin" # corehostify externally-provided binaries (csc, vbc, etc.) $BinariesForCoreHost | ForEach-Object { @@ -99,4 +100,4 @@ cp "$RepoRoot\scripts\dotnet-dnx.cmd" "$OutputDir\bin\dotnet-dnx.cmd" # Copy in AppDeps $env:PATH = "$OutputDir\bin;$StartPath" header "Acquiring Native App Dependencies" -_cmd "$RepoRoot\scripts\build\build_appdeps.cmd ""$OutputDir""" \ No newline at end of file +_cmd "$RepoRoot\scripts\build\build_appdeps.cmd ""$OutputDir""" diff --git a/scripts/compile/compile-stage.sh b/scripts/compile/compile-stage.sh index 47d2021f3..ea254bd04 100755 --- a/scripts/compile/compile-stage.sh +++ b/scripts/compile/compile-stage.sh @@ -79,7 +79,13 @@ done cp -R $RUNTIME_OUTPUT_DIR/* $OUTPUT_DIR/bin # Deploy CLR host to the output +if [[ "$OSNAME" == "osx" ]]; then + COREHOST_LIBNAME=libclihost.dylib +else + COREHOST_LIBNAME=libclihost.so +fi cp "$HOST_DIR/corehost" "$OUTPUT_DIR/bin" +cp "$HOST_DIR/${COREHOST_LIBNAME}" "$OUTPUT_DIR/bin" # corehostify externally-provided binaries (csc, vbc, etc.) for binary in ${BINARIES_FOR_COREHOST[@]} @@ -118,4 +124,4 @@ fi # Stamp the output with the commit metadata COMMIT=$(git rev-parse HEAD) echo $COMMIT > $OUTPUT_DIR/.version -echo $DOTNET_BUILD_VERSION >> $OUTPUT_DIR/.version \ No newline at end of file +echo $DOTNET_BUILD_VERSION >> $OUTPUT_DIR/.version diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs index 0e3e35156..7c5114fe8 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs @@ -170,7 +170,7 @@ namespace Microsoft.DotNet.Cli.Utils .Select(f => Path.Combine(packageDir, f)) .FirstOrDefault(); - fileName = CoreHost.Path; + fileName = CoreHost.HostExePath; var depsArg = string.Empty; diff --git a/src/Microsoft.DotNet.Cli.Utils/Constants.cs b/src/Microsoft.DotNet.Cli.Utils/Constants.cs index e4edf3504..78b4019ae 100644 --- a/src/Microsoft.DotNet.Cli.Utils/Constants.cs +++ b/src/Microsoft.DotNet.Cli.Utils/Constants.cs @@ -9,8 +9,12 @@ namespace Microsoft.DotNet.Cli.Utils { public static readonly string ProjectFileName = "project.json"; public static readonly string ExeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty; - - public static readonly string HostExecutableName = "corehost" + ExeSuffix; + + // Priority order of runnable suffixes to look for and run + public static readonly string[] RunnableSuffixes = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? new string[] { ".exe", ".cmd", ".bat" } + : new string[] { string.Empty }; + public static readonly string DefaultConfiguration = "Debug"; public static readonly string BinDirectoryName = "bin"; public static readonly string ObjDirectoryName = "obj"; @@ -26,5 +30,11 @@ namespace Microsoft.DotNet.Cli.Utils public static readonly string StaticLibSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".lib" : ".a" ; public static readonly string ResponseFileSuffix = ".rsp"; + + public static readonly string HostExecutableName = "corehost" + ExeSuffix; + public static readonly string[] HostBinaryNames = new string[] { + HostExecutableName, + (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "clihost" : "libclihost") + DynamicLibSuffix + }; } } diff --git a/src/Microsoft.DotNet.Cli.Utils/CoreHost.cs b/src/Microsoft.DotNet.Cli.Utils/CoreHost.cs index 8bffb58c4..a428e90e4 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CoreHost.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CoreHost.cs @@ -5,26 +5,45 @@ namespace Microsoft.DotNet.Cli.Utils { public static class CoreHost { - internal static string _path; + internal static string _hostDir; + internal static string _hostExePath; - public static string FileName = "corehost" + FileNameSuffixes.CurrentPlatform.Exe; - - public static string Path + public static string HostExePath { get { - if (_path == null) + if (_hostExePath == null) { - _path = Env.GetCommandPath(FileName, new[] {string.Empty}); + _hostExePath = Path.Combine(HostDir, Constants.HostExecutableName); } - - return _path; + return _hostExePath; } } - public static void CopyTo(string destinationPath) + private static string HostDir { - File.Copy(Path, destinationPath, overwrite: true); + get + { + if (_hostDir == null) + { + _hostDir = Path.GetDirectoryName(Env.GetCommandPath( + Constants.HostExecutableName, new[] {string.Empty})); + } + + return _hostDir; + } + } + + public static void CopyTo(string destinationPath, string hostExeName) + { + foreach (var binaryName in Constants.HostBinaryNames) + { + var outputBinaryName = binaryName.Equals(Constants.HostExecutableName) + ? hostExeName : binaryName; + var outputBinaryPath = Path.Combine(destinationPath, outputBinaryName); + var hostBinaryPath = Path.Combine(HostDir, binaryName); + File.Copy(hostBinaryPath, outputBinaryPath, overwrite: true); + } } } -} \ No newline at end of file +} diff --git a/src/Microsoft.DotNet.Compiler.Common/ProjectContextExtensions.cs b/src/Microsoft.DotNet.Compiler.Common/ProjectContextExtensions.cs index 2e8384229..5561bfde0 100644 --- a/src/Microsoft.DotNet.Compiler.Common/ProjectContextExtensions.cs +++ b/src/Microsoft.DotNet.Compiler.Common/ProjectContextExtensions.cs @@ -102,7 +102,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common .SelectMany(e => e.RuntimeAssets()) .CopyTo(outputPath); - CoreHost.CopyTo(Path.Combine(outputPath, context.ProjectFile.Name + Constants.ExeSuffix)); + CoreHost.CopyTo(outputPath, context.ProjectFile.Name + Constants.ExeSuffix); } } diff --git a/src/Microsoft.DotNet.Tools.Publish/PublishCommand.cs b/src/Microsoft.DotNet.Tools.Publish/PublishCommand.cs index a22d8eb80..98c62a336 100644 --- a/src/Microsoft.DotNet.Tools.Publish/PublishCommand.cs +++ b/src/Microsoft.DotNet.Tools.Publish/PublishCommand.cs @@ -149,18 +149,21 @@ namespace Microsoft.DotNet.Tools.Publish return 0; } - var hostPath = Path.Combine(AppContext.BaseDirectory, Constants.HostExecutableName); - if (!File.Exists(hostPath)) + foreach (var binaryName in Constants.HostBinaryNames) { - Reporter.Error.WriteLine($"Cannot find {Constants.HostExecutableName} in the dotnet directory.".Red()); - return 1; + var hostBinaryPath = Path.Combine(AppContext.BaseDirectory, binaryName); + if (!File.Exists(hostBinaryPath)) + { + Reporter.Error.WriteLine($"Cannot find {binaryName} in the dotnet directory.".Red()); + return 1; + } + + var outputBinaryName = binaryName.Equals(Constants.HostExecutableName) ? (context.ProjectFile.Name + Constants.ExeSuffix) : binaryName; + var outputBinaryPath = Path.Combine(outputPath, outputBinaryName); + + File.Copy(hostBinaryPath, outputBinaryPath, overwrite: true); } - var outputExe = Path.Combine(outputPath, context.ProjectFile.Name + Constants.ExeSuffix); - - // Copy the host - File.Copy(hostPath, outputExe, overwrite: true); - return 0; } diff --git a/src/corehost/cli/CMakeLists.txt b/src/corehost/cli/CMakeLists.txt index ecc504b46..e5bc544f1 100644 --- a/src/corehost/cli/CMakeLists.txt +++ b/src/corehost/cli/CMakeLists.txt @@ -12,19 +12,15 @@ endif() set (CMAKE_CXX_STANDARD 11) include_directories(../common) +include_directories(.) # CMake does not recommend using globbing since it messes with the freshness checks set(SOURCES ../corehost.cpp ../common/trace.cpp - ../common/utils.cpp + ../common/utils.cpp) - args.cpp - clihost.cpp - coreclr.cpp - deps_resolver.cpp - servicing_index.cpp) if(WIN32) list(APPEND SOURCES ../common/pal.windows.cpp) diff --git a/src/corehost/cli/clihost.cpp b/src/corehost/cli/clihost.cpp index c0c13e207..f1c1a4f20 100644 --- a/src/corehost/cli/clihost.cpp +++ b/src/corehost/cli/clihost.cpp @@ -8,8 +8,6 @@ #include "utils.h" #include "coreclr.h" -SHARED_API const pal::char_t* g_LIBHOST_NAME = MAKE_LIBNAME("clihost"); - enum StatusCode { // 0x80 prefix to distinguish from corehost main's error codes. diff --git a/src/corehost/cli/libhost.h b/src/corehost/cli/libhost.h new file mode 100644 index 000000000..28cc39cae --- /dev/null +++ b/src/corehost/cli/libhost.h @@ -0,0 +1,4 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#define LIBHOST_NAME MAKE_LIBNAME("clihost") diff --git a/src/corehost/corehost.cpp b/src/corehost/corehost.cpp index d70a86835..60efc2b72 100644 --- a/src/corehost/corehost.cpp +++ b/src/corehost/corehost.cpp @@ -1,11 +1,11 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -#include "common/trace.h" -#include "common/pal.h" -#include "common/utils.h" +#include "trace.h" +#include "pal.h" +#include "utils.h" +#include "libhost.h" -extern const pal::char_t* g_LIBHOST_NAME; extern int corehost_main(const int argc, const pal::char_t* argv[]); namespace @@ -36,7 +36,7 @@ typedef int (*corehost_main_fn) (const int argc, const pal::char_t* argv[]); StatusCode load_host_lib(const pal::string_t& lib_dir, pal::dll_t* h_host, corehost_main_fn* main_fn) { pal::string_t host_path = lib_dir; - append_path(&host_path, g_LIBHOST_NAME); + append_path(&host_path, LIBHOST_NAME); // Missing library if (!pal::file_exists(host_path)) @@ -136,12 +136,7 @@ int main(const int argc, const pal::char_t* argv[]) trace::info(_X("Calling host entrypoint from library at own dir %s"), own_dir.c_str()); return host_main(argc, argv); - // DLL missing is not fatal. - case StatusCode::CoreHostLibMissingFailure: - trace::info(_X("Calling statically linked entrypoint from own exe")); - return corehost_main(argc, argv); - - // Some other fatal error. + // Some other fatal error including StatusCode::CoreHostLibMissingFailure. default: trace::error(_X("Error loading the host library from own dir: %s; Status=%08X"), own_dir.c_str(), code); return code;