Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ffigen] Add Header Files to CBuilder Sources #2098

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

MiniPiku
Copy link

This pull request fixes an issue where changes to header files (.h) in native asset builds did not invalidate the build cache, causing stale builds with CBuilder. As noted by @dcharkes in #1332, the sources list previously omitted header files, missing their dependency updates. This PR implements Option 1 from the issue: adding .h files to sources to ensure rebuilds occur when headers change. Along with updating the README.md for reflecting the necessary changes made.

Changes Made

  1. Updated Example and Test Projects

    • Modified CBuilder configurations to include .h files in the sources list across multiple projects:
      • pkgs/native_assets_cli/example/build/native_add_library/hook/build.dart:
        • Added 'src/$packageName.h' and 'src/dart_api_dl.h'.
      • pkgs/native_assets_cli/example/build/use_dart_api/hook/build.dart:
        • Added corresponding .h files (e.g., use_dart_api.h, dart_api_dl.h).
  2. Documented CBuilder.sources
    Added documentation to the sources parameter in the CBuilder.library constructor in pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart:

  • Purpose: Guides users to include both .c and .h files, aligning with the new behavior and Clang compatibility notes from the issue.
  1. Updated README
    Added a note to pkgs/native_assets_cli/README.md under "Usage"

- Added .h files to sources list in example/build/native_add_library/hook/build.dart
- Documented sources parameter in CBuilder.library constructor to include .h files
- Added note to native_assets_cli/README.md about including .h files in sources
@MiniPiku
Copy link
Author

The PR resolves the issue: #1332
@dcharkes @HosseinYousefi
kindly review the PR
thank you :)

@MiniPiku MiniPiku changed the title Add Header Files to CBuilder Sources [ffigen]Add Header Files to CBuilder Sources Mar 13, 2025
@MiniPiku MiniPiku changed the title [ffigen]Add Header Files to CBuilder Sources [ffigen] Add Header Files to CBuilder Sources Mar 13, 2025
/// Supported by Clang-like compilers, which can optimize with precompiled
/// headers when `.h` files are included. If a compiler does not support this,
/// the build system may filter `.h` files from the compilation step while
/// still tracking them as dependencies.
super.sources = const [],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the comment should go on the field rather than the constructor argument.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the whole segment be moved or just this portion?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We comment fields not constructor params, so all of it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup done removed that part

@@ -50,6 +50,23 @@ experiment is only available on the master channel.
We do breaking changes regularly! So frequently bump `package:native_assets_cli`
and use dev/master SDK for CI.

**Note:** When configuring `CBuilder` in your `hook/build.dart`,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not have CBuilder documentation here. The native assets cli can be used with other builders. Add the documentation to the CBuilder instead.

/// sources: [
/// 'src/native_add_library.c',
/// 'src/native_add_library.h',
/// 'src/dart_api_dl.c',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Omit dart_api_dl from the documentation, it doesn't add extra info but it does complicate things. That's not great for documentation.

/// 'src/dart_api_dl.h',
/// ],
/// ```
/// Supported by Clang-like compilers, which can optimize with precompiled
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CBuilder should work for all currently supported compilers. If this doesn't work for example for MSVC we need to filter the header files. Please remove this comment and test if it works for Windows.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -43,7 +43,7 @@ assets work on Dart stable, but prefer using the dev releases as we regularly
break things.

To use native assets in Flutter, use
`flutter config --enable-experiment=native-assets` and then
`flutter config --enable-experiment=native-assets` and t
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spurious edit

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my bad

Copy link

PR Health

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

API leaks ✔️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbols
License Headers ✔️
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
Files
no missing headers

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/jni/lib/src/third_party/generated_bindings.dart
pkgs/objective_c/lib/src/ns_input_stream.dart

@MiniPiku
Copy link
Author

MiniPiku commented Mar 16, 2025

@dcharkes just a follow up ,i have fixed the areas of concern
can you kindly take a look and suggest further changes if needed

@dcharkes
Copy link
Collaborator

Please go over all the hook/build.dart files and include .h files were possible:

