Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSwaroop Sridhar <Swaroop.Sridhar@microsoft.com>2020-05-01 19:24:13 +0300
committerGitHub <noreply@github.com>2020-05-01 19:24:13 +0300
commit47ec733ba79b196e4e09d0c89bad245155002353 (patch)
tree98fc7124abbcb678abe9687e757a77e638560f05
parent6d1f7e01d3429054ec3dcb7c75b3450b9fe1429e (diff)
[release/5.0-preview4] Revert processing bundles in framework (#35679)v5.0.0-preview.4.20251.6
This commit reverts: Revert "Single-File: Process bundles in the framework (#34274)" This reverts commit 78b303df8fbb242985d049a277d0d199cafd51b5. Revert "Single-File Bundler: Add a FileSize test (#35149)" This reverts commit 779588a509b81d909ac5d496c172949ec1f1ddcc. *Customer Scenario* Publishing apps as a self-contained single-file doesn't work as expected. * Publish needs to generate hostpolicy and hostfxr separate from the single file bundle * Cross-platform publishing is incorrect *Problem* Since Static-apphost is not yet ready, processing bundle content in hostpolicy means that hostpolicy and hostfxr DLLs need to be separate from the bundle. This causes self-contained single-file apps to not be a "single file" temporarily. The change also requires supporting changes from the SDK, to publish hostfxr and hostpolicy as separate files, and to invoke HostModel library with arguments that facilitate cross-platform publishing. *Solution* To solve these, problem, this change reverts: Revert "Single-File: Process bundles in the framework (#34274)" commit 78b303df8fbb242985d049a277d0d199cafd51b5. and a dependent test-only change: Revert "Single-File Bundler: Add a FileSize test (#35149)" commit 779588a509b81d909ac5d496c172949ec1f1ddcc. *Risk* Medium The change is contained to only host components: apphost, hostpolicy, and hostfxr. However, the change is big, and needs testing in runtime and SDK repos. *Testing* Manually tested the SDK by inserting apphost, hostfxr, hostpolicy, and hostmodel library from this build into the `dotnet/packs` preview-4 SDK from https://github.com/dotnet/sdk/pull/11518 build. Verified that: * Singlefile apps can be published and run OK for { Windows, Linux, Osx } x {netcoreapp3.0, netcoreapp3.1, netcoreapp5.0} * Cross-targeting builds of single-file apps build and run OK (ex: built on Windos, run on Mac).
-rw-r--r--src/installer/corehost/cli/apphost/CMakeLists.txt19
-rw-r--r--src/installer/corehost/cli/apphost/bundle/dir_utils.cpp (renamed from src/installer/corehost/cli/bundle/dir_utils.cpp)0
-rw-r--r--src/installer/corehost/cli/apphost/bundle/dir_utils.h (renamed from src/installer/corehost/cli/bundle/dir_utils.h)0
-rw-r--r--src/installer/corehost/cli/apphost/bundle/extractor.cpp (renamed from src/installer/corehost/cli/bundle/extractor.cpp)10
-rw-r--r--src/installer/corehost/cli/apphost/bundle/extractor.h (renamed from src/installer/corehost/cli/bundle/extractor.h)0
-rw-r--r--src/installer/corehost/cli/apphost/bundle/file_entry.cpp (renamed from src/installer/corehost/cli/bundle/file_entry.cpp)15
-rw-r--r--src/installer/corehost/cli/apphost/bundle/file_entry.h (renamed from src/installer/corehost/cli/bundle/file_entry.h)1
-rw-r--r--src/installer/corehost/cli/apphost/bundle/file_type.h (renamed from src/installer/corehost/cli/bundle/file_type.h)0
-rw-r--r--src/installer/corehost/cli/apphost/bundle/header.cpp (renamed from src/installer/corehost/cli/bundle/header.cpp)24
-rw-r--r--src/installer/corehost/cli/apphost/bundle/header.h (renamed from src/installer/corehost/cli/bundle/header.h)24
-rw-r--r--src/installer/corehost/cli/apphost/bundle/manifest.cpp (renamed from src/installer/corehost/cli/bundle/manifest.cpp)4
-rw-r--r--src/installer/corehost/cli/apphost/bundle/manifest.h (renamed from src/installer/corehost/cli/bundle/manifest.h)8
-rw-r--r--src/installer/corehost/cli/apphost/bundle/marker.cpp (renamed from src/installer/corehost/cli/apphost/bundle_marker.cpp)8
-rw-r--r--src/installer/corehost/cli/apphost/bundle/marker.h (renamed from src/installer/corehost/cli/apphost/bundle_marker.h)12
-rw-r--r--src/installer/corehost/cli/apphost/bundle/reader.cpp (renamed from src/installer/corehost/cli/bundle/reader.cpp)11
-rw-r--r--src/installer/corehost/cli/apphost/bundle/reader.h (renamed from src/installer/corehost/cli/bundle/reader.h)19
-rw-r--r--src/installer/corehost/cli/apphost/bundle/runner.cpp65
-rw-r--r--src/installer/corehost/cli/apphost/bundle/runner.h40
-rw-r--r--src/installer/corehost/cli/bundle/info.cpp157
-rw-r--r--src/installer/corehost/cli/bundle/info.h91
-rw-r--r--src/installer/corehost/cli/bundle/runner.cpp83
-rw-r--r--src/installer/corehost/cli/bundle/runner.h49
-rw-r--r--src/installer/corehost/cli/deps_entry.cpp118
-rw-r--r--src/installer/corehost/cli/deps_entry.h14
-rw-r--r--src/installer/corehost/cli/deps_format.cpp7
-rw-r--r--src/installer/corehost/cli/fxr/command_line.cpp3
-rw-r--r--src/installer/corehost/cli/fxr/corehost_init.cpp3
-rw-r--r--src/installer/corehost/cli/fxr/corehost_init.h3
-rw-r--r--src/installer/corehost/cli/fxr/fx_muxer.cpp8
-rw-r--r--src/installer/corehost/cli/fxr/hostfxr.cpp18
-rw-r--r--src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp1
-rw-r--r--src/installer/corehost/cli/host_interface.h5
-rw-r--r--src/installer/corehost/cli/host_startup_info.h1
-rw-r--r--src/installer/corehost/cli/hostcommon/CMakeLists.txt6
-rw-r--r--src/installer/corehost/cli/hostfxr.h7
-rw-r--r--src/installer/corehost/cli/hostmisc/pal.h8
-rw-r--r--src/installer/corehost/cli/hostmisc/pal.unix.cpp30
-rw-r--r--src/installer/corehost/cli/hostmisc/pal.windows.cpp31
-rw-r--r--src/installer/corehost/cli/hostmisc/utils.cpp19
-rw-r--r--src/installer/corehost/cli/hostmisc/utils.h2
-rw-r--r--src/installer/corehost/cli/hostpolicy/CMakeLists.txt10
-rw-r--r--src/installer/corehost/cli/hostpolicy/args.cpp46
-rw-r--r--src/installer/corehost/cli/hostpolicy/deps_resolver.cpp6
-rw-r--r--src/installer/corehost/cli/hostpolicy/deps_resolver.h12
-rw-r--r--src/installer/corehost/cli/hostpolicy/hostpolicy.cpp15
-rw-r--r--src/installer/corehost/cli/hostpolicy/hostpolicy_init.cpp10
-rw-r--r--src/installer/corehost/cli/hostpolicy/hostpolicy_init.h1
-rw-r--r--src/installer/corehost/cli/ijwhost/ijwthunk.cpp6
-rw-r--r--src/installer/corehost/cli/json/rapidjson/document.h4
-rw-r--r--src/installer/corehost/cli/json_parser.cpp62
-rw-r--r--src/installer/corehost/cli/json_parser.h20
-rw-r--r--src/installer/corehost/cli/runtime_config.cpp5
-rw-r--r--src/installer/corehost/cli/test/mockhostpolicy/mockhostpolicy.cpp1
-rw-r--r--src/installer/corehost/corehost.cpp141
-rw-r--r--src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs18
-rw-r--r--src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs2
-rw-r--r--src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs17
-rw-r--r--src/installer/test/Assets/TestProjects/AppWithSubDirs/Program.cs6
-rw-r--r--src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs64
-rw-r--r--src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleRename.cs4
-rw-r--r--src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs34
-rw-r--r--src/installer/test/Microsoft.NET.HostModel.Tests/Helpers/BundleHelper.cs97
-rw-r--r--src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs5
-rw-r--r--src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleLegacy.cs1
-rw-r--r--src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundlerConsistencyTests.cs76
-rw-r--r--src/installer/test/TestUtils/TestApp.cs2
-rw-r--r--src/installer/test/TestUtils/TestProject.cs1
67 files changed, 477 insertions, 1113 deletions
diff --git a/src/installer/corehost/cli/apphost/CMakeLists.txt b/src/installer/corehost/cli/apphost/CMakeLists.txt
index ba01e32ec47..d77f2bfa981 100644
--- a/src/installer/corehost/cli/apphost/CMakeLists.txt
+++ b/src/installer/corehost/cli/apphost/CMakeLists.txt
@@ -18,11 +18,26 @@ endif()
set(SKIP_VERSIONING 1)
set(SOURCES
- ./bundle_marker.cpp
+ ./bundle/file_entry.cpp
+ ./bundle/manifest.cpp
+ ./bundle/header.cpp
+ ./bundle/marker.cpp
+ ./bundle/reader.cpp
+ ./bundle/extractor.cpp
+ ./bundle/runner.cpp
+ ./bundle/dir_utils.cpp
)
set(HEADERS
- ./bundle_marker.h
+ ./bundle/file_type.h
+ ./bundle/file_entry.h
+ ./bundle/manifest.h
+ ./bundle/header.h
+ ./bundle/marker.h
+ ./bundle/reader.h
+ ./bundle/extractor.h
+ ./bundle/runner.h
+ ./bundle/dir_utils.h
)
if(CLR_CMAKE_TARGET_WIN32)
diff --git a/src/installer/corehost/cli/bundle/dir_utils.cpp b/src/installer/corehost/cli/apphost/bundle/dir_utils.cpp
index eede9529812..eede9529812 100644
--- a/src/installer/corehost/cli/bundle/dir_utils.cpp
+++ b/src/installer/corehost/cli/apphost/bundle/dir_utils.cpp
diff --git a/src/installer/corehost/cli/bundle/dir_utils.h b/src/installer/corehost/cli/apphost/bundle/dir_utils.h
index ffe0acffb60..ffe0acffb60 100644
--- a/src/installer/corehost/cli/bundle/dir_utils.h
+++ b/src/installer/corehost/cli/apphost/bundle/dir_utils.h
diff --git a/src/installer/corehost/cli/bundle/extractor.cpp b/src/installer/corehost/cli/apphost/bundle/extractor.cpp
index 04c5205da9d..71bb2259e9d 100644
--- a/src/installer/corehost/cli/bundle/extractor.cpp
+++ b/src/installer/corehost/cli/apphost/bundle/extractor.cpp
@@ -197,10 +197,7 @@ void extractor_t::extract_new(reader_t& reader)
begin();
for (const file_entry_t& entry : m_manifest.files)
{
- if (entry.needs_extraction())
- {
- extract(entry, reader);
- }
+ extract(entry, reader);
}
commit_dir();
}
@@ -214,11 +211,6 @@ void extractor_t::verify_recover_extraction(reader_t& reader)
for (const file_entry_t& entry : m_manifest.files)
{
- if (!entry.needs_extraction())
- {
- continue;
- }
-
pal::string_t file_path = ext_dir;
append_path(&file_path, entry.relative_path().c_str());
diff --git a/src/installer/corehost/cli/bundle/extractor.h b/src/installer/corehost/cli/apphost/bundle/extractor.h
index 73b75ecdd09..73b75ecdd09 100644
--- a/src/installer/corehost/cli/bundle/extractor.h
+++ b/src/installer/corehost/cli/apphost/bundle/extractor.h
diff --git a/src/installer/corehost/cli/bundle/file_entry.cpp b/src/installer/corehost/cli/apphost/bundle/file_entry.cpp
index 775117fb9a1..ba4b235fa93 100644
--- a/src/installer/corehost/cli/bundle/file_entry.cpp
+++ b/src/installer/corehost/cli/apphost/bundle/file_entry.cpp
@@ -33,18 +33,3 @@ file_entry_t file_entry_t::read(reader_t &reader)
return entry;
}
-
-bool file_entry_t::needs_extraction() const
-{
- switch (m_type)
- {
- // Once the runtime can load assemblies from bundle,
- // file_type_t::assembly should be in this category
- case file_type_t::deps_json:
- case file_type_t::runtime_config_json:
- return false;
-
- default:
- return true;
- }
-}
diff --git a/src/installer/corehost/cli/bundle/file_entry.h b/src/installer/corehost/cli/apphost/bundle/file_entry.h
index c89d3ce0a5f..efe405cc9a6 100644
--- a/src/installer/corehost/cli/bundle/file_entry.h
+++ b/src/installer/corehost/cli/apphost/bundle/file_entry.h
@@ -58,7 +58,6 @@ namespace bundle
int64_t offset() const { return m_offset; }
int64_t size() const { return m_size; }
file_type_t type() const { return m_type; }
- bool needs_extraction() const;
static file_entry_t read(reader_t &reader);
diff --git a/src/installer/corehost/cli/bundle/file_type.h b/src/installer/corehost/cli/apphost/bundle/file_type.h
index acbfca06859..acbfca06859 100644
--- a/src/installer/corehost/cli/bundle/file_type.h
+++ b/src/installer/corehost/cli/apphost/bundle/file_type.h
diff --git a/src/installer/corehost/cli/bundle/header.cpp b/src/installer/corehost/cli/apphost/bundle/header.cpp
index 7e6f778464d..23695bb93f1 100644
--- a/src/installer/corehost/cli/bundle/header.cpp
+++ b/src/installer/corehost/cli/apphost/bundle/header.cpp
@@ -9,23 +9,29 @@
using namespace bundle;
-bool header_fixed_t::is_valid() const
+// The AppHost expects the bundle_header to be an exact_match for which it was built.
+// The framework accepts backwards compatible header versions.
+bool header_fixed_t::is_valid(bool exact_match) const
{
if (num_embedded_files <= 0)
{
return false;
}
- // .net 5 host expects the version information to be 2.0
- // .net core 3 single-file bundles are handled within the netcoreapp3.x apphost, and are not processed here in the framework.
- return (major_version == header_t::major_version) && (minor_version == header_t::minor_version);
+ if (exact_match)
+ {
+ return (major_version == header_t::major_version) && (minor_version == header_t::minor_version);
+ }
+
+ return ((major_version < header_t::major_version) ||
+ (major_version == header_t::major_version && minor_version <= header_t::minor_version));
}
-header_t header_t::read(reader_t& reader)
+header_t header_t::read(reader_t& reader, bool need_exact_version)
{
const header_fixed_t* fixed_header = reinterpret_cast<const header_fixed_t*>(reader.read_direct(sizeof(header_fixed_t)));
- if (!fixed_header->is_valid())
+ if (!fixed_header->is_valid(need_exact_version))
{
trace::error(_X("Failure processing application bundle."));
trace::error(_X("Bundle header version compatibility check failed."));
@@ -38,8 +44,10 @@ header_t header_t::read(reader_t& reader)
// bundle_id is a component of the extraction path
reader.read_path_string(header.m_bundle_id);
- const header_fixed_v2_t *v2_header = reinterpret_cast<const header_fixed_v2_t*>(reader.read_direct(sizeof(header_fixed_v2_t)));
- header.m_v2_header = *v2_header;
+ if (fixed_header->major_version > 1)
+ {
+ header.m_v2_header = reinterpret_cast<const header_fixed_v2_t*>(reader.read_direct(sizeof(header_fixed_v2_t)));
+ }
return header;
}
diff --git a/src/installer/corehost/cli/bundle/header.h b/src/installer/corehost/cli/apphost/bundle/header.h
index f9ec85f4221..1b1696219dc 100644
--- a/src/installer/corehost/cli/bundle/header.h
+++ b/src/installer/corehost/cli/apphost/bundle/header.h
@@ -32,8 +32,9 @@ namespace bundle
uint32_t minor_version;
int32_t num_embedded_files;
- bool is_valid() const;
+ bool is_valid(bool exact_match = false) const;
};
+#pragma pack(pop)
// netcoreapp3_compat_mode flag is set on a .net5 app, which chooses to build single-file apps in .netcore3.x compat mode,
// This indicates that:
@@ -45,13 +46,12 @@ namespace bundle
netcoreapp3_compat_mode = 1
};
+#pragma pack(push, 1)
struct location_t
{
public:
int64_t offset;
int64_t size;
-
- bool is_valid() const { return offset != 0; }
};
// header_fixed_v2_t is available in single-file apps targetting .net5+ frameworks.
@@ -65,8 +65,6 @@ namespace bundle
location_t deps_json_location;
location_t runtimeconfig_json_location;
header_flags_t flags;
-
- bool is_netcoreapp3_compat_mode() const { return (flags & header_flags_t::netcoreapp3_compat_mode) != 0; }
};
#pragma pack(pop)
@@ -76,17 +74,14 @@ namespace bundle
header_t(int32_t num_embedded_files = 0)
: m_num_embedded_files(num_embedded_files)
, m_bundle_id()
- , m_v2_header()
+ , m_v2_header(NULL)
+
{
}
- static header_t read(reader_t& reader);
- const pal::string_t& bundle_id() const { return m_bundle_id; }
- int32_t num_embedded_files() const { return m_num_embedded_files; }
-
- const location_t& deps_json_location() const { return m_v2_header.deps_json_location; }
- const location_t& runtimeconfig_json_location() const { return m_v2_header.runtimeconfig_json_location; }
- bool is_netcoreapp3_compat_mode() const { return m_v2_header.is_netcoreapp3_compat_mode(); }
+ static header_t read(reader_t& reader, bool need_exact_version);
+ const pal::string_t& bundle_id() { return m_bundle_id; }
+ int32_t num_embedded_files() { return m_num_embedded_files; }
static const uint32_t major_version = 2;
static const uint32_t minor_version = 0;
@@ -94,7 +89,8 @@ namespace bundle
private:
int32_t m_num_embedded_files;
pal::string_t m_bundle_id;
- header_fixed_v2_t m_v2_header;
+ const header_fixed_v2_t* m_v2_header;
+
};
}
#endif // __HEADER_H__
diff --git a/src/installer/corehost/cli/bundle/manifest.cpp b/src/installer/corehost/cli/apphost/bundle/manifest.cpp
index 55f1ff1e639..6de65d3a96b 100644
--- a/src/installer/corehost/cli/bundle/manifest.cpp
+++ b/src/installer/corehost/cli/apphost/bundle/manifest.cpp
@@ -12,9 +12,7 @@ manifest_t manifest_t::read(reader_t& reader, int32_t num_files)
for (int32_t i = 0; i < num_files; i++)
{
- file_entry_t entry = file_entry_t::read(reader);
- manifest.files.push_back(std::move(entry));
- manifest.m_need_extraction |= entry.needs_extraction();
+ manifest.files.emplace_back(file_entry_t::read(reader));
}
return manifest;
diff --git a/src/installer/corehost/cli/bundle/manifest.h b/src/installer/corehost/cli/apphost/bundle/manifest.h
index af1f9fa9198..ee8cd1edab5 100644
--- a/src/installer/corehost/cli/bundle/manifest.h
+++ b/src/installer/corehost/cli/apphost/bundle/manifest.h
@@ -16,17 +16,9 @@ namespace bundle
class manifest_t
{
public:
- manifest_t()
- : m_need_extraction(false) {}
-
std::vector<file_entry_t> files;
static manifest_t read(reader_t &reader, int32_t num_files);
-
- bool files_need_extraction() { return m_need_extraction; }
-
- private:
- bool m_need_extraction;
};
}
#endif // __MANIFEST_H__
diff --git a/src/installer/corehost/cli/apphost/bundle_marker.cpp b/src/installer/corehost/cli/apphost/bundle/marker.cpp
index d8ea15bdd4f..d2302923226 100644
--- a/src/installer/corehost/cli/apphost/bundle_marker.cpp
+++ b/src/installer/corehost/cli/apphost/bundle/marker.cpp
@@ -2,12 +2,14 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-#include "bundle_marker.h"
+#include "marker.h"
#include "pal.h"
#include "trace.h"
#include "utils.h"
-int64_t bundle_marker_t::header_offset()
+using namespace bundle;
+
+int64_t marker_t::header_offset()
{
// Contains the bundle_placeholder default value at compile time.
// If this is a single-file bundle, the last 8 bytes are replaced
@@ -25,7 +27,7 @@ int64_t bundle_marker_t::header_offset()
0xee, 0x3b, 0x2d, 0xce, 0x24, 0xb3, 0x6a, 0xae
};
- volatile bundle_marker_t* marker = reinterpret_cast<volatile bundle_marker_t *>(placeholder);
+ volatile marker_t* marker = reinterpret_cast<volatile marker_t *>(placeholder);
return marker->locator.bundle_header_offset;
}
diff --git a/src/installer/corehost/cli/apphost/bundle_marker.h b/src/installer/corehost/cli/apphost/bundle/marker.h
index c5065fdac19..52e185fbe79 100644
--- a/src/installer/corehost/cli/apphost/bundle_marker.h
+++ b/src/installer/corehost/cli/apphost/bundle/marker.h
@@ -2,13 +2,15 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-#ifndef __BUNDLE_MARKER_H__
-#define __BUNDLE_MARKER_H__
+#ifndef __MARKER_H__
+#define __MARKER_H__
#include <cstdint>
+namespace bundle
+{
#pragma pack(push, 1)
- union bundle_marker_t
+ union marker_t
{
public:
uint8_t placeholder[40];
@@ -26,5 +28,5 @@
};
#pragma pack(pop)
-
-#endif // __BUNDLE_MARKER_H__
+}
+#endif // __MARKER_H__
diff --git a/src/installer/corehost/cli/bundle/reader.cpp b/src/installer/corehost/cli/apphost/bundle/reader.cpp
index 2e5135da564..e2fa9b6574c 100644
--- a/src/installer/corehost/cli/bundle/reader.cpp
+++ b/src/installer/corehost/cli/apphost/bundle/reader.cpp
@@ -8,9 +8,9 @@
using namespace bundle;
-const char* reader_t::add_without_overflow(const char* ptr, int64_t len)
+const int8_t* reader_t::add_without_overflow(const int8_t* ptr, int64_t len)
{
- const char* new_ptr = ptr + len;
+ const int8_t* new_ptr = ptr + len;
// The following check will fail in case len < 0 (which is also an error while reading)
// even if the actual arthmetic didn't overflow.
@@ -38,7 +38,7 @@ void reader_t::set_offset(int64_t offset)
void reader_t::bounds_check(int64_t len)
{
- const char* post_read_ptr = add_without_overflow(m_ptr, len);
+ const int8_t* post_read_ptr = add_without_overflow(m_ptr, len);
// It is legal for post_read_ptr == m_bound_ptr after reading the last byte.
if (m_ptr < m_base_ptr || post_read_ptr > m_bound_ptr)
@@ -88,14 +88,11 @@ size_t reader_t::read_path_length()
return length;
}
-size_t reader_t::read_path_string(pal::string_t &str)
+void reader_t::read_path_string(pal::string_t &str)
{
- const char* start_ptr = m_ptr;
size_t size = read_path_length();
std::unique_ptr<uint8_t[]> buffer{ new uint8_t[size + 1] };
read(buffer.get(), size);
buffer[size] = 0; // null-terminator
pal::clr_palstring(reinterpret_cast<const char*>(buffer.get()), &str);
-
- return m_ptr - start_ptr; // This subtraction can't overflow because addition above is bounds_checked
}
diff --git a/src/installer/corehost/cli/bundle/reader.h b/src/installer/corehost/cli/apphost/bundle/reader.h
index 8a1212d94b8..1824ece515a 100644
--- a/src/installer/corehost/cli/bundle/reader.h
+++ b/src/installer/corehost/cli/apphost/bundle/reader.h
@@ -13,20 +13,19 @@ namespace bundle
// Helper class for reading sequentially from the memory-mapped bundle file.
struct reader_t
{
- reader_t(const char* base_ptr, int64_t bound, int64_t start_offset = 0)
+ reader_t(const int8_t* base_ptr, int64_t bound)
: m_base_ptr(base_ptr)
, m_ptr(base_ptr)
, m_bound(bound)
, m_bound_ptr(add_without_overflow(base_ptr, bound))
{
- set_offset(start_offset);
}
public:
void set_offset(int64_t offset);
- operator const char*() const
+ operator const int8_t*() const
{
return m_ptr;
}
@@ -47,26 +46,26 @@ namespace bundle
// Return a pointer to the requested bytes within the memory-mapped file.
// Skip over len bytes.
- const char* read_direct(int64_t len)
+ const int8_t* read_direct(int64_t len)
{
bounds_check(len);
- const char *ptr = m_ptr;
+ const int8_t *ptr = m_ptr;
m_ptr += len;
return ptr;
}
size_t read_path_length();
- size_t read_path_string(pal::string_t &str);
+ void read_path_string(pal::string_t &str);
private:
void bounds_check(int64_t len = 1);
- static const char* add_without_overflow(const char* ptr, int64_t len);
+ static const int8_t* add_without_overflow(const int8_t* ptr, int64_t len);
- const char* const m_base_ptr;
- const char* m_ptr;
+ const int8_t* const m_base_ptr;
+ const int8_t* m_ptr;
const int64_t m_bound;
- const char* const m_bound_ptr;
+ const int8_t* const m_bound_ptr;
};
}
diff --git a/src/installer/corehost/cli/apphost/bundle/runner.cpp b/src/installer/corehost/cli/apphost/bundle/runner.cpp
new file mode 100644
index 00000000000..50d74235d7a
--- /dev/null
+++ b/src/installer/corehost/cli/apphost/bundle/runner.cpp
@@ -0,0 +1,65 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include <memory>
+#include "extractor.h"
+#include "runner.h"
+#include "trace.h"
+#include "header.h"
+#include "marker.h"
+#include "manifest.h"
+
+using namespace bundle;
+
+void runner_t::map_host()
+{
+ m_bundle_map = (int8_t *) pal::map_file_readonly(m_bundle_path, m_bundle_length);
+
+ if (m_bundle_map == nullptr)
+ {
+ trace::error(_X("Failure processing application bundle."));
+ trace::error(_X("Couldn't memory map the bundle file for reading."));
+ throw StatusCode::BundleExtractionIOError;
+ }
+}
+
+void runner_t::unmap_host()
+{
+ if (!pal::unmap_file(m_bundle_map, m_bundle_length))
+ {
+ trace::warning(_X("Failed to unmap bundle after extraction."));
+ }
+}
+
+// Current support for executing single-file bundles involves
+// extraction of embedded files to actual files on disk.
+// This method implements the file extraction functionality at startup.
+StatusCode runner_t::extract()
+{
+ try
+ {
+ map_host();
+ reader_t reader(m_bundle_map, m_bundle_length);
+
+ // Read the bundle header
+ reader.set_offset(marker_t::header_offset());
+ header_t header = header_t::read(reader, /* need_exact_version: */ true);
+
+ // Read the bundle manifest
+ // Reader is at the correct offset
+ manifest_t manifest = manifest_t::read(reader, header.num_embedded_files());
+
+ // Extract the files
+ extractor_t extractor(header.bundle_id(), m_bundle_path, manifest);
+ m_extraction_dir = extractor.extract(reader);
+
+ unmap_host();
+ return StatusCode::Success;
+ }
+ catch (StatusCode e)
+ {
+ return e;
+ }
+}
+
diff --git a/src/installer/corehost/cli/apphost/bundle/runner.h b/src/installer/corehost/cli/apphost/bundle/runner.h
new file mode 100644
index 00000000000..07dadede0fd
--- /dev/null
+++ b/src/installer/corehost/cli/apphost/bundle/runner.h
@@ -0,0 +1,40 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#ifndef __RUNNER_H__
+#define __RUNNER_H__
+
+#include "error_codes.h"
+
+namespace bundle
+{
+ class runner_t
+ {
+ public:
+ runner_t(const pal::string_t& bundle_path)
+ : m_bundle_path(bundle_path)
+ , m_bundle_map(nullptr)
+ , m_bundle_length(0)
+ {
+ }
+
+ StatusCode extract();
+
+ pal::string_t extraction_dir()
+ {
+ return m_extraction_dir;
+ }
+
+ private:
+ void map_host();
+ void unmap_host();
+
+ pal::string_t m_bundle_path;
+ pal::string_t m_extraction_dir;
+ int8_t* m_bundle_map;
+ size_t m_bundle_length;
+ };
+}
+
+#endif // __RUNNER_H__
diff --git a/src/installer/corehost/cli/bundle/info.cpp b/src/installer/corehost/cli/bundle/info.cpp
deleted file mode 100644
index 3fef4220890..00000000000
--- a/src/installer/corehost/cli/bundle/info.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#include "trace.h"
-#include "info.h"
-#include "utils.h"
-
-using namespace bundle;
-
-// Global single-file bundle information, if any
-const info_t* info_t::the_app = nullptr;
-
-info_t::info_t(const pal::char_t* bundle_path,
- const pal::char_t* app_path,
- int64_t header_offset)
- : m_bundle_path(bundle_path)
- , m_bundle_size(0)
- , m_header_offset(header_offset)
-{
- m_base_path = get_directory(m_bundle_path);
-
- // Single-file bundles currently only support deps/runtime config json files
- // named based on the app.dll. Any other name for these configuration files
- // mentioned via the command line are assumed to be actual files on disk.
- //
- // Supporting custom names for these config files is straightforward (with associated changes in bundler and SDK).
- // There is no known use-case for it yet, and the facility is TBD.
-
- m_deps_json = config_t(get_deps_from_app_binary(m_base_path, app_path));
- m_runtimeconfig_json = config_t(get_runtime_config_path(m_base_path, get_filename_without_ext(app_path)));
-}
-
-StatusCode info_t::process_bundle(const pal::char_t* bundle_path, const pal::char_t* app_path, int64_t header_offset)
-{
- if (header_offset == 0)
- {
- // Not a single-file bundle.
- return StatusCode::Success;
- }
-
- static info_t info(bundle_path, app_path, header_offset);
- StatusCode status = info.process_header();
-
- if (status != StatusCode::Success)
- {
- return status;
- }
-
- trace::info(_X("Single-File bundle details:"));
- trace::info(_X("DepsJson Offset:[%lx] Size[%lx]"), info.m_header.deps_json_location().offset, info.m_header.deps_json_location().size);
- trace::info(_X("RuntimeConfigJson Offset:[%lx] Size[%lx]"), info.m_header.runtimeconfig_json_location().offset, info.m_header.runtimeconfig_json_location().size);
- trace::info(_X(".net core 3 compatibility mode: [%s]"), info.m_header.is_netcoreapp3_compat_mode() ? _X("Yes") : _X("No"));
-
- the_app = &info;
-
- return StatusCode::Success;
-}
-
-StatusCode info_t::process_header()
-{
- try
- {
- const char* addr = map_bundle();
-
- reader_t reader(addr, m_bundle_size, m_header_offset);
-
- m_header = header_t::read(reader);
- m_deps_json.set_location(&m_header.deps_json_location());
- m_runtimeconfig_json.set_location(&m_header.runtimeconfig_json_location());
-
- unmap_bundle(addr);
-
- return StatusCode::Success;
- }
- catch (StatusCode e)
- {
- return e;
- }
-}
-
-char* info_t::config_t::map(const pal::string_t& path, const location_t* &location)
-{
- assert(is_single_file_bundle());
-
- const bundle::info_t* app = bundle::info_t::the_app;
- if (app->m_deps_json.matches(path))
- {
- location = app->m_deps_json.m_location;
- }
- else if (app->m_runtimeconfig_json.matches(path))
- {
- location = app->m_runtimeconfig_json.m_location;
- }
- else
- {
- return nullptr;
- }
-
- // When necessary to map the deps.json or runtimeconfig.json files, we map the whole single-file bundle,
- // and return the address at the appropriate offset.
- // This is because:
- // * The host is the only code that is currently running and trying to map the bundle.
- // * Files can only be memory mapped at page-aligned offsets, and in whole page units.
- // Therefore, mapping only portions of the bundle will involve align-down/round-up calculations, and associated offset adjustments.
- // We choose the simpler approach of rounding to the whole file
- // * There is no performance limitation due to a larger sized mapping, since we actually only read the pages with relevant contents.
- // * Files that are too large to be mapped (ex: that exhaust 32-bit virtual address space) are not supported.
-
- char* addr = (char*)pal::mmap_copy_on_write(app->m_bundle_path);
- if (addr == nullptr)
- {
- trace::error(_X("Failure processing application bundle."));
- trace::error(_X("Failed to map bundle file [%s]"), path.c_str());
- }
-
- trace::info(_X("Mapped bundle for [%s]"), path.c_str());
-
- return addr + location->offset;
-}
-
-void info_t::config_t::unmap(const char* addr, const location_t* location)
-{
- // Adjust to the beginning of the bundle.
- addr -= location->offset;
- bundle::info_t::the_app->unmap_bundle(addr);
-}
-
-const char* info_t::map_bundle()
-{
- const void *addr = pal::mmap_read(m_bundle_path, &m_bundle_size);
-
- if (addr == nullptr)
- {
- trace::error(_X("Failure processing application bundle."));
- trace::error(_X("Couldn't memory map the bundle file for reading."));
- throw StatusCode::BundleExtractionIOError;
- }
-
- trace::info(_X("Mapped application bundle"));
-
- return (const char *)addr;
-}
-
-void info_t::unmap_bundle(const char* addr) const
-{
- if (!pal::munmap((void*)addr, m_bundle_size))
- {
- trace::warning(_X("Failed to unmap bundle after extraction."));
- }
- else
- {
- trace::info(_X("Unmapped application bundle"));
- }
-}
-
-
diff --git a/src/installer/corehost/cli/bundle/info.h b/src/installer/corehost/cli/bundle/info.h
deleted file mode 100644
index 0f3db559fc2..00000000000
--- a/src/installer/corehost/cli/bundle/info.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#ifndef __INFO_H_
-#define __INFO_H_
-
-#include "error_codes.h"
-#include "header.h"
-
-// bundle::info supports:
-// * API for identification of a single-file app bundle, and
-// * Minimal probing and mapping functionality only for the app.runtimeconfig.json and app.deps.json files.
-// bundle::info is used by HostFxr to read the above config files.
-
-namespace bundle
-{
- struct info_t
- {
- struct config_t
- {
- config_t()
- : m_location(nullptr) {}
-
- config_t(const config_t& config)
- {
- m_path = config.m_path;
- m_location = config.m_location;
- }
-
- config_t(const pal::string_t& path, const location_t *location=nullptr)
- {
- m_path = path;
- m_location = location;
- }
-
- bool matches(const pal::string_t& path) const
- {
- return m_location->is_valid() && path.compare(m_path) == 0;
- }
-
- static bool probe(const pal::string_t& path)
- {
- return is_single_file_bundle() &&
- (the_app->m_deps_json.matches(path) || the_app->m_runtimeconfig_json.matches(path));
- }
-
- void set_location(const location_t* location)
- {
- m_location = location;
- }
-
- static char* map(const pal::string_t& path, const location_t* &location);
- static void unmap(const char* addr, const location_t* location);
-
- private:
- pal::string_t m_path;
- const location_t *m_location;
- };
-
- static StatusCode process_bundle(const pal::char_t* bundle_path, const pal::char_t *app_path, int64_t header_offset);
- static bool is_single_file_bundle() { return the_app != nullptr; }
-
- bool is_netcoreapp3_compat_mode() const { return m_header.is_netcoreapp3_compat_mode(); }
- const pal::string_t& base_path() const { return m_base_path; }
- int64_t header_offset() const { return m_header_offset; }
-
- // Global single-file info object
- static const info_t* the_app;
-
- protected:
- info_t(const pal::char_t* bundle_path,
- const pal::char_t* app_path,
- int64_t header_offset);
-
- const char* map_bundle();
- void unmap_bundle(const char* addr) const;
-
- pal::string_t m_bundle_path;
- pal::string_t m_base_path;
- size_t m_bundle_size;
- int64_t m_header_offset;
- header_t m_header;
- config_t m_deps_json;
- config_t m_runtimeconfig_json;
-
- private:
- StatusCode process_header();
- };
-}
-#endif // __INFO_H_
diff --git a/src/installer/corehost/cli/bundle/runner.cpp b/src/installer/corehost/cli/bundle/runner.cpp
deleted file mode 100644
index 58d10a81785..00000000000
--- a/src/installer/corehost/cli/bundle/runner.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#include <memory>
-#include "extractor.h"
-#include "runner.h"
-#include "trace.h"
-#include "header.h"
-#include "manifest.h"
-#include "utils.h"
-
-using namespace bundle;
-
-// This method processes the bundle manifest.
-// It also implements the extraction of files that cannot be directly processed from the bundle.
-StatusCode runner_t::extract()
-{
- try
- {
- const char* addr = map_bundle();
-
- // Set the Reader at header_offset
- reader_t reader(addr, m_bundle_size, m_header_offset);
-
- // Read the bundle header
- m_header = header_t::read(reader);
- m_deps_json.set_location(&m_header.deps_json_location());
- m_runtimeconfig_json.set_location(&m_header.runtimeconfig_json_location());
-
- // Read the bundle manifest
- m_manifest = manifest_t::read(reader, m_header.num_embedded_files());
-
- // Extract the files if necessary
- if (m_manifest.files_need_extraction())
- {
- extractor_t extractor(m_header.bundle_id(), m_bundle_path, m_manifest);
- m_extraction_path = extractor.extract(reader);
- }
-
- unmap_bundle(addr);
-
- return StatusCode::Success;
- }
- catch (StatusCode e)
- {
- return e;
- }
-}
-
-const file_entry_t* runner_t::probe(const pal::string_t& path) const
-{
- for (const file_entry_t& entry : m_manifest.files)
- {
- if (entry.relative_path() == path)
- {
- return &entry;
- }
- }
-
- return nullptr;
-}
-
-bool runner_t::locate(const pal::string_t& relative_path, pal::string_t& full_path) const
-{
- const bundle::runner_t* app = bundle::runner_t::app();
- const bundle::file_entry_t* entry = app->probe(relative_path);
-
- if (entry == nullptr)
- {
- full_path.clear();
- return false;
- }
-
- // Currently, all files except deps.json and runtimeconfig.json are extracted to disk.
- // The json files are not queried by the host using this method.
- assert(entry->needs_extraction());
-
- full_path.assign(app->extraction_path());
- append_path(&full_path, relative_path.c_str());
-
- return true;
-}
diff --git a/src/installer/corehost/cli/bundle/runner.h b/src/installer/corehost/cli/bundle/runner.h
deleted file mode 100644
index fb4d74bf877..00000000000
--- a/src/installer/corehost/cli/bundle/runner.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#ifndef __RUNNER_H__
-#define __RUNNER_H__
-
-#include "error_codes.h"
-#include "header.h"
-#include "manifest.h"
-#include "info.h"
-
-// bundle::runner extends bundle::info to supports:
-// * Reading the bundle manifest and identifying file locations for the runtime
-// * Extracting bundled files to disk when necessary
-// bundle::runner is used by HostPolicy.
-
-namespace bundle
-{
- class runner_t : public info_t
- {
- public:
- runner_t(const pal::char_t* bundle_path,
- const pal::char_t *app_path,
- int64_t header_offset)
- : info_t(bundle_path, app_path, header_offset) {}
-
- const pal::string_t& extraction_path() const { return m_extraction_path; }
-
- const file_entry_t *probe(const pal::string_t& path) const;
- bool locate(const pal::string_t& relative_path, pal::string_t& full_path) const;
-
- static StatusCode process_manifest_and_extract()
- {
- return ((runner_t*) the_app)->extract();
- }
-
- static const runner_t* app() { return (const runner_t*)the_app; }
-
- private:
-
- StatusCode extract();
-
- manifest_t m_manifest;
- pal::string_t m_extraction_path;
- };
-}
-
-#endif // __RUNNER_H__
diff --git a/src/installer/corehost/cli/deps_entry.cpp b/src/installer/corehost/cli/deps_entry.cpp
index 449403fa038..08d196c1741 100644
--- a/src/installer/corehost/cli/deps_entry.cpp
+++ b/src/installer/corehost/cli/deps_entry.cpp
@@ -6,39 +6,9 @@
#include "utils.h"
#include "deps_entry.h"
#include "trace.h"
-#include "bundle/runner.h"
-static pal::string_t normalize_dir_separator(const pal::string_t& path)
-{
- // Entry relative path contains '/' separator, sanitize it to use
- // platform separator. Perf: avoid extra copy if it matters.
- pal::string_t normalized_path = path;
- if (_X('/') != DIR_SEPARATOR)
- {
- replace_char(&normalized_path, _X('/'), DIR_SEPARATOR);
- }
-
- return normalized_path;
-}
-// -----------------------------------------------------------------------------
-// Given a "base" directory, determine the resolved path for this file.
-//
-// * If this file exists within the single-file bundle candidate is
-// the full-path to the extracted file.
-// * Otherwise, candidate is the full local path of the file.
-//
-// Parameters:
-// base - The base directory to look for the relative path of this entry
-// ietf_dir - If this is a resource asset, the IETF intermediate directory
-// look_in_base - Whether to search as a relative path
-// look_in_bundle - Whether to look within the single-file bundle
-// str - If the method returns true, contains the file path for this deps entry
-//
-// Returns:
-// If the file exists in the path relative to the "base" directory within the
-// single-file or on disk.
-bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_dir, bool look_in_base, bool look_in_bundle, pal::string_t* str) const
+bool deps_entry_t::to_path(const pal::string_t& base, bool look_in_base, pal::string_t* str) const
{
pal::string_t& candidate = *str;
@@ -50,41 +20,20 @@ bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_
return false;
}
- pal::string_t normalized_path = normalize_dir_separator(asset.relative_path);
-
- // Reserve space for the path below
- candidate.reserve(base.length() + ietf_dir.length() + normalized_path.length() + 3);
-
- pal::string_t file_path = look_in_base ? get_filename(normalized_path) : normalized_path;
- pal::string_t sub_path = ietf_dir;
- append_path(&sub_path, file_path.c_str());
-
- if (look_in_bundle && bundle::info_t::is_single_file_bundle())
+ // Entry relative path contains '/' separator, sanitize it to use
+ // platform separator. Perf: avoid extra copy if it matters.
+ pal::string_t pal_relative_path = asset.relative_path;
+ if (_X('/') != DIR_SEPARATOR)
{
- const bundle::runner_t* app = bundle::runner_t::app();
-
- if (base.compare(app->base_path()) == 0)
- {
- // If sub_path is found in the single-file bundle,
- // app::locate() will set candidate to the full-path to the assembly extracted out to disk.
- if (app->locate(sub_path, candidate))
- {
- trace::verbose(_X(" %s found in bundle [%s]"), sub_path.c_str(), candidate.c_str());
- return true;
- }
- else
- {
- trace::verbose(_X(" %s not found in bundle"), sub_path.c_str());
- }
- }
- else
- {
- trace::verbose(_X(" %s not searched in bundle base path %s doesn't match bundle base %s."),
- sub_path.c_str(), base.c_str(), app->base_path().c_str());
- }
+ replace_char(&pal_relative_path, _X('/'), DIR_SEPARATOR);
}
+ // Reserve space for the path below
+ candidate.reserve(base.length() +
+ pal_relative_path.length() + 3);
+
candidate.assign(base);
+ pal::string_t sub_path = look_in_base ? get_filename(pal_relative_path) : pal_relative_path;
append_path(&candidate, sub_path.c_str());
bool exists = pal::file_exists(candidate);
@@ -98,7 +47,6 @@ bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_
{
trace::verbose(_X(" %s path query exists %s"), query_type, candidate.c_str());
}
-
return exists;
}
@@ -107,50 +55,55 @@ bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_
//
// Parameters:
// base - The base directory to look for the relative path of this entry
-// str - If the method returns true, contains the file path for this deps entry
+// str - If the method returns true, contains the file path for this deps
+// entry relative to the "base" directory
//
// Returns:
// If the file exists in the path relative to the "base" directory.
//
-bool deps_entry_t::to_dir_path(const pal::string_t& base, bool look_in_bundle, pal::string_t* str) const
+bool deps_entry_t::to_dir_path(const pal::string_t& base, pal::string_t* str) const
{
- pal::string_t ietf_dir;
-
if (asset_type == asset_types::resources)
{
- pal::string_t pal_relative_path = normalize_dir_separator(asset.relative_path);
+ pal::string_t pal_relative_path = asset.relative_path;
+ if (_X('/') != DIR_SEPARATOR)
+ {
+ replace_char(&pal_relative_path, _X('/'), DIR_SEPARATOR);
+ }
// Resources are represented as "lib/<netstandrd_ver>/<ietf-code>/<ResourceAssemblyName.dll>" in the deps.json.
// The <ietf-code> is the "directory" in the pal_relative_path below, so extract it.
- ietf_dir = get_directory(pal_relative_path);
+ pal::string_t ietf_dir = get_directory(pal_relative_path);
+ pal::string_t ietf = ietf_dir;
// get_directory returns with DIR_SEPARATOR appended that we need to remove.
- remove_trailing_dir_seperator(&ietf_dir);
+ remove_trailing_dir_seperator(&ietf);
// Extract IETF code from "lib/<netstandrd_ver>/<ietf-code>"
- ietf_dir = get_filename(ietf_dir);
-
- trace::verbose(_X("Detected a resource asset, will query dir/ietf-tag/resource base: %s ietf: %s asset: %s"),
- base.c_str(), ietf_dir.c_str(), asset.name.c_str());
+ ietf = get_filename(ietf);
+
+ pal::string_t base_ietf_dir = base;
+ append_path(&base_ietf_dir, ietf.c_str());
+ trace::verbose(_X("Detected a resource asset, will query dir/ietf-tag/resource base: %s asset: %s"), base_ietf_dir.c_str(), asset.name.c_str());
+ return to_path(base_ietf_dir, true, str);
}
-
- return to_path(base, ietf_dir, true, look_in_bundle, str);
+ return to_path(base, true, str);
}
-
// -----------------------------------------------------------------------------
// Given a "base" directory, yield the relative path of this file in the package
// layout.
//
// Parameters:
// base - The base directory to look for the relative path of this entry
-// str - If the method returns true, contains the file path for this deps entry
+// str - If the method returns true, contains the file path for this deps
+// entry relative to the "base" directory
//
// Returns:
// If the file exists in the path relative to the "base" directory.
//
-bool deps_entry_t::to_rel_path(const pal::string_t& base, bool look_in_bundle, pal::string_t* str) const
+bool deps_entry_t::to_rel_path(const pal::string_t& base, pal::string_t* str) const
{
- return to_path(base, _X(""), false, look_in_bundle, str);
+ return to_path(base, false, str);
}
// -----------------------------------------------------------------------------
@@ -159,7 +112,8 @@ bool deps_entry_t::to_rel_path(const pal::string_t& base, bool look_in_bundle, p
//
// Parameters:
// base - The base directory to look for the relative path of this entry
-// str - If the method returns true, contains the file path for this deps entry
+// str - If the method returns true, contains the file path for this deps
+// entry relative to the "base" directory
//
// Returns:
// If the file exists in the path relative to the "base" directory.
@@ -186,5 +140,5 @@ bool deps_entry_t::to_full_path(const pal::string_t& base, pal::string_t* str) c
append_path(&new_base, library_path.c_str());
}
- return to_rel_path(new_base, false, str);
+ return to_rel_path(new_base, str);
}
diff --git a/src/installer/corehost/cli/deps_entry.h b/src/installer/corehost/cli/deps_entry.h
index 2c66b1f0552..d06e2988aa3 100644
--- a/src/installer/corehost/cli/deps_entry.h
+++ b/src/installer/corehost/cli/deps_entry.h
@@ -52,19 +52,17 @@ struct deps_entry_t
bool is_serviceable;
bool is_rid_specific;
- // Given a "base" dir, yield the file path within this directory or single-file bundle.
- bool to_dir_path(const pal::string_t& base, bool look_in_bundle, pal::string_t* str) const;
+ // Given a "base" dir, yield the filepath within this directory or relative to this directory based on "look_in_base"
+ bool to_path(const pal::string_t& base, bool look_in_base, pal::string_t* str) const;
+
+ // Given a "base" dir, yield the file path within this directory.
+ bool to_dir_path(const pal::string_t& base, pal::string_t* str) const;
// Given a "base" dir, yield the relative path in the package layout.
- bool to_rel_path(const pal::string_t& base, bool look_in_bundle, pal::string_t* str) const;
+ bool to_rel_path(const pal::string_t& base, pal::string_t* str) const;
// Given a "base" dir, yield the relative path with package name, version in the package layout.
bool to_full_path(const pal::string_t& root, pal::string_t* str) const;
-
-private:
- // Given a "base" dir, yield the filepath within this directory or relative to this directory based on "look_in_base"
- // Returns a path within the single-file bundle, or a file on disk,
- bool to_path(const pal::string_t& base, const pal::string_t& ietf_code, bool look_in_base, bool look_in_bundle, pal::string_t* str) const;
};
#endif // __DEPS_ENTRY_H_
diff --git a/src/installer/corehost/cli/deps_format.cpp b/src/installer/corehost/cli/deps_format.cpp
index 873dd815c7a..b098d953025 100644
--- a/src/installer/corehost/cli/deps_format.cpp
+++ b/src/installer/corehost/cli/deps_format.cpp
@@ -6,7 +6,6 @@
#include "deps_format.h"
#include "utils.h"
#include "trace.h"
-#include "bundle/info.h"
#include <tuple>
#include <array>
#include <iterator>
@@ -427,16 +426,16 @@ bool deps_json_t::has_package(const pal::string_t& name, const pal::string_t& ve
bool deps_json_t::load(bool is_framework_dependent, const pal::string_t& deps_path, const rid_fallback_graph_t& rid_fallback_graph)
{
m_deps_file = deps_path;
- m_file_exists = bundle::info_t::config_t::probe(deps_path) || pal::file_exists(deps_path);
+ m_file_exists = pal::file_exists(deps_path);
- json_parser_t json;
+ // If file doesn't exist, then assume parsed.
if (!m_file_exists)
{
- // If file doesn't exist, then assume parsed.
trace::verbose(_X("Could not locate the dependencies manifest file [%s]. Some libraries may fail to resolve."), deps_path.c_str());
return true;
}
+ json_parser_t json;
if (!json.parse_file(deps_path))
{
return false;
diff --git a/src/installer/corehost/cli/fxr/command_line.cpp b/src/installer/corehost/cli/fxr/command_line.cpp
index 045f7700e74..e3563947c3c 100644
--- a/src/installer/corehost/cli/fxr/command_line.cpp
+++ b/src/installer/corehost/cli/fxr/command_line.cpp
@@ -9,7 +9,6 @@
#include "sdk_info.h"
#include <trace.h>
#include <utils.h>
-#include "bundle/info.h"
namespace
{
@@ -145,7 +144,7 @@ namespace
if (mode == host_mode_t::apphost)
{
app_candidate = host_info.app_path;
- doesAppExist = bundle::info_t::is_single_file_bundle() || pal::realpath(&app_candidate);
+ doesAppExist = pal::realpath(&app_candidate);
}
else
{
diff --git a/src/installer/corehost/cli/fxr/corehost_init.cpp b/src/installer/corehost/cli/fxr/corehost_init.cpp
index d8a5f249829..22a3921f8e9 100644
--- a/src/installer/corehost/cli/fxr/corehost_init.cpp
+++ b/src/installer/corehost/cli/fxr/corehost_init.cpp
@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
#include "corehost_init.h"
-#include "bundle/info.h"
void make_cstr_arr(const std::vector<pal::string_t>& arr, std::vector<const pal::char_t*>* out)
{
@@ -133,8 +132,6 @@ const host_interface_t& corehost_init_t::get_host_init_data()
hi.host_info_dotnet_root = m_host_info_dotnet_root.c_str();
hi.host_info_app_path = m_host_info_app_path.c_str();
- hi.single_file_bundle_header_offset = bundle::info_t::is_single_file_bundle() ? bundle::info_t::the_app->header_offset() : 0;
-
return hi;
}
diff --git a/src/installer/corehost/cli/fxr/corehost_init.h b/src/installer/corehost/cli/fxr/corehost_init.h
index 0d7f87ae92f..eedc2e70d22 100644
--- a/src/installer/corehost/cli/fxr/corehost_init.h
+++ b/src/installer/corehost/cli/fxr/corehost_init.h
@@ -8,7 +8,7 @@
#include "host_interface.h"
#include "host_startup_info.h"
#include "fx_definition.h"
-
+
class corehost_init_t
{
private:
@@ -37,7 +37,6 @@ private:
const pal::string_t m_host_info_host_path;
const pal::string_t m_host_info_dotnet_root;
const pal::string_t m_host_info_app_path;
-
public:
corehost_init_t(
const pal::string_t& host_command,
diff --git a/src/installer/corehost/cli/fxr/fx_muxer.cpp b/src/installer/corehost/cli/fxr/fx_muxer.cpp
index 31c8c177978..00584e4a91e 100644
--- a/src/installer/corehost/cli/fxr/fx_muxer.cpp
+++ b/src/installer/corehost/cli/fxr/fx_muxer.cpp
@@ -27,7 +27,6 @@
#include "sdk_info.h"
#include "sdk_resolver.h"
#include "roll_fwd_on_no_candidate_fx_option.h"
-#include "bundle/info.h"
namespace
{
@@ -263,7 +262,6 @@ namespace
pal::string_t& runtime_config,
const runtime_config_t::settings_t& override_settings)
{
- // Check for the runtimeconfig.json file specified at the command line
if (!runtime_config.empty() && !pal::realpath(&runtime_config))
{
trace::error(_X("The specified runtimeconfig.json [%s] does not exist"), runtime_config.c_str());
@@ -295,11 +293,6 @@ namespace
host_mode_t detect_operating_mode(const host_startup_info_t& host_info)
{
- if (bundle::info_t::is_single_file_bundle())
- {
- return host_mode_t::apphost;
- }
-
if (coreclr_exists_in_dir(host_info.dotnet_root))
{
// Detect between standalone apphost or legacy split mode (specifying --depsfile and --runtimeconfig)
@@ -364,7 +357,6 @@ namespace
{
pal::string_t runtime_config = command_line::get_option_value(opts, known_options::runtime_config, _X(""));
- // This check is for --depsfile option, which must be an actual file.
pal::string_t deps_file = command_line::get_option_value(opts, known_options::deps_file, _X(""));
if (!deps_file.empty() && !pal::realpath(&deps_file))
{
diff --git a/src/installer/corehost/cli/fxr/hostfxr.cpp b/src/installer/corehost/cli/fxr/hostfxr.cpp
index 1fdfa210489..c9a346b799b 100644
--- a/src/installer/corehost/cli/fxr/hostfxr.cpp
+++ b/src/installer/corehost/cli/fxr/hostfxr.cpp
@@ -14,7 +14,6 @@
#include "sdk_resolver.h"
#include "hostfxr.h"
#include "host_context.h"
-#include "bundle/info.h"
namespace
{
@@ -25,23 +24,6 @@ namespace
}
}
-SHARED_API int HOSTFXR_CALLTYPE hostfxr_main_bundle_startupinfo(const int argc, const pal::char_t* argv[], const pal::char_t* host_path, const pal::char_t* dotnet_root, const pal::char_t* app_path, int64_t bundle_header_offset)
-{
- trace_hostfxr_entry_point(_X("hostfxr_main_bundle_startupinfo"));
-
- StatusCode bundleStatus = bundle::info_t::process_bundle(host_path, app_path, bundle_header_offset);
- if (bundleStatus != StatusCode::Success)
- {
- trace::error(_X("A fatal error occured while processing application bundle"));
- return bundleStatus;
- }
-
- host_startup_info_t startup_info(host_path, dotnet_root, app_path);
-
- return fx_muxer_t::execute(pal::string_t(), argc, argv, startup_info, nullptr, 0, nullptr);
-}
-
-
SHARED_API int HOSTFXR_CALLTYPE hostfxr_main_startupinfo(const int argc, const pal::char_t* argv[], const pal::char_t* host_path, const pal::char_t* dotnet_root, const pal::char_t* app_path)
{
trace_hostfxr_entry_point(_X("hostfxr_main_startupinfo"));
diff --git a/src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp b/src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp
index de3291fecc5..049d61a62a5 100644
--- a/src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp
+++ b/src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp
@@ -29,6 +29,7 @@ namespace
trace::verbose(_X("--- Resolving %s version from deps json [%s]"), LIBHOSTPOLICY_NAME, deps_json.c_str());
pal::string_t retval;
+
json_parser_t json;
if (!json.parse_file(deps_json))
{
diff --git a/src/installer/corehost/cli/host_interface.h b/src/installer/corehost/cli/host_interface.h
index 72295aee99e..c7148e0ddc6 100644
--- a/src/installer/corehost/cli/host_interface.h
+++ b/src/installer/corehost/cli/host_interface.h
@@ -7,7 +7,6 @@
#include <cstddef>
#include "pal.h"
-#include "bundle/info.h"
enum host_mode_t
{
@@ -59,7 +58,6 @@ struct host_interface_t
const pal::char_t* host_info_host_path;
const pal::char_t* host_info_dotnet_root;
const pal::char_t* host_info_app_path;
- size_t single_file_bundle_header_offset;
// !! 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)
@@ -93,8 +91,7 @@ static_assert(offsetof(host_interface_t, host_command) == 26 * sizeof(size_t), "
static_assert(offsetof(host_interface_t, host_info_host_path) == 27 * sizeof(size_t), "Struct offset breaks backwards compatibility");
static_assert(offsetof(host_interface_t, host_info_dotnet_root) == 28 * sizeof(size_t), "Struct offset breaks backwards compatibility");
static_assert(offsetof(host_interface_t, host_info_app_path) == 29 * sizeof(size_t), "Struct offset breaks backwards compatibility");
-static_assert(offsetof(host_interface_t, single_file_bundle_header_offset) == 30 * sizeof(size_t), "Struct offset breaks backwards compatibility");
-static_assert(sizeof(host_interface_t) == 31 * sizeof(size_t), "Did you add static asserts for the newly added fields?");
+static_assert(sizeof(host_interface_t) == 30 * 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)
diff --git a/src/installer/corehost/cli/host_startup_info.h b/src/installer/corehost/cli/host_startup_info.h
index cdc2746021a..4cb4b3e92b9 100644
--- a/src/installer/corehost/cli/host_startup_info.h
+++ b/src/installer/corehost/cli/host_startup_info.h
@@ -11,7 +11,6 @@
struct host_startup_info_t
{
host_startup_info_t() {}
-
host_startup_info_t(
const pal::char_t* host_path_value,
const pal::char_t* dotnet_root_value,
diff --git a/src/installer/corehost/cli/hostcommon/CMakeLists.txt b/src/installer/corehost/cli/hostcommon/CMakeLists.txt
index 8ad0c8d09f4..deac26114aa 100644
--- a/src/installer/corehost/cli/hostcommon/CMakeLists.txt
+++ b/src/installer/corehost/cli/hostcommon/CMakeLists.txt
@@ -23,9 +23,6 @@ set(SOURCES
../version.cpp
../version_compatibility_range.cpp
../runtime_config.cpp
- ../bundle/info.cpp
- ../bundle/reader.cpp
- ../bundle/header.cpp
)
set(HEADERS
@@ -40,9 +37,6 @@ set(HEADERS
../version.h
../version_compatibility_range.h
../runtime_config.h
- ../bundle/info.h
- ../bundle/reader.h
- ../bundle/header.h
)
set(SKIP_VERSIONING 1)
diff --git a/src/installer/corehost/cli/hostfxr.h b/src/installer/corehost/cli/hostfxr.h
index f0bc0a53e22..040b7c78d87 100644
--- a/src/installer/corehost/cli/hostfxr.h
+++ b/src/installer/corehost/cli/hostfxr.h
@@ -37,13 +37,6 @@ typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_main_startupinfo_fn)(
const char_t *host_path,
const char_t *dotnet_root,
const char_t *app_path);
-typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_main_bundle_startupinfo_fn)(
- const int argc,
- const char_t** argv,
- const char_t* host_path,
- const char_t* dotnet_root,
- const char_t* app_path,
- int64_t bundle_header_offset);
typedef void(HOSTFXR_CALLTYPE *hostfxr_error_writer_fn)(const char_t *message);
typedef hostfxr_error_writer_fn(HOSTFXR_CALLTYPE *hostfxr_set_error_writer_fn)(hostfxr_error_writer_fn error_writer);
diff --git a/src/installer/corehost/cli/hostmisc/pal.h b/src/installer/corehost/cli/hostmisc/pal.h
index 10cb0e2c302..432756a3f37 100644
--- a/src/installer/corehost/cli/hostmisc/pal.h
+++ b/src/installer/corehost/cli/hostmisc/pal.h
@@ -165,7 +165,7 @@ namespace pal
inline bool rmdir (const char_t* path) { return RemoveDirectoryW(path) != 0; }
inline int rename(const char_t* old_name, const char_t* new_name) { return ::_wrename(old_name, new_name); }
inline int remove(const char_t* path) { return ::_wremove(path); }
- inline bool munmap(void* addr, size_t length) { return UnmapViewOfFile(addr) != 0; }
+ inline bool unmap_file(void* addr, size_t length) { return UnmapViewOfFile(addr) != 0; }
inline int get_pid() { return GetCurrentProcessId(); }
inline void sleep(uint32_t milliseconds) { Sleep(milliseconds); }
#else
@@ -222,7 +222,7 @@ namespace pal
inline bool rmdir(const char_t* path) { return ::rmdir(path) == 0; }
inline int rename(const char_t* old_name, const char_t* new_name) { return ::rename(old_name, new_name); }
inline int remove(const char_t* path) { return ::remove(path); }
- inline bool munmap(void* addr, size_t length) { return ::munmap(addr, length) == 0; }
+ inline bool unmap_file(void* addr, size_t length) { return munmap(addr, length) == 0; }
inline int get_pid() { return getpid(); }
inline void sleep(uint32_t milliseconds) { usleep(milliseconds * 1000); }
@@ -257,9 +257,7 @@ namespace pal
return fallbackRid;
}
- const void* mmap_read(const string_t& path, size_t* length = nullptr);
- void* mmap_copy_on_write(const string_t& path, size_t* length = nullptr);
-
+ void* map_file_readonly(const string_t& path, size_t& length);
bool touch_file(const string_t& path);
bool realpath(string_t* path, bool skip_error_logging = false);
bool file_exists(const string_t& path);
diff --git a/src/installer/corehost/cli/hostmisc/pal.unix.cpp b/src/installer/corehost/cli/hostmisc/pal.unix.cpp
index 3626761b0ec..2ca39c3793a 100644
--- a/src/installer/corehost/cli/hostmisc/pal.unix.cpp
+++ b/src/installer/corehost/cli/hostmisc/pal.unix.cpp
@@ -70,7 +70,7 @@ bool pal::touch_file(const pal::string_t& path)
return true;
}
-static void* map_file(const pal::string_t& path, size_t* length, int prot, int flags)
+void* pal::map_file_readonly(const pal::string_t& path, size_t& length)
{
int fd = open(path.c_str(), O_RDONLY);
if (fd == -1)
@@ -86,35 +86,21 @@ static void* map_file(const pal::string_t& path, size_t* length, int prot, int f
close(fd);
return nullptr;
}
- size_t size = buf.st_size;
- if (length != nullptr)
- {
- *length = size;
- }
-
- void* address = mmap(nullptr, size, prot, flags, fd, 0);
+ length = buf.st_size;
+ void* address = mmap(nullptr, length, PROT_READ, MAP_SHARED, fd, 0);
- if (address == MAP_FAILED)
+ if(address == nullptr)
{
trace::error(_X("Failed to map file. mmap(%s) failed with error %d"), path.c_str(), errno);
- address = nullptr;
+ close(fd);
+ return nullptr;
}
close(fd);
return address;
}
-const void* pal::mmap_read(const string_t& path, size_t* length)
-{
- return map_file(path, length, PROT_READ, MAP_SHARED);
-}
-
-void* pal::mmap_copy_on_write(const string_t& path, size_t* length)
-{
- return map_file(path, length, PROT_READ | PROT_WRITE, MAP_PRIVATE);
-}
-
bool pal::getcwd(pal::string_t* recv)
{
recv->clear();
@@ -504,10 +490,10 @@ bool pal::get_default_installation_dir(pal::string_t* recv)
pal::string_t trim_quotes(pal::string_t stringToCleanup)
{
pal::char_t quote_array[2] = {'\"', '\''};
- for (size_t index = 0; index < sizeof(quote_array)/sizeof(quote_array[0]); index++)
+ for(size_t index = 0; index < sizeof(quote_array)/sizeof(quote_array[0]); index++)
{
size_t pos = stringToCleanup.find(quote_array[index]);
- while (pos != std::string::npos)
+ while(pos != std::string::npos)
{
stringToCleanup = stringToCleanup.erase(pos, 1);
pos = stringToCleanup.find(quote_array[index]);
diff --git a/src/installer/corehost/cli/hostmisc/pal.windows.cpp b/src/installer/corehost/cli/hostmisc/pal.windows.cpp
index f8348a05d16..0cb6d2f91d9 100644
--- a/src/installer/corehost/cli/hostmisc/pal.windows.cpp
+++ b/src/installer/corehost/cli/hostmisc/pal.windows.cpp
@@ -76,7 +76,7 @@ bool pal::touch_file(const pal::string_t& path)
return true;
}
-static void* map_file(const pal::string_t& path, size_t *length, DWORD mapping_protect, DWORD view_desired_access)
+void* pal::map_file_readonly(const pal::string_t& path, size_t &length)
{
HANDLE file = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
@@ -86,19 +86,16 @@ static void* map_file(const pal::string_t& path, size_t *length, DWORD mapping_p
return nullptr;
}
- if (length != nullptr)
+ LARGE_INTEGER fileSize;
+ if (GetFileSizeEx(file, &fileSize) == 0)
{
- LARGE_INTEGER fileSize;
- if (GetFileSizeEx(file, &fileSize) == 0)
- {
- trace::error(_X("Failed to map file. GetFileSizeEx(%s) failed with error %d"), path.c_str(), GetLastError());
- CloseHandle(file);
- return nullptr;
- }
- *length = (size_t)fileSize.QuadPart;
+ trace::error(_X("Failed to map file. GetFileSizeEx(%s) failed with error %d"), path.c_str(), GetLastError());
+ CloseHandle(file);
+ return nullptr;
}
+ length = (size_t)fileSize.QuadPart;
- HANDLE map = CreateFileMappingW(file, NULL, mapping_protect, 0, 0, NULL);
+ HANDLE map = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
if (map == NULL)
{
@@ -107,7 +104,7 @@ static void* map_file(const pal::string_t& path, size_t *length, DWORD mapping_p
return nullptr;
}
- void *address = MapViewOfFile(map, view_desired_access, 0, 0, 0);
+ void *address = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
if (address == NULL)
{
@@ -123,16 +120,6 @@ static void* map_file(const pal::string_t& path, size_t *length, DWORD mapping_p
return address;
}
-const void* pal::mmap_read(const string_t& path, size_t* length)
-{
- return map_file(path, length, PAGE_READONLY, FILE_MAP_READ);
-}
-
-void* pal::mmap_copy_on_write(const string_t& path, size_t* length)
-{
- return map_file(path, length, PAGE_WRITECOPY, FILE_MAP_READ | FILE_MAP_COPY);
-}
-
bool pal::getcwd(pal::string_t* recv)
{
recv->clear();
diff --git a/src/installer/corehost/cli/hostmisc/utils.cpp b/src/installer/corehost/cli/hostmisc/utils.cpp
index 4a3208af237..4e0d8ab3170 100644
--- a/src/installer/corehost/cli/hostmisc/utils.cpp
+++ b/src/installer/corehost/cli/hostmisc/utils.cpp
@@ -4,7 +4,6 @@
#include "utils.h"
#include "trace.h"
-#include "bundle/info.h"
bool library_exists_in_dir(const pal::string_t& lib_dir, const pal::string_t& lib_name, pal::string_t* p_lib_path)
{
@@ -366,7 +365,6 @@ pal::string_t get_deps_from_app_binary(const pal::string_t& app_base, const pal:
{
pal::string_t deps_file;
auto app_name = get_filename(app);
-
deps_file.reserve(app_base.length() + 1 + app_name.length() + 5);
deps_file.append(app_base);
@@ -379,28 +377,19 @@ pal::string_t get_deps_from_app_binary(const pal::string_t& app_base, const pal:
return deps_file;
}
-pal::string_t get_runtime_config_path(const pal::string_t& path, const pal::string_t& name)
+void get_runtime_config_paths(const pal::string_t& path, const pal::string_t& name, pal::string_t* cfg, pal::string_t* dev_cfg)
{
auto json_path = path;
auto json_name = name + _X(".runtimeconfig.json");
append_path(&json_path, json_name.c_str());
- return json_path;
-}
+ cfg->assign(json_path);
-pal::string_t get_runtime_config_dev_path(const pal::string_t& path, const pal::string_t& name)
-{
auto dev_json_path = path;
auto dev_json_name = name + _X(".runtimeconfig.dev.json");
append_path(&dev_json_path, dev_json_name.c_str());
- return dev_json_path;
-}
-
-void get_runtime_config_paths(const pal::string_t& path, const pal::string_t& name, pal::string_t* cfg, pal::string_t* dev_cfg)
-{
- cfg->assign(get_runtime_config_path(path, name));
- dev_cfg->assign(get_runtime_config_dev_path(path, name));
+ dev_cfg->assign(dev_json_path);
- trace::verbose(_X("Runtime config is cfg=%s dev=%s"), cfg->c_str(), dev_cfg->c_str());
+ trace::verbose(_X("Runtime config is cfg=%s dev=%s"), json_path.c_str(), dev_json_path.c_str());
}
pal::string_t get_dotnet_root_from_fxr_path(const pal::string_t &fxr_path)
diff --git a/src/installer/corehost/cli/hostmisc/utils.h b/src/installer/corehost/cli/hostmisc/utils.h
index 7de346c7bce..2f13193e608 100644
--- a/src/installer/corehost/cli/hostmisc/utils.h
+++ b/src/installer/corehost/cli/hostmisc/utils.h
@@ -45,8 +45,6 @@ size_t index_of_non_numeric(const pal::string_t& str, unsigned i);
bool try_stou(const pal::string_t& str, unsigned* num);
pal::string_t get_dotnet_root_env_var_name();
pal::string_t get_deps_from_app_binary(const pal::string_t& app_base, const pal::string_t& app);
-pal::string_t get_runtime_config_path(const pal::string_t& path, const pal::string_t& name);
-pal::string_t get_runtime_config_dev_path(const pal::string_t& path, const pal::string_t& name);
void get_runtime_config_paths(const pal::string_t& path, const pal::string_t& name, pal::string_t* cfg, pal::string_t* dev_cfg);
pal::string_t get_dotnet_root_from_fxr_path(const pal::string_t &fxr_path);
diff --git a/src/installer/corehost/cli/hostpolicy/CMakeLists.txt b/src/installer/corehost/cli/hostpolicy/CMakeLists.txt
index ca2c78fa279..c05c876e1d9 100644
--- a/src/installer/corehost/cli/hostpolicy/CMakeLists.txt
+++ b/src/installer/corehost/cli/hostpolicy/CMakeLists.txt
@@ -19,11 +19,6 @@ set(SOURCES
./hostpolicy_context.cpp
./hostpolicy.cpp
./hostpolicy_init.cpp
- ../bundle/dir_utils.cpp
- ../bundle/extractor.cpp
- ../bundle/file_entry.cpp
- ../bundle/manifest.cpp
- ../bundle/runner.cpp
)
set(HEADERS
@@ -35,11 +30,6 @@ set(HEADERS
./hostpolicy_context.h
../hostpolicy.h
./hostpolicy_init.h
- ../bundle/dir_utils.h
- ../bundle/extractor.h
- ../bundle/file_entry.h
- ../bundle/manifest.h
- ../bundle/runner.h
)
include(../lib.cmake)
diff --git a/src/installer/corehost/cli/hostpolicy/args.cpp b/src/installer/corehost/cli/hostpolicy/args.cpp
index f022d23ae5f..562f70baea8 100644
--- a/src/installer/corehost/cli/hostpolicy/args.cpp
+++ b/src/installer/corehost/cli/hostpolicy/args.cpp
@@ -4,7 +4,6 @@
#include "args.h"
#include <utils.h>
-#include "bundle/runner.h"
arguments_t::arguments_t()
: host_mode(host_mode_t::invalid)
@@ -102,47 +101,6 @@ bool parse_arguments(
args);
}
-bool set_root_from_app(const pal::string_t& managed_application_path,
- arguments_t& args)
-{
- args.managed_application = managed_application_path;
-
- if (args.managed_application.empty())
- {
- // Managed app being empty by itself is not a failure. Host may be initialized from a config file.
- assert(args.host_mode != host_mode_t::apphost);
- return true;
- }
-
- if (bundle::info_t::is_single_file_bundle())
- {
- const bundle::runner_t* app = bundle::runner_t::app();
- args.app_root = app->base_path();
-
- // Check for the main app within the bundle.
- // locate() sets args.managed_application to the full path of the app extracted to disk.
- pal::string_t managed_application_name = get_filename(managed_application_path);
- if (app->locate(managed_application_name, args.managed_application))
- {
- return true;
- }
-
- trace::info(_X("Managed application [%s] not found in single-file bundle"), managed_application_name.c_str());
-
- // If the main assembly is not found in the bundle, continue checking on disk
- // for very unlikely case where the main app.dll was itself excluded from the app bundle.
- return pal::realpath(&args.managed_application);
- }
-
- if (pal::realpath(&args.managed_application))
- {
- args.app_root = get_directory(args.managed_application);
- return true;
- }
-
- return false;
-}
-
bool init_arguments(
const pal::string_t& managed_application_path,
const host_startup_info_t& host_info,
@@ -157,11 +115,13 @@ bool init_arguments(
args.host_path = host_info.host_path;
args.additional_deps_serialized = additional_deps_serialized;
- if (!set_root_from_app(managed_application_path, args))
+ args.managed_application = managed_application_path;
+ if (!args.managed_application.empty() && !pal::realpath(&args.managed_application))
{
trace::error(_X("Failed to locate managed application [%s]"), args.managed_application.c_str());
return false;
}
+ args.app_root = get_directory(args.managed_application);
if (!deps_file.empty())
{
diff --git a/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp b/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp
index 06ededa7e60..2e245b56dee 100644
--- a/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp
+++ b/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp
@@ -316,7 +316,7 @@ bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::str
// If the deps json has the package name and version, then someone has already done rid selection and
// put the right asset in the dir. So checking just package name and version would suffice.
// No need to check further for the exact asset relative sub path.
- if (config.probe_deps_json->has_package(entry.library_name, entry.library_version) && entry.to_dir_path(probe_dir, false, candidate))
+ if (config.probe_deps_json->has_package(entry.library_name, entry.library_version) && entry.to_dir_path(probe_dir, candidate))
{
trace::verbose(_X(" Probed deps json and matched '%s'"), candidate->c_str());
return true;
@@ -334,7 +334,7 @@ bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::str
{
if (entry.is_rid_specific)
{
- if (entry.to_rel_path(deps_dir, true, candidate))
+ if (entry.to_rel_path(deps_dir, candidate))
{
trace::verbose(_X(" Probed deps dir and matched '%s'"), candidate->c_str());
return true;
@@ -343,7 +343,7 @@ bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::str
else
{
// Non-rid assets, lookup in the published dir.
- if (entry.to_dir_path(deps_dir, true, candidate))
+ if (entry.to_dir_path(deps_dir, candidate))
{
trace::verbose(_X(" Probed deps dir and matched '%s'"), candidate->c_str());
return true;
diff --git a/src/installer/corehost/cli/hostpolicy/deps_resolver.h b/src/installer/corehost/cli/hostpolicy/deps_resolver.h
index f2b27d4620a..d61a78c3179 100644
--- a/src/installer/corehost/cli/hostpolicy/deps_resolver.h
+++ b/src/installer/corehost/cli/hostpolicy/deps_resolver.h
@@ -14,7 +14,6 @@
#include "deps_format.h"
#include "deps_entry.h"
#include "runtime_config.h"
-#include "bundle/runner.h"
// Probe paths to be resolved for ordering
struct probe_paths_t
@@ -186,17 +185,6 @@ public:
static const pal::string_t s_empty;
return s_empty;
}
- if (m_host_mode == host_mode_t::apphost)
- {
- if (bundle::info_t::is_single_file_bundle())
- {
- const bundle::runner_t* app = bundle::runner_t::app();
- if (app->is_netcoreapp3_compat_mode())
- {
- return app->extraction_path();
- }
- }
- }
return m_app_dir;
}
diff --git a/src/installer/corehost/cli/hostpolicy/hostpolicy.cpp b/src/installer/corehost/cli/hostpolicy/hostpolicy.cpp
index c2a933ec364..5c7d766a87d 100644
--- a/src/installer/corehost/cli/hostpolicy/hostpolicy.cpp
+++ b/src/installer/corehost/cli/hostpolicy/hostpolicy.cpp
@@ -18,7 +18,6 @@
#include <corehost_context_contract.h>
#include <hostpolicy.h>
#include "hostpolicy_context.h"
-#include "bundle/runner.h"
namespace
{
@@ -355,7 +354,7 @@ int corehost_init(
}
int corehost_main_init(
- hostpolicy_init_t& hostpolicy_init,
+ hostpolicy_init_t &hostpolicy_init,
const int argc,
const pal::char_t* argv[],
const pal::string_t& location,
@@ -368,15 +367,6 @@ int corehost_main_init(
hostpolicy_init.host_info.parse(argc, argv);
}
- if (bundle::info_t::is_single_file_bundle())
- {
- StatusCode status = bundle::runner_t::process_manifest_and_extract();
- if (status != StatusCode::Success)
- {
- return status;
- }
- }
-
return corehost_init(hostpolicy_init, argc, argv, location, args);
}
@@ -444,9 +434,6 @@ int corehost_libhost_init(const hostpolicy_init_t &hostpolicy_init, const pal::s
// Host info should always be valid in the delegate scenario
assert(hostpolicy_init.host_info.is_valid(host_mode_t::libhost));
- // Single-file bundle is only expected in apphost mode.
- assert(!bundle::info_t::is_single_file_bundle());
-
return corehost_init(hostpolicy_init, 0, nullptr, location, args);
}
diff --git a/src/installer/corehost/cli/hostpolicy/hostpolicy_init.cpp b/src/installer/corehost/cli/hostpolicy/hostpolicy_init.cpp
index 3e0d02a17c5..c6103f7af91 100644
--- a/src/installer/corehost/cli/hostpolicy/hostpolicy_init.cpp
+++ b/src/installer/corehost/cli/hostpolicy/hostpolicy_init.cpp
@@ -4,7 +4,6 @@
#include "hostpolicy_init.h"
#include <trace.h>
-#include "bundle/runner.h"
void make_palstr_arr(int argc, const pal::char_t** argv, std::vector<pal::string_t>* out)
{
@@ -127,15 +126,6 @@ bool hostpolicy_init_t::init(host_interface_t* input, hostpolicy_init_t* init)
// For the backwards compat case, this will be later initialized with argv[0]
}
- if (input->version_lo >= offsetof(host_interface_t, single_file_bundle_header_offset) + sizeof(input->single_file_bundle_header_offset))
- {
- if (input->single_file_bundle_header_offset != 0)
- {
- static bundle::runner_t bundle_runner(input->host_info_host_path, input->host_info_app_path, input->single_file_bundle_header_offset);
- bundle::info_t::the_app = &bundle_runner;
- }
- }
-
return true;
}
diff --git a/src/installer/corehost/cli/hostpolicy/hostpolicy_init.h b/src/installer/corehost/cli/hostpolicy/hostpolicy_init.h
index 8d2ea616fcc..18af97c9c25 100644
--- a/src/installer/corehost/cli/hostpolicy/hostpolicy_init.h
+++ b/src/installer/corehost/cli/hostpolicy/hostpolicy_init.h
@@ -8,7 +8,6 @@
#include "host_interface.h"
#include "host_startup_info.h"
#include "fx_definition.h"
-#include "bundle/info.h"
struct hostpolicy_init_t
{
diff --git a/src/installer/corehost/cli/ijwhost/ijwthunk.cpp b/src/installer/corehost/cli/ijwhost/ijwthunk.cpp
index 2b05bcfe708..b2329112162 100644
--- a/src/installer/corehost/cli/ijwhost/ijwthunk.cpp
+++ b/src/installer/corehost/cli/ijwhost/ijwthunk.cpp
@@ -73,7 +73,7 @@ bool patch_vtable_entries(PEDecoder& pe)
error_writer_scope_t writer_scope(swallow_trace);
size_t currentThunk = 0;
- for (size_t i = 0; i < numFixupRecords; ++i)
+ for(size_t i = 0; i < numFixupRecords; ++i)
{
if (pFixupTable[i].Type & COR_VTABLE_PTRSIZED)
{
@@ -81,7 +81,7 @@ bool patch_vtable_entries(PEDecoder& pe)
#ifdef _WIN64
DWORD oldProtect;
- if (!VirtualProtect(pointers, (sizeof(BYTE*) * pFixupTable[i].Count), PAGE_READWRITE, &oldProtect))
+ if(!VirtualProtect(pointers, (sizeof(BYTE*) * pFixupTable[i].Count), PAGE_READWRITE, &oldProtect))
{
trace::error(_X("Failed to change the vtfixup table from RO to R/W failed.\n"));
return false;
@@ -101,7 +101,7 @@ bool patch_vtable_entries(PEDecoder& pe)
#ifdef _WIN64
DWORD _;
- if (!VirtualProtect(pointers, (sizeof(BYTE*) * pFixupTable[i].Count), oldProtect, &_))
+ if(!VirtualProtect(pointers, (sizeof(BYTE*) * pFixupTable[i].Count), oldProtect, &_))
{
trace::warning(_X("Failed to change the vtfixup table from R/W back to RO failed.\n"));
}
diff --git a/src/installer/corehost/cli/json/rapidjson/document.h b/src/installer/corehost/cli/json/rapidjson/document.h
index 74666e3423e..9783fe4acc9 100644
--- a/src/installer/corehost/cli/json/rapidjson/document.h
+++ b/src/installer/corehost/cli/json/rapidjson/document.h
@@ -2094,11 +2094,11 @@ private:
const SizeType len1 = GetStringLength();
const SizeType len2 = rhs.GetStringLength();
- if (len1 != len2) { return false; }
+ if(len1 != len2) { return false; }
const Ch* const str1 = GetString();
const Ch* const str2 = rhs.GetString();
- if (str1 == str2) { return true; } // fast path for constant string
+ if(str1 == str2) { return true; } // fast path for constant string
return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
}
diff --git a/src/installer/corehost/cli/json_parser.cpp b/src/installer/corehost/cli/json_parser.cpp
index c6f0cbbf0c9..9814f3215d6 100644
--- a/src/installer/corehost/cli/json_parser.cpp
+++ b/src/installer/corehost/cli/json_parser.cpp
@@ -42,9 +42,9 @@ std::streampos get_utf8_bom_length(pal::istream_t& stream)
return 3;
}
-void get_line_column_from_offset(const char* data, uint64_t size, size_t offset, int *line, int *column)
+void get_line_column_from_offset(const std::vector<char>& json, size_t offset, int *line, int *column)
{
- assert(offset < size);
+ assert(offset < json.size());
*line = *column = 1;
@@ -52,12 +52,12 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,
{
(*column)++;
- if (data[i] == '\n')
+ if (json[i] == '\n')
{
(*line)++;
*column = 1;
}
- else if (data[i] == '\r' && data[i + 1] == '\n')
+ else if (json[i] == '\r' && json[i + 1] == '\n')
{
(*line)++;
*column = 1;
@@ -75,30 +75,32 @@ void json_parser_t::realloc_buffer(size_t size)
m_json[size] = '\0';
}
-bool json_parser_t::parse_json(char* data, int64_t size, const pal::string_t& context)
+bool json_parser_t::parse_json(const pal::string_t& context)
{
+ assert(!m_json.empty());
+
#ifdef _WIN32
// Can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings. m_document will store
// data in UTF-16 (with pal::char_t as the character type), but it
// has to know that data is encoded in UTF-8 to convert during parsing.
constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag
- | rapidjson::ParseFlag::kParseCommentsFlag;
- m_document.Parse<flags, rapidjson::UTF8<>>(data);
-#else // _WIN32
- m_document.ParseInsitu<rapidjson::ParseFlag::kParseCommentsFlag>(data);
-#endif // _WIN32
+ | rapidjson::ParseFlag::kParseCommentsFlag;
+ m_document.Parse<flags, rapidjson::UTF8<>>(m_json.data());
+#else
+ m_document.ParseInsitu<rapidjson::ParseFlag::kParseCommentsFlag>(m_json.data());
+#endif
if (m_document.HasParseError())
{
int line, column;
size_t offset = m_document.GetErrorOffset();
- get_line_column_from_offset(data, size, offset, &line, &column);
+ get_line_column_from_offset(m_json, offset, &line, &column);
trace::error(_X("A JSON parsing exception occurred in [%s], offset %zu (line %d, column %d): %s"),
- context.c_str(), offset, line, column,
- rapidjson::GetParseError_En(m_document.GetParseError()));
+ context.c_str(), offset, line, column,
+ rapidjson::GetParseError_En(m_document.GetParseError()));
return false;
}
@@ -128,37 +130,5 @@ bool json_parser_t::parse_stream(pal::istream_t& stream,
realloc_buffer(stream_size - current_pos);
stream.read(m_json.data(), stream_size - current_pos);
- return parse_json(m_json.data(), m_json.size(), context);
-}
-
-bool json_parser_t::parse_file(const pal::string_t& path)
-{
- // This code assumes that the caller has checked that the file `path` exists
- // either within the bundle, or as a real file on disk.
- assert(m_bundle_data == nullptr);
- assert(m_bundle_location == nullptr);
-
- if (bundle::info_t::is_single_file_bundle())
- {
- m_bundle_data = bundle::info_t::config_t::map(path, m_bundle_location);
- // The mapping will be unmapped by the json_parser destructor.
- // The mapping cannot be immediately released due to in-situ parsing on Linux.
-
- if (m_bundle_data != nullptr)
- {
- bool result = parse_json(m_bundle_data, m_bundle_location->size, path);
- return result;
- }
- }
-
- pal::ifstream_t file{ path };
- return parse_stream(file, path);
-}
-
-json_parser_t::~json_parser_t()
-{
- if (m_bundle_data != nullptr)
- {
- bundle::info_t::config_t::unmap(m_bundle_data, m_bundle_location);
- }
+ return parse_json(context);
}
diff --git a/src/installer/corehost/cli/json_parser.h b/src/installer/corehost/cli/json_parser.h
index 16ed21bd033..e5c477b1171 100644
--- a/src/installer/corehost/cli/json_parser.h
+++ b/src/installer/corehost/cli/json_parser.h
@@ -9,7 +9,6 @@
#include "rapidjson/document.h"
#include "rapidjson/fwd.h"
#include <vector>
-#include "bundle/info.h"
class json_parser_t {
public:
@@ -22,15 +21,12 @@ class json_parser_t {
using document_t = rapidjson::GenericDocument<internal_encoding_type_t>;
const document_t& document() const { return m_document; }
-
bool parse_stream(pal::istream_t& stream, const pal::string_t& context);
- bool parse_file(const pal::string_t& path);
-
- json_parser_t()
- : m_bundle_data(nullptr)
- , m_bundle_location(nullptr) {}
-
- ~json_parser_t();
+ bool parse_file(const pal::string_t& path)
+ {
+ pal::ifstream_t file{path};
+ return parse_stream(file, path);
+ }
private:
// This is a vector of char and not pal::char_t because JSON data
@@ -40,12 +36,8 @@ class json_parser_t {
std::vector<char> m_json;
document_t m_document;
- // If a json file is parsed from a single-file bundle, the following two fields represent:
- char* m_bundle_data; // The memory mapped bytes of the application bundle.
- const bundle::location_t* m_bundle_location; // Location of this json file within the bundle.
-
void realloc_buffer(size_t size);
- bool parse_json(char* data, int64_t size, const pal::string_t& context);
+ bool parse_json(const pal::string_t& context);
};
#endif // __JSON_PARSER_H__
diff --git a/src/installer/corehost/cli/runtime_config.cpp b/src/installer/corehost/cli/runtime_config.cpp
index d41aa2a0573..2026da52d81 100644
--- a/src/installer/corehost/cli/runtime_config.cpp
+++ b/src/installer/corehost/cli/runtime_config.cpp
@@ -9,7 +9,6 @@
#include "runtime_config.h"
#include "trace.h"
#include "utils.h"
-#include "bundle/info.h"
#include <cassert>
// The semantics of applying the runtimeconfig.json values follows, in the following steps from
@@ -339,8 +338,6 @@ bool runtime_config_t::ensure_dev_config_parsed()
return true;
}
- // runtimeconfig.dev.json is never bundled into the single-file app.
- // So, only a file on disk is processed.
json_parser_t json;
if (!json.parse_file(m_dev_path))
{
@@ -401,7 +398,7 @@ bool runtime_config_t::ensure_parsed()
trace::verbose(_X("Did not successfully parse the runtimeconfig.dev.json"));
}
- if (!bundle::info_t::config_t::probe(m_path) && !pal::file_exists(m_path))
+ if (!pal::file_exists(m_path))
{
// Not existing is not an error.
return true;
diff --git a/src/installer/corehost/cli/test/mockhostpolicy/mockhostpolicy.cpp b/src/installer/corehost/cli/test/mockhostpolicy/mockhostpolicy.cpp
index 2130fe7b2f9..4a0567f3f35 100644
--- a/src/installer/corehost/cli/test/mockhostpolicy/mockhostpolicy.cpp
+++ b/src/installer/corehost/cli/test/mockhostpolicy/mockhostpolicy.cpp
@@ -66,7 +66,6 @@ SHARED_API int HOSTPOLICY_CALLTYPE corehost_load(host_interface_t* init)
std::cout << "mock host_info_host_path:" << tostr(init->host_info_host_path).data() << std::endl;
std::cout << "mock host_info_dotnet_root:" << tostr(init->host_info_dotnet_root).data() << std::endl;
std::cout << "mock host_info_app_path:" << tostr(init->host_info_app_path).data() << std::endl;
- std::cout << "mock single_file_bundle_header_offset:" << std::hex << init->single_file_bundle_header_offset << std::endl;
if (init->fx_names.len == 0)
{
diff --git a/src/installer/corehost/corehost.cpp b/src/installer/corehost/corehost.cpp
index 55b8ed62982..bb6b4ce60e5 100644
--- a/src/installer/corehost/corehost.cpp
+++ b/src/installer/corehost/corehost.cpp
@@ -11,7 +11,8 @@
#include "utils.h"
#if defined(FEATURE_APPHOST)
-#include "bundle_marker.h"
+#include "cli/apphost/bundle/marker.h"
+#include "cli/apphost/bundle/runner.h"
#if defined(_WIN32)
#include "cli/apphost/apphost.windows.h"
@@ -83,14 +84,6 @@ bool is_exe_enabled_for_execution(pal::string_t* app_dll)
#define CURHOST_EXE
#endif
-void need_newer_framework_error()
-{
- pal::string_t url = get_download_url();
- trace::error(_X(" _ To run this application, you need to install a newer version of .NET Core."));
- trace::error(_X(""));
- trace::error(_X(" - %s&apphost_version=%s"), url.c_str(), _STRINGIFY(COMMON_HOST_PKG_VER));
-}
-
#if defined(CURHOST_EXE)
int exe_start(const int argc, const pal::char_t* argv[])
@@ -104,8 +97,8 @@ int exe_start(const int argc, const pal::char_t* argv[])
pal::string_t app_path;
pal::string_t app_root;
- bool requires_hostfxr_startupinfo_interface = false;
-
+ bool requires_v2_hostfxr_interface = false;
+
#if defined(FEATURE_APPHOST)
pal::string_t embedded_app_name;
if (!is_exe_enabled_for_execution(&embedded_app_name))
@@ -122,17 +115,29 @@ int exe_start(const int argc, const pal::char_t* argv[])
auto pos_path_char = embedded_app_name.find(DIR_SEPARATOR);
if (pos_path_char != pal::string_t::npos)
{
- requires_hostfxr_startupinfo_interface = true;
+ requires_v2_hostfxr_interface = true;
}
- app_path.assign(get_directory(host_path));
- append_path(&app_path, embedded_app_name.c_str());
+ if (bundle::marker_t::is_bundle())
+ {
+ bundle::runner_t bundle_runner(host_path);
+ StatusCode bundle_status = bundle_runner.extract();
+
+ if (bundle_status != StatusCode::Success)
+ {
+ trace::error(_X("A fatal error was encountered. Could not extract contents of the bundle"));
+ return bundle_status;
+ }
- if (bundle_marker_t::is_bundle())
+ app_path.assign(bundle_runner.extraction_dir());
+ }
+ else
{
- trace::info(_X("Detected Single-File app bundle"));
+ app_path.assign(get_directory(host_path));
}
- else if (!pal::realpath(&app_path))
+
+ append_path(&app_path, embedded_app_name.c_str());
+ if (!pal::realpath(&app_path))
{
trace::error(_X("The application to execute does not exist: '%s'."), app_path.c_str());
return StatusCode::LibHostAppRootFindFailure;
@@ -195,88 +200,58 @@ int exe_start(const int argc, const pal::char_t* argv[])
// Obtain the entrypoints.
int rc;
-#if defined(FEATURE_APPHOST)
- if (bundle_marker_t::is_bundle())
- {
- hostfxr_main_bundle_startupinfo_fn hostfxr_main_bundle_startupinfo = reinterpret_cast<hostfxr_main_bundle_startupinfo_fn>(pal::get_symbol(fxr, "hostfxr_main_bundle_startupinfo"));
- if (hostfxr_main_bundle_startupinfo != nullptr)
- {
- const pal::char_t* host_path_cstr = host_path.c_str();
- const pal::char_t* dotnet_root_cstr = dotnet_root.empty() ? nullptr : dotnet_root.c_str();
- const pal::char_t* app_path_cstr = app_path.empty() ? nullptr : app_path.c_str();
- int64_t bundle_header_offset = bundle_marker_t::header_offset();
-
- trace::info(_X("Invoking fx resolver [%s] hostfxr_main_bundle_startupinfo"), fxr_path.c_str());
- trace::info(_X("Host path: [%s]"), host_path.c_str());
- trace::info(_X("Dotnet path: [%s]"), dotnet_root.c_str());
- trace::info(_X("App path: [%s]"), app_path.c_str());
- trace::info(_X("Bundle Header Offset: [%lx]"), bundle_header_offset);
-
- hostfxr_set_error_writer_fn set_error_writer_fn = reinterpret_cast<hostfxr_set_error_writer_fn>(pal::get_symbol(fxr, "hostfxr_set_error_writer"));
- propagate_error_writer_t propagate_error_writer_to_hostfxr(set_error_writer_fn);
- rc = hostfxr_main_bundle_startupinfo(argc, argv, host_path_cstr, dotnet_root_cstr, app_path_cstr, bundle_header_offset);
- }
- else
- {
- // The host components will be statically linked with the app-host: https://github.com/dotnet/runtime/issues/32823
- // Once this work is completed, an outdated hostfxr can only be found for framework-related apps.
- trace::error(_X("The required library %s does not support single-file apps."), fxr_path.c_str());
- need_newer_framework_error();
- rc = StatusCode::FrameworkMissingFailure;
- }
- }
- else
-#endif // defined(FEATURE_APPHOST)
+ hostfxr_main_startupinfo_fn main_fn_v2 = reinterpret_cast<hostfxr_main_startupinfo_fn>(pal::get_symbol(fxr, "hostfxr_main_startupinfo"));
+ if (main_fn_v2 != nullptr)
{
- hostfxr_main_startupinfo_fn hostfxr_main_startupinfo = reinterpret_cast<hostfxr_main_startupinfo_fn>(pal::get_symbol(fxr, "hostfxr_main_startupinfo"));
- if (hostfxr_main_startupinfo != nullptr)
- {
- const pal::char_t* host_path_cstr = host_path.c_str();
- const pal::char_t* dotnet_root_cstr = dotnet_root.empty() ? nullptr : dotnet_root.c_str();
- const pal::char_t* app_path_cstr = app_path.empty() ? nullptr : app_path.c_str();
+ const pal::char_t* host_path_cstr = host_path.c_str();
+ const pal::char_t* dotnet_root_cstr = dotnet_root.empty() ? nullptr : dotnet_root.c_str();
+ const pal::char_t* app_path_cstr = app_path.empty() ? nullptr : app_path.c_str();
- trace::info(_X("Invoking fx resolver [%s] hostfxr_main_startupinfo"), fxr_path.c_str());
- trace::info(_X("Host path: [%s]"), host_path.c_str());
- trace::info(_X("Dotnet path: [%s]"), dotnet_root.c_str());
- trace::info(_X("App path: [%s]"), app_path.c_str());
+ trace::info(_X("Invoking fx resolver [%s] v2"), fxr_path.c_str());
+ trace::info(_X("Host path: [%s]"), host_path.c_str());
+ trace::info(_X("Dotnet path: [%s]"), dotnet_root.c_str());
+ trace::info(_X("App path: [%s]"), app_path.c_str());
- hostfxr_set_error_writer_fn set_error_writer_fn = reinterpret_cast<hostfxr_set_error_writer_fn>(pal::get_symbol(fxr, "hostfxr_set_error_writer"));
+ hostfxr_set_error_writer_fn set_error_writer_fn = reinterpret_cast<hostfxr_set_error_writer_fn>(pal::get_symbol(fxr, "hostfxr_set_error_writer"));
+ {
propagate_error_writer_t propagate_error_writer_to_hostfxr(set_error_writer_fn);
- rc = hostfxr_main_startupinfo(argc, argv, host_path_cstr, dotnet_root_cstr, app_path_cstr);
+ rc = main_fn_v2(argc, argv, host_path_cstr, dotnet_root_cstr, app_path_cstr);
- // This check exists to provide an error message for UI apps when running 3.0 apps on 2.0 only hostfxr, which doesn't support error writer redirection.
if (trace::get_error_writer() != nullptr && rc == static_cast<int>(StatusCode::FrameworkMissingFailure) && !set_error_writer_fn)
{
- need_newer_framework_error();
+ pal::string_t url = get_download_url();
+ trace::error(_X(" _ To run this application, you need to install a newer version of .NET."));
+ trace::error(_X(""));
+ trace::error(_X(" - %s"), url.c_str());
}
}
+ }
+ else
+ {
+ if (requires_v2_hostfxr_interface)
+ {
+ trace::error(_X("The required library %s does not support relative app dll paths."), fxr_path.c_str());
+ rc = StatusCode::CoreHostEntryPointFailure;
+ }
else
{
- if (requires_hostfxr_startupinfo_interface)
+ trace::info(_X("Invoking fx resolver [%s] v1"), fxr_path.c_str());
+
+ // Previous corehost trace messages must be printed before calling trace::setup in hostfxr
+ trace::flush();
+
+ // For compat, use the v1 interface. This requires additional file I\O to re-parse parameters and
+ // for apphost, does not support DOTNET_ROOT or dll with different name for exe.
+ hostfxr_main_fn main_fn_v1 = reinterpret_cast<hostfxr_main_fn>(pal::get_symbol(fxr, "hostfxr_main"));
+ if (main_fn_v1 != nullptr)
{
- trace::error(_X("The required library %s does not support relative app dll paths."), fxr_path.c_str());
- rc = StatusCode::CoreHostEntryPointFailure;
+ rc = main_fn_v1(argc, argv);
}
else
{
- trace::info(_X("Invoking fx resolver [%s] v1"), fxr_path.c_str());
-
- // Previous corehost trace messages must be printed before calling trace::setup in hostfxr
- trace::flush();
-
- // For compat, use the v1 interface. This requires additional file I\O to re-parse parameters and
- // for apphost, does not support DOTNET_ROOT or dll with different name for exe.
- hostfxr_main_fn main_fn_v1 = reinterpret_cast<hostfxr_main_fn>(pal::get_symbol(fxr, "hostfxr_main"));
- if (main_fn_v1 != nullptr)
- {
- rc = main_fn_v1(argc, argv);
- }
- else
- {
- trace::error(_X("The required library %s does not contain the expected entry point."), fxr_path.c_str());
- rc = StatusCode::CoreHostEntryPointFailure;
- }
+ trace::error(_X("The required library %s does not contain the expected entry point."), fxr_path.c_str());
+ rc = StatusCode::CoreHostEntryPointFailure;
}
}
}
diff --git a/src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs b/src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs
index 29e9635d4fd..320969c101d 100644
--- a/src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs
+++ b/src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs
@@ -90,7 +90,7 @@ namespace Microsoft.NET.HostModel.Bundle
return fileRelativePath.Equals(RuntimeConfigDevJson);
}
- bool ShouldExclude(FileType type, string relativePath)
+ bool ShouldExclude(FileType type)
{
switch (type)
{
@@ -100,7 +100,7 @@ namespace Microsoft.NET.HostModel.Bundle
return false;
case FileType.NativeBinary:
- return !Options.HasFlag(BundleOptions.BundleNativeBinaries) || Target.ShouldExclude(relativePath);
+ return !Options.HasFlag(BundleOptions.BundleNativeBinaries);
case FileType.Symbols:
return !Options.HasFlag(BundleOptions.BundleSymbolFiles);
@@ -229,24 +229,22 @@ namespace Microsoft.NET.HostModel.Bundle
foreach (var fileSpec in fileSpecs)
{
- string relativePath = fileSpec.BundleRelativePath;
-
- if (IsHost(relativePath))
+ if (IsHost(fileSpec.BundleRelativePath))
{
continue;
}
- if (ShouldIgnore(relativePath))
+ if (ShouldIgnore(fileSpec.BundleRelativePath))
{
- Tracer.Log($"Ignore: {relativePath}");
+ Tracer.Log($"Ignore: {fileSpec.BundleRelativePath}");
continue;
}
FileType type = InferType(fileSpec);
- if (ShouldExclude(type, relativePath))
+ if (ShouldExclude(type))
{
- Tracer.Log($"Exclude [{type}]: {relativePath}");
+ Tracer.Log($"Exclude [{type}]: {fileSpec.BundleRelativePath}");
fileSpec.Excluded = true;
continue;
}
@@ -255,7 +253,7 @@ namespace Microsoft.NET.HostModel.Bundle
{
FileType targetType = Target.TargetSpecificFileType(type);
long startOffset = AddToBundle(bundle, file, targetType);
- FileEntry entry = BundleManifest.AddEntry(targetType, relativePath, startOffset, file.Length);
+ FileEntry entry = BundleManifest.AddEntry(targetType, fileSpec.BundleRelativePath, startOffset, file.Length);
Tracer.Log($"Embed: {entry}");
}
}
diff --git a/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs b/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs
index 9c171ae2da7..bd2b340971e 100644
--- a/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs
+++ b/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs
@@ -59,7 +59,7 @@ namespace Microsoft.NET.HostModel.Bundle
enum HeaderFlags : ulong
{
None = 0,
- NetcoreApp3CompatMode = 1
+ NetcoreApp3CompatMode = 2
}
// Bundle ID is a string that is used to uniquely
diff --git a/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs b/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs
index 87b1c65202e..1f6f61a7eee 100644
--- a/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs
+++ b/src/installer/managed/Microsoft.NET.HostModel/Bundle/TargetInfo.cs
@@ -27,6 +27,8 @@ namespace Microsoft.NET.HostModel.Bundle
public TargetInfo(OSPlatform? os, Version targetFrameworkVersion)
{
+ Version net50 = new Version(5, 0);
+
OS = os ?? HostOS;
FrameworkVersion = targetFrameworkVersion ?? net50;
@@ -69,21 +71,6 @@ namespace Microsoft.NET.HostModel.Bundle
// The .net core 3 apphost doesn't care about semantics of FileType -- all files are extracted at startup.
// However, the apphost checks that the FileType value is within expected bounds, so set it to the first enumeration.
public FileType TargetSpecificFileType(FileType fileType) => (BundleVersion == 1) ? FileType.Unknown : fileType;
-
- // In .net core 3.x, bundle processing happens within the AppHost.
- // Therefore HostFxr and HostPolicy can be bundled within the single-file app.
- // In .net 5, bundle processing happens in HostFxr and HostPolicy libraries.
- // Therefore, these libraries themselves cannot be bundled into the single-file app.
- // This problem is mitigated by statically linking these host components with the AppHost.
- // https://github.com/dotnet/runtime/issues/32823
- public bool ShouldExclude(string relativePath) =>
- (FrameworkVersion.Major != 3) && (relativePath.Equals(HostFxr) || relativePath.Equals(HostPolicy));
-
- readonly Version net50 = new Version(5, 0);
- string HostFxr => IsWindows ? "hostfxr.dll" : IsLinux ? "libhostfxr.so" : "libhostfxr.dylib";
- string HostPolicy => IsWindows ? "hostpolicy.dll" : IsLinux ? "libhostpolicy.so" : "libhostpolicy.dylib";
-
-
}
}
diff --git a/src/installer/test/Assets/TestProjects/AppWithSubDirs/Program.cs b/src/installer/test/Assets/TestProjects/AppWithSubDirs/Program.cs
index 5b51c37991b..20c24839186 100644
--- a/src/installer/test/Assets/TestProjects/AppWithSubDirs/Program.cs
+++ b/src/installer/test/Assets/TestProjects/AppWithSubDirs/Program.cs
@@ -4,6 +4,7 @@
using System;
using System.IO;
+using System.Reflection;
namespace AppWithSubDirs
{
@@ -11,7 +12,10 @@ namespace AppWithSubDirs
{
public static void Main(string[] args)
{
- string baseDir = Path.Combine(AppContext.BaseDirectory, "Sentence");
+ string baseDir =
+ Path.Combine(
+ Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
+ "Sentence");
string Part(string dir="", string subdir="", string subsubdir="")
{
diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs
index 26dbc3a00ef..5f35a406c91 100644
--- a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs
+++ b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs
@@ -7,7 +7,9 @@ using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.CoreSetup.Test;
using Microsoft.NET.HostModel.Bundle;
using System;
+using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Threading;
using Xunit;
@@ -27,19 +29,24 @@ namespace AppHost.Bundle.Tests
{
var fixture = sharedTestState.TestFixture.Copy();
var hostName = BundleHelper.GetHostName(fixture);
+ var appName = Path.GetFileNameWithoutExtension(hostName);
+ string publishPath = BundleHelper.GetPublishPath(fixture);
// Publish the bundle
- string singleFile;
- Bundler bundler = BundleHelper.BundleApp(fixture, out singleFile);
+ var bundleDir = BundleHelper.GetBundleDir(fixture);
+ var bundler = new Bundler(hostName, bundleDir.FullName, BundleOptions.BundleAllContent);
+ string singleFile = BundleHelper.GenerateBundle(bundler, publishPath);
+
+ // Compute bundled files
+ var bundledFiles = bundler.BundleManifest.Files.Select(file => file.RelativePath).ToList();
// Verify expected files in the bundle directory
- var bundleDir = BundleHelper.GetBundleDir(fixture);
bundleDir.Should().HaveFile(hostName);
- bundleDir.Should().NotHaveFiles(BundleHelper.GetBundledFiles(fixture));
+ bundleDir.Should().NotHaveFiles(bundledFiles);
// Create a directory for extraction.
- var extractBaseDir = BundleHelper.GetExtractionRootDir(fixture);
- extractBaseDir.Should().NotHaveDirectory(BundleHelper.GetAppBaseName(fixture));
+ var extractBaseDir = BundleHelper.GetExtractDir(fixture);
+ extractBaseDir.Should().NotHaveDirectory(appName);
// Run the bundled app for the first time, and extract files to
// $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id
@@ -53,22 +60,27 @@ namespace AppHost.Bundle.Tests
.And
.HaveStdOutContaining("Hello World");
- var extractDir = BundleHelper.GetExtractionDir(fixture, bundler);
- extractDir.Should().HaveFiles(BundleHelper.GetExtractedFiles(fixture));
- extractDir.Should().NotHaveFiles(BundleHelper.GetFilesNeverExtracted(fixture));
+ string extractPath = Path.Combine(extractBaseDir.FullName, appName, bundler.BundleManifest.BundleID);
+ var extractDir = new DirectoryInfo(extractPath);
+ extractDir.Should().OnlyHaveFiles(bundledFiles);
+ extractDir.Should().NotHaveFile(hostName);
}
[Fact]
private void Bundle_extraction_is_reused()
{
var fixture = sharedTestState.TestFixture.Copy();
+ var hostName = BundleHelper.GetHostName(fixture);
+ var appName = Path.GetFileNameWithoutExtension(hostName);
+ string publishPath = BundleHelper.GetPublishPath(fixture);
// Publish the bundle
- string singleFile;
- Bundler bundler = BundleHelper.BundleApp(fixture, out singleFile, BundleOptions.BundleNativeBinaries);
+ var bundleDir = BundleHelper.GetBundleDir(fixture);
+ var bundler = new Bundler(hostName, bundleDir.FullName, BundleOptions.BundleAllContent);
+ string singleFile = BundleHelper.GenerateBundle(bundler, publishPath);
// Create a directory for extraction.
- var extractBaseDir = BundleHelper.GetExtractionRootDir(fixture);
+ var extractBaseDir = BundleHelper.GetExtractDir(fixture);
// Run the bunded app for the first time, and extract files to
// $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id
@@ -82,8 +94,8 @@ namespace AppHost.Bundle.Tests
.And
.HaveStdOutContaining("Hello World");
- var appBaseName = BundleHelper.GetAppBaseName(fixture);
- var extractDir = BundleHelper.GetExtractionDir(fixture, bundler);
+ string extractPath = Path.Combine(extractBaseDir.FullName, appName, bundler.BundleManifest.BundleID);
+ var extractDir = new DirectoryInfo(extractPath);
extractDir.Refresh();
DateTime firstWriteTime = extractDir.LastWriteTimeUtc;
@@ -113,14 +125,20 @@ namespace AppHost.Bundle.Tests
var fixture = sharedTestState.TestFixture.Copy();
var hostName = BundleHelper.GetHostName(fixture);
var appName = Path.GetFileNameWithoutExtension(hostName);
+ string publishPath = BundleHelper.GetPublishPath(fixture);
// Publish the bundle
- string singleFile;
- Bundler bundler = BundleHelper.BundleApp(fixture, out singleFile, BundleOptions.BundleNativeBinaries);
+ var bundleDir = BundleHelper.GetBundleDir(fixture);
+ var bundler = new Bundler(hostName, bundleDir.FullName, BundleOptions.BundleAllContent);
+ string singleFile = BundleHelper.GenerateBundle(bundler, publishPath);
+
+ // Compute bundled files
+ List<string> bundledFiles = bundler.BundleManifest.Files.Select(file => file.RelativePath).ToList();
// Create a directory for extraction.
- var extractBaseDir = BundleHelper.GetExtractionRootDir(fixture);
-
+ var extractBaseDir = BundleHelper.GetExtractDir(fixture);
+ string extractPath = Path.Combine(extractBaseDir.FullName, appName, bundler.BundleManifest.BundleID);
+ var extractDir = new DirectoryInfo(extractPath);
// Run the bunded app for the first time, and extract files to
// $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id
@@ -134,14 +152,10 @@ namespace AppHost.Bundle.Tests
.And
.HaveStdOutContaining("Hello World");
- // Remove the extracted files, but keep the extraction directory
- var extractDir = BundleHelper.GetExtractionDir(fixture, bundler);
- var extractedFiles = BundleHelper.GetExtractedFiles(fixture);
-
- Array.ForEach(extractedFiles, file => File.Delete(Path.Combine(extractDir.FullName, file)));
+ bundledFiles.ForEach(file => File.Delete(Path.Combine(extractPath, file)));
extractDir.Should().Exist();
- extractDir.Should().NotHaveFiles(extractedFiles);
+ extractDir.Should().NotHaveFiles(bundledFiles);
// Run the bundled app again (recover deleted files)
Command.Create(singleFile)
@@ -154,7 +168,7 @@ namespace AppHost.Bundle.Tests
.And
.HaveStdOutContaining("Hello World");
- extractDir.Should().HaveFiles(extractedFiles);
+ extractDir.Should().HaveFiles(bundledFiles);
}
diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleRename.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleRename.cs
index 581a1155c98..5466743fc5d 100644
--- a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleRename.cs
+++ b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleRename.cs
@@ -51,13 +51,11 @@ namespace AppHost.Bundle.Tests
.CaptureStdOut()
.Start();
- while (!File.Exists(waitFile) && !singleExe.Process.HasExited)
+ while (!File.Exists(waitFile))
{
Thread.Sleep(100);
}
- Assert.True(File.Exists(waitFile));
-
File.Move(singleFile, renameFile);
File.Create(resumeFile).Close();
diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs
index 33e05b5c050..59360c09f99 100644
--- a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs
+++ b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs
@@ -2,12 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using BundleTests.Helpers;
-using Microsoft.DotNet.Cli.Build.Framework;
-using Microsoft.NET.HostModel.Bundle;
-using Microsoft.DotNet.CoreSetup.Test;
using System;
using Xunit;
+using Microsoft.DotNet.Cli.Build.Framework;
+using BundleTests.Helpers;
+using Microsoft.DotNet.CoreSetup.Test;
namespace AppHost.Bundle.Tests
{
@@ -32,16 +31,11 @@ namespace AppHost.Bundle.Tests
.HaveStdOutContaining("Wow! We now say hello to the big world and you.");
}
- // BundleOptions.BundleNativeBinaries: Test when the payload data files are unbundled, and beside the single-file app.
- // BundleOptions.BundleAllContent: Test when the payload data files are bundled and extracted to temporary directory.
- // Once the runtime can load assemblies from the bundle, BundleOptions.None can be used in place of BundleOptions.BundleNativeBinaries.
- [InlineData(BundleOptions.BundleNativeBinaries)]
- [InlineData(BundleOptions.BundleAllContent)]
- [Theory]
- public void Bundled_Framework_dependent_App_Run_Succeeds(BundleOptions options)
+ [Fact]
+ public void Bundled_Framework_dependent_App_Run_Succeeds()
{
var fixture = sharedTestState.TestFrameworkDependentFixture.Copy();
- var singleFile = BundleHelper.BundleApp(fixture, options);
+ var singleFile = BundleHelper.BundleApp(fixture);
// Run the bundled app (extract files)
RunTheApp(singleFile);
@@ -50,13 +44,11 @@ namespace AppHost.Bundle.Tests
RunTheApp(singleFile);
}
- [InlineData(BundleOptions.BundleNativeBinaries)]
- [InlineData(BundleOptions.BundleAllContent)]
- [Theory]
- public void Bundled_Self_Contained_App_Run_Succeeds(BundleOptions options)
+ [Fact]
+ public void Bundled_Self_Contained_App_Run_Succeeds()
{
var fixture = sharedTestState.TestSelfContainedFixture.Copy();
- var singleFile = BundleHelper.BundleApp(fixture, options);
+ var singleFile = BundleHelper.BundleApp(fixture);
// Run the bundled app (extract files)
RunTheApp(singleFile);
@@ -65,13 +57,11 @@ namespace AppHost.Bundle.Tests
RunTheApp(singleFile);
}
- [InlineData(BundleOptions.BundleNativeBinaries)]
- [InlineData(BundleOptions.BundleAllContent)]
- [Theory]
- public void Bundled_With_Empty_File_Succeeds(BundleOptions options)
+ [Fact]
+ public void Bundled_With_Empty_File_Succeeds()
{
var fixture = sharedTestState.TestAppWithEmptyFileFixture.Copy();
- var singleFile = BundleHelper.BundleApp(fixture, options);
+ var singleFile = BundleHelper.BundleApp(fixture);
// Run the app
RunTheApp(singleFile);
diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/Helpers/BundleHelper.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/Helpers/BundleHelper.cs
index c5f77179436..e941becc236 100644
--- a/src/installer/test/Microsoft.NET.HostModel.Tests/Helpers/BundleHelper.cs
+++ b/src/installer/test/Microsoft.NET.HostModel.Tests/Helpers/BundleHelper.cs
@@ -40,32 +40,6 @@ namespace BundleTests.Helpers
return Path.GetFileName(fixture.TestProject.AppDll);
}
- public static string GetAppBaseName(TestProjectFixture fixture)
- {
- return Path.GetFileNameWithoutExtension(GetAppName(fixture));
- }
-
- public static string[] GetBundledFiles(TestProjectFixture fixture)
- {
- string appBaseName = GetAppBaseName(fixture);
- return new string[] { $"{appBaseName}.dll", $"{appBaseName}.deps.json", $"{appBaseName}.runtimeconfig.json" };
- }
-
- public static string[] GetExtractedFiles(TestProjectFixture fixture)
- {
- string appBaseName = GetAppBaseName(fixture);
- return new string[] { $"{appBaseName}.dll" };
- }
-
- public static string[] GetFilesNeverExtracted(TestProjectFixture fixture)
- {
- string appBaseName = GetAppBaseName(fixture);
- return new string[] { $"{appBaseName}.deps.json",
- $"{appBaseName}.runtimeconfig.json",
- Path.GetFileName(fixture.TestProject.HostFxrDll),
- Path.GetFileName(fixture.TestProject.HostPolicyDll) };
- }
-
public static string GetPublishPath(TestProjectFixture fixture)
{
return Path.Combine(fixture.TestProject.ProjectDirectory, "publish");
@@ -76,28 +50,13 @@ namespace BundleTests.Helpers
return Directory.CreateDirectory(Path.Combine(fixture.TestProject.ProjectDirectory, "bundle"));
}
- public static string GetExtractionRootPath(TestProjectFixture fixture)
- {
- return Path.Combine(fixture.TestProject.ProjectDirectory, "extract");
- }
-
- public static DirectoryInfo GetExtractionRootDir(TestProjectFixture fixture)
+ public static DirectoryInfo GetExtractDir(TestProjectFixture fixture)
{
- return Directory.CreateDirectory(GetExtractionRootPath(fixture));
- }
-
- public static string GetExtractionPath(TestProjectFixture fixture, Bundler bundler)
- {
- return Path.Combine(GetExtractionRootPath(fixture), GetAppBaseName(fixture), bundler.BundleManifest.BundleID);
-
- }
- public static DirectoryInfo GetExtractionDir(TestProjectFixture fixture, Bundler bundler)
- {
- return new DirectoryInfo(GetExtractionPath(fixture, bundler));
+ return Directory.CreateDirectory(Path.Combine(fixture.TestProject.ProjectDirectory, "extract"));
}
/// Generate a bundle containind the (embeddable) files in sourceDir
- public static string GenerateBundle(Bundler bundler, string sourceDir, string outputDir, bool copyExludedFiles=true)
+ public static string GenerateBundle(Bundler bundler, string sourceDir)
{
// Convert sourceDir to absolute path
sourceDir = Path.GetFullPath(sourceDir);
@@ -114,22 +73,7 @@ namespace BundleTests.Helpers
fileSpecs.Add(new FileSpec(file, Path.GetRelativePath(sourceDir, file)));
}
- var singleFile = bundler.GenerateBundle(fileSpecs);
-
- if (copyExludedFiles)
- {
- foreach (var spec in fileSpecs)
- {
- if (spec.Excluded)
- {
- var outputFilePath = Path.Combine(outputDir, spec.BundleRelativePath);
- Directory.CreateDirectory(Path.GetDirectoryName(outputFilePath));
- File.Copy(spec.SourcePath, outputFilePath, true);
- }
- }
- }
-
- return singleFile;
+ return bundler.GenerateBundle(fileSpecs);
}
// Bundle to a single-file
@@ -137,40 +81,23 @@ namespace BundleTests.Helpers
// instead of the SDK via /p:PublishSingleFile=true.
// This is necessary when the test needs the latest changes in the AppHost,
// which may not (yet) be available in the SDK.
- public static Bundler BundleApp(TestProjectFixture fixture,
- out string singleFile,
- BundleOptions options = BundleOptions.BundleNativeBinaries,
- Version targetFrameworkVersion = null,
- bool copyExcludedFiles = true)
+ //
+ // Currently, AppHost can only handle bundles if all content is extracted to disk on startup.
+ // Therefore, the BundleOption is BundleAllContent by default.
+ // The default should be BundleOptions.None once host/runtime no longer requires full-extraction.
+ public static string BundleApp(TestProjectFixture fixture,
+ BundleOptions options = BundleOptions.BundleAllContent,
+ Version targetFrameworkVersion = null)
{
var hostName = GetHostName(fixture);
string publishPath = GetPublishPath(fixture);
var bundleDir = GetBundleDir(fixture);
var bundler = new Bundler(hostName, bundleDir.FullName, options, targetFrameworkVersion: targetFrameworkVersion);
- singleFile = GenerateBundle(bundler, publishPath, bundleDir.FullName, copyExcludedFiles);
-
- return bundler;
- }
-
- // The defaut option for Bundling apps is BundleOptions.BundleNativeBinaries
- // Until CoreCLR runtime can learn how to process assemblies from the bundle.
- // This is because CoreCLR expects System.Private.Corelib.dll to be beside CoreCLR.dll
- public static string BundleApp(TestProjectFixture fixture,
- BundleOptions options = BundleOptions.BundleNativeBinaries,
- Version targetFrameworkVersion = null)
- {
- string singleFile;
- BundleApp(fixture, out singleFile, options, targetFrameworkVersion);
+ string singleFile = GenerateBundle(bundler, publishPath);
return singleFile;
}
- public static Bundler Bundle(TestProjectFixture fixture, BundleOptions options = BundleOptions.None)
- {
- string singleFile;
- return BundleApp(fixture, out singleFile, options, copyExcludedFiles:false);
- }
-
public static void AddLongNameContentToAppWithSubDirs(TestProjectFixture fixture)
{
// For tests using the AppWithSubDirs, One of the sub-directories with a really long name
diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs
index e4949b47750..3199b1559ff 100644
--- a/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs
+++ b/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs
@@ -7,6 +7,7 @@ using System.IO;
using Xunit;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.CoreSetup.Test;
+using Microsoft.NET.HostModel.Bundle;
using BundleTests.Helpers;
namespace Microsoft.NET.HostModel.Tests
@@ -40,7 +41,9 @@ namespace Microsoft.NET.HostModel.Tests
RunTheApp(Path.Combine(publishPath, hostName));
// Bundle to a single-file
- string singleFile = BundleHelper.BundleApp(fixture);
+ // Bundle all content, until the host can handle other scenarios.
+ Bundler bundler = new Bundler(hostName, singleFileDir, BundleOptions.BundleAllContent);
+ string singleFile = BundleHelper.GenerateBundle(bundler, publishPath);
// Run the extracted app
RunTheApp(singleFile);
diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleLegacy.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleLegacy.cs
index 7b9d6863607..a9c9b700064 100644
--- a/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleLegacy.cs
+++ b/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleLegacy.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.IO;
using Xunit;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.CoreSetup.Test;
diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundlerConsistencyTests.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundlerConsistencyTests.cs
index 00f3b1cc843..efa13283bd1 100644
--- a/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundlerConsistencyTests.cs
+++ b/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundlerConsistencyTests.cs
@@ -92,10 +92,18 @@ namespace Microsoft.NET.HostModel.Tests
public void TestFilesAlwaysBundled(BundleOptions options)
{
var fixture = sharedTestState.TestFixture.Copy();
- var bundler = BundleHelper.Bundle(fixture, options);
- var bundledFiles = BundleHelper.GetBundledFiles(fixture);
- Array.ForEach(bundledFiles, file => bundler.BundleManifest.Contains(file).Should().BeTrue());
+ var hostName = BundleHelper.GetHostName(fixture);
+ var appName = Path.GetFileNameWithoutExtension(hostName);
+ string publishPath = BundleHelper.GetPublishPath(fixture);
+ var bundleDir = BundleHelper.GetBundleDir(fixture);
+
+ var bundler = new Bundler(hostName, bundleDir.FullName, options);
+ BundleHelper.GenerateBundle(bundler, publishPath);
+
+ bundler.BundleManifest.Contains($"{appName}.dll").Should().BeTrue();
+ bundler.BundleManifest.Contains($"{appName}.deps.json").Should().BeTrue();
+ bundler.BundleManifest.Contains($"{appName}.runtimeconfig.json").Should().BeTrue();
}
[InlineData(BundleOptions.None)]
@@ -107,16 +115,20 @@ namespace Microsoft.NET.HostModel.Tests
public void TestFilesNeverBundled(BundleOptions options)
{
var fixture = sharedTestState.TestFixture.Copy();
- var appBaseName = BundleHelper.GetAppBaseName(fixture);
+
+ var hostName = BundleHelper.GetHostName(fixture);
+ var appName = Path.GetFileNameWithoutExtension(hostName);
string publishPath = BundleHelper.GetPublishPath(fixture);
+ var bundleDir = BundleHelper.GetBundleDir(fixture);
// Make up a app.runtimeconfig.dev.json file in the publish directory.
- File.Copy(Path.Combine(publishPath, $"{appBaseName}.runtimeconfig.json"),
- Path.Combine(publishPath, $"{appBaseName}.runtimeconfig.dev.json"));
+ File.Copy(Path.Combine(publishPath, $"{appName}.runtimeconfig.json"),
+ Path.Combine(publishPath, $"{appName}.runtimeconfig.dev.json"));
- var bundler = BundleHelper.Bundle(fixture, options);
+ var bundler = new Bundler(hostName, bundleDir.FullName, options);
+ BundleHelper.GenerateBundle(bundler, publishPath);
- bundler.BundleManifest.Contains($"{appBaseName}.runtimeconfig.dev.json").Should().BeFalse();
+ bundler.BundleManifest.Contains($"{appName}.runtimeconfig.dev.json").Should().BeFalse();
}
[InlineData(BundleOptions.None)]
@@ -125,10 +137,16 @@ namespace Microsoft.NET.HostModel.Tests
public void TestBundlingSymbols(BundleOptions options)
{
var fixture = sharedTestState.TestFixture.Copy();
- var appBaseName = BundleHelper.GetAppBaseName(fixture);
- var bundler = BundleHelper.Bundle(fixture, options);
- bundler.BundleManifest.Contains($"{appBaseName}.pdb").Should().Be(options.HasFlag(BundleOptions.BundleSymbolFiles));
+ var hostName = BundleHelper.GetHostName(fixture);
+ var appName = Path.GetFileNameWithoutExtension(hostName);
+ string publishPath = BundleHelper.GetPublishPath(fixture);
+ var bundleDir = BundleHelper.GetBundleDir(fixture);
+
+ var bundler = new Bundler(hostName, bundleDir.FullName, options);
+ BundleHelper.GenerateBundle(bundler, publishPath);
+
+ bundler.BundleManifest.Contains($"{appName}.pdb").Should().Be(options.HasFlag(BundleOptions.BundleSymbolFiles));
}
[InlineData(BundleOptions.None)]
@@ -137,28 +155,30 @@ namespace Microsoft.NET.HostModel.Tests
public void TestBundlingNativeBinaries(BundleOptions options)
{
var fixture = sharedTestState.TestFixture.Copy();
- var coreclr = Path.GetFileName(fixture.TestProject.CoreClrDll);
- var bundler = BundleHelper.Bundle(fixture, options);
- bundler.BundleManifest.Contains($"{coreclr}").Should().Be(options.HasFlag(BundleOptions.BundleNativeBinaries));
- }
+ var hostName = BundleHelper.GetHostName(fixture);
+ var hostfxr = Path.GetFileName(fixture.TestProject.HostFxrDll);
+ string publishPath = BundleHelper.GetPublishPath(fixture);
+ var bundleDir = BundleHelper.GetBundleDir(fixture);
- [Fact]
- public void TestFileSizes()
- {
- var fixture = sharedTestState.TestFixture.Copy();
- var bundler = BundleHelper.Bundle(fixture);
- var publishPath = BundleHelper.GetPublishPath(fixture);
+ var bundler = new Bundler(hostName, bundleDir.FullName, options);
+ BundleHelper.GenerateBundle(bundler, publishPath);
- bundler.BundleManifest.Files.ForEach(file =>
- Assert.True(file.Size == new FileInfo(Path.Combine(publishPath, file.RelativePath)).Length));
+ bundler.BundleManifest.Contains($"{hostfxr}").Should().Be(options.HasFlag(BundleOptions.BundleNativeBinaries));
}
[Fact]
public void TestAssemblyAlignment()
{
var fixture = sharedTestState.TestFixture.Copy();
- var bundler = BundleHelper.Bundle(fixture);
+
+ var hostName = BundleHelper.GetHostName(fixture);
+ var appName = Path.GetFileNameWithoutExtension(hostName);
+ string publishPath = BundleHelper.GetPublishPath(fixture);
+ var bundleDir = BundleHelper.GetBundleDir(fixture);
+
+ var bundler = new Bundler(hostName, bundleDir.FullName, BundleOptions.BundleAllContent);
+ BundleHelper.GenerateBundle(bundler, publishPath);
bundler.BundleManifest.Files.ForEach(file =>
Assert.True((file.Type != FileType.Assembly) || (file.Offset % Bundler.AssemblyAlignment == 0)));
@@ -168,7 +188,13 @@ namespace Microsoft.NET.HostModel.Tests
public void TestWithAdditionalContentAfterBundleMetadata()
{
var fixture = sharedTestState.TestFixture.Copy();
- string singleFile = BundleHelper.BundleApp(fixture);
+
+ var hostName = BundleHelper.GetHostName(fixture);
+ var bundleDir = BundleHelper.GetBundleDir(fixture);
+ string publishPath = BundleHelper.GetPublishPath(fixture);
+
+ var bundler = new Bundler(hostName, bundleDir.FullName, BundleOptions.BundleAllContent);
+ string singleFile = BundleHelper.GenerateBundle(bundler, publishPath);
using (var file = File.OpenWrite(singleFile))
{
diff --git a/src/installer/test/TestUtils/TestApp.cs b/src/installer/test/TestUtils/TestApp.cs
index a1ff67d95c8..3e4e72f1fe7 100644
--- a/src/installer/test/TestUtils/TestApp.cs
+++ b/src/installer/test/TestUtils/TestApp.cs
@@ -16,7 +16,6 @@ namespace Microsoft.DotNet.CoreSetup.Test
public string RuntimeDevConfigJson { get; private set; }
public string HostPolicyDll { get; private set; }
public string HostFxrDll { get; private set; }
- public string CoreClrDll { get; private set; }
public string AssemblyName { get; }
@@ -56,7 +55,6 @@ namespace Microsoft.DotNet.CoreSetup.Test
RuntimeDevConfigJson = Path.Combine(Location, $"{AssemblyName}.runtimeconfig.dev.json");
HostPolicyDll = Path.Combine(Location, RuntimeInformationExtensions.GetSharedLibraryFileNameForCurrentPlatform("hostpolicy"));
HostFxrDll = Path.Combine(Location, RuntimeInformationExtensions.GetSharedLibraryFileNameForCurrentPlatform("hostfxr"));
- CoreClrDll = Path.Combine(Location, RuntimeInformationExtensions.GetSharedLibraryFileNameForCurrentPlatform("coreclr"));
}
}
}
diff --git a/src/installer/test/TestUtils/TestProject.cs b/src/installer/test/TestUtils/TestProject.cs
index b512f4c1e6b..5fd9135beec 100644
--- a/src/installer/test/TestUtils/TestProject.cs
+++ b/src/installer/test/TestUtils/TestProject.cs
@@ -22,7 +22,6 @@ namespace Microsoft.DotNet.CoreSetup.Test
public string AppExe { get => BuiltApp?.AppExe; }
public string HostPolicyDll { get => BuiltApp?.HostPolicyDll; }
public string HostFxrDll { get => BuiltApp?.HostFxrDll; }
- public string CoreClrDll { get => BuiltApp?.CoreClrDll; }
public TestApp BuiltApp { get; private set; }