p-hatan/ mirror

pub repository

mirror.p-hatan.com

code_assets

2.1.0

This library contains the hook protocol specification for bundling native code with Dart packages.

Cached in Iran · Upstream SHA-256 matched

Download archive

Readme

package:code_assets Coverage Status pub package package publisher

This package provides the API for code assets to be used with package:hooks.

A code asset is an asset containing executable code which respects the native application binary interface (ABI). These assets are bundled with a Dart or Flutter application. They can be produced by compiling C, C++, Objective-C, Rust, or Go code for example.

This package is used in a build hook (hook/build.dart) to inform the Dart and Flutter SDKs about the code assets that need to be bundled with an application.

Code assets can be added in a build hook as follows:

import 'package:code_assets/code_assets.dart';
import 'package:hooks/hooks.dart';

void main(List<String> args) async {
  await build(args, (input, output) async {
    if (input.config.buildCodeAssets) {
      final packageName = input.packageName;
      final assetPathInPackage = input.packageRoot.resolve('...');
      final assetPathDownload = input.outputDirectoryShared.resolve('...');

      output.assets.code.add(
        CodeAsset(
          package: packageName,
          name: '...',
          linkMode: DynamicLoadingBundled(),
          file: assetPathInPackage,
        ),
      );
    }
  });
}

When compiling C, C++ or Objective-C code from source, consider using package:native_toolchain_c with a build hook and a link hook. First, define the C library specification in a shared file:

import 'package:native_toolchain_c/native_toolchain_c.dart';

/// The C build specification for the sqlite library.
///
/// It is used by the build and link hooks in the `hook/` directory.
final cLibrary = CLibrary(
  name: 'sqlite3',
  assetName: 'src/third_party/sqlite3.g.dart',
  sources: ['third_party/sqlite/sqlite3.c'],
);

Next, compile the library in the build hook:

import 'package:code_assets/code_assets.dart';
import 'package:hooks/hooks.dart';
import 'package:sqlite/src/c_library.dart';

void main(List<String> args) async {
  await build(args, (input, output) async {
    if (input.config.buildCodeAssets) {
      await cLibrary.build(
        input: input,
        output: output,
        defines: {
          if (input.config.code.targetOS == OS.windows)
            // Ensure symbols are exported in dll.
            'SQLITE_API': '__declspec(dllexport)',
        },
      );
    }
  });
}

Finally, tree-shake and link the library in the link hook:

import 'package:hooks/hooks.dart';
import 'package:native_toolchain_c/native_toolchain_c.dart';
import 'package:record_use/record_use.dart';
import 'package:sqlite/src/c_library.dart';
import 'package:sqlite/src/third_party/record_use_mapping.dart';

void main(List<String> arguments) async {
  await link(arguments, (input, output) async {
    await cLibrary.link(
      input: input,
      output: output,
      linkerOptions: LinkerOptions.treeshake(
        symbolsToKeep: input.recordedUses?.calls.keys.cast<Method>().map(
          (e) => recordUseMapping[e.name]!,
        ),
      ),
    );
  });
}

See the full example in example/sqlite/.

When interfacing with system libraryies, the API in this package is enough:

import 'package:code_assets/code_assets.dart';
import 'package:hooks/hooks.dart';

void main(List<String> args) async {
  await build(args, (input, output) async {
    if (input.config.buildCodeAssets) {
      switch (input.config.code.targetOS) {
        case OS.android || OS.iOS || OS.linux || OS.macOS:
          output.assets.code.add(
            CodeAsset(
              package: 'host_name',
              name: 'src/third_party/unix.dart',
              linkMode: LookupInProcess(),
            ),
          );
        case OS.windows:
          output.assets.code.add(
            CodeAsset(
              package: 'host_name',
              name: 'src/third_party/windows.dart',
              linkMode: DynamicLoadingSystem(Uri.file('ws2_32.dll')),
            ),
          );
        case final os:
          throw UnsupportedError('Unsupported OS: ${os.name}.');
      }
    }
  });
}

See the full example in example/host_name/.

Custom Operating Systems and Architectures

SDK authors can define custom OSes and Architectures that they support in a helper package like:

extension CustomOS on OS {
  static final ohos = OS.fromString('ohos');
}

extension CustomArchitecture on Architecture {
  static final mips = Architecture.fromString('mips');
}

The users of those SDKs can import this helper package to use the custom OSes and Architectures in their build hooks.

For more information see dart.dev/tools/hooks.

Changelog

2.1.0

  • Added Architecture.arm64e.

2.0.0

  • Validate bundled dynamic libraries by reading their header: when the file is a recognized ELF, Mach-O, or PE binary, check that it was built for the target architecture. Reject multi-architecture Mach-O output because hooks run once per target architecture. A file the built-in validators do not recognize, or a recognized library built for an architecture they do not know, warns on the supplied logger instead of failing.
  • Bump the dependency on package:hooks to ^2.2.0.
  • Breaking change: Overrode == and hashCode in OS, Architecture, and Sanitizer to support custom targets. These objects can no longer be used as keys of const maps and sets.
    • Migration: Use final (runtime) maps and sets instead of const, or use the string representations (e.g., OS.name, Architecture.name) as keys if const is required.
  • Support custom target OS, architecture, and santizer in protocol extension.