dacoharkes-macbookpro2:native dacoharkes$ find pkgs/native_assets_cli/ -type f -name "*.h"
pkgs/native_assets_cli//example/build/native_dynamic_linking/src/debug.h
pkgs/native_assets_cli//example/build/native_dynamic_linking/src/add.h
pkgs/native_assets_cli//example/build/native_dynamic_linking/src/math.h
pkgs/native_assets_cli//example/build/download_asset/src/native_add.h
pkgs/native_assets_cli//example/build/native_add_library/src/native_add_library.h
pkgs/native_assets_cli//example/build/use_dart_api/src/dart_api.h
pkgs/native_assets_cli//example/build/use_dart_api/src/dart_version.h
pkgs/native_assets_cli//example/build/use_dart_api/src/dart_embedder_api.h
pkgs/native_assets_cli//example/build/use_dart_api/src/dart_native_api.h
pkgs/native_assets_cli//example/build/use_dart_api/src/internal/dart_api_dl_impl.h
pkgs/native_assets_cli//example/build/use_dart_api/src/use_dart_api.h
pkgs/native_assets_cli//example/build/use_dart_api/src/dart_tools_api.h
pkgs/native_assets_cli//example/build/use_dart_api/src/dart_api_dl.h
dacoharkes-macbookpro2:native dacoharkes$ find pkgs/native_assets_builder/ -type f -name "*.h"
pkgs/native_assets_builder//test_data/native_dynamic_linking/src/debug.h
pkgs/native_assets_builder//test_data/native_dynamic_linking/src/add.h
pkgs/native_assets_builder//test_data/native_dynamic_linking/src/math.h
pkgs/native_assets_builder//test_data/native_subtract/src/native_subtract.h
pkgs/native_assets_builder//test_data/native_add_duplicate/src/native_add.h
pkgs/native_assets_builder//test_data/native_add/src/native_add.h
pkgs/native_assets_builder//test_data/add_asset_link/src/native_add.h
pkgs/native_assets_builder//test_data/drop_dylib_link/src/native_multiply.h
pkgs/native_assets_builder//test_data/drop_dylib_link/src/native_add.h
pkgs/native_assets_builder//test_data/treeshaking_native_libs/src/native_multiply.h
pkgs/native_assets_builder//test_data/treeshaking_native_libs/src/native_add.h
pkgs/native_assets_builder//test_data/native_add_add_source/src/native_multiply.h
pkgs/native_assets_builder//test_data/native_add_add_symbol/src/native_add.h
pkgs/native_assets_builder//test_data/native_add_version_skew/src/native_add.h
dacoharkes-macbookpro2:native dacoharkes$ find pkgs/native_toolchain_c/ -type f -name "*.h"
pkgs/native_toolchain_c//test/cbuilder/testfiles/includes/include/includes.h
pkgs/native_toolchain_c//test/cbuilder/testfiles/dynamically_linked/src/debug.h
pkgs/native_toolchain_c//test/cbuilder/testfiles/dynamically_linked/src/math.h

Also, in many places in the unit tests only the .c files are listed. Please also check there if .h files should be added:

62 results - 32 files

pkgs/native_assets_builder/test/build_runner/build_dependencies_test.dart:
  46            containsAll([
  47:             tempUri.resolve('native_add/src/native_add.c'),
  48:             tempUri.resolve('native_subtract/src/native_subtract.c'),
  49              if (!Platform.isWindows) ...[

pkgs/native_assets_builder/test/build_runner/build_runner_caching_test.dart:
   42            result.dependencies,
   43:           contains(packageUri.resolve('src/native_add.c')),
   44          );

   76            result.dependencies,
   77:           contains(packageUri.resolve('src/native_add.c')),
   78          );

  122  
  123:         final cUri = packageUri.resolve('src/').resolve('native_add.c');
  124          expect(

pkgs/native_assets_builder/test/build_runner/build_runner_failure_test.dart:
  37            result.dependencies,
  38:           contains(packageUri.resolve('src/native_add.c')),
  39          );

  91            result.dependencies,
  92:           contains(packageUri.resolve('src/native_add.c')),
  93          );

