Merge pull request #2392 from schellap/fxr-pol
Make hostfxr backward compatible with hostpolicy
This commit is contained in:
commit
5f2183489f
15 changed files with 392 additions and 321 deletions
|
@ -107,46 +107,26 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
}
|
||||
|
||||
arguments.Add("exec");
|
||||
|
||||
if (runtimeConfigPath != null)
|
||||
{
|
||||
arguments.Add("--runtimeconfig");
|
||||
arguments.Add(runtimeConfigPath);
|
||||
}
|
||||
|
||||
if (depsFilePath != null)
|
||||
{
|
||||
arguments.Add("--depsfile");
|
||||
arguments.Add(depsFilePath);
|
||||
}
|
||||
|
||||
arguments.Add("--additionalprobingpath");
|
||||
arguments.Add(nugetPackagesRoot);
|
||||
|
||||
arguments.Add(commandPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
host = CoreHost.HostExePath;
|
||||
|
||||
arguments.Add(commandPath);
|
||||
|
||||
if (runtimeConfigPath != null)
|
||||
{
|
||||
arguments.Add("--runtimeconfig");
|
||||
arguments.Add(runtimeConfigPath);
|
||||
}
|
||||
|
||||
if (depsFilePath != null)
|
||||
{
|
||||
arguments.Add("--depsfile");
|
||||
arguments.Add(depsFilePath);
|
||||
}
|
||||
|
||||
arguments.Add("--additionalprobingpath");
|
||||
arguments.Add(nugetPackagesRoot);
|
||||
}
|
||||
if (runtimeConfigPath != null)
|
||||
{
|
||||
arguments.Add("--runtimeconfig");
|
||||
arguments.Add(runtimeConfigPath);
|
||||
}
|
||||
if (depsFilePath != null)
|
||||
{
|
||||
arguments.Add("--depsfile");
|
||||
arguments.Add(depsFilePath);
|
||||
}
|
||||
|
||||
arguments.Add("--additionalprobingpath");
|
||||
arguments.Add(nugetPackagesRoot);
|
||||
|
||||
arguments.Add(commandPath);
|
||||
arguments.AddRange(commandArguments);
|
||||
|
||||
return CreateCommandSpec(host, arguments, commandResolutionStrategy);
|
||||
|
|
|
@ -18,8 +18,11 @@ arguments_t::arguments_t() :
|
|||
{
|
||||
}
|
||||
|
||||
bool parse_arguments(const pal::string_t& deps_path, const std::vector<pal::string_t>& probe_paths, host_mode_t mode,
|
||||
const int argc, const pal::char_t* argv[], pal::string_t* runtime_config, arguments_t* arg_out)
|
||||
bool parse_arguments(
|
||||
const pal::string_t& deps_path,
|
||||
const std::vector<pal::string_t>& probe_paths,
|
||||
host_mode_t mode,
|
||||
const int argc, const pal::char_t* argv[], arguments_t* arg_out)
|
||||
{
|
||||
arguments_t& args = *arg_out;
|
||||
// Get the full name of the application
|
||||
|
@ -67,32 +70,9 @@ bool parse_arguments(const pal::string_t& deps_path, const std::vector<pal::stri
|
|||
args.app_argc = argc - 1;
|
||||
}
|
||||
|
||||
std::unordered_map<pal::string_t, std::vector<pal::string_t>> opts;
|
||||
std::vector<pal::string_t> known_opts = { _X("--depsfile"), _X("--additionalprobingpath"), _X("--runtimeconfig") };
|
||||
int num_args = 0;
|
||||
if (!parse_known_args(args.app_argc, args.app_argv, known_opts, &opts, &num_args))
|
||||
if (!deps_path.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
args.app_argc -= num_args;
|
||||
args.app_argv += num_args;
|
||||
pal::string_t opts_deps_file = _X("--depsfile");
|
||||
pal::string_t opts_probe_path = _X("--additionalprobingpath");
|
||||
pal::string_t opts_runtime_config = _X("--runtimeconfig");
|
||||
pal::string_t deps_file = get_last_known_arg(opts, opts_deps_file, deps_path);
|
||||
*runtime_config = get_last_known_arg(opts, opts_runtime_config, _X(""));
|
||||
if (opts.count(opts_probe_path))
|
||||
{
|
||||
for (const auto& str : opts[opts_probe_path])
|
||||
{
|
||||
args.probe_paths.push_back(str);
|
||||
}
|
||||
}
|
||||
|
||||
if (!deps_file.empty())
|
||||
{
|
||||
args.deps_path = deps_file;
|
||||
args.deps_path = deps_path;
|
||||
args.app_dir = get_directory(args.deps_path);
|
||||
}
|
||||
|
||||
|
|
|
@ -115,6 +115,6 @@ struct arguments_t
|
|||
}
|
||||
};
|
||||
|
||||
bool parse_arguments(const pal::string_t& deps_path, const std::vector<pal::string_t>& probe_paths, host_mode_t mode, const int argc, const pal::char_t* argv[], pal::string_t* runtime_config, arguments_t* args);
|
||||
bool parse_arguments(const pal::string_t& deps_path, const std::vector<pal::string_t>& probe_paths, host_mode_t mode, const int argc, const pal::char_t* argv[], arguments_t* args);
|
||||
|
||||
#endif // ARGS_H
|
||||
|
|
|
@ -184,8 +184,7 @@ bool deps_resolver_t::try_roll_forward(const deps_entry_t& entry,
|
|||
}
|
||||
|
||||
void deps_resolver_t::setup_probe_config(
|
||||
const corehost_init_t* init,
|
||||
const runtime_config_t& config,
|
||||
const hostpolicy_init_t& init,
|
||||
const arguments_t& args)
|
||||
{
|
||||
if (pal::directory_exists(args.dotnet_extensions))
|
||||
|
@ -195,11 +194,11 @@ void deps_resolver_t::setup_probe_config(
|
|||
if (pal::directory_exists(ext_ni))
|
||||
{
|
||||
// Servicing NI probe.
|
||||
m_probes.push_back(probe_config_t::svc_ni(ext_ni, config.get_patch_roll_fwd(), config.get_prerelease_roll_fwd()));
|
||||
m_probes.push_back(probe_config_t::svc_ni(ext_ni, init.patch_roll_forward, init.prerelease_roll_forward));
|
||||
}
|
||||
|
||||
// Servicing normal probe.
|
||||
m_probes.push_back(probe_config_t::svc(args.dotnet_extensions, config.get_patch_roll_fwd(), config.get_prerelease_roll_fwd()));
|
||||
m_probes.push_back(probe_config_t::svc(args.dotnet_extensions, init.patch_roll_forward, init.prerelease_roll_forward));
|
||||
}
|
||||
|
||||
if (pal::directory_exists(args.dotnet_packages_cache))
|
||||
|
|
|
@ -24,20 +24,20 @@ struct probe_paths_t
|
|||
class deps_resolver_t
|
||||
{
|
||||
public:
|
||||
deps_resolver_t(const corehost_init_t* init, const runtime_config_t& config, const arguments_t& args)
|
||||
deps_resolver_t(const hostpolicy_init_t& init, const arguments_t& args)
|
||||
// Important: FX dir should come from "init" than "config",
|
||||
// since the host could be launching from FX dir.
|
||||
: m_fx_dir(init->fx_dir())
|
||||
: m_fx_dir(init.fx_dir)
|
||||
, m_app_dir(args.app_dir)
|
||||
, m_coreclr_index(-1)
|
||||
, m_portable(config.get_portable())
|
||||
, m_portable(init.is_portable)
|
||||
, m_deps(nullptr)
|
||||
, m_fx_deps(nullptr)
|
||||
{
|
||||
m_deps_file = args.deps_path;
|
||||
if (m_portable)
|
||||
{
|
||||
m_fx_deps_file = get_fx_deps(m_fx_dir, config.get_fx_name());
|
||||
m_fx_deps_file = get_fx_deps(m_fx_dir, init.fx_name);
|
||||
trace::verbose(_X("Using %s FX deps file"), m_fx_deps_file.c_str());
|
||||
trace::verbose(_X("Using %s deps file"), m_deps_file.c_str());
|
||||
m_fx_deps = std::unique_ptr<deps_json_t>(new deps_json_t(false, m_fx_deps_file));
|
||||
|
@ -49,14 +49,13 @@ public:
|
|||
}
|
||||
|
||||
setup_additional_probes(args.probe_paths);
|
||||
setup_probe_config(init, config, args);
|
||||
setup_probe_config(init, args);
|
||||
}
|
||||
|
||||
bool valid() { return m_deps->is_valid() && (!m_portable || m_fx_deps->is_valid()); }
|
||||
|
||||
void setup_probe_config(
|
||||
const corehost_init_t* init,
|
||||
const runtime_config_t& config,
|
||||
const hostpolicy_init_t& init,
|
||||
const arguments_t& args);
|
||||
|
||||
void setup_additional_probes(const std::vector<pal::string_t>& probe_paths);
|
||||
|
|
|
@ -254,18 +254,21 @@ int muxer_usage()
|
|||
return StatusCode::InvalidArgFailure;
|
||||
}
|
||||
|
||||
int fx_muxer_t::parse_args_and_execute(const pal::string_t& own_dir, int argoff, int argc, const pal::char_t* argv[], bool exec_mode, bool* is_an_app)
|
||||
int fx_muxer_t::parse_args_and_execute(
|
||||
const pal::string_t& own_dir,
|
||||
const pal::string_t& own_dll,
|
||||
int argoff, int argc, const pal::char_t* argv[], bool exec_mode, host_mode_t mode, bool* is_an_app)
|
||||
{
|
||||
*is_an_app = true;
|
||||
|
||||
std::vector<pal::string_t> known_opts = { _X("--additionalprobingpath") };
|
||||
if (exec_mode)
|
||||
if (exec_mode || mode == host_mode_t::split_fx || mode == host_mode_t::standalone)
|
||||
{
|
||||
known_opts.push_back(_X("--depsfile"));
|
||||
known_opts.push_back(_X("--runtimeconfig"));
|
||||
}
|
||||
|
||||
// Parse the known muxer arguments if any.
|
||||
// Parse the known arguments if any.
|
||||
int num_parsed = 0;
|
||||
std::unordered_map<pal::string_t, std::vector<pal::string_t>> opts;
|
||||
if (!parse_known_args(argc - argoff, &argv[argoff], known_opts, &opts, &num_parsed))
|
||||
|
@ -273,41 +276,44 @@ int fx_muxer_t::parse_args_and_execute(const pal::string_t& own_dir, int argoff,
|
|||
trace::error(_X("Failed to parse supported arguments."));
|
||||
return InvalidArgFailure;
|
||||
}
|
||||
int cur_i = argoff + num_parsed;
|
||||
if (cur_i >= argc)
|
||||
{
|
||||
return muxer_usage();
|
||||
}
|
||||
|
||||
pal::string_t app_candidate = argv[cur_i];
|
||||
bool is_app_runnable = ends_with(app_candidate, _X(".dll"), false) || ends_with(app_candidate, _X(".exe"), false);
|
||||
|
||||
// If exec mode is on, then check we have a dll at this point
|
||||
if (exec_mode)
|
||||
{
|
||||
if (!is_app_runnable)
|
||||
{
|
||||
trace::error(_X("dotnet exec needs a dll to execute. Try dotnet [--help]"));
|
||||
return InvalidArgFailure;
|
||||
}
|
||||
}
|
||||
// For non-exec, there is CLI invocation or app.dll execution after known args.
|
||||
else
|
||||
{
|
||||
// Test if we have a real dll at this point.
|
||||
if (!is_app_runnable)
|
||||
{
|
||||
// No we don't have a dll, this must be routed to the CLI.
|
||||
*is_an_app = false;
|
||||
return Success;
|
||||
}
|
||||
}
|
||||
|
||||
// Transform dotnet [exec] [--additionalprobingpath path] [--depsfile file] dll [args] -> dotnet dll [args]
|
||||
|
||||
std::vector<const pal::char_t*> vec_argv;
|
||||
const pal::char_t** new_argv = argv;
|
||||
int new_argc = argc;
|
||||
std::vector<const pal::char_t*> vec_argv;
|
||||
pal::string_t app_candidate = own_dll;
|
||||
int cur_i = argoff + num_parsed;
|
||||
if (mode != host_mode_t::standalone)
|
||||
{
|
||||
trace::verbose(_X("App not in standalone mode, so expecting more arguments..."));
|
||||
if (cur_i >= argc)
|
||||
{
|
||||
return muxer_usage();
|
||||
}
|
||||
|
||||
app_candidate = argv[cur_i];
|
||||
bool is_app_runnable = ends_with(app_candidate, _X(".dll"), false) || ends_with(app_candidate, _X(".exe"), false);
|
||||
trace::verbose(_X("App %s runnable=[%d]"), app_candidate.c_str(), is_app_runnable);
|
||||
// If exec mode is on, then check we have a dll at this point
|
||||
if (exec_mode)
|
||||
{
|
||||
if (!is_app_runnable)
|
||||
{
|
||||
trace::error(_X("dotnet exec needs a dll to execute. Try dotnet [--help]"));
|
||||
return InvalidArgFailure;
|
||||
}
|
||||
}
|
||||
// For non-exec, non-standalone there is CLI invocation or app.dll execution after known args.
|
||||
else
|
||||
{
|
||||
// Test if we have a real dll at this point.
|
||||
if (!is_app_runnable)
|
||||
{
|
||||
// No we don't have a dll, this must be routed to the CLI.
|
||||
*is_an_app = false;
|
||||
return AppArgNotRunnable;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur_i != 1)
|
||||
{
|
||||
vec_argv.resize(argc - cur_i + 1, 0); // +1 for dotnet
|
||||
|
@ -317,28 +323,36 @@ int fx_muxer_t::parse_args_and_execute(const pal::string_t& own_dir, int argoff,
|
|||
new_argc = vec_argv.size();
|
||||
}
|
||||
|
||||
// Transform dotnet [exec] [--additionalprobingpath path] [--depsfile file] [dll] [args] -> dotnet [dll] [args]
|
||||
return read_config_and_execute(own_dir, app_candidate, opts, new_argc, new_argv, mode);
|
||||
}
|
||||
|
||||
int fx_muxer_t::read_config_and_execute(
|
||||
const pal::string_t& own_dir,
|
||||
const pal::string_t& app_candidate,
|
||||
const std::unordered_map<pal::string_t, std::vector<pal::string_t>>& opts,
|
||||
int new_argc, const pal::char_t** new_argv, host_mode_t mode)
|
||||
{
|
||||
pal::string_t opts_deps_file = _X("--depsfile");
|
||||
pal::string_t opts_probe_path = _X("--additionalprobingpath");
|
||||
pal::string_t opts_runtime_config = _X("--runtimeconfig");
|
||||
|
||||
pal::string_t deps_file = get_last_known_arg(opts, opts_deps_file, _X(""));
|
||||
pal::string_t runtime_config = get_last_known_arg(opts, opts_runtime_config, _X(""));
|
||||
std::vector<pal::string_t> probe_paths = opts.count(opts_probe_path) ? opts[opts_probe_path] : std::vector<pal::string_t>();
|
||||
|
||||
trace::verbose(_X("Current argv is %s"), app_candidate.c_str());
|
||||
std::vector<pal::string_t> probe_paths = opts.count(opts_probe_path) ? opts.find(opts_probe_path)->second : std::vector<pal::string_t>();
|
||||
|
||||
pal::string_t app_or_deps = deps_file.empty() ? app_candidate : deps_file;
|
||||
pal::string_t config_file, dev_config_file;
|
||||
|
||||
if(runtime_config.empty())
|
||||
if (runtime_config.empty())
|
||||
{
|
||||
trace::verbose(_X("Finding runtimeconfig.json from [%s]"), app_candidate.c_str());
|
||||
get_runtime_config_paths_from_app(app_candidate, &config_file, &dev_config_file);
|
||||
trace::verbose(_X("App runtimeconfig.json from [%s]"), app_candidate.c_str());
|
||||
get_runtime_config_paths_from_app(app_candidate, &config_file, &dev_config_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace::verbose(_X("Finding runtimeconfig.json from [%s]"), runtime_config.c_str());
|
||||
get_runtime_config_paths_from_arg(runtime_config, &config_file, &dev_config_file);
|
||||
trace::verbose(_X("Specified runtimeconfig.json from [%s]"), runtime_config.c_str());
|
||||
get_runtime_config_paths_from_arg(runtime_config, &config_file, &dev_config_file);
|
||||
}
|
||||
|
||||
runtime_config_t config(config_file, dev_config_file);
|
||||
|
@ -361,14 +375,19 @@ int fx_muxer_t::parse_args_and_execute(const pal::string_t& own_dir, int argoff,
|
|||
if (config.get_portable())
|
||||
{
|
||||
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_paths, fx_dir, host_mode_t::muxer, &config);
|
||||
pal::string_t fx_dir = (mode == host_mode_t::split_fx) ? own_dir : resolve_fx_dir(own_dir, &config);
|
||||
corehost_init_t init(deps_file, probe_paths, fx_dir, mode, config);
|
||||
return execute_app(fx_dir, &init, new_argc, new_argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace::verbose(_X("Executing as a standalone app as per config file [%s]"), config_file.c_str());
|
||||
pal::string_t impl_dir = get_directory(app_or_deps);
|
||||
pal::string_t impl_dir;
|
||||
if (!hostpolicy_exists_in_svc(&impl_dir))
|
||||
{
|
||||
impl_dir = get_directory(app_or_deps);
|
||||
}
|
||||
trace::verbose(_X("The host impl directory before probing deps is [%s]"), impl_dir.c_str());
|
||||
if (!library_exists_in_dir(impl_dir, LIBHOSTPOLICY_NAME, nullptr) && !probe_paths.empty() && !deps_file.empty())
|
||||
{
|
||||
bool found = false;
|
||||
|
@ -392,7 +411,7 @@ int fx_muxer_t::parse_args_and_execute(const pal::string_t& own_dir, int argoff,
|
|||
}
|
||||
impl_dir = get_directory(candidate);
|
||||
}
|
||||
corehost_init_t init(deps_file, probe_paths, _X(""), host_mode_t::muxer, &config);
|
||||
corehost_init_t init(deps_file, probe_paths, _X(""), mode, config);
|
||||
return execute_app(impl_dir, &init, new_argc, new_argv);
|
||||
}
|
||||
}
|
||||
|
@ -400,13 +419,6 @@ int fx_muxer_t::parse_args_and_execute(const pal::string_t& own_dir, int argoff,
|
|||
/* static */
|
||||
int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
|
||||
{
|
||||
trace::verbose(_X("--- Executing in muxer mode..."));
|
||||
|
||||
if (argc <= 1)
|
||||
{
|
||||
return muxer_usage();
|
||||
}
|
||||
|
||||
pal::string_t own_path;
|
||||
|
||||
// Get the full name of the application
|
||||
|
@ -415,15 +427,40 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
|
|||
trace::error(_X("Failed to locate current executable"));
|
||||
return StatusCode::LibHostCurExeFindFailure;
|
||||
}
|
||||
auto own_dir = get_directory(own_path);
|
||||
pal::string_t own_name = get_filename(own_path);
|
||||
pal::string_t own_dir = get_directory(own_path);
|
||||
|
||||
bool is_an_app = false;
|
||||
if (pal::strcasecmp(_X("exec"), argv[1]) == 0)
|
||||
pal::string_t own_dll_filename = get_executable(own_name) + _X(".dll");
|
||||
pal::string_t own_dll = own_dir;
|
||||
append_path(&own_dll, own_dll_filename.c_str());
|
||||
|
||||
trace::info(_X("Own DLL path=[%s]"), own_dll.c_str());
|
||||
auto mode = detect_operating_mode(own_dir, own_dll, own_name);
|
||||
bool is_an_app = true;
|
||||
if (mode == host_mode_t::split_fx)
|
||||
{
|
||||
return parse_args_and_execute(own_dir, 2, argc, argv, true, &is_an_app); // arg offset 2 for dotnet, exec
|
||||
trace::verbose(_X("--- Executing in split/FX mode..."));
|
||||
return parse_args_and_execute(own_dir, own_dll, 1, argc, argv, false, host_mode_t::split_fx, &is_an_app);
|
||||
}
|
||||
if (mode == host_mode_t::standalone)
|
||||
{
|
||||
trace::verbose(_X("--- Executing in standalone mode..."));
|
||||
return parse_args_and_execute(own_dir, own_dll, 1, argc, argv, false, host_mode_t::standalone, &is_an_app);
|
||||
}
|
||||
|
||||
int result = parse_args_and_execute(own_dir, 1, argc, argv, false, &is_an_app); // arg offset 1 for dotnet
|
||||
trace::verbose(_X("--- Executing in muxer mode..."));
|
||||
|
||||
if (argc <= 1)
|
||||
{
|
||||
return muxer_usage();
|
||||
}
|
||||
|
||||
if (pal::strcasecmp(_X("exec"), argv[1]) == 0)
|
||||
{
|
||||
return parse_args_and_execute(own_dir, own_dll, 2, argc, argv, true, host_mode_t::muxer, &is_an_app); // arg offset 2 for dotnet, exec
|
||||
}
|
||||
|
||||
int result = parse_args_and_execute(own_dir, own_dll, 1, argc, argv, false, host_mode_t::muxer, &is_an_app); // arg offset 1 for dotnet
|
||||
if (is_an_app)
|
||||
{
|
||||
return result;
|
||||
|
@ -452,6 +489,6 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
|
|||
new_argv[1] = sdk_dotnet.c_str();
|
||||
|
||||
trace::verbose(_X("Using dotnet SDK dll=[%s]"), sdk_dotnet.c_str());
|
||||
return parse_args_and_execute(own_dir, 1, new_argv.size(), new_argv.data(), false, &is_an_app);
|
||||
return parse_args_and_execute(own_dir, own_dll, 1, new_argv.size(), new_argv.data(), false, host_mode_t::muxer, &is_an_app);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,11 @@ class corehost_init_t;
|
|||
class runtime_config_t;
|
||||
struct fx_ver_t;
|
||||
|
||||
#include "libhost.h"
|
||||
|
||||
int execute_app(
|
||||
const pal::string_t& impl_dll_dir,
|
||||
const corehost_init_t* init,
|
||||
corehost_init_t* init,
|
||||
const int argc,
|
||||
const pal::char_t* argv[]);
|
||||
|
||||
|
@ -16,7 +18,12 @@ class fx_muxer_t
|
|||
public:
|
||||
static int execute(const int argc, const pal::char_t* argv[]);
|
||||
private:
|
||||
static int parse_args_and_execute(const pal::string_t& own_dir, int argoff, int argc, const pal::char_t* argv[], bool exec_mode, bool* can_execute);
|
||||
static int read_config_and_execute(
|
||||
const pal::string_t& own_dir,
|
||||
const pal::string_t& app_candidate,
|
||||
const std::unordered_map<pal::string_t, std::vector<pal::string_t>>& opts,
|
||||
int new_argc, const pal::char_t** new_argv, host_mode_t mode);
|
||||
static int parse_args_and_execute(const pal::string_t& own_dir, const pal::string_t& own_dll, int argoff, int argc, const pal::char_t* argv[], bool exec_mode, host_mode_t mode, bool* can_execute);
|
||||
static pal::string_t resolve_fx_dir(const pal::string_t& muxer_path, runtime_config_t* runtime);
|
||||
static pal::string_t resolve_cli_version(const pal::string_t& global);
|
||||
static bool resolve_sdk_dotnet_path(const pal::string_t& own_dir, pal::string_t* cli_sdk);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "libhost.h"
|
||||
#include "runtime_config.h"
|
||||
|
||||
typedef int(*corehost_load_fn) (const corehost_init_t* init);
|
||||
typedef int(*corehost_load_fn) (const host_interface_t* init);
|
||||
typedef int(*corehost_main_fn) (const int argc, const pal::char_t* argv[]);
|
||||
typedef int(*corehost_unload_fn) ();
|
||||
|
||||
|
@ -47,7 +47,7 @@ int load_host_library(
|
|||
|
||||
int execute_app(
|
||||
const pal::string_t& impl_dll_dir,
|
||||
const corehost_init_t* init,
|
||||
corehost_init_t* init,
|
||||
const int argc,
|
||||
const pal::char_t* argv[])
|
||||
{
|
||||
|
@ -63,15 +63,16 @@ int execute_app(
|
|||
trace::error(_X("Could not load host policy library from [%s]"), impl_dll_dir.c_str());
|
||||
if (init->fx_dir() == impl_dll_dir)
|
||||
{
|
||||
pal::string_t name = init->runtime_config()->get_fx_name();
|
||||
pal::string_t version = init->runtime_config()->get_fx_version();
|
||||
trace::error(_X("This may be because the targeted framework [%s %s] was not found."),
|
||||
pal::string_t name = init->fx_name();
|
||||
pal::string_t version = init->fx_version();
|
||||
trace::error(_X("This may be because the targeted framework [\"%s\": \"%s\"] was not found."),
|
||||
name.c_str(), version.c_str());
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
if ((code = host_load(init)) == 0)
|
||||
const host_interface_t& intf = init->get_host_init_data();
|
||||
if ((code = host_load(&intf)) == 0)
|
||||
{
|
||||
code = host_main(argc, argv);
|
||||
(void)host_unload();
|
||||
|
@ -100,7 +101,7 @@ bool hostpolicy_exists_in_svc(pal::string_t* resolved_dir)
|
|||
{
|
||||
replace_char(&rel_dir, '/', DIR_SEPARATOR);
|
||||
}
|
||||
|
||||
|
||||
pal::string_t path = svc_dir;
|
||||
append_path(&path, _STRINGIFY(HOST_POLICY_PKG_NAME));
|
||||
|
||||
|
@ -113,8 +114,8 @@ bool hostpolicy_exists_in_svc(pal::string_t* resolved_dir)
|
|||
{
|
||||
try_patch_roll_forward_in_dir(path, lib_ver, &max_ver);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
append_path(&path, max_ver.c_str());
|
||||
append_path(&path, rel_dir.c_str());
|
||||
|
||||
|
@ -132,38 +133,7 @@ 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(""), std::vector<pal::string_t>(), 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(""), std::vector<pal::string_t>(), _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;
|
||||
}
|
||||
fx_muxer_t muxer;
|
||||
return muxer.execute(argc, argv);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,13 +12,12 @@
|
|||
#include "libhost.h"
|
||||
#include "error_codes.h"
|
||||
|
||||
hostpolicy_init_t g_init;
|
||||
|
||||
corehost_init_t* g_init = nullptr;
|
||||
|
||||
int run(const corehost_init_t* init, const runtime_config_t& config, const arguments_t& args)
|
||||
int run(const arguments_t& args)
|
||||
{
|
||||
// Load the deps resolver
|
||||
deps_resolver_t resolver(init, config, args);
|
||||
deps_resolver_t resolver(g_init, args);
|
||||
|
||||
if (!resolver.valid())
|
||||
{
|
||||
|
@ -82,15 +81,10 @@ int run(const corehost_init_t* init, const runtime_config_t& config, const argum
|
|||
deps.c_str(),
|
||||
};
|
||||
|
||||
|
||||
std::vector<std::string> cfg_keys;
|
||||
std::vector<std::string> cfg_values;
|
||||
config.config_kv(&cfg_keys, &cfg_values);
|
||||
|
||||
for (int i = 0; i < cfg_keys.size(); ++i)
|
||||
for (int i = 0; i < g_init.cfg_keys.size(); ++i)
|
||||
{
|
||||
property_keys.push_back(cfg_keys[i].c_str());
|
||||
property_values.push_back(cfg_values[i].c_str());
|
||||
property_keys.push_back(g_init.cfg_keys[i].c_str());
|
||||
property_values.push_back(g_init.cfg_values[i].c_str());
|
||||
}
|
||||
|
||||
size_t property_size = property_keys.size();
|
||||
|
@ -188,26 +182,20 @@ int run(const corehost_init_t* init, const runtime_config_t& config, const argum
|
|||
return exit_code;
|
||||
}
|
||||
|
||||
SHARED_API int corehost_load(corehost_init_t* init)
|
||||
SHARED_API int corehost_load(host_interface_t* init)
|
||||
{
|
||||
g_init = init;
|
||||
|
||||
trace::setup();
|
||||
|
||||
if (g_init->version() != corehost_init_t::s_version)
|
||||
|
||||
if (!hostpolicy_init_t::init(init, &g_init))
|
||||
{
|
||||
trace::error(_X("Error loading hostpolicy %s; interface mismatch between hostpolicy [%d] and hostfxr [%d]"),
|
||||
_STRINGIFY(HOST_POLICY_PKG_VER), corehost_init_t::s_version, g_init->version());
|
||||
trace::error(_X("Specifically, the structure of corehost_init_t has changed, do not know how to interpret it"));
|
||||
return StatusCode::LibHostInitFailure;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SHARED_API int corehost_main(const int argc, const pal::char_t* argv[])
|
||||
{
|
||||
assert(g_init);
|
||||
|
||||
if (trace::is_enabled())
|
||||
{
|
||||
trace::info(_X("--- Invoked policy [%s/%s/%s] main = {"),
|
||||
|
@ -221,9 +209,8 @@ SHARED_API int corehost_main(const int argc, const pal::char_t* argv[])
|
|||
}
|
||||
trace::info(_X("}"));
|
||||
|
||||
trace::info(_X("Host mode: %d"), g_init->host_mode());
|
||||
trace::info(_X("Deps file: %s"), g_init->deps_file().c_str());
|
||||
for (const auto& probe : g_init->probe_paths())
|
||||
trace::info(_X("Deps file: %s"), g_init.deps_file.c_str());
|
||||
for (const auto& probe : g_init.probe_paths)
|
||||
{
|
||||
trace::info(_X("Additional probe dir: %s"), probe.c_str());
|
||||
}
|
||||
|
@ -231,8 +218,7 @@ SHARED_API int corehost_main(const int argc, const pal::char_t* argv[])
|
|||
|
||||
// Take care of arguments
|
||||
arguments_t args;
|
||||
pal::string_t runtime_config;
|
||||
if (!parse_arguments(g_init->deps_file(), g_init->probe_paths(), g_init->host_mode(), argc, argv, &runtime_config, &args))
|
||||
if (!parse_arguments(g_init.deps_file, g_init.probe_paths, g_init.host_mode, argc, argv, &args))
|
||||
{
|
||||
return StatusCode::LibHostInvalidArgs;
|
||||
}
|
||||
|
@ -241,36 +227,10 @@ SHARED_API int corehost_main(const int argc, const pal::char_t* argv[])
|
|||
args.print();
|
||||
}
|
||||
|
||||
if (g_init->runtime_config())
|
||||
{
|
||||
return run(g_init, *g_init->runtime_config(), args);
|
||||
}
|
||||
else
|
||||
{
|
||||
pal::string_t config_file, dev_config_file;
|
||||
if (runtime_config.empty())
|
||||
{
|
||||
get_runtime_config_paths_from_app(args.managed_application, &config_file, &dev_config_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_runtime_config_paths_from_arg(runtime_config, &config_file, &dev_config_file);
|
||||
}
|
||||
runtime_config_t config(config_file, dev_config_file);
|
||||
|
||||
if (!config.is_valid())
|
||||
{
|
||||
trace::error(_X("Invalid runtimeconfig.json [%s] [%s]"), config.get_path().c_str(), config.get_dev_path().c_str());
|
||||
return StatusCode::InvalidConfigFile;
|
||||
}
|
||||
// TODO: This is ugly. The whole runtime config/probe paths business should all be resolved by and come from the hostfxr.cpp.
|
||||
args.probe_paths.insert(args.probe_paths.end(), config.get_probe_paths().begin(), config.get_probe_paths().end());
|
||||
return run(g_init, config, args);
|
||||
}
|
||||
return run(args);
|
||||
}
|
||||
|
||||
SHARED_API int corehost_unload()
|
||||
{
|
||||
g_init = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ void get_runtime_config_paths_from_app(const pal::string_t& app, pal::string_t*
|
|||
trace::verbose(_X("Runtime config is cfg=%s dev=%s"), json_path.c_str(), dev_json_path.c_str());
|
||||
|
||||
dev_cfg->assign(dev_json_path);
|
||||
cfg -> assign(json_path);
|
||||
cfg->assign(json_path);
|
||||
}
|
||||
|
||||
void get_runtime_config_paths_from_arg(const pal::string_t& arg, pal::string_t* cfg, pal::string_t* dev_cfg)
|
||||
|
@ -41,29 +41,11 @@ void get_runtime_config_paths_from_arg(const pal::string_t& arg, pal::string_t*
|
|||
trace::verbose(_X("Runtime config is cfg=%s dev=%s"), json_path.c_str(), dev_json_path.c_str());
|
||||
|
||||
dev_cfg->assign(dev_json_path);
|
||||
cfg -> assign(json_path);
|
||||
cfg->assign(json_path);
|
||||
}
|
||||
|
||||
host_mode_t detect_operating_mode(const int argc, const pal::char_t* argv[], pal::string_t* p_own_dir)
|
||||
host_mode_t detect_operating_mode(const pal::string_t& own_dir, const pal::string_t& own_dll, const pal::string_t& own_name)
|
||||
{
|
||||
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 host_mode_t::invalid;
|
||||
}
|
||||
|
||||
pal::string_t own_name = get_filename(own_path);
|
||||
pal::string_t own_dir = get_directory(own_path);
|
||||
if (p_own_dir)
|
||||
{
|
||||
p_own_dir->assign(own_dir);
|
||||
}
|
||||
|
||||
pal::string_t own_dll_filename = get_executable(own_name) + _X(".dll");
|
||||
pal::string_t own_dll = own_dir;
|
||||
append_path(&own_dll, own_dll_filename.c_str());
|
||||
trace::info(_X("Own DLL path=[%s]"), own_dll.c_str());
|
||||
if (coreclr_exists_in_dir(own_dir) || pal::file_exists(own_dll))
|
||||
{
|
||||
pal::string_t own_deps_json = own_dir;
|
||||
|
@ -117,7 +99,6 @@ void try_patch_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t&
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void try_prerelease_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str)
|
||||
{
|
||||
pal::string_t path = cur_dir;
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
#ifndef __LIBHOST_H__
|
||||
#define __LIBHOST_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "trace.h"
|
||||
#include "runtime_config.h"
|
||||
#include "fx_ver.h"
|
||||
|
||||
enum host_mode_t
|
||||
|
@ -17,51 +19,97 @@ enum host_mode_t
|
|||
class fx_ver_t;
|
||||
class runtime_config_t;
|
||||
|
||||
#define _HOST_INTERFACE_PACK 1
|
||||
#pragma pack(push, _HOST_INTERFACE_PACK)
|
||||
struct strarr_t
|
||||
{
|
||||
// DO NOT modify this struct. It is used in a layout
|
||||
// dependent manner. Create another for your use.
|
||||
size_t len;
|
||||
const pal::char_t** arr;
|
||||
};
|
||||
|
||||
struct host_interface_t
|
||||
{
|
||||
size_t version_lo; // Just assign sizeof() to this field.
|
||||
size_t version_hi; // Breaking changes to the layout -- increment HOST_INTERFACE_LAYOUT_VERSION
|
||||
strarr_t config_keys;
|
||||
strarr_t config_values;
|
||||
const pal::char_t* fx_dir;
|
||||
const pal::char_t* fx_name;
|
||||
const pal::char_t* deps_file;
|
||||
size_t is_portable;
|
||||
strarr_t probe_paths;
|
||||
size_t patch_roll_forward;
|
||||
size_t prerelease_roll_forward;
|
||||
size_t host_mode;
|
||||
// !! WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING
|
||||
// !! 1. Only append to this structure to maintain compat.
|
||||
// !! 2. Any nested structs should not use compiler specific padding (pack with _HOST_INTERFACE_PACK)
|
||||
// !! 3. Do not take address of the fields of this struct or be prepared to deal with unaligned accesses.
|
||||
// !! 4. Must be POD types; only use non-const size_t and pointer types; no access modifiers.
|
||||
// !! 5. Do not reorder fields or change any existing field types.
|
||||
// !! 6. Add static asserts for fields you add.
|
||||
};
|
||||
#pragma pack(pop)
|
||||
static_assert(_HOST_INTERFACE_PACK == 1, "Packing size should not be modified for back compat");
|
||||
static_assert(offsetof(host_interface_t, version_lo) == 0 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(offsetof(host_interface_t, version_hi) == 1 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(offsetof(host_interface_t, config_keys) == 2 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(offsetof(host_interface_t, config_values) == 4 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(offsetof(host_interface_t, fx_dir) == 6 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(offsetof(host_interface_t, fx_name) == 7 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(offsetof(host_interface_t, deps_file) == 8 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(offsetof(host_interface_t, is_portable) == 9 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(offsetof(host_interface_t, probe_paths) == 10 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(offsetof(host_interface_t, patch_roll_forward) == 12 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(offsetof(host_interface_t, prerelease_roll_forward) == 13 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(offsetof(host_interface_t, host_mode) == 14 * sizeof(size_t), "Struct offset breaks backwards compatibility");
|
||||
static_assert(sizeof(host_interface_t) == 15 * sizeof(size_t), "Did you add static asserts for the newly added fields?");
|
||||
|
||||
#define HOST_INTERFACE_LAYOUT_VERSION_HI 0x16041101 // YYMMDD:nn always increases when layout breaks compat.
|
||||
#define HOST_INTERFACE_LAYOUT_VERSION_LO sizeof(host_interface_t)
|
||||
|
||||
class corehost_init_t
|
||||
{
|
||||
// // WARNING // WARNING // WARNING // WARNING // WARNING // WARNING //
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !! If you change this class layout increment the s_version field; !!
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
public:
|
||||
static const int s_version = 0x8003;
|
||||
private:
|
||||
int m_version;
|
||||
std::vector<pal::string_t> m_probe_paths;
|
||||
const pal::string_t m_deps_file;
|
||||
std::vector<pal::string_t> m_clr_keys;
|
||||
std::vector<pal::string_t> m_clr_values;
|
||||
std::vector<const pal::char_t*> m_clr_keys_cstr;
|
||||
std::vector<const pal::char_t*> m_clr_values_cstr;
|
||||
const pal::string_t m_fx_dir;
|
||||
const pal::string_t m_fx_name;
|
||||
const pal::string_t m_deps_file;
|
||||
bool m_portable;
|
||||
std::vector<pal::string_t> m_probe_paths;
|
||||
std::vector<const pal::char_t*> m_probe_paths_cstr;
|
||||
bool m_patch_roll_forward;
|
||||
bool m_prerelease_roll_forward;
|
||||
host_mode_t m_host_mode;
|
||||
const runtime_config_t* m_runtime_config;
|
||||
host_interface_t m_host_interface;
|
||||
const pal::string_t m_fx_ver;
|
||||
public:
|
||||
corehost_init_t(
|
||||
const pal::string_t& deps_file,
|
||||
const std::vector<pal::string_t>& probe_paths,
|
||||
const pal::string_t& fx_dir,
|
||||
const host_mode_t mode,
|
||||
const runtime_config_t* runtime_config)
|
||||
const runtime_config_t& runtime_config)
|
||||
: m_fx_dir(fx_dir)
|
||||
, m_runtime_config(runtime_config)
|
||||
, m_fx_name(runtime_config.get_fx_name())
|
||||
, m_deps_file(deps_file)
|
||||
, m_portable(runtime_config.get_portable())
|
||||
, m_probe_paths(probe_paths)
|
||||
, m_patch_roll_forward(runtime_config.get_patch_roll_fwd())
|
||||
, m_prerelease_roll_forward(runtime_config.get_prerelease_roll_fwd())
|
||||
, m_host_mode(mode)
|
||||
, m_version(s_version)
|
||||
, m_host_interface()
|
||||
, m_fx_ver(runtime_config.get_fx_version())
|
||||
{
|
||||
}
|
||||
|
||||
const host_mode_t host_mode() const
|
||||
{
|
||||
return m_host_mode;
|
||||
}
|
||||
|
||||
const pal::string_t& deps_file() const
|
||||
{
|
||||
return m_deps_file;
|
||||
}
|
||||
|
||||
const std::vector<pal::string_t>& probe_paths() const
|
||||
{
|
||||
return m_probe_paths;
|
||||
runtime_config.config_kv(&m_clr_keys, &m_clr_values);
|
||||
make_cstr_arr(m_clr_keys, &m_clr_keys_cstr);
|
||||
make_cstr_arr(m_clr_values, &m_clr_values_cstr);
|
||||
make_cstr_arr(m_probe_paths, &m_probe_paths_cstr);
|
||||
}
|
||||
|
||||
const pal::string_t& fx_dir() const
|
||||
|
@ -69,21 +117,128 @@ public:
|
|||
return m_fx_dir;
|
||||
}
|
||||
|
||||
const runtime_config_t* runtime_config() const
|
||||
const pal::string_t& fx_name() const
|
||||
{
|
||||
return m_runtime_config;
|
||||
return m_fx_name;
|
||||
}
|
||||
|
||||
int version() const
|
||||
const pal::string_t& fx_version() const
|
||||
{
|
||||
return m_version;
|
||||
return m_fx_ver;
|
||||
}
|
||||
|
||||
const host_interface_t& get_host_init_data()
|
||||
{
|
||||
host_interface_t& hi = m_host_interface;
|
||||
|
||||
hi.version_lo = HOST_INTERFACE_LAYOUT_VERSION_LO;
|
||||
hi.version_hi = HOST_INTERFACE_LAYOUT_VERSION_HI;
|
||||
|
||||
hi.config_keys.len = m_clr_keys_cstr.size();
|
||||
hi.config_keys.arr = m_clr_keys_cstr.data();
|
||||
|
||||
hi.config_values.len = m_clr_values_cstr.size();
|
||||
hi.config_values.arr = m_clr_values_cstr.data();
|
||||
|
||||
hi.fx_dir = m_fx_dir.c_str();
|
||||
hi.fx_name = m_fx_name.c_str();
|
||||
hi.deps_file = m_deps_file.c_str();
|
||||
hi.is_portable = m_portable;
|
||||
|
||||
hi.probe_paths.len = m_probe_paths_cstr.size();
|
||||
hi.probe_paths.arr = m_probe_paths_cstr.data();
|
||||
|
||||
hi.patch_roll_forward = m_patch_roll_forward;
|
||||
hi.prerelease_roll_forward = m_prerelease_roll_forward;
|
||||
hi.host_mode = m_host_mode;
|
||||
|
||||
return hi;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static void make_cstr_arr(const std::vector<pal::string_t>& arr, std::vector<const pal::char_t*>* out)
|
||||
{
|
||||
out->reserve(arr.size());
|
||||
for (const auto& str : arr)
|
||||
{
|
||||
out->push_back(str.c_str());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct hostpolicy_init_t
|
||||
{
|
||||
std::vector<std::string> cfg_keys;
|
||||
std::vector<std::string> cfg_values;
|
||||
pal::string_t deps_file;
|
||||
std::vector<pal::string_t> probe_paths;
|
||||
pal::string_t fx_dir;
|
||||
pal::string_t fx_name;
|
||||
host_mode_t host_mode;
|
||||
bool patch_roll_forward;
|
||||
bool prerelease_roll_forward;
|
||||
bool is_portable;
|
||||
|
||||
static bool init(host_interface_t* input, hostpolicy_init_t* init)
|
||||
{
|
||||
// Check if there are any breaking changes.
|
||||
if (input->version_hi != HOST_INTERFACE_LAYOUT_VERSION_HI)
|
||||
{
|
||||
trace::error(_X("The version of the data layout used to initialize %s is [0x%04x]; expected version [0x%04x]"), LIBHOSTPOLICY_NAME, input->version_hi, HOST_INTERFACE_LAYOUT_VERSION_HI);
|
||||
return false;
|
||||
}
|
||||
// Check if the size is at least what we expect to contain.
|
||||
if (input->version_lo < HOST_INTERFACE_LAYOUT_VERSION_LO)
|
||||
{
|
||||
trace::error(_X("The size of the data layout used to initialize %s is %d; expected at least %d"), LIBHOSTPOLICY_NAME, input->version_lo, HOST_INTERFACE_LAYOUT_VERSION_LO);
|
||||
return false;
|
||||
}
|
||||
trace::verbose(_X("Reading from host interface version: [0x%04x:%d] to initialize policy version: [0x%04x:%d]"), input->version_hi, input->version_lo, HOST_INTERFACE_LAYOUT_VERSION_HI, HOST_INTERFACE_LAYOUT_VERSION_LO);
|
||||
|
||||
make_stdstr_arr(input->config_keys.len, input->config_keys.arr, &init->cfg_keys);
|
||||
make_stdstr_arr(input->config_values.len, input->config_values.arr, &init->cfg_values);
|
||||
|
||||
init->fx_dir = input->fx_dir;
|
||||
init->fx_name = input->fx_name;
|
||||
init->deps_file = input->deps_file;
|
||||
init->is_portable = input->is_portable;
|
||||
|
||||
make_palstr_arr(input->probe_paths.len, input->probe_paths.arr, &init->probe_paths);
|
||||
|
||||
init->patch_roll_forward = input->patch_roll_forward;
|
||||
init->prerelease_roll_forward = input->prerelease_roll_forward;
|
||||
init->host_mode = (host_mode_t) input->host_mode;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
static void make_palstr_arr(int argc, const pal::char_t** argv, std::vector<pal::string_t>* out)
|
||||
{
|
||||
out->reserve(argc);
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
out->push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void make_stdstr_arr(int argc, const pal::char_t** argv, std::vector<std::string>* out)
|
||||
{
|
||||
out->reserve(argc);
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
out->push_back(pal::to_stdstring(argv[i]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void get_runtime_config_paths_from_app(const pal::string_t& file, pal::string_t* config_file, pal::string_t* dev_config_file);
|
||||
void get_runtime_config_paths_from_arg(const pal::string_t& file, pal::string_t* config_file, pal::string_t* dev_config_file);
|
||||
|
||||
host_mode_t detect_operating_mode(const int argc, const pal::char_t* argv[], pal::string_t* own_dir = nullptr);
|
||||
host_mode_t detect_operating_mode(const pal::string_t& own_dir, const pal::string_t& own_dll, const pal::string_t& own_name);
|
||||
bool hostpolicy_exists_in_svc(pal::string_t* resolved_dir);
|
||||
|
||||
void try_patch_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str);
|
||||
void try_prerelease_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str);
|
||||
|
|
|
@ -208,11 +208,11 @@ const std::list<pal::string_t>& runtime_config_t::get_probe_paths() const
|
|||
return m_probe_paths;
|
||||
}
|
||||
|
||||
void runtime_config_t::config_kv(std::vector<std::string>* keys, std::vector<std::string>* values) const
|
||||
void runtime_config_t::config_kv(std::vector<pal::string_t>* keys, std::vector<pal::string_t>* values) const
|
||||
{
|
||||
for (const auto& kv : m_properties)
|
||||
{
|
||||
keys->push_back(pal::to_stdstring(kv.first));
|
||||
values->push_back(pal::to_stdstring(kv.second));
|
||||
keys->push_back(kv.first);
|
||||
values->push_back(kv.second);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// 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 __RUNTIME_CONFIG_H__
|
||||
#define __RUNTIME_CONFIG_H__
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "pal.h"
|
||||
|
@ -10,11 +13,6 @@ typedef web::json::value json_value;
|
|||
|
||||
class runtime_config_t
|
||||
{
|
||||
// // WARNING // WARNING // WARNING // WARNING // WARNING // WARNING //
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !! If you change this class layout increment the !!
|
||||
// !! corehost_init_t::s_version field; !!
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
public:
|
||||
runtime_config_t(const pal::string_t& path, const pal::string_t& dev_path);
|
||||
bool is_valid() { return m_valid; }
|
||||
|
@ -28,7 +26,7 @@ public:
|
|||
bool get_prerelease_roll_fwd() const;
|
||||
bool get_portable() const;
|
||||
bool parse_opts(const json_value& opts);
|
||||
void config_kv(std::vector<std::string>*, std::vector<std::string>*) const;
|
||||
void config_kv(std::vector<pal::string_t>*, std::vector<pal::string_t>*) const;
|
||||
|
||||
private:
|
||||
bool ensure_parsed();
|
||||
|
@ -48,3 +46,4 @@ private:
|
|||
bool m_portable;
|
||||
bool m_valid;
|
||||
};
|
||||
#endif // __RUNTIME_CONFIG_H__
|
|
@ -5,25 +5,26 @@
|
|||
#define __ERROR_CODES_H__
|
||||
enum StatusCode
|
||||
{
|
||||
Success = 0,
|
||||
InvalidArgFailure = 0x81,
|
||||
CoreHostLibLoadFailure = 0x82,
|
||||
CoreHostLibMissingFailure = 0x83,
|
||||
CoreHostEntryPointFailure = 0x84,
|
||||
CoreHostCurExeFindFailure = 0x85,
|
||||
CoreHostResolveModeFailure = 0x86,
|
||||
CoreClrResolveFailure = 0x87,
|
||||
CoreClrBindFailure = 0x88,
|
||||
CoreClrInitFailure = 0x89,
|
||||
CoreClrExeFailure = 0x90,
|
||||
ResolverInitFailure = 0x91,
|
||||
ResolverResolveFailure = 0x92,
|
||||
LibHostCurExeFindFailure = 0x93,
|
||||
LibHostInitFailure = 0x94,
|
||||
LibHostMuxFailure = 0x95,
|
||||
LibHostExecModeFailure = 0x96,
|
||||
LibHostSdkFindFailure = 0x97,
|
||||
LibHostInvalidArgs = 0x98,
|
||||
InvalidConfigFile = 0x99,
|
||||
Success = 0,
|
||||
InvalidArgFailure = 0x80008081,
|
||||
CoreHostLibLoadFailure = 0x80008082,
|
||||
CoreHostLibMissingFailure = 0x80008083,
|
||||
CoreHostEntryPointFailure = 0x80008084,
|
||||
CoreHostCurExeFindFailure = 0x80008085,
|
||||
CoreHostResolveModeFailure = 0x80008086,
|
||||
CoreClrResolveFailure = 0x80008087,
|
||||
CoreClrBindFailure = 0x80008088,
|
||||
CoreClrInitFailure = 0x80008089,
|
||||
CoreClrExeFailure = 0x8000808a,
|
||||
ResolverInitFailure = 0x8000808b,
|
||||
ResolverResolveFailure = 0x8000808c,
|
||||
LibHostCurExeFindFailure = 0x8000808d,
|
||||
LibHostInitFailure = 0x8000808e,
|
||||
LibHostMuxFailure = 0x8000808f,
|
||||
LibHostExecModeFailure = 0x80008090,
|
||||
LibHostSdkFindFailure = 0x80008091,
|
||||
LibHostInvalidArgs = 0x80008092,
|
||||
InvalidConfigFile = 0x80008093,
|
||||
AppArgNotRunnable = 0x80008094
|
||||
};
|
||||
#endif // __ERROR_CODES_H__
|
||||
|
|
|
@ -124,13 +124,14 @@ namespace Microsoft.DotNet.Tools.Run
|
|||
return result;
|
||||
}
|
||||
|
||||
List<string> hostArgs = new List<string>();
|
||||
if (!_context.TargetFramework.IsDesktop())
|
||||
{
|
||||
// Add Nuget Packages Probing Path
|
||||
var nugetPackagesRoot = _context.PackagesDirectory;
|
||||
var probingPathArg = "--additionalprobingpath";
|
||||
_args.Insert(0, nugetPackagesRoot);
|
||||
_args.Insert(0, probingPathArg);
|
||||
hostArgs.Insert(0, nugetPackagesRoot);
|
||||
hostArgs.Insert(0, probingPathArg);
|
||||
}
|
||||
|
||||
// Now launch the output and give it the results
|
||||
|
@ -161,11 +162,13 @@ namespace Microsoft.DotNet.Tools.Run
|
|||
// The executable is a ".dll", we need to call it through dotnet.exe
|
||||
var muxer = new Muxer();
|
||||
|
||||
command = Command.Create(muxer.MuxerPath, Enumerable.Concat(new[] { "exec", outputName }, _args));
|
||||
command = Command.Create(muxer.MuxerPath, Enumerable.Concat(
|
||||
Enumerable.Concat(new string[] { "exec" }, hostArgs),
|
||||
Enumerable.Concat(new string[] { outputName }, _args)));
|
||||
}
|
||||
else
|
||||
{
|
||||
command = Command.Create(outputName, _args);
|
||||
command = Command.Create(outputName, Enumerable.Concat(hostArgs, _args));
|
||||
}
|
||||
|
||||
result = command
|
||||
|
|
Loading…
Reference in a new issue