1.2.1

  • Avoid throwing a null-assertion error/exception when input.config.code is accessed but input.config.buildCodeAssets is false. Instead, throw a clear and descriptive StateError.

1.2.0

  • Added an optional sanitizer parameter to CodeConfig and CodeAssetExtension supporting asan, msan, and tsan.

1.1.0

  • Bumped dependency on package:hooks to ^2.0.0 and implemented the new outputFiles protocol extension method to track generated files for cache invalidation, correctly omitting non-local assets like system libraries.

1.0.0

  • Stable release.

0.19.10

  • Document input.packageRoot in more places.
  • Document CodeAsset.id package namespacing.

0.19.9

  • Document that asset file paths must be absolute.

0.19.8

  • Polished README.md, Dartdocs, and examples.

0.19.7

  • Bump examples to use package:ffigen 20.0.0-dev.0.

0.19.6

  • Added a library comment detailing how to use the package.
  • Fixed duplicate asset id detection with assets coming from both build and link hooks.

0.19.5

  • Bump package:hooks to 0.20.0.

0.19.4

  • Add doc comments to all public members.

0.19.3

  • Mark this package as in preview.

0.19.1

  • Bump the SDK constraint to at least the one from package:hooks to fix dartdoc generation on https://pub.dev.

0.19.0

  • Split up package:native_assets_cli in package:hooks, package:code_assets, and package:data_assets.

0.1.0

  • Initial version.

Installing

export PUB_HOSTED_URL=https://pub.mirror.p-hatan.com
flutter pub add code_assets
pubspec.yaml
name: code_assets
description: >-
  This library contains the hook protocol specification for bundling native code
  with Dart packages.

version: 2.1.0

repository: https://github.com/dart-lang/native/tree/main/pkgs/code_assets

topics:
  - assets
  - ffi
  - hooks
  - interop
  - native-assets

resolution: workspace

environment:
  sdk: '>=3.10.0 <4.0.0'

dependencies:
  collection: ^1.19.1
  hooks: ^2.2.0
  logging: ^1.3.0

dev_dependencies:
  dart_flutter_team_lints: ^3.5.2
  json_schema: ^5.2.0 # May only be used in tool/ and test/json_schema/.
  native_test_helpers:
    path: ../native_test_helpers/
  test: ^1.25.15

Version history

VersionPublishedArchiveSHA-256
0.1.0-wip2025-04-01T06:36:09.074999ZCached402ac1c896e2183932ae7562fee2179e09530539e2d8fcf8488377dd9e63a61e
0.19.02025-05-01T07:48:54.186748ZCached2d1f99d221a174275a7992152039264dcb69521bb61fb541544187b0eeeda018
0.19.12025-05-21T14:14:35.176372ZCacheda863a007e22fb4fc09077e5fe83933e125176d641faaa6c3a24a747a3d263f9a
0.19.22025-05-21T16:03:48.341954ZCached052a360e836e657949c3ce98c0744cf32d68ccd634406a35b772828dd5305e56
0.19.32025-05-21T17:44:38.125066ZCachedd1bacf6f0c507acc817e053f8186b79a600eeed78dbd04edcb8c5a8a07a37e1f
0.19.42025-06-12T11:32:11.738051ZCacheddd7ed641b7f642092092969f2dcd5845ab31c9f3efead0c06ca437bf9ce8a8b2
0.19.52025-08-04T11:27:33.764955ZCached7f42899e7b22f7810ea8c2b281c979add25555fbe391dde539621069e20b90b4
0.19.62025-08-27T14:57:14.301202ZCached3b182b03a2f263ad6ab47cdadf9b64daa1d2d72ac941a277f685fb77ba96cbd5
0.19.72025-09-02T18:11:34.541385ZCached5865a34983367f6884e8311f67d9ae459945b99bad20c0e66484a1aae7feaae0
0.19.82025-10-13T07:47:53.647276ZCachedf25d387079d2bfd71341ed2952d107b369bfba49d867d9e29a32101dbd5bdfb2
0.19.92025-10-20T09:36:00.539492ZCached450f46c55509b7215f2b2ead126bad1567a2edf3207ea0eb7a91d3d508cea0f8
0.19.102025-10-27T12:25:33.463120ZCachedae0db647e668cbb295a3527f0938e4039e004c80099dce2f964102373f5ce0b5
1.0.02025-11-07T15:23:12.528866ZCached83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687
1.1.02026-05-18T15:37:07.071983ZCacheddad6bf6b9f4f378b0a69edbf42584d336efd1a9ce15deb1ba591cbb1b5ff440f
1.2.02026-05-27T14:44:06.516402ZCached67cf6d84013f9c601e42a6f8a6b74c4c0d9dc1a1619d775f2b28b732d3551b85
1.2.12026-06-01T07:31:45.772811ZCachedbf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8
2.0.02026-08-18T07:24:51.463053ZCachedcfd4f5f575a49c5f10ca856e9846073f1e6c3ee94912377eea5f6cefc5272941
2.1.02026-09-16T15:33:35.119756ZCached828110d598123b5ea96c00c9f3c72105bf79f8ee36c20a39b26209ade421ec57

Dependencies

collection "^1.19.1"

hooks "^2.2.0"

logging "^1.3.0"