pkgs/native_assets_builder/test/build_runner/build_runner_non_root_package_test.dart:
  50            result.dependencies,
  51:           contains(packageUri.resolve('src/native_add.c')),
  52          );

pkgs/native_assets_builder/test/test_data/native_dynamic_linking_test.dart:
  82        expect(dependencies, [
  83:         testPackageUri.resolve('src/debug.c'),
  84:         testPackageUri.resolve('src/math.c'),
  85:         testPackageUri.resolve('src/add.c'),
  86        ]);

pkgs/native_assets_builder/test_data/add_asset_link/hook/build.dart:
  22        sources: [
  23:         'src/native_add.c',
  24        ],

pkgs/native_assets_builder/test_data/drop_dylib_link/hook/build.dart:
  21        sources: [
  22:         'src/native_add.c',
  23        ],

  35        sources: [
  36:         'src/native_multiply.c',
  37        ],

pkgs/native_assets_builder/test_data/native_add/hook/build.dart:
  16        assetName: 'src/${packageName}_bindings_generated.dart',
  17:       sources: ['src/$packageName.c'],
  18      );

pkgs/native_assets_builder/test_data/native_add_add_source/hook/build.dart:
  14        assetName: '${packageName}_bindings_generated.dart',
  15:       sources: ['src/$packageName.c', 'src/native_multiply.c'],
  16      );

pkgs/native_assets_builder/test_data/native_add_duplicate/hook/build.dart:
  16        assetName: 'src/${packageName}_bindings_generated.dart',
  17:       sources: ['src/$duplicatedPackageName.c'],
  18      );

pkgs/native_assets_builder/test_data/native_add_version_skew/hook/build.dart:
  14        assetName: 'src/native_add_bindings_generated.dart',
  15:       sources: ['src/native_add.c'],
  16      );

pkgs/native_assets_builder/test_data/native_add_version_skew_2/hook/build.dart:
  14        assetName: 'src/native_add_bindings_generated.dart',
  15:       sources: ['src/native_add.c'],
  16        dartBuildFiles: [],

pkgs/native_assets_builder/test_data/native_dynamic_linking/hook/build.dart:
  19          assetName: 'debug',
  20:         sources: ['src/debug.c'],
  21          buildMode: BuildMode.debug,

  25          assetName: 'math',
  26:         sources: ['src/math.c'],
  27          libraries: ['debug'],

  32          assetName: 'add.dart',
  33:         sources: ['src/add.c'],
  34          libraries: ['math'],

pkgs/native_assets_builder/test_data/native_subtract/hook/build.dart:
  14        assetName: 'src/${packageName}_bindings_generated.dart',
  15:       sources: ['src/$packageName.c'],
  16      );

pkgs/native_assets_builder/test_data/treeshaking_native_libs/hook/build.dart:
  13        assetName: 'src/${input.packageName}_bindings_generated.dart',
  14:       sources: ['src/native_add.c', 'src/native_multiply.c'],
  15        linkModePreference:

pkgs/native_assets_cli/example/build/download_asset/lib/src/hook_helpers/c_build.dart:
  19      assetName: 'native_add.dart',
  20:     sources: ['src/native_add.c'],
  21    );

pkgs/native_assets_cli/example/build/native_add_library/hook/build.dart:
  14        assetName: '$packageName.dart',
  15:       sources: ['src/$packageName.c'],
  16      );

pkgs/native_assets_cli/example/build/native_dynamic_linking/hook/build.dart:
  19          assetName: 'debug',
  20:         sources: ['src/debug.c'],
  21        ),

  24          assetName: 'math',
  25:         sources: ['src/math.c'],
  26          libraries: ['debug'],

  30          assetName: 'add.dart',
  31:         sources: ['src/add.c'],
  32          libraries: ['math'],

pkgs/native_assets_cli/example/build/use_dart_api/hook/build.dart:
  14        assetName: 'src/${packageName}_bindings_generated.dart',
  15:       sources: ['src/$packageName.c', 'src/dart_api_dl.c'],
  16      );

