Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 4b628f4

Browse files
authored
Add support for framework-dependent apphost (#3888)
Add support for framework-dependent apphost
1 parent da2eafd commit 4b628f4

30 files changed

+907
-372
lines changed

src/corehost/cli/args.cpp

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
arguments_t::arguments_t() :
1010
managed_application(_X("")),
11-
own_path(_X("")),
12-
app_dir(_X("")),
11+
host_path(_X("")),
12+
app_root(_X("")),
1313
app_argc(0),
1414
app_argv(nullptr),
1515
core_servicing(_X("")),
@@ -62,34 +62,11 @@ bool parse_arguments(
6262
{
6363
arguments_t& args = *arg_out;
6464

65-
// Try to use argv[0] as own_path to allow for hosts located elsewhere
66-
if (argc >= 1)
67-
{
68-
args.own_path = argv[0];
69-
if (!args.own_path.empty())
70-
{
71-
trace::info(_X("Attempting to use argv[0] as path [%s]"), args.own_path.c_str());
72-
if (!get_path_from_argv(&args.own_path))
73-
{
74-
trace::warning(_X("Failed to resolve argv[0] as path [%s]. Using location of current executable instead."), args.own_path.c_str());
75-
args.own_path.clear();
76-
}
77-
}
78-
}
65+
args.host_path = init.host_info.host_path;
7966

80-
// Get the full name of the application
81-
if (args.own_path.empty() && (!pal::get_own_executable_path(&args.own_path) || !pal::realpath(&args.own_path)))
67+
if (init.host_mode != host_mode_t::apphost)
8268
{
83-
trace::error(_X("Failed to resolve full path of the current executable [%s]"), args.own_path.c_str());
84-
return false;
85-
}
86-
87-
auto own_name = get_filename(args.own_path);
88-
auto own_dir = get_directory(args.own_path);
89-
90-
if (init.host_mode != host_mode_t::standalone)
91-
{
92-
// corerun mode. First argument is managed app
69+
// First argument is managed app
9370
if (argc < 2)
9471
{
9572
return false;
@@ -100,32 +77,28 @@ bool parse_arguments(
10077
trace::error(_X("Failed to locate managed application [%s]"), args.managed_application.c_str());
10178
return false;
10279
}
103-
args.app_dir = get_directory(args.managed_application);
80+
args.app_root = get_directory(args.managed_application);
10481
args.app_argc = argc - 2;
10582
args.app_argv = &argv[2];
10683
}
10784
else
10885
{
109-
// coreconsole mode. Find the managed app in the same directory
110-
pal::string_t managed_app(own_dir);
111-
112-
managed_app.append(get_executable(own_name));
113-
managed_app.append(_X(".dll"));
114-
args.managed_application = managed_app;
86+
// Find the managed app in the same directory
87+
args.managed_application = init.host_info.app_path;
11588
if (!pal::realpath(&args.managed_application))
11689
{
11790
trace::error(_X("Failed to locate managed application [%s]"), args.managed_application.c_str());
11891
return false;
11992
}
120-
args.app_dir = own_dir;
93+
args.app_root = init.host_info.dotnet_root;
12194
args.app_argv = &argv[1];
12295
args.app_argc = argc - 1;
12396
}
12497

12598
if (!init.deps_file.empty())
12699
{
127100
args.deps_path = init.deps_file;
128-
args.app_dir = get_directory(args.deps_path);
101+
args.app_root = get_directory(args.deps_path);
129102
}
130103

131104
for (const auto& probe : init.probe_paths)
@@ -135,7 +108,7 @@ bool parse_arguments(
135108

136109
if (args.deps_path.empty())
137110
{
138-
const auto& app_base = args.app_dir;
111+
const auto& app_base = args.app_root;
139112
auto app_name = get_filename(args.managed_application);
140113

141114
args.deps_path.reserve(app_base.length() + 1 + app_name.length() + 5);
@@ -151,7 +124,7 @@ bool parse_arguments(
151124

152125
pal::get_default_servicing_directory(&args.core_servicing);
153126

154-
setup_shared_store_paths(init, own_dir, &args);
127+
setup_shared_store_paths(init, get_directory(args.host_path), &args);
155128

156129
return true;
157130
}

src/corehost/cli/args.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ struct probe_config_t
9090

9191
struct arguments_t
9292
{
93-
pal::string_t own_path;
94-
pal::string_t app_dir;
93+
pal::string_t host_path;
94+
pal::string_t app_root;
9595
pal::string_t deps_path;
9696
pal::string_t core_servicing;
9797
std::vector<pal::string_t> probe_paths;
@@ -108,8 +108,8 @@ struct arguments_t
108108
{
109109
if (trace::is_enabled())
110110
{
111-
trace::verbose(_X("-- arguments_t: own_path='%s' app_dir='%s' deps='%s' core_svc='%s' mgd_app='%s'"),
112-
own_path.c_str(), app_dir.c_str(), deps_path.c_str(), core_servicing.c_str(), managed_application.c_str());
111+
trace::verbose(_X("-- arguments_t: host_path='%s' app_root='%s' deps='%s' core_svc='%s' mgd_app='%s'"),
112+
host_path.c_str(), app_root.c_str(), deps_path.c_str(), core_servicing.c_str(), managed_application.c_str());
113113
for (const auto& probe : probe_paths)
114114
{
115115
trace::verbose(_X("-- arguments_t: probe dir: '%s'"), probe.c_str());

src/corehost/cli/deps_format.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ bool deps_json_t::process_targets(const json_value& json, const pal::string_t& t
320320
return true;
321321
}
322322

323-
bool deps_json_t::load_portable(const pal::string_t& deps_path, const json_value& json, const pal::string_t& target_name, const rid_fallback_graph_t& rid_fallback_graph)
323+
bool deps_json_t::load_framework_dependent(const pal::string_t& deps_path, const json_value& json, const pal::string_t& target_name, const rid_fallback_graph_t& rid_fallback_graph)
324324
{
325325
if (!process_runtime_targets(json, target_name, rid_fallback_graph, &m_rid_assets))
326326
{
@@ -367,7 +367,7 @@ bool deps_json_t::load_portable(const pal::string_t& deps_path, const json_value
367367
return true;
368368
}
369369

370-
bool deps_json_t::load_standalone(const pal::string_t& deps_path, const json_value& json, const pal::string_t& target_name)
370+
bool deps_json_t::load_self_contained(const pal::string_t& deps_path, const json_value& json, const pal::string_t& target_name)
371371
{
372372
if (!process_targets(json, target_name, &m_assets))
373373
{
@@ -438,7 +438,7 @@ bool deps_json_t::has_package(const pal::string_t& name, const pal::string_t& ve
438438
// Load the deps file and parse its "entry" lines which contain the "fields" of
439439
// the entry. Populate an array of these entries.
440440
//
441-
bool deps_json_t::load(bool portable, const pal::string_t& deps_path, const rid_fallback_graph_t& rid_fallback_graph)
441+
bool deps_json_t::load(bool is_framework_dependent, const pal::string_t& deps_path, const rid_fallback_graph_t& rid_fallback_graph)
442442
{
443443
m_deps_file = deps_path;
444444
m_file_exists = pal::file_exists(deps_path);
@@ -473,9 +473,9 @@ bool deps_json_t::load(bool portable, const pal::string_t& deps_path, const rid_
473473
runtime_target.as_string():
474474
runtime_target.at(_X("name")).as_string();
475475

476-
trace::verbose(_X("Loading deps file... %s as portable=[%d]"), deps_path.c_str(), portable);
476+
trace::verbose(_X("Loading deps file... %s as framework dependent=[%d]"), deps_path.c_str(), is_framework_dependent);
477477

478-
return (portable) ? load_portable(deps_path, json, name, rid_fallback_graph) : load_standalone(deps_path, json, name);
478+
return (is_framework_dependent) ? load_framework_dependent(deps_path, json, name, rid_fallback_graph) : load_self_contained(deps_path, json, name);
479479
}
480480
catch (const std::exception& je)
481481
{

src/corehost/cli/deps_format.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,25 @@ class deps_json_t
3333
{
3434
}
3535

36-
deps_json_t(bool portable, const pal::string_t& deps_path)
37-
: deps_json_t(portable, deps_path, m_rid_fallback_graph /* dummy */)
36+
deps_json_t(bool is_framework_dependent, const pal::string_t& deps_path)
37+
: deps_json_t(is_framework_dependent, deps_path, m_rid_fallback_graph /* dummy */)
3838
{
3939
}
4040

41-
deps_json_t(bool portable, const pal::string_t& deps_path, const rid_fallback_graph_t& graph)
41+
deps_json_t(bool is_framework_dependent, const pal::string_t& deps_path, const rid_fallback_graph_t& graph)
4242
: deps_json_t()
4343
{
44-
m_valid = load(portable, deps_path, graph);
44+
m_valid = load(is_framework_dependent, deps_path, graph);
4545
}
4646

47-
void parse(bool portable, const pal::string_t& deps_path)
47+
void parse(bool is_framework_dependent, const pal::string_t& deps_path)
4848
{
49-
m_valid = load(portable, deps_path, m_rid_fallback_graph /* dummy */);
49+
m_valid = load(is_framework_dependent, deps_path, m_rid_fallback_graph /* dummy */);
5050
}
5151

52-
void parse(bool portable, const pal::string_t& deps_path, const rid_fallback_graph_t& graph)
52+
void parse(bool is_framework_dependent, const pal::string_t& deps_path, const rid_fallback_graph_t& graph)
5353
{
54-
m_valid = load(portable, deps_path, graph);
54+
m_valid = load(is_framework_dependent, deps_path, graph);
5555
}
5656

5757
const std::vector<deps_entry_t>& get_entries(deps_entry_t::asset_types type) const
@@ -85,9 +85,9 @@ class deps_json_t
8585
}
8686

8787
private:
88-
bool load_standalone(const pal::string_t& deps_path, const json_value& json, const pal::string_t& target_name);
89-
bool load_portable(const pal::string_t& deps_path, const json_value& json, const pal::string_t& target_name, const rid_fallback_graph_t& rid_fallback_graph);
90-
bool load(bool portable, const pal::string_t& deps_path, const rid_fallback_graph_t& rid_fallback_graph);
88+
bool load_self_contained(const pal::string_t& deps_path, const json_value& json, const pal::string_t& target_name);
89+
bool load_framework_dependent(const pal::string_t& deps_path, const json_value& json, const pal::string_t& target_name, const rid_fallback_graph_t& rid_fallback_graph);
90+
bool load(bool is_framework_dependent, const pal::string_t& deps_path, const rid_fallback_graph_t& rid_fallback_graph);
9191
bool process_runtime_targets(const json_value& json, const pal::string_t& target_name, const rid_fallback_graph_t& rid_fallback_graph, rid_specific_assets_t* p_assets);
9292
bool process_targets(const json_value& json, const pal::string_t& target_name, deps_assets_t* p_assets);
9393

src/corehost/cli/deps_resolver.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ bool deps_resolver_t::resolve_tpa_list(
542542
// A minor\major roll-forward affects which layer wins
543543
bool is_minor_or_major_roll_forward = m_fx_definitions[i]->did_minor_or_major_roll_forward_occur();
544544

545-
const auto& deps_entries = m_portable ? m_fx_definitions[i]->get_deps().get_entries(deps_entry_t::asset_types::runtime) : empty;
545+
const auto& deps_entries = m_is_framework_dependent ? m_fx_definitions[i]->get_deps().get_entries(deps_entry_t::asset_types::runtime) : empty;
546546
for (const auto& entry : deps_entries)
547547
{
548548
if (!process_entry(m_fx_definitions[i]->get_dir(), entry, i, is_minor_or_major_roll_forward))
@@ -588,12 +588,12 @@ void deps_resolver_t::init_known_entry_path(const deps_entry_t& entry, const pal
588588

589589
void deps_resolver_t::resolve_additional_deps(const hostpolicy_init_t& init)
590590
{
591-
if (!m_portable)
591+
if (!m_is_framework_dependent)
592592
{
593-
// Additional deps.json support is only available for portable apps due to the following constraints:
593+
// Additional deps.json support is only available for framework-dependent apps due to the following constraints:
594594
//
595-
// 1) Unlike Portable Apps, Standalone apps do not have details of the SharedFX and Version they target.
596-
// 2) Unlike Portable Apps, Standalone apps do not have RID fallback graph that is required for looking up
595+
// 1) Unlike framework-dependent Apps, self-contained apps do not have details of the SharedFX and Version they target.
596+
// 2) Unlike framework-dependent Apps, self-contained apps do not have RID fallback graph that is required for looking up
597597
// the correct native assets from nuget packages.
598598

599599
return;
@@ -727,7 +727,7 @@ bool deps_resolver_t::resolve_probe_dirs(
727727
}
728728
else
729729
{
730-
// For standalone apps, apphost.exe will be renamed. Do not use the full package name
730+
// For self-contained apps do not use the full package name
731731
// because of rid-fallback could happen (ex: CentOS falling back to RHEL)
732732
if ((entry.asset.name == _X("apphost")) && ends_with(entry.library_name, _X(".Microsoft.NETCore.DotNetAppHost"), false))
733733
{
@@ -797,7 +797,7 @@ bool deps_resolver_t::resolve_probe_dirs(
797797
// Entrypoint to resolve TPA, native and resources path ordering to pass to CoreCLR.
798798
//
799799
// Parameters:
800-
// app_dir - The application local directory
800+
// app_root - The application local directory
801801
// package_dir - The directory path to where packages are restored
802802
// package_cache_dir - The directory path to secondary cache for packages
803803
// clr_dir - The directory where the host loads the CLR

src/corehost/cli/deps_resolver.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ class deps_resolver_t
4141
public:
4242
deps_resolver_t(hostpolicy_init_t& init, const arguments_t& args)
4343
: m_fx_definitions(init.fx_definitions)
44-
, m_app_dir(args.app_dir)
44+
, m_app_dir(args.app_root)
4545
, m_managed_app(args.managed_application)
46-
, m_portable(init.is_portable)
46+
, m_is_framework_dependent(init.is_framework_dependent)
4747
, m_core_servicing(args.core_servicing)
4848
{
4949
int root_framework = m_fx_definitions.size() - 1;
@@ -218,8 +218,8 @@ class deps_resolver_t
218218
// Fallback probe dir
219219
std::vector<pal::string_t> m_additional_probes;
220220

221-
// Is the deps file portable app?
222-
bool m_portable;
221+
// Is the deps file for an app using shared frameworks?
222+
bool m_is_framework_dependent;
223223
};
224224

225225
#endif // DEPS_RESOLVER_H

src/corehost/cli/dll/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ set(SOURCES
4040
../breadcrumbs.cpp
4141
../args.cpp
4242
../hostpolicy.cpp
43+
../host_startup_info.cpp
4344
../coreclr.cpp
4445
../deps_resolver.cpp
4546
../deps_format.cpp

src/corehost/cli/exe/apphost/CMakeLists.txt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,21 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
1818
endif()
1919

2020
set(SKIP_VERSIONING 1)
21+
22+
include_directories(./)
23+
include_directories(../../json/casablanca/include)
24+
25+
set(SOURCES
26+
startup_config.cpp
27+
../../json/casablanca/src/json/json.cpp
28+
../../json/casablanca/src/json/json_parsing.cpp
29+
../../json/casablanca/src/json/json_serialization.cpp
30+
../../json/casablanca/src/utilities/asyncrt_utils.cpp
31+
../../fxr/fx_ver.cpp
32+
)
33+
2134
include(../exe.cmake)
22-
set(SOURCES)
35+
2336
add_definitions(-DFEATURE_APPHOST=1)
2437

2538
install_library_and_symbols (apphost)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
#include "pal.h"
5+
#include "trace.h"
6+
#include "utils.h"
7+
#include "cpprest/json.h"
8+
#include "startup_config.h"
9+
10+
startup_config_t::startup_config_t()
11+
: m_valid(false)
12+
{
13+
}
14+
15+
void startup_config_t::parse(const pal::string_t& path)
16+
{
17+
trace::verbose(_X("Attempting to read startup config: %s"), path.c_str());
18+
19+
m_valid = parse_internal(path);
20+
if (!m_valid)
21+
{
22+
trace::verbose(_X("Did not successfully parse the startup.config.json"));
23+
}
24+
}
25+
26+
bool startup_config_t::parse_internal(const pal::string_t& path)
27+
{
28+
pal::string_t retval;
29+
if (!pal::file_exists(path))
30+
{
31+
// Not existing is not an error.
32+
return true;
33+
}
34+
35+
pal::ifstream_t file(path);
36+
if (!file.good())
37+
{
38+
trace::verbose(_X("File stream not good %s"), path.c_str());
39+
return false;
40+
}
41+
42+
if (skip_utf8_bom(&file))
43+
{
44+
trace::verbose(_X("UTF-8 BOM skipped while reading [%s]"), path.c_str());
45+
}
46+
47+
try
48+
{
49+
const auto root = web::json::value::parse(file);
50+
const auto& json = root.as_object();
51+
const auto options = json.find(_X("startupOptions"));
52+
if (options != json.end())
53+
{
54+
const auto& prop_obj = options->second.as_object();
55+
56+
auto appRoot = prop_obj.find(_X("appRoot"));
57+
if (appRoot != prop_obj.end())
58+
{
59+
m_app_root = appRoot->second.as_string();
60+
}
61+
}
62+
}
63+
catch (const std::exception& je)
64+
{
65+
pal::string_t jes;
66+
(void)pal::utf8_palstring(je.what(), &jes);
67+
trace::error(_X("A JSON parsing exception occurred in [%s]: %s"), path.c_str(), jes.c_str());
68+
return false;
69+
}
70+
71+
return true;
72+
}

0 commit comments

Comments
 (0)