Ideally, the bundler should be:
- Able to embed any file required to run a .Net Core app -- managed assemblies, native binaries, configuration files, data files, etc.
- Able to generate cross-platform bundles (ex: publish a single-file for Linux target from Windows)
- Deterministic (generate the exact same single-file on multiple runs)
- Amenable to post-processing (ex: signing tools)
Given a .net core app published with respect to a specific runtime, the bundler transforms the AppHost
binary to a single-file bundle by:
- Appending the managed app and its dependencies as a binary-blob at the end of the
AppHost
executable. - Writing meta-data to identify the binary as a single-file bundle, and a manifest of the embedded files.
The bundling tool will append the following contents to the AppHost
binary:
-
The actual files to be published into the single file (including the managed app)
-
A bundle header containing:
- The bundler tool version
- A bundle identifier: which is a path-compatible cryptographically strong name.
- This identifier is used to distinguish bundles for different versions of the same app.
- This identifier is used as part of the bundle extraction mechanism as described in this document.
- Currently, a new bundle identifier is generated for each bundle transformation. In future, the bundle identifiers should be generated by hashing the contents of the bundle -- so that bundle transformation is deterministic.
- Offset of the bundle manifest
-
A bundle manifest that describes:
- The location of embeded files (offset and size)
- The type of the embedded files: MSIL assemblies, ready-to-run assemblies, configuration files (ex:
app.deps.json
app.runtimeconfig.json
), or others.
Every AppHost
has a static variable that identifies the location of the single-file header (if any).
By default, this value is zero, which indicates that the AppHost
is not a bundle.
The bundler tool rewrites this value with the location of the bundle header.
This ensures that the bundle-header is not position constrained (ex: at the end of the file), so that tools like signtool
can post-process the bundle file.
The bundler should ideally be located close to the core-host, since their implementation is closely related. Therefore, the bundler will be implemented in the core-setup
repo.
The bundling tool is implemented as a library in the Microsoft.NET.HostModel package. This library is used by the SDK in order to publish a .net core app as a single-file.
Codesign tool on mac-os performs strict consistency checks, and cannot tolerate the additional files appended at the end of the AppHost
executable.
Further work is necessary to update the binary headers to make the bundle file compatible for signing.