Skip to content

Commit 47ec733

Browse files
[release/5.0-preview4] Revert processing bundles in framework (#35679)
This commit reverts: Revert "Single-File: Process bundles in the framework (#34274)" This reverts commit 78b303d. Revert "Single-File Bundler: Add a FileSize test (#35149)" This reverts commit 779588a. *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 78b303d. and a dependent test-only change: Revert "Single-File Bundler: Add a FileSize test (#35149)" commit 779588a. *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 dotnet/sdk#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).
1 parent 6d1f7e0 commit 47ec733

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+477
-1113
lines changed

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,26 @@ endif()
1818
set(SKIP_VERSIONING 1)
1919

2020
set(SOURCES
21-
./bundle_marker.cpp
21+
./bundle/file_entry.cpp
22+
./bundle/manifest.cpp
23+
./bundle/header.cpp
24+
./bundle/marker.cpp
25+
./bundle/reader.cpp
26+
./bundle/extractor.cpp
27+
./bundle/runner.cpp
28+
./bundle/dir_utils.cpp
2229
)
2330

2431
set(HEADERS
25-
./bundle_marker.h
32+
./bundle/file_type.h
33+
./bundle/file_entry.h
34+
./bundle/manifest.h
35+
./bundle/header.h
36+
./bundle/marker.h
37+
./bundle/reader.h
38+
./bundle/extractor.h
39+
./bundle/runner.h
40+
./bundle/dir_utils.h
2641
)
2742

2843
if(CLR_CMAKE_TARGET_WIN32)

src/installer/corehost/cli/bundle/extractor.cpp renamed to src/installer/corehost/cli/apphost/bundle/extractor.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,7 @@ void extractor_t::extract_new(reader_t& reader)
197197
begin();
198198
for (const file_entry_t& entry : m_manifest.files)
199199
{
200-
if (entry.needs_extraction())
201-
{
202-
extract(entry, reader);
203-
}
200+
extract(entry, reader);
204201
}
205202
commit_dir();
206203
}
@@ -214,11 +211,6 @@ void extractor_t::verify_recover_extraction(reader_t& reader)
214211

215212
for (const file_entry_t& entry : m_manifest.files)
216213
{
217-
if (!entry.needs_extraction())
218-
{
219-
continue;
220-
}
221-
222214
pal::string_t file_path = ext_dir;
223215
append_path(&file_path, entry.relative_path().c_str());
224216

src/installer/corehost/cli/bundle/file_entry.cpp renamed to src/installer/corehost/cli/apphost/bundle/file_entry.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,3 @@ file_entry_t file_entry_t::read(reader_t &reader)
3333

3434
return entry;
3535
}
36-
37-
bool file_entry_t::needs_extraction() const
38-
{
39-
switch (m_type)
40-
{
41-
// Once the runtime can load assemblies from bundle,
42-
// file_type_t::assembly should be in this category
43-
case file_type_t::deps_json:
44-
case file_type_t::runtime_config_json:
45-
return false;
46-
47-
default:
48-
return true;
49-
}
50-
}

src/installer/corehost/cli/bundle/file_entry.h renamed to src/installer/corehost/cli/apphost/bundle/file_entry.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ namespace bundle
5858
int64_t offset() const { return m_offset; }
5959
int64_t size() const { return m_size; }
6060
file_type_t type() const { return m_type; }
61-
bool needs_extraction() const;
6261

6362
static file_entry_t read(reader_t &reader);
6463

src/installer/corehost/cli/bundle/header.cpp renamed to src/installer/corehost/cli/apphost/bundle/header.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,29 @@
99

1010
using namespace bundle;
1111