pkgs/native_assets_cli/lib/src/api/build.dart:
  32  ///       sources: [
  33: ///         'src/$packageName.c',
  34  ///       ],

pkgs/native_assets_cli/lib/src/api/builder.dart:
  36  ///       sources: [
  37: ///         'src/$packageName.c',
  38  ///       ],

pkgs/native_assets_cli/test/example/native_add_library_test.dart:
  85      expect(await assets.allExist(), true);
  86:     expect(dependencies, [testPackageUri.resolve('src/$name.c')]);
  87    });

pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart:
  91      expect(dependencies, [
  92:       testPackageUri.resolve('src/debug.c'),
  93:       testPackageUri.resolve('src/math.c'),
  94:       testPackageUri.resolve('src/add.c'),
  95      ]);

pkgs/native_assets_cli/test/model/dependencies_test.dart:
  26    final dependencies = Dependencies([
  27:     Uri.file('src/bar.c'),
  28:     Uri.file('src/baz.c'),
  29      Uri.directory('src/bla/'),

  38      await dir.create();
  39:     final fileUri = tempUri.resolve('bla.c');
  40      final file = File.fromUri(fileUri);

pkgs/native_toolchain_c/test/cbuilder/cbuilder_build_failure_test.dart:
  19      final addCOriginalUri = packageUri.resolve(
  20:       'test/cbuilder/testfiles/add/src/add.c',
  21      );
  22:     final addCUri = tempUri.resolve('add.c');
  23      final addCOriginalContents =

pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_android_test.dart:
  140  }) async {
  141:   final addCUri = packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
  142    const name = 'add';

pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_ios_test.dart:
   65                    Language.c => packageUri.resolve(
   66:                     'test/cbuilder/testfiles/add/src/add.c',
   67                    ),

  233  ) async {
  234:   final addCUri = packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
  235    const name = 'add';

pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_linux_host_test.dart:
  41          final addCUri = packageUri.resolve(
  42:           'test/cbuilder/testfiles/add/src/add.c',
  43          );

pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_macos_host_test.dart:
   48                Language.c => packageUri.resolve(
   49:                 'test/cbuilder/testfiles/add/src/add.c',
   50                ),

  156  ) async {
  157:   final addCUri = packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
  158    const name = 'add';

pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_windows_host_test.dart:
  83            final addCUri = packageUri.resolve(
  84:             'test/cbuilder/testfiles/add/src/add.c',
  85            );

pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart:
   41          final helloWorldCUri = packageUri.resolve(
   42:           'test/cbuilder/testfiles/hello_world/src/hello_world.c',
   43          );

  126          final addCUri = packageUri.resolve(
  127:           'test/cbuilder/testfiles/add/src/add.c',
  128          );

  230      final definesCUri = packageUri.resolve(
  231:       'test/cbuilder/testfiles/defines/src/defines.c',
  232      );

  297      final includesCUri = packageUri.resolve(
  298:       'test/cbuilder/testfiles/includes/src/includes.c',
  299      );

  349      final tempUri2 = await tempDirForTest();
  350:     final addCUri = packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
  351      const name = 'add';

  562      final dynamicallyLinkedCUri = dynamicallyLinkedSrcUri.resolve(
  563:       'dynamically_linked.c',
  564      );
  565:     final debugCUri = dynamicallyLinkedSrcUri.resolve('debug.c');
  566:     final mathCUri = dynamicallyLinkedSrcUri.resolve('math.c');
  567  

  667    final definesCUri = packageUri.resolve(
  668:     'test/cbuilder/testfiles/defines/src/defines.c',
  669    );

pkgs/native_toolchain_c/test/clinker/build_testfiles.dart:
  16  ) async {
  17:   final test1Uri = packageUri.resolve('test/clinker/testfiles/linker/test1.c');
  18:   final test2Uri = packageUri.resolve('test/clinker/testfiles/linker/test2.c');
  19    if (!await File.fromUri(test1Uri).exists() ||

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants