From ba01becc4414a09e20de3b341fb729d287b9860b Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Tue, 13 Aug 2024 09:57:53 +0200 Subject: [PATCH 01/14] Add `CBuilder.dynamicallyLinkTo` option --- .github/workflows/native.yaml | 2 +- .../native_dynamic_linking/hook/build.dart | 27 +------- .../example/native_dynamic_linking_test.dart | 3 - .../lib/src/cbuilder/cbuilder.dart | 36 ++++++++++- .../test/cbuilder/cbuilder_test.dart | 63 +++++++++++++++++++ .../test/cbuilder/testfiles/add/src/add.c | 12 +--- .../test/cbuilder/testfiles/add/src/add.h | 13 ++++ .../src/dynamically_linked.c | 5 ++ 8 files changed, 121 insertions(+), 40 deletions(-) create mode 100644 pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.h create mode 100644 pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml index 2aab3d265..3ed905927 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -142,7 +142,7 @@ jobs: - run: dart --enable-experiment=native-assets test working-directory: pkgs/${{ matrix.package }}/example/build/native_dynamic_linking/ - if: ${{ matrix.package == 'native_assets_cli' && matrix.sdk == 'dev' && !matrix.breaking-change && matrix.os != 'windows' }} + if: ${{ matrix.package == 'native_assets_cli' && matrix.sdk == 'dev' && !matrix.breaking-change }} - run: dart --enable-experiment=native-assets test working-directory: pkgs/${{ matrix.package }}/example/build/native_add_app/ diff --git a/pkgs/native_assets_cli/example/build/native_dynamic_linking/hook/build.dart b/pkgs/native_assets_cli/example/build/native_dynamic_linking/hook/build.dart index 88b3d2d12..a396df219 100644 --- a/pkgs/native_assets_cli/example/build/native_dynamic_linking/hook/build.dart +++ b/pkgs/native_assets_cli/example/build/native_dynamic_linking/hook/build.dart @@ -26,9 +26,7 @@ void main(List args) async { sources: [ 'src/math.c', ], - // TODO(https://github.com/dart-lang/native/issues/190): Use specific - // API for linking once available. - flags: config.dynamicLinkingFlags('debug'), + dynamicallyLinkTo: ['debug'], ), CBuilder.library( name: 'add', @@ -36,13 +34,11 @@ void main(List args) async { sources: [ 'src/add.c', ], - // TODO(https://github.com/dart-lang/native/issues/190): Use specific - // API for linking once available. - flags: config.dynamicLinkingFlags('math'), + dynamicallyLinkTo: ['math'], ) ]; - // Note: This builders need to be run sequentially because they depend on + // Note: These builders need to be run sequentially because they depend on // each others output. for (final builder in builders) { await builder.run( @@ -53,20 +49,3 @@ void main(List args) async { } }); } - -extension on BuildConfig { - List dynamicLinkingFlags(String libraryName) => switch (targetOS) { - OS.macOS => [ - '-L${outputDirectory.toFilePath()}', - '-l$libraryName', - ], - OS.linux => [ - '-Wl,-rpath=\$ORIGIN/.', - '-L${outputDirectory.toFilePath()}', - '-l$libraryName', - ], - // TODO(https://github.com/dart-lang/native/issues/1415): Enable support - // for Windows once linker flags are supported by CBuilder. - _ => throw UnimplementedError('Unsupported OS: $targetOS'), - }; -} diff --git a/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart b/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart index a721b058f..e447ad4ca 100644 --- a/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart +++ b/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart @@ -6,9 +6,6 @@ 'mac-os': Timeout.factor(2), 'windows': Timeout.factor(10), }) -// TODO(https://github.com/dart-lang/native/issues/1415): Enable support -// for Windows once linker flags are supported by CBuilder. -@TestOn('!windows') library; import 'dart:convert'; diff --git a/pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart b/pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart index 81d6b8f11..c9568b18e 100644 --- a/pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart +++ b/pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart @@ -47,6 +47,15 @@ class CBuilder extends CTool implements Builder { /// Defaults to `true`. final bool ndebugDefine; + /// Libraries to dynamically link to. + /// + /// The libraries are expected to be at the root of the output directory of + /// the build hook invocation. + /// + /// When using this option ensure that the builders producing the libraries + /// to link to are run before this builder. + final List dynamicallyLinkTo; + CBuilder.library({ required super.name, super.assetName, @@ -63,6 +72,7 @@ class CBuilder extends CTool implements Builder { super.defines = const {}, this.buildModeDefine = true, this.ndebugDefine = true, + this.dynamicallyLinkTo = const [], super.pic = true, super.std, super.language = Language.c, @@ -85,6 +95,7 @@ class CBuilder extends CTool implements Builder { super.defines = const {}, this.buildModeDefine = true, this.ndebugDefine = true, + this.dynamicallyLinkTo = const [], bool? pie = false, super.std, super.language = Language.c, @@ -151,7 +162,10 @@ class CBuilder extends CTool implements Builder { executable: type == OutputType.executable ? exeUri : null, // ignore: invalid_use_of_visible_for_testing_member installName: installName, - flags: flags, + flags: [ + ...flags, + ...config.dynamicLinkingFlags(dynamicallyLinkTo), + ], defines: { ...defines, if (buildModeDefine) config.buildMode.name.toUpperCase(): null, @@ -202,3 +216,23 @@ class CBuilder extends CTool implements Builder { } } } + +extension on BuildConfig { + List dynamicLinkingFlags(List libraries) => + switch (targetOS) { + OS.macOS || OS.iOS => [ + '-L${outputDirectory.toFilePath()}', + for (final library in libraries) '-l$library', + ], + OS.linux || OS.android => [ + '-Wl,-rpath=\$ORIGIN/.', + '-L${outputDirectory.toFilePath()}', + for (final library in libraries) '-l$library', + ], + OS.windows => [ + for (final library in libraries) + outputDirectory.resolve('$library.lib').toFilePath(), + ], + _ => throw UnimplementedError('Unsupported OS: $targetOS'), + }; +} diff --git a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart index 3906383e7..f5332b4d6 100644 --- a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart +++ b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart @@ -554,6 +554,69 @@ void main() { expect(compilerInvocation, contains('-l stdc++')); } }); + + test('CBuilder dynamicallyLinkTo', () async { + final tempUri = await tempDirForTest(); + final dynamicallyLinkedCUri = packageUri.resolve( + 'test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c'); + final addSrcUri = packageUri.resolve('test/cbuilder/testfiles/add/src/'); + final addCUri = addSrcUri.resolve('add.c'); + + if (!await File.fromUri(dynamicallyLinkedCUri).exists()) { + throw Exception('Run the test from the root directory.'); + } + const name = 'dynamically_linked'; + + final logMessages = []; + final logger = createCapturingLogger(logMessages); + + final buildConfig = BuildConfig.build( + outputDirectory: tempUri, + packageName: name, + packageRoot: tempUri, + targetArchitecture: Architecture.current, + targetOS: OS.current, + buildMode: BuildMode.release, + // Ignored by executables. + linkModePreference: LinkModePreference.dynamic, + cCompiler: CCompilerConfig( + compiler: cc, + envScript: envScript, + envScriptArgs: envScriptArgs, + ), + linkingEnabled: false, + ); + final buildOutput = BuildOutput(); + + final builders = [ + CBuilder.library( + name: 'add', + assetName: 'add', + sources: [addCUri.toFilePath()], + ), + CBuilder.executable( + name: name, + includes: [addSrcUri.toFilePath()], + sources: [dynamicallyLinkedCUri.toFilePath()], + dynamicallyLinkTo: ['add'], + ) + ]; + for (final builder in builders) { + await builder.run( + config: buildConfig, + output: buildOutput, + logger: logger, + ); + } + + final executableUri = tempUri.resolve(OS.current.executableFileName(name)); + expect(await File.fromUri(executableUri).exists(), true); + final result = await runProcess( + executable: executableUri, + logger: logger, + ); + expect(result.exitCode, 3); + }); } Future testDefines({ diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.c index 6a16ccab6..dc755d033 100644 --- a/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.c +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.c @@ -2,17 +2,7 @@ // 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. -#include - -#ifdef DEBUG -#include -#endif - -#if _WIN32 -#define FFI_EXPORT __declspec(dllexport) -#else -#define FFI_EXPORT -#endif +#include "add.h" FFI_EXPORT int32_t add(int32_t a, int32_t b) { #ifdef DEBUG diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.h b/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.h new file mode 100644 index 000000000..2fa187184 --- /dev/null +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.h @@ -0,0 +1,13 @@ +// Copyright (c) 2024, 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. + +#include + +#if _WIN32 +#define FFI_EXPORT __declspec(dllexport) +#else +#define FFI_EXPORT +#endif + +FFI_EXPORT int32_t add(int32_t a, int32_t b); diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c new file mode 100644 index 000000000..131f6c870 --- /dev/null +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c @@ -0,0 +1,5 @@ +#include "add.h" + +int main() { + return add(1, 2); +} From f599be379352c38a33805db111198c600a514fc9 Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Tue, 13 Aug 2024 09:59:50 +0200 Subject: [PATCH 02/14] Add file header --- .../testfiles/dynamically_linked/src/dynamically_linked.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c index 131f6c870..57d182bbb 100644 --- a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c @@ -1,3 +1,7 @@ +// Copyright (c) 2024, 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. + #include "add.h" int main() { From 94882a51fdb0737210c76f7f70b9cb6016c0d4c1 Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Fri, 6 Dec 2024 21:36:07 +0100 Subject: [PATCH 03/14] Add `libraries` and `libraryDirectories` to `CTool` --- .../native_dynamic_linking/hook/build.dart | 4 +- .../lib/src/cbuilder/cbuilder.dart | 46 +++------- .../lib/src/cbuilder/clinker.dart | 8 ++ .../lib/src/cbuilder/ctool.dart | 30 ++++++- .../lib/src/cbuilder/run_cbuilder.dart | 31 +++++-- .../test/cbuilder/cbuilder_test.dart | 87 +++++++++++++------ .../test/cbuilder/testfiles/add/src/add.c | 12 ++- .../testfiles/dynamically_linked/src/debug.c | 20 +++++ .../testfiles/dynamically_linked/src/debug.h | 11 +++ .../src/dynamically_linked.c | 4 +- .../testfiles/dynamically_linked/src/math.c | 11 +++ .../add.h => dynamically_linked/src/math.h} | 6 +- 12 files changed, 194 insertions(+), 76 deletions(-) create mode 100644 pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.c create mode 100644 pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.h create mode 100644 pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/math.c rename pkgs/native_toolchain_c/test/cbuilder/testfiles/{add/src/add.h => dynamically_linked/src/math.h} (69%) diff --git a/pkgs/native_assets_cli/example/build/native_dynamic_linking/hook/build.dart b/pkgs/native_assets_cli/example/build/native_dynamic_linking/hook/build.dart index a396df219..0713eab62 100644 --- a/pkgs/native_assets_cli/example/build/native_dynamic_linking/hook/build.dart +++ b/pkgs/native_assets_cli/example/build/native_dynamic_linking/hook/build.dart @@ -26,7 +26,7 @@ void main(List args) async { sources: [ 'src/math.c', ], - dynamicallyLinkTo: ['debug'], + libraries: ['debug'], ), CBuilder.library( name: 'add', @@ -34,7 +34,7 @@ void main(List args) async { sources: [ 'src/add.c', ], - dynamicallyLinkTo: ['math'], + libraries: ['math'], ) ]; diff --git a/pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart b/pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart index c9568b18e..8e99e7ebc 100644 --- a/pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart +++ b/pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart @@ -47,21 +47,14 @@ class CBuilder extends CTool implements Builder { /// Defaults to `true`. final bool ndebugDefine; - /// Libraries to dynamically link to. - /// - /// The libraries are expected to be at the root of the output directory of - /// the build hook invocation. - /// - /// When using this option ensure that the builders producing the libraries - /// to link to are run before this builder. - final List dynamicallyLinkTo; - CBuilder.library({ required super.name, super.assetName, super.sources = const [], super.includes = const [], super.frameworks = CTool.defaultFrameworks, + super.libraries = const [], + super.libraryDirectories = CTool.defaultLibraryDirectories, @Deprecated( 'Newer Dart and Flutter SDKs automatically add the Dart hook ' 'sources as dependencies.', @@ -72,7 +65,6 @@ class CBuilder extends CTool implements Builder { super.defines = const {}, this.buildModeDefine = true, this.ndebugDefine = true, - this.dynamicallyLinkTo = const [], super.pic = true, super.std, super.language = Language.c, @@ -86,6 +78,8 @@ class CBuilder extends CTool implements Builder { super.sources = const [], super.includes = const [], super.frameworks = CTool.defaultFrameworks, + super.libraries = const [], + super.libraryDirectories = CTool.defaultLibraryDirectories, @Deprecated( 'Newer Dart and Flutter SDKs automatically add the Dart hook ' 'sources as dependencies.', @@ -95,7 +89,6 @@ class CBuilder extends CTool implements Builder { super.defines = const {}, this.buildModeDefine = true, this.ndebugDefine = true, - this.dynamicallyLinkTo = const [], bool? pie = false, super.std, super.language = Language.c, @@ -143,6 +136,10 @@ class CBuilder extends CTool implements Builder { // ignore: deprecated_member_use_from_same_package for (final source in this.dartBuildFiles) packageRoot.resolve(source), ]; + final libraryDirectories = [ + for (final directory in this.libraryDirectories) + outDir.resolveUri(Uri.file(directory)), + ]; // ignore: deprecated_member_use if (!config.dryRun) { final task = RunCBuilder( @@ -152,6 +149,8 @@ class CBuilder extends CTool implements Builder { sources: sources, includes: includes, frameworks: frameworks, + libraries: libraries, + libraryDirectories: libraryDirectories, dynamicLibrary: type == OutputType.library && linkMode == DynamicLoadingBundled() ? libUri @@ -162,10 +161,7 @@ class CBuilder extends CTool implements Builder { executable: type == OutputType.executable ? exeUri : null, // ignore: invalid_use_of_visible_for_testing_member installName: installName, - flags: [ - ...flags, - ...config.dynamicLinkingFlags(dynamicallyLinkTo), - ], + flags: flags, defines: { ...defines, if (buildModeDefine) config.buildMode.name.toUpperCase(): null, @@ -216,23 +212,3 @@ class CBuilder extends CTool implements Builder { } } } - -extension on BuildConfig { - List dynamicLinkingFlags(List libraries) => - switch (targetOS) { - OS.macOS || OS.iOS => [ - '-L${outputDirectory.toFilePath()}', - for (final library in libraries) '-l$library', - ], - OS.linux || OS.android => [ - '-Wl,-rpath=\$ORIGIN/.', - '-L${outputDirectory.toFilePath()}', - for (final library in libraries) '-l$library', - ], - OS.windows => [ - for (final library in libraries) - outputDirectory.resolve('$library.lib').toFilePath(), - ], - _ => throw UnimplementedError('Unsupported OS: $targetOS'), - }; -} diff --git a/pkgs/native_toolchain_c/lib/src/cbuilder/clinker.dart b/pkgs/native_toolchain_c/lib/src/cbuilder/clinker.dart index b79174967..aa804863e 100644 --- a/pkgs/native_toolchain_c/lib/src/cbuilder/clinker.dart +++ b/pkgs/native_toolchain_c/lib/src/cbuilder/clinker.dart @@ -29,6 +29,8 @@ class CLinker extends CTool implements Linker { super.sources = const [], super.includes = const [], super.frameworks = CTool.defaultFrameworks, + super.libraries = const [], + super.libraryDirectories = CTool.defaultLibraryDirectories, @visibleForTesting super.installName, super.flags = const [], super.defines = const {}, @@ -68,6 +70,10 @@ class CLinker extends CTool implements Linker { for (final directory in this.includes) packageRoot.resolveUri(Uri.file(directory)), ]; + final libraryDirectories = [ + for (final directory in this.libraryDirectories) + outDir.resolveUri(Uri.file(directory)), + ]; final task = RunCBuilder( config: config, codeConfig: config.codeConfig, @@ -76,6 +82,8 @@ class CLinker extends CTool implements Linker { sources: sources, includes: includes, frameworks: frameworks, + libraries: libraries, + libraryDirectories: libraryDirectories, dynamicLibrary: linkMode == DynamicLoadingBundled() ? libUri : null, staticLibrary: linkMode == StaticLinking() ? libUri : null, // ignore: invalid_use_of_visible_for_testing_member diff --git a/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart b/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart index 1a977e106..8eee41004 100644 --- a/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart +++ b/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart @@ -6,6 +6,7 @@ import 'package:meta/meta.dart'; import 'package:native_assets_cli/code_assets.dart'; import 'cbuilder.dart'; +import 'clinker.dart'; import 'language.dart'; import 'optimization_level.dart'; import 'output_type.dart'; @@ -14,7 +15,7 @@ abstract class CTool { /// What kind of artifact to build. final OutputType type; - /// Name of the library or executable to linkg. + /// Name of the library or executable to build. /// /// The filename will be decided by [LinkConfig.targetOS] and /// [OSLibraryNaming.libraryFileName] or @@ -50,7 +51,7 @@ abstract class CTool { /// /// Defaults to `['Foundation']`. /// - /// Framworks will not be automatically reported as dependencies of the hook. + /// Frameworks will not be automatically reported as dependencies of the hook. /// Frameworks can be mentioned by name if they are available on the system, /// so the file path is not known. If you're depending on your own frameworks /// report them as dependencies of the hook by calling @@ -58,8 +59,31 @@ abstract class CTool { /// manually. final List frameworks; + /// The default [frameworks]. static const List defaultFrameworks = ['Foundation']; + /// Libraries to link to. + /// + /// In addition to the system default directories, libraries will be searched + /// for in [libraryDirectories]. + /// + /// If you want to link to a library that was built by another [CBuilder] or + /// [CLinker], either leave the default [libraryDirectories] or include `'.'` + /// in the list. + final List libraries; + + /// Directories to search for [libraries], in addition to the system default + /// directories. + /// + /// Resolved against [LinkConfig.outputDirectory]. + /// + /// Defaults to `['.']`, which means the [LinkConfig.outputDirectory] will be + /// searched for libraries. + final List libraryDirectories; + + /// The default [libraryDirectories]. + static const List defaultLibraryDirectories = ['.']; + /// TODO(https://github.com/dart-lang/native/issues/54): Move to [LinkConfig] /// or hide in public API. @visibleForTesting @@ -130,6 +154,8 @@ abstract class CTool { required this.sources, required this.includes, required this.frameworks, + required this.libraries, + required this.libraryDirectories, required this.installName, required this.flags, required this.defines, diff --git a/pkgs/native_toolchain_c/lib/src/cbuilder/run_cbuilder.dart b/pkgs/native_toolchain_c/lib/src/cbuilder/run_cbuilder.dart index 8342f109c..a4b8197c1 100644 --- a/pkgs/native_toolchain_c/lib/src/cbuilder/run_cbuilder.dart +++ b/pkgs/native_toolchain_c/lib/src/cbuilder/run_cbuilder.dart @@ -28,6 +28,8 @@ class RunCBuilder { final List sources; final List includes; final List frameworks; + final List libraries; + final List libraryDirectories; final Uri? executable; final Uri? dynamicLibrary; final Uri? staticLibrary; @@ -56,6 +58,8 @@ class RunCBuilder { this.sources = const [], this.includes = const [], required this.frameworks, + this.libraries = const [], + this.libraryDirectories = const [], this.executable, this.dynamicLibrary, this.staticLibrary, @@ -298,8 +302,7 @@ class RunCBuilder { if (executable != null) ...[ '-o', outDir.resolveUri(executable!).toFilePath(), - ], - if (dynamicLibrary != null) ...[ + ] else if (dynamicLibrary != null) ...[ '--shared', '-o', outFile!.toFilePath(), @@ -310,6 +313,19 @@ class RunCBuilder { ], ...linkerOptions?.postSourcesFlags(toolInstance.tool, sourceFiles) ?? [], + if (executable != null || dynamicLibrary != null) ...[ + if (config.targetOS case OS.android || OS.linux) + // During bundling code assets are all placed in the same directory. + // Setting this rpath allows the binary to find other code assets + // it is linked against. + if (linkerOptions != null) + '-rpath=\$ORIGIN' + else + '-Wl,-rpath=\$ORIGIN', + for (final directory in libraryDirectories) + '-L${directory.toFilePath()}', + for (final library in libraries) '-l$library', + ], ], logger: logger, captureOutput: false, @@ -344,17 +360,20 @@ class RunCBuilder { ...sources.map((e) => e.toFilePath()), '/link', '/out:${outDir.resolveUri(executable!).toFilePath()}', - ], - if (dynamicLibrary != null) ...[ + ] else if (dynamicLibrary != null) ...[ ...sources.map((e) => e.toFilePath()), '/link', '/DLL', '/out:${outDir.resolveUri(dynamicLibrary!).toFilePath()}', - ], - if (staticLibrary != null) ...[ + ] else if (staticLibrary != null) ...[ '/c', ...sources.map((e) => e.toFilePath()), ], + if (executable != null || dynamicLibrary != null) ...[ + for (final directory in libraryDirectories) + '/LIBPATH:${directory.toFilePath()}', + for (final library in libraries) '$library.lib', + ], ], workingDirectory: outDir, environment: environment, diff --git a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart index f5332b4d6..3ff8eb9da 100644 --- a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart +++ b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart @@ -555,12 +555,16 @@ void main() { } }); - test('CBuilder dynamicallyLinkTo', () async { + test('CBuilder libraries and libraryDirectories', () async { final tempUri = await tempDirForTest(); - final dynamicallyLinkedCUri = packageUri.resolve( - 'test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c'); - final addSrcUri = packageUri.resolve('test/cbuilder/testfiles/add/src/'); - final addCUri = addSrcUri.resolve('add.c'); + final tempUri2 = await tempDirForTest(); + + final dynamicallyLinkedSrcUri = + packageUri.resolve('test/cbuilder/testfiles/dynamically_linked/src/'); + final dynamicallyLinkedCUri = + dynamicallyLinkedSrcUri.resolve('dynamically_linked.c'); + final debugCUri = dynamicallyLinkedSrcUri.resolve('debug.c'); + final mathCUri = dynamicallyLinkedSrcUri.resolve('math.c'); if (!await File.fromUri(dynamicallyLinkedCUri).exists()) { throw Exception('Run the test from the root directory.'); @@ -570,35 +574,66 @@ void main() { final logMessages = []; final logger = createCapturingLogger(logMessages); - final buildConfig = BuildConfig.build( + final buildConfigBuilder = BuildConfigBuilder() + ..setupHookConfig( + buildAssetTypes: [CodeAsset.type], + packageName: name, + packageRoot: tempUri, + targetOS: OS.current, + buildMode: BuildMode.release, + ) + ..setupBuildConfig( + linkingEnabled: false, + dryRun: false, + ) + ..setupCodeConfig( + targetArchitecture: Architecture.current, + // Ignored by executables. + linkModePreference: LinkModePreference.dynamic, + cCompilerConfig: cCompiler, + ); + buildConfigBuilder.setupBuildRunConfig( outputDirectory: tempUri, - packageName: name, - packageRoot: tempUri, - targetArchitecture: Architecture.current, - targetOS: OS.current, - buildMode: BuildMode.release, - // Ignored by executables. - linkModePreference: LinkModePreference.dynamic, - cCompiler: CCompilerConfig( - compiler: cc, - envScript: envScript, - envScriptArgs: envScriptArgs, - ), - linkingEnabled: false, + outputDirectoryShared: tempUri2, ); - final buildOutput = BuildOutput(); + final buildConfig = BuildConfig(buildConfigBuilder.json); + final buildOutput = BuildOutputBuilder(); + + final debugBuilder = CBuilder.library( + name: 'debug', + assetName: 'debug', + includes: [dynamicallyLinkedSrcUri.toFilePath()], + sources: [debugCUri.toFilePath()], + ); + + await debugBuilder.run( + config: buildConfig, + output: buildOutput, + logger: logger, + ); + + final debugLibraryFile = + File.fromUri(tempUri.resolve(OS.current.dylibFileName('debug'))); + final nestedDebugLibraryFile = File.fromUri( + tempUri.resolve('debug/').resolve(OS.current.dylibFileName('debug')), + ); + await nestedDebugLibraryFile.parent.create(recursive: true); + await debugLibraryFile.rename(nestedDebugLibraryFile.path); final builders = [ CBuilder.library( - name: 'add', - assetName: 'add', - sources: [addCUri.toFilePath()], + name: 'math', + assetName: 'math', + includes: [dynamicallyLinkedSrcUri.toFilePath()], + sources: [mathCUri.toFilePath()], + libraries: ['debug'], + libraryDirectories: ['debug'], ), CBuilder.executable( name: name, - includes: [addSrcUri.toFilePath()], + includes: [dynamicallyLinkedSrcUri.toFilePath()], sources: [dynamicallyLinkedCUri.toFilePath()], - dynamicallyLinkTo: ['add'], + libraries: ['math'], ) ]; for (final builder in builders) { @@ -609,6 +644,8 @@ void main() { ); } + await nestedDebugLibraryFile.rename(debugLibraryFile.path); + final executableUri = tempUri.resolve(OS.current.executableFileName(name)); expect(await File.fromUri(executableUri).exists(), true); final result = await runProcess( diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.c index dc755d033..6a16ccab6 100644 --- a/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.c +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.c @@ -2,7 +2,17 @@ // 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. -#include "add.h" +#include + +#ifdef DEBUG +#include +#endif + +#if _WIN32 +#define FFI_EXPORT __declspec(dllexport) +#else +#define FFI_EXPORT +#endif FFI_EXPORT int32_t add(int32_t a, int32_t b) { #ifdef DEBUG diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.c new file mode 100644 index 000000000..92e42f1d2 --- /dev/null +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.c @@ -0,0 +1,20 @@ +// Copyright (c) 2024, 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. + +#include "debug.h" + +#ifdef DEBUG +#include +#include +#endif + +int debug_printf(const char* format, ...) { +#ifdef DEBUG + va_list args; + va_start(args, format); + int ret = vprintf(format, args); + va_end(args); + return ret; +#endif +} diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.h b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.h new file mode 100644 index 000000000..557cba0d1 --- /dev/null +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.h @@ -0,0 +1,11 @@ +// Copyright (c) 2024, 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. + +#if _WIN32 +#define MYLIB_EXPORT __declspec(dllexport) +#else +#define MYLIB_EXPORT +#endif + +MYLIB_EXPORT int debug_printf(const char * format, ...); diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c index 57d182bbb..b2d259261 100644 --- a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c @@ -2,8 +2,8 @@ // 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. -#include "add.h" +#include "math.h" int main() { - return add(1, 2); + return math_add(1, 2); } diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/math.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/math.c new file mode 100644 index 000000000..08313a5bb --- /dev/null +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/math.c @@ -0,0 +1,11 @@ +// Copyright (c) 2024, 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. + +#include "debug.h" +#include "math.h" + +int32_t math_add(int32_t a, int32_t b) { + debug_printf("Adding %i and %i.\n", a, b); + return a + b; +} diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.h b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/math.h similarity index 69% rename from pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.h rename to pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/math.h index 2fa187184..7d22a65c8 100644 --- a/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.h +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/math.h @@ -5,9 +5,9 @@ #include #if _WIN32 -#define FFI_EXPORT __declspec(dllexport) +#define MYLIB_EXPORT __declspec(dllexport) #else -#define FFI_EXPORT +#define MYLIB_EXPORT #endif -FFI_EXPORT int32_t add(int32_t a, int32_t b); +MYLIB_EXPORT int32_t math_add(int32_t a, int32_t b); From 25712657307dc305827d1c68fa54df225305292c Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Sun, 8 Dec 2024 14:48:14 +0100 Subject: [PATCH 04/14] Update changelog --- pkgs/native_toolchain_c/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/native_toolchain_c/CHANGELOG.md b/pkgs/native_toolchain_c/CHANGELOG.md index d0edf147c..0d1a8e172 100644 --- a/pkgs/native_toolchain_c/CHANGELOG.md +++ b/pkgs/native_toolchain_c/CHANGELOG.md @@ -4,6 +4,7 @@ https://github.com/dart-lang/native/issues/1611 - Make optimization level configurable. Defaults to `-3s` and `/O3`. https://github.com/dart-lang/native/issues/1267 +- Add `libraries` and `libraryDirectories` to `CTool`. ## 0.6.0 From 1676912c76c334447a6e576db795472e28a7ba85 Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Mon, 9 Dec 2024 07:27:25 +0100 Subject: [PATCH 05/14] Update `native_dynamic_linking` test data --- .../native_dynamic_linking/hook/build.dart | 28 ++----------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/pkgs/native_assets_builder/test_data/native_dynamic_linking/hook/build.dart b/pkgs/native_assets_builder/test_data/native_dynamic_linking/hook/build.dart index 79b97a40e..0713eab62 100644 --- a/pkgs/native_assets_builder/test_data/native_dynamic_linking/hook/build.dart +++ b/pkgs/native_assets_builder/test_data/native_dynamic_linking/hook/build.dart @@ -26,9 +26,7 @@ void main(List args) async { sources: [ 'src/math.c', ], - // TODO(https://github.com/dart-lang/native/issues/190): Use specific - // API for linking once available. - flags: config.dynamicLinkingFlags('debug'), + libraries: ['debug'], ), CBuilder.library( name: 'add', @@ -36,13 +34,11 @@ void main(List args) async { sources: [ 'src/add.c', ], - // TODO(https://github.com/dart-lang/native/issues/190): Use specific - // API for linking once available. - flags: config.dynamicLinkingFlags('math'), + libraries: ['math'], ) ]; - // Note: This builders need to be run sequentially because they depend on + // Note: These builders need to be run sequentially because they depend on // each others output. for (final builder in builders) { await builder.run( @@ -53,21 +49,3 @@ void main(List args) async { } }); } - -extension on BuildConfig { - List dynamicLinkingFlags(String libraryName) => switch (targetOS) { - OS.macOS => [ - '-L${outputDirectory.toFilePath()}', - '-l$libraryName', - ], - OS.linux => [ - r'-Wl,-rpath=$ORIGIN', - '-L${outputDirectory.toFilePath()}', - '-l$libraryName', - ], - OS.windows => [ - outputDirectory.resolve('$libraryName.lib').toFilePath(), - ], - _ => throw UnimplementedError('Unsupported OS: $targetOS'), - }; -} From 0937ee8eb55e56891b47d0bf708b41e182ccd24f Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Mon, 9 Dec 2024 18:29:37 +0100 Subject: [PATCH 06/14] Fix formatting of ctool.dart --- pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart b/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart index 8eee41004..15d8e3e39 100644 --- a/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart +++ b/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart @@ -63,20 +63,20 @@ abstract class CTool { static const List defaultFrameworks = ['Foundation']; /// Libraries to link to. - /// + /// /// In addition to the system default directories, libraries will be searched /// for in [libraryDirectories]. - /// - /// If you want to link to a library that was built by another [CBuilder] or + /// + /// If you want to link to a library that was built by another [CBuilder] or /// [CLinker], either leave the default [libraryDirectories] or include `'.'` /// in the list. final List libraries; /// Directories to search for [libraries], in addition to the system default /// directories. - /// + /// /// Resolved against [LinkConfig.outputDirectory]. - /// + /// /// Defaults to `['.']`, which means the [LinkConfig.outputDirectory] will be /// searched for libraries. final List libraryDirectories; From a579d3eee906912a427b34ab156e2b6180632bcf Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Mon, 9 Dec 2024 18:30:03 +0100 Subject: [PATCH 07/14] Reformat native_dynamic_linking_test.dart a bit --- .../example/native_dynamic_linking_test.dart | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart b/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart index e447ad4ca..87f9fb08e 100644 --- a/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart +++ b/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart @@ -48,19 +48,22 @@ void main() async { final configBuilder = BuildConfigBuilder() ..setupHookConfig( - packageRoot: testPackageUri, - packageName: name, - targetOS: OS.current, - buildAssetTypes: [CodeAsset.type], - buildMode: dryRun ? null : BuildMode.debug) + packageRoot: testPackageUri, + packageName: name, + targetOS: OS.current, + buildAssetTypes: [CodeAsset.type], + buildMode: dryRun ? null : BuildMode.debug, + ) ..setupBuildRunConfig( - outputDirectory: outputDirectory, - outputDirectoryShared: outputDirectoryShared) + outputDirectory: outputDirectory, + outputDirectoryShared: outputDirectoryShared, + ) ..setupBuildConfig(linkingEnabled: false, dryRun: dryRun) ..setupCodeConfig( - targetArchitecture: dryRun ? null : Architecture.current, - linkModePreference: LinkModePreference.dynamic, - cCompilerConfig: dryRun ? null : cCompiler); + targetArchitecture: dryRun ? null : Architecture.current, + linkModePreference: LinkModePreference.dynamic, + cCompilerConfig: dryRun ? null : cCompiler, + ); final buildConfigUri = testTempUri.resolve('build_config.json'); await File.fromUri(buildConfigUri) From 6b0b2c5d55cd82563f7c4e5180ce5b954b10af53 Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Mon, 9 Dec 2024 18:30:28 +0100 Subject: [PATCH 08/14] Run native_dynamic_linking_test.dart on windows --- .../test/example/native_dynamic_linking_test.dart | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart b/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart index 87f9fb08e..18418f103 100644 --- a/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart +++ b/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart @@ -17,12 +17,6 @@ import 'package:test/test.dart'; import '../helpers.dart'; void main() async { - if (Platform.isWindows) { - // TODO(https://github.com/dart-lang/native/issues/1415): Enable support - // for Windows once linker flags are supported by CBuilder. - return; - } - late Uri tempUri; const name = 'native_dynamic_linking'; From 8f8c84acc74d79f9c296067468eec117ac123a33 Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Mon, 9 Dec 2024 18:46:46 +0100 Subject: [PATCH 09/14] Fix doc comment --- pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart b/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart index 15d8e3e39..13e9ff0ad 100644 --- a/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart +++ b/pkgs/native_toolchain_c/lib/src/cbuilder/ctool.dart @@ -11,11 +11,12 @@ import 'language.dart'; import 'optimization_level.dart'; import 'output_type.dart'; +/// Common options for [CBuilder] and [CLinker]. abstract class CTool { /// What kind of artifact to build. final OutputType type; - /// Name of the library or executable to build. + /// Name of the library or executable to build or link. /// /// The filename will be decided by [LinkConfig.targetOS] and /// [OSLibraryNaming.libraryFileName] or From d2e13b3a10757a6683bf9fa26fdf66e75e4c87c5 Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Mon, 9 Dec 2024 18:51:40 +0100 Subject: [PATCH 10/14] Return wether comparison was successful --- pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart | 2 +- .../testfiles/dynamically_linked/src/dynamically_linked.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart index 3ff8eb9da..064364b87 100644 --- a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart +++ b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart @@ -652,7 +652,7 @@ void main() { executable: executableUri, logger: logger, ); - expect(result.exitCode, 3); + expect(result.exitCode, 0); }); } diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c index b2d259261..c8cc6d94b 100644 --- a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/dynamically_linked.c @@ -5,5 +5,5 @@ #include "math.h" int main() { - return math_add(1, 2); + return math_add(1, 2) == 3 ? 0 : 1; } From 074d465d4a2572c283c09d24b43fd0eaab988d90 Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Mon, 9 Dec 2024 19:07:46 +0100 Subject: [PATCH 11/14] Fix debug_printf in production mode --- .../test_data/native_dynamic_linking/src/debug.c | 2 ++ .../example/build/native_dynamic_linking/src/debug.c | 2 ++ .../test/cbuilder/testfiles/dynamically_linked/src/debug.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/pkgs/native_assets_builder/test_data/native_dynamic_linking/src/debug.c b/pkgs/native_assets_builder/test_data/native_dynamic_linking/src/debug.c index 92e42f1d2..b840d62a5 100644 --- a/pkgs/native_assets_builder/test_data/native_dynamic_linking/src/debug.c +++ b/pkgs/native_assets_builder/test_data/native_dynamic_linking/src/debug.c @@ -16,5 +16,7 @@ int debug_printf(const char* format, ...) { int ret = vprintf(format, args); va_end(args); return ret; +#else + return 0; #endif } diff --git a/pkgs/native_assets_cli/example/build/native_dynamic_linking/src/debug.c b/pkgs/native_assets_cli/example/build/native_dynamic_linking/src/debug.c index 92e42f1d2..b840d62a5 100644 --- a/pkgs/native_assets_cli/example/build/native_dynamic_linking/src/debug.c +++ b/pkgs/native_assets_cli/example/build/native_dynamic_linking/src/debug.c @@ -16,5 +16,7 @@ int debug_printf(const char* format, ...) { int ret = vprintf(format, args); va_end(args); return ret; +#else + return 0; #endif } diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.c index 92e42f1d2..b840d62a5 100644 --- a/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.c +++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/dynamically_linked/src/debug.c @@ -16,5 +16,7 @@ int debug_printf(const char* format, ...) { int ret = vprintf(format, args); va_end(args); return ret; +#else + return 0; #endif } From 6e5d7a75074f08694234261c04863eb465f3293e Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Mon, 9 Dec 2024 21:28:18 +0100 Subject: [PATCH 12/14] Make `CBuilder` test pass on linux --- .../test/cbuilder/cbuilder_test.dart | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart index 064364b87..d076c7fd9 100644 --- a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart +++ b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart @@ -620,32 +620,36 @@ void main() { await nestedDebugLibraryFile.parent.create(recursive: true); await debugLibraryFile.rename(nestedDebugLibraryFile.path); - final builders = [ - CBuilder.library( - name: 'math', - assetName: 'math', - includes: [dynamicallyLinkedSrcUri.toFilePath()], - sources: [mathCUri.toFilePath()], - libraries: ['debug'], - libraryDirectories: ['debug'], - ), - CBuilder.executable( - name: name, - includes: [dynamicallyLinkedSrcUri.toFilePath()], - sources: [dynamicallyLinkedCUri.toFilePath()], - libraries: ['math'], - ) - ]; - for (final builder in builders) { - await builder.run( - config: buildConfig, - output: buildOutput, - logger: logger, - ); - } + final mathBuilder = CBuilder.library( + name: 'math', + assetName: 'math', + includes: [dynamicallyLinkedSrcUri.toFilePath()], + sources: [mathCUri.toFilePath()], + libraries: ['debug'], + libraryDirectories: ['debug'], + ); + + await mathBuilder.run( + config: buildConfig, + output: buildOutput, + logger: logger, + ); await nestedDebugLibraryFile.rename(debugLibraryFile.path); + final executableBuilder = CBuilder.executable( + name: name, + includes: [dynamicallyLinkedSrcUri.toFilePath()], + sources: [dynamicallyLinkedCUri.toFilePath()], + libraries: ['math'], + ); + + await executableBuilder.run( + config: buildConfig, + output: buildOutput, + logger: logger, + ); + final executableUri = tempUri.resolve(OS.current.executableFileName(name)); expect(await File.fromUri(executableUri).exists(), true); final result = await runProcess( From 7e93fc5c71fe90a9765a32190feb6adacf00f42c Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Mon, 9 Dec 2024 21:28:38 +0100 Subject: [PATCH 13/14] Skip native_dynamic_linking_test.dart on Windows --- .../test/example/native_dynamic_linking_test.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart b/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart index 18418f103..4fb7c956b 100644 --- a/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart +++ b/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart @@ -6,6 +6,10 @@ 'mac-os': Timeout.factor(2), 'windows': Timeout.factor(10), }) +// TODO(https://github.com/dart-lang/native/issues/190): Enable once +// https://github.com/dart-lang/sdk/commit/903eea6bfb8ee405587f0866a1d1e92eea45d29e +// has landed in dev channel. +@TestOn('!windows') library; import 'dart:convert'; From d6c129eab9ff82551872ffdfe4aac5ecac62a5d2 Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Mon, 9 Dec 2024 21:47:11 +0100 Subject: [PATCH 14/14] Disable `dart test` in `example/build/native_dynamic_linking` on windows --- .github/workflows/native.yaml | 5 ++++- .../test/example/native_dynamic_linking_test.dart | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml index 3ed905927..84ea83274 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -142,7 +142,10 @@ jobs: - run: dart --enable-experiment=native-assets test working-directory: pkgs/${{ matrix.package }}/example/build/native_dynamic_linking/ - if: ${{ matrix.package == 'native_assets_cli' && matrix.sdk == 'dev' && !matrix.breaking-change }} + # TODO(https://github.com/dart-lang/native/issues/190): Enable on windows once + # https://github.com/dart-lang/sdk/commit/903eea6bfb8ee405587f0866a1d1e92eea45d29e + # has landed in dev channel. + if: ${{ matrix.package == 'native_assets_cli' && matrix.sdk == 'dev' && !matrix.breaking-change && matrix.os != 'windows' }} - run: dart --enable-experiment=native-assets test working-directory: pkgs/${{ matrix.package }}/example/build/native_add_app/ diff --git a/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart b/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart index 4fb7c956b..b70e28274 100644 --- a/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart +++ b/pkgs/native_assets_cli/test/example/native_dynamic_linking_test.dart @@ -6,7 +6,7 @@ 'mac-os': Timeout.factor(2), 'windows': Timeout.factor(10), }) -// TODO(https://github.com/dart-lang/native/issues/190): Enable once +// TODO(https://github.com/dart-lang/native/issues/190): Enable on windows once // https://github.com/dart-lang/sdk/commit/903eea6bfb8ee405587f0866a1d1e92eea45d29e // has landed in dev channel. @TestOn('!windows')