12-
bool header_fixed_t::is_valid() const
12+
// The AppHost expects the bundle_header to be an exact_match for which it was built.
13+
// The framework accepts backwards compatible header versions.
14+
bool header_fixed_t::is_valid(bool exact_match) const
1315
{
1416
if (num_embedded_files <= 0)
1517
{
1618
return false;
1719
}
1820

19-
// .net 5 host expects the version information to be 2.0
20-
// .net core 3 single-file bundles are handled within the netcoreapp3.x apphost, and are not processed here in the framework.
21-
return (major_version == header_t::major_version) && (minor_version == header_t::minor_version);
21+
if (exact_match)
22+
{
23+
return (major_version == header_t::major_version) && (minor_version == header_t::minor_version);
24+
}
25+
26+
return ((major_version < header_t::major_version) ||
27+
(major_version == header_t::major_version && minor_version <= header_t::minor_version));
2228
}
2329

24-
header_t header_t::read(reader_t& reader)
30+
header_t header_t::read(reader_t& reader, bool need_exact_version)
2531
{
2632
const header_fixed_t* fixed_header = reinterpret_cast<const header_fixed_t*>(reader.read_direct(sizeof(header_fixed_t)));
2733

28-
if (!fixed_header->is_valid())
34+
if (!fixed_header->is_valid(need_exact_version))
2935
{
3036
trace::error(_X("Failure processing application bundle."));
3137
trace::error(_X("Bundle header version compatibility check failed."));
@@ -38,8 +44,10 @@ header_t header_t::read(reader_t& reader)
3844
// bundle_id is a component of the extraction path
3945
reader.read_path_string(header.m_bundle_id);
4046

41-
const header_fixed_v2_t *v2_header = reinterpret_cast<const header_fixed_v2_t*>(reader.read_direct(sizeof(header_fixed_v2_t)));
42-
header.m_v2_header = *v2_header;
47+
if (fixed_header->major_version > 1)
48+
{
49+
header.m_v2_header = reinterpret_cast<const header_fixed_v2_t*>(reader.read_direct(sizeof(header_fixed_v2_t)));
50+
}
4351

4452
return header;
4553
}

src/installer/corehost/cli/bundle/header.h renamed to src/installer/corehost/cli/apphost/bundle/header.h

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ namespace bundle
3232
uint32_t minor_version;
3333
int32_t num_embedded_files;
3434

35-
bool is_valid() const;
35+
bool is_valid(bool exact_match = false) const;
3636
};
37+
#pragma pack(pop)
3738

3839
// netcoreapp3_compat_mode flag is set on a .net5 app, which chooses to build single-file apps in .netcore3.x compat mode,
3940
// This indicates that:
@@ -45,13 +46,12 @@ namespace bundle
4546
netcoreapp3_compat_mode = 1
4647
};
4748

49+
#pragma pack(push, 1)
4850
struct location_t
4951
{
5052
public:
5153
int64_t offset;
5254
int64_t size;
53-
54-
bool is_valid() const { return offset != 0; }
5555
};
5656

5757
// header_fixed_v2_t is available in single-file apps targetting .net5+ frameworks.
@@ -65,8 +65,6 @@ namespace bundle
6565
location_t deps_json_location;
6666
location_t runtimeconfig_json_location;
6767
header_flags_t flags;
68-
69-
bool is_netcoreapp3_compat_mode() const { return (flags & header_flags_t::netcoreapp3_compat_mode) != 0; }
7068
};
7169
#pragma pack(pop)
7270

@@ -76,25 +74,23 @@ namespace bundle
7674
header_t(int32_t num_embedded_files = 0)
7775
: m_num_embedded_files(num_embedded_files)
7876
, m_bundle_id()
79-
, m_v2_header()
77+
, m_v2_header(NULL)
78+
8079
{
8180
}
8281

