Merge pull request #1984 from schellap/fxr-move2

Make corehost shim thinner
This commit is contained in:
Senthil 2016-03-22 11:19:20 -07:00
commit 61a47dade4
13 changed files with 226 additions and 268 deletions

View file

@ -22,7 +22,6 @@ include_directories(./json/casablanca/include)
# CMake does not recommend using globbing since it messes with the freshness checks
set(SOURCES
libhost.cpp
#deps_format.cpp
#./json/casablanca/src/json/json.cpp
@ -33,7 +32,6 @@ set(SOURCES
./fxr/fx_ver.cpp
../corehost.cpp
../policy_load.cpp
../common/trace.cpp
../common/utils.cpp)

View file

@ -19,13 +19,13 @@ include_directories(../json/casablanca/include)
set(SOURCES
../../common/trace.cpp
../../common/utils.cpp
../../policy_load.cpp
../libhost.cpp
../runtime_config.cpp
../json/casablanca/src/json/json.cpp
../json/casablanca/src/json/json_parsing.cpp
../json/casablanca/src/json/json_serialization.cpp
../json/casablanca/src/utilities/asyncrt_utils.cpp
./hostfxr.cpp
./fx_ver.cpp
./fx_muxer.cpp)

View file

@ -11,8 +11,7 @@
#include "trace.h"
#include "runtime_config.h"
#include "cpprest/json.h"
#include "corehost.h"
#include "policy_load.h"
#include "error_codes.h"
typedef web::json::value json_value;
@ -265,13 +264,13 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
trace::verbose(_X("Executing as a portable app as per config file [%s]"), config_file.c_str());
pal::string_t fx_dir = resolve_fx_dir(own_dir, &config);
corehost_init_t init(_X(""), _X(""), fx_dir, host_mode_t::muxer, &config);
return policy_load_t::execute_app(fx_dir, &init, argc, argv);
return execute_app(fx_dir, &init, argc, argv);
}
else
{
trace::verbose(_X("Executing as a standlone app as per config file [%s]"), config_file.c_str());
corehost_init_t init(_X(""), _X(""), _X(""), host_mode_t::muxer, &config);
return policy_load_t::execute_app(get_directory(app_path), &init, argc, argv);
return execute_app(get_directory(app_path), &init, argc, argv);
}
}
else
@ -323,14 +322,14 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
trace::verbose(_X("Executing as a portable app as per config file [%s]"), config_file.c_str());
pal::string_t fx_dir = resolve_fx_dir(own_dir, &config);
corehost_init_t init(deps_file, probe_path, fx_dir, host_mode_t::muxer, &config);
return policy_load_t::execute_app(fx_dir, &init, new_argv.size(), new_argv.data());
return execute_app(fx_dir, &init, new_argv.size(), new_argv.data());
}
else
{
trace::verbose(_X("Executing as a standalone app as per config file [%s]"), config_file.c_str());
corehost_init_t init(deps_file, probe_path, _X(""), host_mode_t::muxer, &config);
pal::string_t impl_dir = get_directory(app_or_deps);
return policy_load_t::execute_app(impl_dir, &init, new_argv.size(), new_argv.data());
return execute_app(impl_dir, &init, new_argv.size(), new_argv.data());
}
}
else
@ -366,20 +365,15 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
trace::verbose(_X("Executing dotnet.dll as a portable app as per config file [%s]"), config_file.c_str());
pal::string_t fx_dir = resolve_fx_dir(own_dir, &config);
corehost_init_t init(_X(""), _X(""), fx_dir, host_mode_t::muxer, &config);
return policy_load_t::execute_app(fx_dir, &init, new_argv.size(), new_argv.data());
return execute_app(fx_dir, &init, new_argv.size(), new_argv.data());
}
else
{
trace::verbose(_X("Executing dotnet.dll as a standalone app as per config file [%s]"), config_file.c_str());
corehost_init_t init(_X(""), _X(""), _X(""), host_mode_t::muxer, &config);
return policy_load_t::execute_app(get_directory(sdk_dotnet), &init, new_argv.size(), new_argv.data());
return execute_app(get_directory(sdk_dotnet), &init, new_argv.size(), new_argv.data());
}
}
}
}
SHARED_API int hostfxr_main(const int argc, const pal::char_t* argv[])
{
trace::setup();
return fx_muxer_t().execute(argc, argv);
}

View file

