# Example

A package `my_package` that ships prebuilt `libmy_lib` binaries on GitHub
Releases, can build them from C sources, and tree-shakes them in its link hook.

## `lib/src/hook_helpers/library.dart`

```dart
import 'package:code_assets/code_assets.dart';
import 'package:hooks/hooks.dart';
import 'package:native_toolchain_c/native_toolchain_c.dart';
import 'package:prebuilt_code_assets/prebuilt_code_assets.dart';
import 'package:record_use/record_use.dart' as record_use;

import 'hashes.dart'; // Generated by tool/regenerate_hashes.dart.

const _recordUseMapping = {'myAdd': 'my_add', 'myMultiply': 'my_multiply'};

final myLibrary = PrebuiltLibrary(
  name: 'my_lib',
  assetName: 'my_package.dart',
  releaseConfig: PrebuiltReleaseConfig.github(
    owner: 'my-org',
    repo: 'my_package',
    version: version,
    fileHashes: fileHashes,
    libraryName: 'my_lib',
  ),
  buildFromSource: (input, output, {required static, checkoutPath}) async {
    final builderOutput = BuildOutputBuilder();
    await CBuilder.library(
      name: 'my_lib',
      assetName: 'my_package.dart',
      sources: ['src/my_lib.c'],
      linkModePreference: static
          ? LinkModePreference.static
          : LinkModePreference.dynamic,
    ).run(input: input, output: builderOutput);
    final built = BuildOutput(builderOutput.json);
    output.dependencies.addAll(built.dependencies);
    return built.assets.code.single.file!;
  },
  usedSymbols: SymbolsResolvers.fromRecordUseMapping(
    const record_use.Library('package:my_package/src/bindings.dart'),
    _recordUseMapping,
  ),
);
```

## `hook/build.dart` and `hook/link.dart`

```dart
// hook/build.dart
import 'package:hooks/hooks.dart';
import 'package:my_package/src/hook_helpers/library.dart';

Future<void> main(List<String> args) async {
  await build(args, (input, output) => myLibrary.build(input: input, output: output));
}
```

```dart
// hook/link.dart
import 'package:hooks/hooks.dart';
import 'package:my_package/src/hook_helpers/library.dart';

Future<void> main(List<String> args) async {
  await link(args, (input, output) => myLibrary.link(input: input, output: output));
}
```

## Release tooling

```dart
// tool/precompile_binaries.dart
// dart tool/precompile_binaries.dart --target-os linux --target-arch x64
import 'package:my_package/src/hook_helpers/library.dart';
import 'package:prebuilt_code_assets/tools.dart';

Future<void> main(List<String> args) =>
    runPrecompileBinariesCli(args, library: myLibrary);
```

```dart
// tool/regenerate_hashes.dart
// dart tool/regenerate_hashes.dart <version> [<directory with binaries>]
import 'package:prebuilt_code_assets/prebuilt_code_assets.dart';
import 'package:prebuilt_code_assets/tools.dart';

Future<void> main(List<String> args) => runRegenerateHashesCli(
  args,
  defaultVersion: '1.0.0',
  releaseConfigForVersion: (version) => PrebuiltReleaseConfig.github(
    owner: 'my-org',
    repo: 'my_package',
    version: version,
    fileHashes: const {},
    libraryName: 'my_lib',
  ),
);
```

`test/integration_test.dart` in this repository runs this whole flow end to end.