83-
static header_t read(reader_t& reader);
84-
const pal::string_t& bundle_id() const { return m_bundle_id; }
85-
int32_t num_embedded_files() const { return m_num_embedded_files; }
86-
87-
const location_t& deps_json_location() const { return m_v2_header.deps_json_location; }
88-
const location_t& runtimeconfig_json_location() const { return m_v2_header.runtimeconfig_json_location; }
89-
bool is_netcoreapp3_compat_mode() const { return m_v2_header.is_netcoreapp3_compat_mode(); }
82+
static header_t read(reader_t& reader, bool need_exact_version);
83+
const pal::string_t& bundle_id() { return m_bundle_id; }
84+
int32_t num_embedded_files() { return m_num_embedded_files; }
9085

9186
static const uint32_t major_version = 2;
9287
static const uint32_t minor_version = 0;
9388

9489
private:
9590
int32_t m_num_embedded_files;
9691
pal::string_t m_bundle_id;
97-
header_fixed_v2_t m_v2_header;
92+
const header_fixed_v2_t* m_v2_header;
93+
9894
};
9995
}
10096
#endif // __HEADER_H__

src/installer/corehost/cli/bundle/manifest.cpp renamed to src/installer/corehost/cli/apphost/bundle/manifest.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ manifest_t manifest_t::read(reader_t& reader, int32_t num_files)
1212

1313
for (int32_t i = 0; i < num_files; i++)
1414
{
15-
file_entry_t entry = file_entry_t::read(reader);
16-
manifest.files.push_back(std::move(entry));
17-
manifest.m_need_extraction |= entry.needs_extraction();
15+
manifest.files.emplace_back(file_entry_t::read(reader));
1816
}
1917

2018
return manifest;

src/installer/corehost/cli/bundle/manifest.h renamed to src/installer/corehost/cli/apphost/bundle/manifest.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,9 @@ namespace bundle
1616
class manifest_t
1717
{
1818
public:
19-
manifest_t()
20-
: m_need_extraction(false) {}
21-
2219
std::vector<file_entry_t> files;
2320

2421
static manifest_t read(reader_t &reader, int32_t num_files);
25-
26-
bool files_need_extraction() { return m_need_extraction; }
27-
28-
private:
29-
bool m_need_extraction;
3022
};
3123
}
3224
#endif // __MANIFEST_H__

src/installer/corehost/cli/apphost/bundle_marker.cpp renamed to src/installer/corehost/cli/apphost/bundle/marker.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
#include "bundle_marker.h"
5+
#include "marker.h"
66
#include "pal.h"
77
#include "trace.h"
88
#include "utils.h"
99

10-
int64_t bundle_marker_t::header_offset()
10+
using namespace bundle;
11+
12+
int64_t marker_t::header_offset()
1113
{
1214
// Contains the bundle_placeholder default value at compile time.
1315
// If this is a single-file bundle, the last 8 bytes are replaced
@@ -25,7 +27,7 @@ int64_t bundle_marker_t::header_offset()
2527
0xee, 0x3b, 0x2d, 0xce, 0x24, 0xb3, 0x6a, 0xae
2628
};
2729

28-
volatile bundle_marker_t* marker = reinterpret_cast<volatile bundle_marker_t *>(placeholder);
30+
volatile marker_t* marker = reinterpret_cast<volatile marker_t *>(placeholder);
2931

3032
return marker->locator.bundle_header_offset;
3133
}

src/installer/corehost/cli/apphost/bundle_marker.h renamed to src/installer/corehost/cli/apphost/bundle/marker.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
#ifndef __BUNDLE_MARKER_H__
6-
#define __BUNDLE_MARKER_H__
5+
#ifndef __MARKER_H__
6+
#define __MARKER_H__
77

88
#include <cstdint>
99

10+
namespace bundle
11+
{
1012
#pragma pack(push, 1)
11-
union bundle_marker_t
13+
union marker_t
1214
{
1315
public:
1416
uint8_t placeholder[40];
@@ -26,5 +28,5 @@
2628
};
2729
#pragma pack(pop)
2830

29-
30-
#endif // __BUNDLE_MARKER_H__
31+
}
32+
#endif // __MARKER_H__

src/installer/corehost/cli/bundle/reader.cpp renamed to src/installer/corehost/cli/apphost/bundle/reader.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
using namespace bundle;
1010

11-
const char* reader_t::add_without_overflow(const char* ptr, int64_t len)
11+
const int8_t* reader_t::add_without_overflow(const int8_t* ptr, int64_t len)
1212
{
13-
const char* new_ptr = ptr + len;
13+
const int8_t* new_ptr = ptr + len;
1414

1515
// The following check will fail in case len < 0 (which is also an error while reading)
1616
// even if the actual arthmetic didn't overflow.
@@ -38,7 +38,7 @@ void reader_t::set_offset(int64_t offset)
3838

3939
void reader_t::bounds_check(int64_t len)
4040
{
41-
const char* post_read_ptr = add_without_overflow(m_ptr, len);
41+
const int8_t* post_read_ptr = add_without_overflow(m_ptr, len);
4242

4343
// It is legal for post_read_ptr == m_bound_ptr after reading the last byte.
4444
if (m_ptr < m_base_ptr || post_read_ptr > m_bound_ptr)
@@ -88,14 +88,11 @@ size_t reader_t::read_path_length()
8888
return length;
8989
}
9090

91-
size_t reader_t::read_path_string(pal::string_t &str)
91+
void reader_t::read_path_string(pal::string_t &str)
9292
{
93-
const char* start_ptr = m_ptr;
9493
size_t size = read_path_length();
9594
std::unique_ptr<uint8_t[]> buffer{ new uint8_t[size + 1] };
9695
read(buffer.get(), size);
9796
buffer[size] = 0; // null-terminator
9897
pal::clr_palstring(reinterpret_cast<const char*>(buffer.get()), &str);
99-
100-
return m_ptr - start_ptr; // This subtraction can't overflow because addition above is bounds_checked
10198
}

src/installer/corehost/cli/bundle/reader.h renamed to src/installer/corehost/cli/apphost/bundle/reader.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,19 @@ namespace bundle
1313
// Helper class for reading sequentially from the memory-mapped bundle file.
1414
struct reader_t
1515
{
16-
reader_t(const char* base_ptr, int64_t bound, int64_t start_offset = 0)
16+
reader_t(const int8_t* base_ptr, int64_t bound)
1717
: m_base_ptr(base_ptr)
1818
, m_ptr(base_ptr)
1919
, m_bound(bound)
2020
, m_bound_ptr(add_without_overflow(base_ptr, bound))
2121
{
22-
set_offset(start_offset);
2322
}
2423

2524
public:
2625

2726
void set_offset(int64_t offset);
2827

29-
operator const char*() const
28+
operator const int8_t*() const
3029
{
3130
return m_ptr;
3231
}
@@ -47,26 +46,26 @@ namespace bundle
4746

4847
// Return a pointer to the requested bytes within the memory-mapped file.
4948
// Skip over len bytes.
50-
const char* read_direct(int64_t len)
49+
const int8_t* read_direct(int64_t len)
5150
{
5251
bounds_check(len);
53-
const char *ptr = m_ptr;
52+
const int8_t *ptr = m_ptr;
5453
m_ptr += len;
5554
return ptr;
5655
}
5756

5857
size_t read_path_length();
59-
size_t read_path_string(pal::string_t &str);
58+
void read_path_string(pal::string_t &str);
6059

6160
private:
6261

6362
void bounds_check(int64_t len = 1);
64-
static const char* add_without_overflow(const char* ptr, int64_t len);
63+
static const int8_t* add_without_overflow(const int8_t* ptr, int64_t len);
6564

66-
const char* const m_base_ptr;
67-
const char* m_ptr;
65+
const int8_t* const m_base_ptr;
66+
const int8_t* m_ptr;
6867
const int64_t m_bound;
69-
const char* const m_bound_ptr;
68+
const int8_t* const m_bound_ptr;
7069
};
7170
}
7271

0 commit comments

Comments
 (0)