Skip to content

Commit 0ec97c9

Browse files
committed
Merge commit '5d5db9e1c019512752b5d4d222eb1ae572b8d33c' into address-comments
2 parents 185fe40 + 5d5db9e commit 0ec97c9

28 files changed

+1031
-135
lines changed

.github/workflows/dart.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ jobs:
1919
build:
2020
strategy:
2121
matrix:
22-
os: [ubuntu, macos]
22+
os: [ubuntu, macos, windows]
2323
sdk: [stable, dev]
2424
package: [c_compiler, native_assets_cli]
2525
exclude:
2626
# Only run analyze against dev on one host.
2727
- os: macos
2828
sdk: dev
29+
- os: windows
30+
sdk: dev
2931

3032
runs-on: ${{ matrix.os }}-latest
3133

@@ -78,7 +80,6 @@ jobs:
7880
flag-name: ${{ matrix.package }}-${{ matrix.os }}
7981
github-token: ${{ secrets.GITHUB_TOKEN }}
8082
parallel: true
81-
path-to-lcov: ./pkgs/${{ matrix.package }}/coverage/lcov.info
8283
if: ${{ matrix.sdk == 'stable' }}
8384

8485
coverage-finished:

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
[![dart](https://github.com/dart-lang/native/actions/workflows/dart.yaml/badge.svg)](https://github.com/dart-lang/native/actions/workflows/dart.yaml)
2+
[![Coverage Status](https://coveralls.io/repos/github/dart-lang/native/badge.svg?branch=main)](https://coveralls.io/github/dart-lang/native?branch=main)
3+
14
## Overview
25

36
This repository is home to Dart packages related to FFI and native assets

pkgs/c_compiler/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![package:c_compiler](https://github.com/dart-lang/native/actions/workflows/c_compiler.yaml/badge.svg)](https://github.com/dart-lang/native/actions/workflows/c_compiler.yaml)
1+
[![dart](https://github.com/dart-lang/native/actions/workflows/dart.yaml/badge.svg)](https://github.com/dart-lang/native/actions/workflows/dart.yaml)
22
[![pub package](https://img.shields.io/pub/v/c_compiler.svg)](https://pub.dev/packages/c_compiler)
33
[![Coverage Status](https://coveralls.io/repos/github/dart-lang/native/badge.svg?branch=main)](https://coveralls.io/github/dart-lang/native?branch=main)
44
<!-- [![package publisher](https://img.shields.io/pub/publisher/c_compiler.svg)](https://pub.dev/packages/c_compiler/publisher) -->

pkgs/c_compiler/lib/src/cbuilder/cbuilder.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ class CBuilder implements Builder {
8080
final exeUri =
8181
outDir.resolve(buildConfig.target.os.executableFileName(name));
8282
final sources = [
83-
for (final source in this.sources) packageRoot.resolve(source),
83+
for (final source in this.sources)
84+
packageRoot.resolveUri(Uri.file(source)),
8485
];
8586
final dartBuildFiles = [
8687
for (final source in this.dartBuildFiles) packageRoot.resolve(source),

pkgs/c_compiler/lib/src/cbuilder/compiler_resolver.dart

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import '../native_toolchain/android_ndk.dart';
1111
import '../native_toolchain/apple_clang.dart';
1212
import '../native_toolchain/clang.dart';
1313
import '../native_toolchain/gcc.dart';
14+
import '../native_toolchain/msvc.dart';
1415
import '../native_toolchain/recognizer.dart';
1516
import '../tool/tool.dart';
1617
import '../tool/tool_error.dart';
@@ -72,6 +73,15 @@ class CompilerResolver {
7273
}
7374
}
7475

76+
if (host.os == OS.windows) {
77+
switch (target) {
78+
case Target.windowsIA32:
79+
return clIA32;
80+
case Target.windowsX64:
81+
return cl;
82+
}
83+
}
84+
7585
return null;
7686
}
7787

@@ -80,7 +90,7 @@ class CompilerResolver {
8090
final configCcUri = getter(buildConfig);
8191
if (configCcUri != null) {
8292
assert(await File.fromUri(configCcUri).exists());
83-
logger?.finer('Using compiler ${configCcUri.path} '
93+
logger?.finer('Using compiler ${configCcUri.toFilePath()} '
8494
'from config[${BuildConfig.ccConfigKey}].');
8595
return (await CompilerRecognizer(configCcUri).resolve(logger: logger))
8696
.first;
@@ -139,6 +149,14 @@ class CompilerResolver {
139149
return i686LinuxGnuGccAr;
140150
}
141151
}
152+
if (host.os == OS.windows) {
153+
switch (target) {
154+
case Target.windowsIA32:
155+
return libIA32;
156+
case Target.windowsX64:
157+
return lib;
158+
}
159+
}
142160

143161
return null;
144162
}
@@ -148,12 +166,37 @@ class CompilerResolver {
148166
final configArUri = getter(buildConfig);
149167
if (configArUri != null) {
150168
assert(await File.fromUri(configArUri).exists());
151-
logger?.finer('Using archiver ${configArUri.path} '
169+
logger?.finer('Using archiver ${configArUri.toFilePath()} '
152170
'from config[${BuildConfig.arConfigKey}].');
153171
return (await ArchiverRecognizer(configArUri).resolve(logger: logger))
154172
.first;
155173
}
156174
logger?.finer('No archiver set in config[${BuildConfig.arConfigKey}].');
157175
return null;
158176
}
177+
178+
Future<Uri?> toolchainEnvironmentScript(ToolInstance compiler) async {
179+
final fromConfig = buildConfig.toolchainEnvScript;
180+
if (fromConfig != null) {
181+
logger?.fine('Using toolchainEnvScript from config: $fromConfig');
182+
return fromConfig;
183+
}
184+
185+
final compilerTool = compiler.tool;
186+
assert(compilerTool == cl);
187+
final vcvarsScript =
188+
(await vcvars(compiler).defaultResolver!.resolve(logger: logger)).first;
189+
return vcvarsScript.uri;
190+
}
191+
192+
List<String>? toolchainEnvironmentScriptArguments() {
193+
final fromConfig = buildConfig.toolchainEnvScriptArgs;
194+
if (fromConfig != null) {
195+
logger?.fine('Using toolchainEnvScriptArgs from config: $fromConfig');
196+
return fromConfig;
197+
}
198+
199+
// vcvars above already has x64 or x86 in the script name.
200+
return null;
201+
}
159202
}

pkgs/c_compiler/lib/src/cbuilder/run_cbuilder.dart

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@
55
import 'package:logging/logging.dart';
66
import 'package:native_assets_cli/native_assets_cli.dart';
77

8+
import '../native_toolchain/apple_clang.dart';
9+
import '../native_toolchain/clang.dart';
10+
import '../native_toolchain/gcc.dart';
11+
import '../native_toolchain/msvc.dart';
812
import '../native_toolchain/xcode.dart';
13+
import '../tool/tool_instance.dart';
14+
import '../utils/env_from_bat.dart';
915
import '../utils/run_process.dart';
1016
import 'compiler_resolver.dart';
1117

@@ -33,15 +39,12 @@ class RunCBuilder {
3339
.length ==
3440
1);
3541

36-
Future<Uri> compiler() async {
37-
final resolver = CompilerResolver(buildConfig: buildConfig, logger: logger);
38-
return (await resolver.resolveCompiler()).uri;
39-
}
42+
late final _resolver =
43+
CompilerResolver(buildConfig: buildConfig, logger: logger);
4044

41-
Future<Uri> archiver() async {
42-
final resolver = CompilerResolver(buildConfig: buildConfig, logger: logger);
43-
return (await resolver.resolveArchiver()).uri;
44-
}
45+
Future<ToolInstance> compiler() async => await _resolver.resolveCompiler();
46+
47+
Future<Uri> archiver() async => (await _resolver.resolveArchiver()).uri;
4548

4649
Future<Uri> iosSdk(IOSSdk iosSdk, {Logger? logger}) async {
4750
if (iosSdk == IOSSdk.iPhoneOs) {
@@ -65,14 +68,26 @@ class RunCBuilder {
6568

6669
Future<void> run() async {
6770
final compiler_ = await compiler();
71+
final compilerTool = compiler_.tool;
72+
if (compilerTool == appleClang ||
73+
compilerTool == clang ||
74+
compilerTool == gcc) {
75+
await runClangLike(compiler: compiler_.uri);
76+
return;
77+
}
78+
assert(compilerTool == cl);
79+
await runCl(compiler: compiler_);
80+
}
81+
82+
Future<void> runClangLike({required Uri compiler}) async {
6883
final isStaticLib = staticLibrary != null;
6984
Uri? archiver_;
7085
if (isStaticLib) {
7186
archiver_ = await archiver();
7287
}
7388

7489
await runProcess(
75-
executable: compiler_,
90+
executable: compiler,
7691
arguments: [
7792
if (target.os == OS.android) ...[
7893
// TODO(dacoharkes): How to solve linking issues?
@@ -93,19 +108,19 @@ class RunCBuilder {
93108
'-isysroot',
94109
(await macosSdk(logger: logger)).toFilePath(),
95110
],
96-
...sources.map((e) => e.path),
111+
...sources.map((e) => e.toFilePath()),
97112
if (executable != null) ...[
98113
'-o',
99-
outDir.resolveUri(executable!).path,
114+
outDir.resolveUri(executable!).toFilePath(),
100115
],
101116
if (dynamicLibrary != null) ...[
102117
'--shared',
103118
'-o',
104-
outDir.resolveUri(dynamicLibrary!).path,
119+
outDir.resolveUri(dynamicLibrary!).toFilePath(),
105120
] else if (staticLibrary != null) ...[
106121
'-c',
107122
'-o',
108-
outDir.resolve('out.o').path,
123+
outDir.resolve('out.o').toFilePath(),
109124
],
110125
],
111126
logger: logger,
@@ -116,13 +131,66 @@ class RunCBuilder {
116131
executable: archiver_!,
117132
arguments: [
118133
'rc',
119-
outDir.resolveUri(staticLibrary!).path,
120-
outDir.resolve('out.o').path,
134+
outDir.resolveUri(staticLibrary!).toFilePath(),
135+
outDir.resolve('out.o').toFilePath(),
136+
],
137+
logger: logger,
138+
captureOutput: false,
139+
);
140+
}
141+
}
142+
143+
Future<void> runCl({required ToolInstance compiler}) async {
144+
final vcvars = (await _resolver.toolchainEnvironmentScript(compiler))!;
145+
final vcvarsArgs = _resolver.toolchainEnvironmentScriptArguments();
146+
final environment = await envFromBat(vcvars, arguments: vcvarsArgs ?? []);
147+
148+
final isStaticLib = staticLibrary != null;
149+
Uri? archiver_;
150+
if (isStaticLib) {
151+
archiver_ = await archiver();
152+
}
153+
154+
final result = await runProcess(
155+
executable: compiler.uri,
156+
arguments: [
157+
if (executable != null) ...[
158+
...sources.map((e) => e.toFilePath()),
159+
'/link',
160+
'/out:${outDir.resolveUri(executable!).toFilePath()}',
161+
],
162+
if (dynamicLibrary != null) ...[
163+
...sources.map((e) => e.toFilePath()),
164+
'/link',
165+
'/DLL',
166+
'/out:${outDir.resolveUri(dynamicLibrary!).toFilePath()}',
167+
],
168+
if (staticLibrary != null) ...[
169+
'/c',
170+
...sources.map((e) => e.toFilePath()),
171+
],
172+
],
173+
workingDirectory: outDir,
174+
environment: environment,
175+
logger: logger,
176+
captureOutput: false,
177+
);
178+
179+
if (staticLibrary != null) {
180+
await runProcess(
181+
executable: archiver_!,
182+
arguments: [
183+
'/out:${staticLibrary!.toFilePath()}',
184+
'*.obj',
121185
],
186+
workingDirectory: outDir,
187+
environment: environment,
122188
logger: logger,
123189
captureOutput: false,
124190
);
125191
}
192+
193+
assert(result.exitCode == 0);
126194
}
127195

128196
static const androidNdkClangTargetFlags = {

pkgs/c_compiler/lib/src/native_toolchain/android_ndk.dart

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ class _AndroidNdkResolver implements ToolResolver {
4040
wrappedResolver: ToolResolvers([
4141
RelativeToolResolver(
4242
toolName: 'Android NDK',
43-
wrappedResolver: PathToolResolver(toolName: 'ndk-build'),
44-
relativePath: Uri(path: '.'),
43+
wrappedResolver: PathToolResolver(
44+
toolName: 'ndk-build',
45+
executableName: Platform.isWindows ? 'ndk-build.cmd' : 'ndk-build',
46+
),
47+
relativePath: Uri(path: ''),
4548
),
4649
InstallLocationResolver(
4750
toolName: 'Android NDK',
@@ -53,6 +56,9 @@ class _AndroidNdkResolver implements ToolResolver {
5356
if (Platform.isMacOS) ...[
5457
'\$HOME/Library/Android/sdk/ndk/*/',
5558
],
59+
if (Platform.isWindows) ...[
60+
'\$HOME/AppData/Local/Android/Sdk/ndk/*/',
61+
],
5662
],
5763
),
5864
]),
@@ -79,21 +85,27 @@ class _AndroidNdkResolver implements ToolResolver {
7985
final hostArchDirs =
8086
(await prebuiltDir.list().toList()).whereType<Directory>().toList();
8187
for (final hostArchDir in hostArchDirs) {
82-
final clangUri = hostArchDir.uri.resolve('bin/clang');
88+
final clangUri = hostArchDir.uri
89+
.resolve('bin/')
90+
.resolve(Target.current.os.executableFileName('clang'));
8391
if (await File.fromUri(clangUri).exists()) {
8492
result.add(await CliVersionResolver.lookupVersion(ToolInstance(
8593
tool: androidNdkClang,
8694
uri: clangUri,
8795
)));
8896
}
89-
final arUri = hostArchDir.uri.resolve('bin/llvm-ar');
97+
final arUri = hostArchDir.uri
98+
.resolve('bin/')
99+
.resolve(Target.current.os.executableFileName('llvm-ar'));
90100
if (await File.fromUri(arUri).exists()) {
91101
result.add(await CliVersionResolver.lookupVersion(ToolInstance(
92102
tool: androidNdkLlvmAr,
93103
uri: arUri,
94104
)));
95105
}
96-
final ldUri = hostArchDir.uri.resolve('bin/ld.lld');
106+
final ldUri = hostArchDir.uri
107+
.resolve('bin/')
108+
.resolve(Target.current.os.executableFileName('ld.lld'));
97109
if (await File.fromUri(arUri).exists()) {
98110
result.add(await CliVersionResolver.lookupVersion(ToolInstance(
99111
tool: androidNdkLld,

0 commit comments

Comments
 (0)