Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
## 2.14.0

* Add a `pkg.useExe` config variable to allow users to customize exactly when
single-file standalone executables are generated.

## 2.13.0

* Generate an [AOT module] instead of a [portable module] in
`pkg-standalone-dev`. Because dev artifacts are only intended to be used on
the current machine, there's no need to trade speed for portability.
`pkg-standalone-dev`. Because dev artifacts are only intended to be used on
the current machine, there's no need to trade speed for portability.

* Add a `pkg-compile-native-dev` task to generate an AOT module with asserts
enabled.

* The `pkg-compile-snapshot-dev` task is now an alias of `pkg-compile-snapshot`
for backward compatibility. For portable modules asserts need be enabled at
runtime with `dart --enable-asserts`.
for backward compatibility. For portable modules asserts need be enabled at
runtime with `dart --enable-asserts`.

[AOT module]: https://dart.dev/tools/dart-compile#aot-snapshot
[portable module]: https://dart.dev/tools/dart-compile#kernel
[AOT module]: https://dart.dev/tools/dart-compile#aot-snapshot
[portable module]: https://dart.dev/tools/dart-compile#kernel

* Add support for new `dartvm` executable on Dart SDK >=3.10.0.

Expand Down
15 changes: 11 additions & 4 deletions doc/standalone.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ Depends on: [`pkg-compile-snapshot`][]

## `pkg-compile-native`

Uses configuration: [`pkg.executables`][], [`pkg.version`][]
Uses configuration: [`pkg.executables`][], [`pkg.version`][], [`pkg.useExe`][],

[`pkg.useExe`]: https://pub.dev/documentation/cli_pkg/latest/cli_pkg/useExe.html

Output: `build/$executable.native`

Compiles each executable in the package to an
[AOT module (aot-snapshot)][aot-snapshot] with asserts disabled.
[AOT module (aot-snapshot)][aot-snapshot] or a
[self-contained executable][exe] (depending on the current platform and
[`pkg.useExe`][]) with asserts disabled.

[exe]: https://dart.dev/tools/dart-compile#exe

[`String.fromEnvironment()`]: https://api.dartlang.org/stable/dart-core/String/String.fromEnvironment.html

Expand Down Expand Up @@ -104,8 +110,9 @@ that can be used to invoke them.

Any OS's packages can be built regardless of the OS running the task, but if the
host OS matches the target OS *and* the architecture is 64-bit, executables will
be built as [AOT modules (aot-snapshot)][aot-snapshot], which are substantially
faster and smaller than the kernel snapshots that are generated otherwise.
be built as [AOT modules (aot-snapshot)][aot-snapshot] or ["exe"][exe], which
are substantially faster and smaller than the kernel snapshots that are
generated otherwise.

The target for the current OS and architecture is always available. However, for
any OS or architecture under experimental Dart SDK support, such task is only
Expand Down
25 changes: 20 additions & 5 deletions lib/src/standalone.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ import 'utils.dart';
/// This defaults to [name].
final standaloneName = InternalConfigVariable.fn<String>(() => name.value);

/// Whether to build a native executable for the current platform instead of an
/// AOT snapshot.
///
/// This is a function that's passed the [CliPlatform] that's being built to
/// allow for different behavior on different platforms.
///
/// This defaults to returning [CliPlatform.useExe] unmodified.
final useExe = InternalConfigVariable.value<bool Function(CliPlatform)>(
(CliPlatform platform) => platform.useExe,
);

/// For each executable entrypoint in [executables], builds a portable module
/// (kernel) to `build/${executable}.snapshot`.
void _compileSnapshot() {
Expand Down Expand Up @@ -66,7 +77,8 @@ void _compileSnapshot() {
}

/// For each executable entrypoint in [executables], builds an AOT module
/// (aot-snapshot) to `build/${executable}.native`.
/// (aot-snapshot) or standalone executable (exe) to
/// `build/${executable}.native`.
///
/// If [enableAsserts] is `true`, this compiles with `--enable-asserts`.
void _compileNative({bool enableAsserts = false}) {
Expand All @@ -85,7 +97,7 @@ void _compileNative({bool enableAsserts = false}) {
'dart',
arguments: [
'compile',
CliPlatform.current.useExe ? 'exe' : 'aot-snapshot',
useExe.value(CliPlatform.current) ? 'exe' : 'aot-snapshot',
if (enableAsserts) '--enable-asserts',
for (var entry in environmentConstants.value.entries)
'-D${entry.key}=${entry.value}',
Expand All @@ -109,6 +121,7 @@ void addStandaloneTasks() {

freezeSharedVariables();
standaloneName.freeze();
useExe.freeze();

addTask(
GrinderTask(
Expand Down Expand Up @@ -211,7 +224,9 @@ Future<void> _buildPackage(CliPlatform platform) async {
var archive = Archive()
..addFile(fileFromString("$standaloneName/src/LICENSE", await license));

if (!platform.useExe) {
var nativeExe = useExe.value(platform);

if (!(platform.useNative && nativeExe)) {
archive.addFile(
fileFromBytes(
"$standaloneName/src/dart${platform.binaryExtension}",
Expand All @@ -222,7 +237,7 @@ Future<void> _buildPackage(CliPlatform platform) async {
}

for (var name in executables.value.keys) {
if (platform.useExe) {
if (platform.useNative && nativeExe) {
archive.addFile(
file(
"$standaloneName/$name${platform.binaryExtension}",
Expand All @@ -240,7 +255,7 @@ Future<void> _buildPackage(CliPlatform platform) async {
}
}

if (!platform.useExe) {
if (!(platform.useNative && nativeExe)) {
// Do this separately from adding entrypoints because multiple executables
// may have the same entrypoint.
for (var name in executables.value.keys) {
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: cli_pkg
version: 2.13.0
version: 2.14.0
description: Grinder tasks for releasing Dart CLI packages.
homepage: https://github.com/google/dart_cli_pkg

Expand Down
54 changes: 54 additions & 0 deletions test/standalone_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,60 @@ void main() {
]).validate();
});

test("can be standalone executables on current platform", () async {
await d.package(pubspec, """
void main(List<String> args) {
pkg.useExe.value = (_) => true;
pkg.addStandaloneTasks();
grind(args);
}
""").create();

await (await grind([
"pkg-standalone-${CliPlatform.current}",
])).shouldExit(0);

await d.archive("my_app/build/my_app-1.2.3-$_archiveSuffix", [
d.dir("my_app", [
d.file("foo$dotExe", anything),
d.file("bar$dotExe", anything),
d.file("qux$dotExe", anything),
d.dir("src", [
d.nothing("foo.snapshot"),
d.nothing("bar.snapshot"),
d.nothing("qux.snapshot"),
]),
]),
]).validate();
});

test("can be aot snapshots on current platform", () async {
await d.package(pubspec, """
void main(List<String> args) {
pkg.useExe.value = (_) => false;
pkg.addStandaloneTasks();
grind(args);
}
""").create();

await (await grind([
"pkg-standalone-${CliPlatform.current}",
])).shouldExit(0);

await d.archive("my_app/build/my_app-1.2.3-$_archiveSuffix", [
d.dir("my_app", [
d.file("foo$dotBat", anything),
d.file("bar$dotBat", anything),
d.file("qux$dotBat", anything),
d.dir("src", [
d.file("foo.snapshot", anything),
d.file("bar.snapshot", anything),
d.file("qux.snapshot", anything),
]),
]),
]).validate();
});

test("can be removed by the user", () async {
await d.package(pubspec, """
void main(List<String> args) {
Expand Down
Loading