@ -4,6 +4,12 @@
class runtime_config_t;
struct fx_ver_t;
int execute_app(
const pal::string_t& impl_dll_dir,
const corehost_init_t* init,
const int argc,
const pal::char_t* argv[]);
class fx_muxer_t
{
public:

View file

@ -60,22 +60,38 @@ pal::string_t fx_ver_t::as_str()
}
/* static */
int fx_ver_t::compare(const fx_ver_t&a, const fx_ver_t& b, bool ignore_build)
int fx_ver_t::compare(const fx_ver_t&a, const fx_ver_t& b)
{
// compare(u.v.w-p+b, x.y.z-q+c)
return
(a.m_major == b.m_major)
? ((a.m_minor == b.m_minor)
? ((a.m_patch == b.m_patch)
? ((a.m_pre.empty() == b.m_pre.empty())
? ((a.m_pre.empty())
? (ignore_build ? 0 : a.m_build.compare(b.m_build))
: a.m_pre.compare(b.m_pre))
: a.m_pre.empty() ? 1 : -1)
: (a.m_patch > b.m_patch ? 1 : -1))
: (a.m_minor > b.m_minor ? 1 : -1))
: ((a.m_major > b.m_major) ? 1 : -1)
;
if (a.m_major != b.m_major)
{
return (a.m_major > b.m_major) ? 1 : -1;
}
if (a.m_minor != b.m_minor)
{
return (a.m_minor > b.m_minor) ? 1 : -1;
}
if (a.m_patch != b.m_patch)
{
return (a.m_patch > b.m_patch) ? 1 : -1;
}
if (a.m_pre.empty() != b.m_pre.empty())
{
// Either a is empty or b is empty
return a.m_pre.empty() ? 1 : -1;
}
// Either both are empty or both are non-empty (may be equal)
int pre_cmp = a.m_pre.compare(b.m_pre);
if (pre_cmp != 0)
{
return pre_cmp;
}
return a.m_build.compare(b.m_build);
}
bool try_stou(const pal::string_t& str, unsigned* num)

View file

@ -3,6 +3,8 @@
#include "pal.h"
// Note: This is not SemVer (esp., in comparing pre-release part, fx_ver_t does not
// compare multiple dot separated identifiers individually.) ex: 1.0.0-beta.2 vs. 1.0.0-beta.11
struct fx_ver_t
{
fx_ver_t(int major, int minor, int patch);
@ -35,6 +37,6 @@ private:
pal::string_t m_pre;
pal::string_t m_build;
static int compare(const fx_ver_t&a, const fx_ver_t& b, bool ignore_build = false);
static int compare(const fx_ver_t&a, const fx_ver_t& b);
};

View file

@ -0,0 +1,134 @@
// 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 <cassert>
#include "trace.h"
#include "pal.h"
#include "utils.h"
#include "libhost.h"
#include "fx_muxer.h"
#include "error_codes.h"
typedef int(*corehost_load_fn) (const corehost_init_t* init);
typedef int(*corehost_main_fn) (const int argc, const pal::char_t* argv[]);
typedef int(*corehost_unload_fn) ();
int load_host_library(
const pal::string_t& lib_dir,
pal::dll_t* h_host,
corehost_load_fn* load_fn,
corehost_main_fn* main_fn,
corehost_unload_fn* unload_fn)
{
pal::string_t host_path;
if (!library_exists_in_dir(lib_dir, LIBHOST_NAME, &host_path))
{
return StatusCode::CoreHostLibMissingFailure;
}
// Load library
if (!pal::load_library(host_path.c_str(), h_host))
{
trace::info(_X("Load library of %s failed"), host_path.c_str());
return StatusCode::CoreHostLibLoadFailure;
}
// Obtain entrypoint symbols
*load_fn = (corehost_load_fn)pal::get_symbol(*h_host, "corehost_load");
*main_fn = (corehost_main_fn)pal::get_symbol(*h_host, "corehost_main");
*unload_fn = (corehost_unload_fn)pal::get_symbol(*h_host, "corehost_unload");
return (*main_fn) && (*load_fn) && (*unload_fn)
? StatusCode::Success
: StatusCode::CoreHostEntryPointFailure;
}
int execute_app(
const pal::string_t& impl_dll_dir,
const corehost_init_t* init,
const int argc,
const pal::char_t* argv[])
{
pal::dll_t corehost;
corehost_main_fn host_main = nullptr;
corehost_load_fn host_load = nullptr;
corehost_unload_fn host_unload = nullptr;
int code = load_host_library(impl_dll_dir, &corehost, &host_load, &host_main, &host_unload);
if (code != StatusCode::Success)
{
trace::error(_X("Could not load host policy library [%s]"), impl_dll_dir.c_str());
return code;
}
if ((code = host_load(init)) == 0)
{
code = host_main(argc, argv);
(void)host_unload();
}
return code;
}
bool hostpolicy_exists_in_svc(pal::string_t* resolved_dir)
{
#ifdef COREHOST_PACKAGE_SERVICING
pal::string_t svc_dir;
if (!pal::getenv(_X("DOTNET_SERVICING"), &svc_dir))
{
return false;
}
pal::string_t path = svc_dir;
append_path(&path, COREHOST_PACKAGE_NAME);
append_path(&path, COREHOST_PACKAGE_VERSION);
append_path(&path, COREHOST_PACKAGE_COREHOST_RELATIVE_DIR);
if (library_exists_in_dir(path, LIBHOST_NAME))
{
resolved_dir->assign(path);
}
return true;
#else
return false;
#endif
}
SHARED_API int hostfxr_main(const int argc, const pal::char_t* argv[])
{
trace::setup();
pal::string_t own_dir;
auto mode = detect_operating_mode(argc, argv, &own_dir);
switch (mode)
{
case muxer:
{
trace::info(_X("Host operating in Muxer mode"));
fx_muxer_t muxer;
return muxer.execute(argc, argv);
}
case split_fx:
{
trace::info(_X("Host operating in split mode; own dir=[%s]"), own_dir.c_str());
corehost_init_t init(_X(""), _X(""), own_dir, host_mode_t::split_fx, nullptr);
return execute_app(own_dir, &init, argc, argv);
}
case standalone:
{
trace::info(_X("Host operating from standalone app dir %s"), own_dir.c_str());
pal::string_t svc_dir;
corehost_init_t init(_X(""), _X(""), _X(""), host_mode_t::standalone, nullptr);
return execute_app(
hostpolicy_exists_in_svc(&svc_dir) ? svc_dir : own_dir, &init, argc, argv);
}
default:
trace::error(_X("Unknown mode detected or could not resolve the mode."));
return StatusCode::CoreHostResolveModeFailure;
}
}

