Skip to content
Open
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
4 changes: 4 additions & 0 deletions pkgs/native_toolchain_c/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
an optional parameter on `CBuilder.run`, `CLinker.run`, `CLibrary.build`, and
`CLibrary.link` (defaulting to `LocalProcessManager`), so process invocations
can be mocked in tests. ([#3072](https://github.com/dart-lang/native/issues/3072))
- Access all file system state through a `package:file` `FileSystem`, exposed as
an optional parameter on `CBuilder.run`, `CLinker.run`, `CLibrary.build`, and
`CLibrary.link` (defaulting to `LocalFileSystem`), so file system access can be
mocked in tests. ([#3072](https://github.com/dart-lang/native/issues/3072))

## 0.19.3

Expand Down
15 changes: 11 additions & 4 deletions pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
// 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.

import 'dart:io';

import 'package:code_assets/code_assets.dart';
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:hooks/hooks.dart';
import 'package:logging/logging.dart';
import 'package:meta/meta.dart';
Expand Down Expand Up @@ -133,6 +133,9 @@ class CBuilder extends CTool implements Builder {
/// If provided, uses [processManager] to spawn processes. Otherwise, uses a
/// [LocalProcessManager] that spawns real processes.
///
/// If provided, uses [fileSystem] to access the file system. Otherwise, uses
/// a [LocalFileSystem] that accesses the real file system.
///
/// If you're using [CBuilder] in a build hook and [CLinker] in a link hook,
/// see [CLibrary] to combine them.
@override
Expand All @@ -141,12 +144,14 @@ class CBuilder extends CTool implements Builder {
required BuildOutputBuilder output,
Logger? logger,
ProcessManager? processManager,
FileSystem? fileSystem,
List<AssetRouting> routing = const [ToAppBundle()],
LinkModePreference? linkModePreference,
Map<String, String?>? defines,
}) async {
logger ??= createDefaultLogger();
processManager ??= const LocalProcessManager();
fileSystem ??= const LocalFileSystem();
if (!input.config.buildCodeAssets) {
logger.info(
'config.buildAssetTypes did not contain CodeAssets, '
Expand All @@ -161,7 +166,7 @@ class CBuilder extends CTool implements Builder {
);
final outDir = input.outputDirectory;
final packageRoot = input.packageRoot;
await Directory.fromUri(outDir).create(recursive: true);
await fileSystem.directory(outDir).create(recursive: true);
final linkMode = getLinkMode(
linkModePreference ??
this.linkModePreference ??
Expand Down Expand Up @@ -199,6 +204,7 @@ class CBuilder extends CTool implements Builder {
codeConfig: input.config.code,
logger: logger,
processManager: processManager,
fileSystem: fileSystem,
sources: sources,
includes: includes,
forcedIncludes: forcedIncludes,
Expand Down Expand Up @@ -246,7 +252,8 @@ class CBuilder extends CTool implements Builder {

final includeFiles = await Stream.fromIterable(includes)
.asyncExpand(
(include) => Directory(include.toFilePath())
(include) => fileSystem!
.directory(include.toFilePath())
.list(recursive: true)
.where((entry) => entry is File)
.map((file) => file.uri),
Expand Down
12 changes: 12 additions & 0 deletions pkgs/native_toolchain_c/lib/src/cbuilder/clibrary.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.

import 'package:code_assets/code_assets.dart';
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:hooks/hooks.dart';
import 'package:logging/logging.dart';
import 'package:process/process.dart';
Expand Down Expand Up @@ -166,11 +168,15 @@ class CLibrary {
///
/// If provided, uses [processManager] to spawn processes. Otherwise, uses a
/// [LocalProcessManager] that spawns real processes.
///
/// If provided, uses [fileSystem] to access the file system. Otherwise, uses
/// a [LocalFileSystem] that accesses the real file system.
Future<void> build({
required BuildInput input,
required BuildOutputBuilder output,
Logger? logger,
ProcessManager? processManager,
FileSystem? fileSystem,
List<AssetRouting>? routing,
LinkModePreference? linkModePreference,
Map<String, String?>? defines,
Expand Down Expand Up @@ -202,6 +208,7 @@ class CLibrary {
output: output,
logger: logger,
processManager: processManager,
fileSystem: fileSystem,
routing:
routing ??
(input.config.linkingEnabled
Expand Down Expand Up @@ -239,11 +246,15 @@ class CLibrary {
///
/// If provided, uses [processManager] to spawn processes. Otherwise, uses a
/// [LocalProcessManager] that spawns real processes.
///
/// If provided, uses [fileSystem] to access the file system. Otherwise, uses
/// a [LocalFileSystem] that accesses the real file system.
Future<void> link({
required LinkInput input,
required LinkOutputBuilder output,
Logger? logger,
ProcessManager? processManager,
FileSystem? fileSystem,
LinkerOptions? linkerOptions,
LinkModePreference? linkModePreference,
Map<String, String?>? defines,
Expand All @@ -258,6 +269,7 @@ class CLibrary {
output: output,
logger: logger,
processManager: processManager,
fileSystem: fileSystem,
linkerOptions: linkerOptions,
linkModePreference: linkModePreference,
sources: assets.map((a) => a.file!.toFilePath()).toList(),
Expand Down
15 changes: 11 additions & 4 deletions pkgs/native_toolchain_c/lib/src/cbuilder/clinker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
// 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.

import 'dart:io';

import 'package:code_assets/code_assets.dart';
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:hooks/hooks.dart';
import 'package:logging/logging.dart';
import 'package:meta/meta.dart';
Expand Down Expand Up @@ -67,6 +67,9 @@ class CLinker extends CTool implements Linker {
/// If provided, uses [processManager] to spawn processes. Otherwise, uses a
/// [LocalProcessManager] that spawns real processes.
///
/// If provided, uses [fileSystem] to access the file system. Otherwise, uses
/// a [LocalFileSystem] that accesses the real file system.
///
/// If you're using [CBuilder] in a build hook and [CLinker] in a link hook,
/// see [CLibrary] to combine them.
@override
Expand All @@ -75,13 +78,15 @@ class CLinker extends CTool implements Linker {
required LinkOutputBuilder output,
Logger? logger,
ProcessManager? processManager,
FileSystem? fileSystem,
LinkerOptions? linkerOptions,
LinkModePreference? linkModePreference,
List<String>? sources,
Map<String, String?>? defines,
}) async {
logger ??= createDefaultLogger();
processManager ??= const LocalProcessManager();
fileSystem ??= const LocalFileSystem();
final effectiveLinkerOptions = linkerOptions ?? this.linkerOptions;
if (effectiveLinkerOptions != null &&
effectiveLinkerOptions.skipWholeLibrary) {
Expand All @@ -90,7 +95,7 @@ class CLinker extends CTool implements Linker {
}
final outDir = input.outputDirectory;
final packageRoot = input.packageRoot;
await Directory.fromUri(outDir).create(recursive: true);
await fileSystem.directory(outDir).create(recursive: true);
final linkMode = getLinkMode(
linkModePreference ??
this.linkModePreference ??
Expand All @@ -117,6 +122,7 @@ class CLinker extends CTool implements Linker {
linkerOptions: linkerOptions ?? this.linkerOptions,
logger: logger,
processManager: processManager,
fileSystem: fileSystem,
sources: resolvedSources,
includes: includes,
frameworks: frameworks,
Expand Down Expand Up @@ -148,7 +154,8 @@ class CLinker extends CTool implements Linker {
}
final includeFiles = await Stream.fromIterable(includes)
.asyncExpand(
(include) => Directory(include.toFilePath())
(include) => fileSystem!
.directory(include.toFilePath())
.list(recursive: true)
.where((entry) => entry is File)
.map((file) => file.uri),
Expand Down
12 changes: 8 additions & 4 deletions pkgs/native_toolchain_c/lib/src/cbuilder/compiler_resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
// 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.

import 'dart:io';

import 'package:code_assets/code_assets.dart';
import 'package:file/file.dart' show FileSystem;
import 'package:file/local.dart';
import 'package:logging/logging.dart';
import 'package:process/process.dart';

Expand All @@ -26,6 +26,7 @@ class CompilerResolver {
final CodeConfig codeConfig;
final Logger? logger;
final ProcessManager processManager;
final FileSystem fileSystem;
final OS hostOS;
final Architecture hostArchitecture;
final ToolResolvingContext context;
Expand All @@ -34,14 +35,17 @@ class CompilerResolver {
required this.codeConfig,
required this.logger,
ProcessManager? processManager,
FileSystem? fileSystem,
OS? hostOS, // Only visible for testing.
Architecture? hostArchitecture, // Only visible for testing.
}) : processManager = processManager ?? const LocalProcessManager(),
fileSystem = fileSystem ?? const LocalFileSystem(),
hostOS = hostOS ?? .current,
hostArchitecture = hostArchitecture ?? .current,
context = ToolResolvingContext(
logger: logger,
processManager: processManager,
fileSystem: fileSystem,
);

Future<ToolInstance> resolveCompiler() async {
Expand Down Expand Up @@ -126,7 +130,7 @@ class CompilerResolver {
Future<ToolInstance?> _tryLoadCompilerFromInput() async {
final inputCcUri = codeConfig.cCompiler?.compiler;
if (inputCcUri != null) {
assert(await File.fromUri(inputCcUri).exists());
assert(await fileSystem.file(inputCcUri).exists());
logger?.finer(
'Using compiler ${inputCcUri.toFilePath()} '
'from BuildInput.cCompiler.cc.',
Expand Down Expand Up @@ -239,7 +243,7 @@ class CompilerResolver {
Future<ToolInstance?> _tryLoadArchiverFromInput() async {
final inputArUri = codeConfig.cCompiler?.archiver;
if (inputArUri != null) {
assert(await File.fromUri(inputArUri).exists());
assert(await fileSystem.file(inputArUri).exists());
logger?.finer(
'Using archiver ${inputArUri.toFilePath()} '
'from BuildInput.cCompiler.ar.',
Expand Down
49 changes: 34 additions & 15 deletions pkgs/native_toolchain_c/lib/src/cbuilder/linker_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +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.

import 'dart:io';

import 'package:code_assets/code_assets.dart';
import 'package:file/file.dart' show FileSystem;

import '../native_toolchain/msvc.dart';
import '../native_toolchain/tool_likeness.dart';
Expand Down Expand Up @@ -104,15 +103,22 @@ extension LinkerOptionsExt on LinkerOptions {
Iterable<String> sourceFiles,
OS targetOS,
Architecture targetArchitecture,
FileSystem fileSystem,
) {
if (tool.isClangLike || tool.isLdLike) {
return _sourceFilesToFlagsForClangLike(tool, sourceFiles, targetOS);
return _sourceFilesToFlagsForClangLike(
tool,
sourceFiles,
targetOS,
fileSystem,
);
} else if (tool == cl) {
return _sourceFilesToFlagsForCl(
tool,
sourceFiles,
targetOS,
targetArchitecture,
fileSystem,
);
} else {
throw UnimplementedError('This package does not know how to run $tool.');
Expand All @@ -123,6 +129,7 @@ extension LinkerOptionsExt on LinkerOptions {
Tool tool,
Iterable<String> sourceFiles,
OS targetOS,
FileSystem fileSystem,
) {
switch (targetOS) {
case .macOS || .iOS:
Expand All @@ -137,7 +144,8 @@ extension LinkerOptionsExt on LinkerOptions {
if (_linkerScriptMode is ManualLinkerScript)
'-exported_symbols_list,${_linkerScriptMode.script.toFilePath()}'
else if (_linkerScriptMode is GenerateLinkerScript)
'-exported_symbols_list,${_createMacSymbolList(_symbols)}',
'-exported_symbols_list,'
'${_createMacSymbolList(_symbols, fileSystem)}',
]),
];

Expand All @@ -157,7 +165,8 @@ extension LinkerOptionsExt on LinkerOptions {
if (_linkerScriptMode is ManualLinkerScript)
'--version-script=${_linkerScriptMode.script.toFilePath()}'
else if (_linkerScriptMode is GenerateLinkerScript)
'--version-script=${_createClangLikeLinkScript(_symbols)}',
'--version-script='
'${_createClangLikeLinkScript(_symbols, fileSystem)}',
if (wholeArchiveSandwich) '--no-whole-archive',
]),
];
Expand All @@ -171,6 +180,7 @@ extension LinkerOptionsExt on LinkerOptions {
Iterable<String> sourceFiles,
OS targetOS,
Architecture targetArch,
FileSystem fileSystem,
) => [
...sourceFiles,
'/link',
Expand All @@ -182,7 +192,7 @@ extension LinkerOptionsExt on LinkerOptions {
if (_linkerScriptMode is ManualLinkerScript)
'/DEF:${_linkerScriptMode.script.toFilePath()}'
else if (_linkerScriptMode is GenerateLinkerScript)
'/DEF:${_createClLinkScript(_symbols)}',
'/DEF:${_createClLinkScript(_symbols, fileSystem)}',
if (stripDebug) '/PDBSTRIPPED',
if (gcSections) '/OPT:REF',
];
Expand All @@ -193,18 +203,24 @@ extension LinkerOptionsExt on LinkerOptions {
/// using `ld -why_live`, see https://www.unix.com/man_page/osx/1/ld/, where
/// the reason will show up as `global-dont-strip`.
/// This might possibly be a Rust only feature.
static String _createMacSymbolList(Iterable<String> symbols) {
final tempDir = Directory.systemTemp.createTempSync();
static String _createMacSymbolList(
Iterable<String> symbols,
FileSystem fileSystem,
) {
final tempDir = fileSystem.systemTempDirectory.createTempSync();
final symbolsFileUri = tempDir.uri.resolve('exported_symbols_list.txt');
final symbolsFile = File.fromUri(symbolsFileUri)..createSync();
final symbolsFile = fileSystem.file(symbolsFileUri)..createSync();
symbolsFile.writeAsStringSync(symbols.map((e) => '_$e').join('\n'));
return symbolsFileUri.toFilePath();
}

static String _createClangLikeLinkScript(Iterable<String> symbols) {
final tempDir = Directory.systemTemp.createTempSync();
static String _createClangLikeLinkScript(
Iterable<String> symbols,
FileSystem fileSystem,
) {
final tempDir = fileSystem.systemTempDirectory.createTempSync();
final symbolsFileUri = tempDir.uri.resolve('symbols.lds');
final symbolsFile = File.fromUri(symbolsFileUri)..createSync();
final symbolsFile = fileSystem.file(symbolsFileUri)..createSync();
symbolsFile.writeAsStringSync('''
{
global:
Expand All @@ -216,10 +232,13 @@ extension LinkerOptionsExt on LinkerOptions {
return symbolsFileUri.toFilePath();
}

static String _createClLinkScript(Iterable<String> symbols) {
final tempDir = Directory.systemTemp.createTempSync();
static String _createClLinkScript(
Iterable<String> symbols,
FileSystem fileSystem,
) {
final tempDir = fileSystem.systemTempDirectory.createTempSync();
final symbolsFileUri = tempDir.uri.resolve('symbols.def');
final symbolsFile = File.fromUri(symbolsFileUri)..createSync();
final symbolsFile = fileSystem.file(symbolsFileUri)..createSync();
symbolsFile.writeAsStringSync('''
LIBRARY MyDLL
EXPORTS
Expand Down
Loading
Loading