View file

@ -4,6 +4,22 @@
#include "utils.h"
#include "trace.h"
bool library_exists_in_dir(const pal::string_t& lib_dir, const pal::string_t& lib_name, pal::string_t* p_lib_path)
{
pal::string_t lib_path = lib_dir;
append_path(&lib_path, lib_name.c_str());
if (!pal::file_exists(lib_path))
{
return false;
}
if (p_lib_path)
{
*p_lib_path = lib_path;
}
return true;
}
bool coreclr_exists_in_dir(const pal::string_t& candidate)
{
pal::string_t test(candidate);

View file

@ -14,6 +14,7 @@ pal::string_t strip_file_ext(const pal::string_t& path);
pal::string_t get_filename(const pal::string_t& path);
pal::string_t get_filename_without_ext(const pal::string_t& path);
void append_path(pal::string_t* path1, const pal::char_t* path2);
bool library_exists_in_dir(const pal::string_t& lib_dir, const pal::string_t& lib_name, pal::string_t* p_lib_path);
bool coreclr_exists_in_dir(const pal::string_t& candidate);
void replace_char(pal::string_t* path, pal::char_t match, pal::char_t repl);
const pal::char_t* get_arch();

View file

@ -3,43 +3,18 @@
#include "trace.h"
#include "utils.h"
#include "corehost.h"
#include "pal.h"
#include "fx_ver.h"
#include "error_codes.h"
#include "policy_load.h"
#include <array>
#define LIBFXR_NAME MAKE_LIBNAME("hostfxr")
bool corehost_t::hostpolicy_exists_in_svc(pal::string_t* resolved_dir)
typedef int(*hostfxr_main_fn) (const int argc, const pal::char_t* argv[]);
pal::string_t resolve_fxr_path(const pal::string_t& own_dir)
{
#ifdef COREHOST_PACKAGE_SERVICING
pal::string_t svc_dir;
if (!pal::getenv(_X("DOTNET_SERVICING"), &svc_dir))
{
return false;
}
pal::string_t path = svc_dir;
append_path(&path, COREHOST_PACKAGE_NAME);
append_path(&path, COREHOST_PACKAGE_VERSION);
append_path(&path, COREHOST_PACKAGE_COREHOST_RELATIVE_DIR);
if (library_exists_in_dir(path, LIBHOST_NAME))
{
resolved_dir->assign(path);
}
return true;
#else
return false;
#endif
}
pal::string_t corehost_t::resolve_fxr_path(const pal::string_t& own_dir)
{
pal::string_t fxr_path;
pal::string_t fxr_dir = own_dir;
append_path(&fxr_dir, _X("dotnethost"));
append_path(&fxr_dir, _X("host"));
append_path(&fxr_dir, _X("fxr"));
if (pal::directory_exists(fxr_dir))
{
@ -65,28 +40,39 @@ pal::string_t corehost_t::resolve_fxr_path(const pal::string_t& own_dir)
pal::string_t max_ver_str = max_ver.as_str();
append_path(&fxr_dir, max_ver_str.c_str());
trace::info(_X("Detected latest fxr version=[%s]..."), fxr_dir.c_str());
}
const pal::string_t* dirs[] = { &fxr_dir, &own_dir };
for (const auto& dir : dirs)
{
trace::info(_X("Considering fxr dir=[%s]..."), fxr_dir.c_str());
if (policy_load_t::library_exists_in_dir(*dir, LIBFXR_NAME, &fxr_path))
pal::string_t ret_path;
if (library_exists_in_dir(fxr_dir, LIBFXR_NAME, &ret_path))
{
trace::info(_X("Resolved fxr [%s]..."), fxr_path.c_str());
return fxr_path;
trace::info(_X("Resolved fxr [%s]..."), ret_path.c_str());
return ret_path;
}
}
pal::string_t fxr_path;
if (library_exists_in_dir(own_dir, LIBFXR_NAME, &fxr_path))
{
trace::info(_X("Resolved fxr [%s]..."), fxr_path.c_str());
return fxr_path;
}
return pal::string_t();
}
int corehost_t::resolve_fx_and_execute_app(const pal::string_t& own_dir, const int argc, const pal::char_t* argv[])
int run(const int argc, const pal::char_t* argv[])
{
pal::string_t own_path;
if (!pal::get_own_executable_path(&own_path) || !pal::realpath(&own_path))
{
trace::error(_X("Failed to locate current executable"));
return StatusCode::CoreHostCurExeFindFailure;
}
pal::dll_t fxr;
pal::string_t fxr_path = resolve_fxr_path(own_dir);
pal::string_t own_dir = get_directory(own_path);
// Load library
pal::string_t fxr_path = resolve_fxr_path(own_dir);
if (!pal::load_library(fxr_path.c_str(), &fxr))
{
trace::info(_X("Load library of %s failed"), fxr_path.c_str());
@ -98,45 +84,6 @@ int corehost_t::resolve_fx_and_execute_app(const pal::string_t& own_dir, const i
return main_fn(argc, argv);
}
int corehost_t::run(const int argc, const pal::char_t* argv[])
{
pal::string_t own_dir;
auto mode = detect_operating_mode(argc, argv, &own_dir);
switch (mode)
{
case muxer:
trace::info(_X("Host operating in Muxer mode"));
return resolve_fx_and_execute_app(own_dir, argc, argv);
case split_fx:
{
trace::info(_X("Host operating in split mode; own dir=[%s]"), own_dir.c_str());
corehost_init_t init(_X(""), _X(""), own_dir, host_mode_t::split_fx, nullptr);
return policy_load_t::execute_app(own_dir, &init, argc, argv);
}
case standalone:
{
trace::info(_X("Host operating from standalone app dir %s"), own_dir.c_str());
pal::string_t svc_dir;
corehost_init_t init(_X(""), _X(""), _X(""), host_mode_t::standalone, nullptr);
return policy_load_t::execute_app(
hostpolicy_exists_in_svc(&svc_dir) ? svc_dir : own_dir, &init, argc, argv);
}
return StatusCode::CoreHostLibMissingFailure;
default:
trace::error(_X("Unknown mode detected or could not resolve the mode."));
return StatusCode::CoreHostResolveModeFailure;
}
}
#include <cassert>
#include "deps_format.h"
#if defined(_WIN32)
int __cdecl wmain(const int argc, const pal::char_t* argv[])
#else
@ -145,9 +92,6 @@ int main(const int argc, const pal::char_t* argv[])
{
trace::setup();
//deps_json_t deps(true, _X("H:\\code\\sharedfx\\PortableApp\\PortableAppWithNative.deps.json"));
//deps_json_t deps2(false, _X("H:\\code\\sharedfx\\StandaloneApp\\StandaloneApp.deps.json"));
if (trace::is_enabled())
{
trace::info(_X("--- Invoked host main = {"));
@ -157,7 +101,7 @@ int main(const int argc, const pal::char_t* argv[])
}
trace::info(_X("}"));
}
corehost_t corehost;
return corehost.run(argc, argv);
return run(argc, argv);
}

View file

@ -1,36 +0,0 @@
// 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 "pal.h"
#include "libhost.h"
#include "policy_load.h"
typedef int(*hostfxr_main_fn) (const int argc, const pal::char_t* argv[]);
class corehost_t
{
public:
int run(const int argc, const pal::char_t* argv[]);
static int execute_app(
const pal::string_t& policy_dir,
const pal::string_t& fx_dir,
const runtime_config_t* config,
const int argc,
const pal::char_t* argv[]);
private:
static int load_host_library(
const pal::string_t& lib_dir,
pal::dll_t* h_host,
corehost_load_fn* load_fn,
corehost_main_fn* main_fn,
corehost_unload_fn* unload_fn);
pal::string_t resolve_fxr_path(const pal::string_t& own_dir);
int resolve_fx_and_execute_app(const pal::string_t& own_dir, const int argc, const pal::char_t* argv[]);
static bool hostpolicy_exists_in_svc(pal::string_t* resolved_path);
static bool library_exists_in_dir(const pal::string_t& lib_dir, const pal::string_t& lib_name, pal::string_t* p_host_path);
};

View file

@ -1,79 +0,0 @@
// 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 "policy_load.h"
#include "corehost.h"
bool policy_load_t::library_exists_in_dir(const pal::string_t& lib_dir, const pal::string_t& lib_name, pal::string_t* p_host_path)
{
pal::string_t host_path = lib_dir;
append_path(&host_path, lib_name.c_str());
if (!pal::file_exists(host_path))
{
return false;
}
if (p_host_path)
{
*p_host_path = host_path;
}
return true;
}
int policy_load_t::load_host_library(
const pal::string_t& lib_dir,
pal::dll_t* h_host,
corehost_load_fn* load_fn,
corehost_main_fn* main_fn,
corehost_unload_fn* unload_fn)
{
pal::string_t host_path;
if (!library_exists_in_dir(lib_dir, LIBHOST_NAME, &host_path))
{
return StatusCode::CoreHostLibMissingFailure;
}
// Load library
if (!pal::load_library(host_path.c_str(), h_host))
{
trace::info(_X("Load library of %s failed"), host_path.c_str());
return StatusCode::CoreHostLibLoadFailure;
}
// Obtain entrypoint symbols
*load_fn = (corehost_load_fn)pal::get_symbol(*h_host, "corehost_load");
*main_fn = (corehost_main_fn)pal::get_symbol(*h_host, "corehost_main");
*unload_fn = (corehost_unload_fn)pal::get_symbol(*h_host, "corehost_unload");
return (*main_fn) && (*load_fn) && (*unload_fn)
? StatusCode::Success
: StatusCode::CoreHostEntryPointFailure;
}
int policy_load_t::execute_app(
const pal::string_t& impl_dll_dir,
const corehost_init_t* init,
const int argc,
const pal::char_t* argv[])
{
pal::dll_t corehost;
corehost_main_fn host_main = nullptr;
corehost_load_fn host_load = nullptr;
corehost_unload_fn host_unload = nullptr;
int code = load_host_library(impl_dll_dir, &corehost, &host_load, &host_main, &host_unload);
if (code != StatusCode::Success)
{
trace::error(_X("Could not load host policy library [%s]"), impl_dll_dir.c_str());
return code;
}
if ((code = host_load(init)) == 0)
{
code = host_main(argc, argv);
(void) host_unload();
}
return code;
}

View file

@ -1,38 +0,0 @@
// 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.
#ifndef __POLICY_LOAD_H__
#define __POLICY_LOAD_H__
#include "pal.h"
#include "utils.h"
#include "trace.h"
#include "error_codes.h"
class corehost_init_t;
class runtime_config_t;
typedef int(*corehost_load_fn) (const corehost_init_t* init);
typedef int(*corehost_main_fn) (const int argc, const pal::char_t* argv[]);
typedef int(*corehost_unload_fn) ();
class policy_load_t
{
public:
static int execute_app(
const pal::string_t& impl_dll_dir,
const corehost_init_t* init,
const int argc,
const pal::char_t* argv[]);
static bool library_exists_in_dir(const pal::string_t& lib_dir, const pal::string_t& lib_name, pal::string_t* p_host_path = nullptr);
static int load_host_library(
const pal::string_t& lib_dir,
pal::dll_t* h_host,
corehost_load_fn* load_fn,
corehost_main_fn* main_fn,
corehost_unload_fn* unload_fn);
};
#endif // __POLICY_LOAD_H__