Skip to content

Commit dfa32c9

Browse files
authored
Merge 0d59319 into f179ec2
2 parents f179ec2 + 0d59319 commit dfa32c9

File tree

4 files changed

+121
-75
lines changed

4 files changed

+121
-75
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ class RunCBuilder {
224224
'${targetAndroidNdkApi!}',
225225
'--sysroot=${androidSysroot(toolInstance).toFilePath()}',
226226
],
227+
if (codeConfig.targetOS == OS.windows)
228+
'--target=${clangWindowsTargetFlags[architecture]!}',
227229
if (codeConfig.targetOS == OS.macOS)
228230
'--target=${appleClangMacosTargetFlags[architecture]!}',
229231
if (codeConfig.targetOS == OS.iOS)
@@ -244,7 +246,8 @@ class RunCBuilder {
244246
installName!.toFilePath(),
245247
],
246248
if (pic != null)
247-
if (toolInstance.tool.isClangLike) ...[
249+
if (toolInstance.tool.isClangLike &&
250+
codeConfig.targetOS != OS.windows) ...[
248251
if (pic!) ...[
249252
if (dynamicLibrary != null) '-fPIC',
250253
// Using PIC for static libraries allows them to be linked into
@@ -419,6 +422,12 @@ class RunCBuilder {
419422
},
420423
};
421424

425+
static const clangWindowsTargetFlags = {
426+
Architecture.arm64: 'arm64-pc-windows-msvc',
427+
Architecture.ia32: 'i386-pc-windows-msvc',
428+
Architecture.x64: 'x86_64-pc-windows-msvc',
429+
};
430+
422431
static const defaultCppLinkStdLib = {
423432
OS.android: 'c++_shared',
424433
OS.fuchsia: 'c++',

pkgs/native_toolchain_c/lib/src/native_toolchain/clang.dart

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:native_assets_cli/code_assets.dart';
6+
57
import '../tool/tool.dart';
68
import '../tool/tool_resolver.dart';
79

@@ -14,10 +16,18 @@ final Tool clang = Tool(
1416
wrappedResolver: CliFilter(
1517
cliArguments: ['--version'],
1618
keepIf: ({required String stdout}) => !stdout.contains('Apple clang'),
17-
wrappedResolver: PathToolResolver(
18-
toolName: 'Clang',
19-
executableName: 'clang',
20-
),
19+
wrappedResolver: ToolResolvers([
20+
PathToolResolver(
21+
toolName: 'Clang',
22+
executableName: OS.current.executableFileName('clang'),
23+
),
24+
InstallLocationResolver(
25+
toolName: 'Clang',
26+
paths: [
27+
'C:/Program Files/LLVM/bin/clang.exe',
28+
],
29+
),
30+
]),
2131
),
2232
),
2333
);
@@ -32,7 +42,7 @@ final Tool llvmAr = Tool(
3242
RelativeToolResolver(
3343
toolName: 'LLVM archiver',
3444
wrappedResolver: clang.defaultResolver!,
35-
relativePath: Uri.file('llvm-ar'),
45+
relativePath: Uri.file(OS.current.executableFileName('llvm-ar')),
3646
),
3747
]),
3848
),
@@ -48,7 +58,7 @@ final Tool lld = Tool(
4858
RelativeToolResolver(
4959
toolName: 'LLD',
5060
wrappedResolver: clang.defaultResolver!,
51-
relativePath: Uri.file('ld.lld'),
61+
relativePath: Uri.file(OS.current.executableFileName('ld.lld')),
5262
),
5363
]),
5464
),

pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_windows_host_test.dart

Lines changed: 90 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,36 @@ library;
1111
import 'dart:io';
1212

1313
import 'package:native_toolchain_c/native_toolchain_c.dart';
14+
import 'package:native_toolchain_c/src/native_toolchain/clang.dart';
1415
import 'package:native_toolchain_c/src/native_toolchain/msvc.dart';
1516
import 'package:native_toolchain_c/src/utils/run_process.dart';
1617
import 'package:test/test.dart';
1718

1819
import '../helpers.dart';
1920

20-
void main() {
21+
void main() async {
2122
if (!Platform.isWindows) {
2223
// Avoid needing status files on Dart SDK CI.
2324
return;
2425
}
2526

27+
final compilers = {
28+
// Either provided to be MSVC or null which defaults to MSVC.
29+
msvc: () async => cCompiler,
30+
// Clang on Windows.
31+
clang: () async => CCompilerConfig(
32+
archiver:
33+
(await llvmAr.defaultResolver!.resolve(logger: logger)).first.uri,
34+
compiler:
35+
(await clang.defaultResolver!.resolve(logger: logger)).first.uri,
36+
linker:
37+
(await lld.defaultResolver!.resolve(logger: logger)).first.uri,
38+
)
39+
};
40+
2641
const targets = [
42+
// TODO(https://github.com/dart-lang/native/issues/170): Support arm64.
43+
// Architecture.arm64,
2744
Architecture.ia32,
2845
Architecture.x64,
2946
];
@@ -36,6 +53,7 @@ void main() {
3653
});
3754

3855
const dumpbinMachine = {
56+
Architecture.arm64: 'ARM64',
3957
Architecture.ia32: 'x86',
4058
Architecture.x64: 'x64',
4159
};
@@ -48,74 +66,79 @@ void main() {
4866
StaticLinking(): 'LIBRARY',
4967
};
5068

51-
for (final linkMode in [DynamicLoadingBundled(), StaticLinking()]) {
52-
for (final target in targets) {
53-
// Cycle through all optimization levels.
54-
final optimizationLevel = optimizationLevels[selectOptimizationLevel];
55-
selectOptimizationLevel =
56-
(selectOptimizationLevel + 1) % optimizationLevels.length;
57-
test('CBuilder $linkMode library $target $optimizationLevel', () async {
58-
final tempUri = await tempDirForTest();
59-
final tempUri2 = await tempDirForTest();
60-
final addCUri =
61-
packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
62-
const name = 'add';
63-
64-
final buildInputBuilder = BuildInputBuilder()
65-
..setupShared(
66-
packageName: name,
67-
packageRoot: tempUri,
68-
outputFile: tempUri.resolve('output.json'),
69-
outputDirectory: tempUri,
70-
outputDirectoryShared: tempUri2,
71-
)
72-
..config.setupBuild(
73-
linkingEnabled: false,
74-
dryRun: false,
75-
)
76-
..config.setupShared(buildAssetTypes: [CodeAsset.type])
77-
..config.setupCode(
78-
targetOS: OS.windows,
79-
targetArchitecture: target,
80-
linkModePreference: linkMode == DynamicLoadingBundled()
81-
? LinkModePreference.dynamic
82-
: LinkModePreference.static,
83-
cCompiler: cCompiler,
69+
for (final compiler in compilers.keys) {
70+
for (final linkMode in [DynamicLoadingBundled(), StaticLinking()]) {
71+
for (final target in targets) {
72+
// Cycle through all optimization levels.
73+
final optimizationLevel = optimizationLevels[selectOptimizationLevel];
74+
selectOptimizationLevel =
75+
(selectOptimizationLevel + 1) % optimizationLevels.length;
76+
test(
77+
'CBuilder ${compiler.name} $linkMode library $target'
78+
' $optimizationLevel', () async {
79+
final tempUri = await tempDirForTest();
80+
final tempUri2 = await tempDirForTest();
81+
final addCUri =
82+
packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
83+
const name = 'add';
84+
85+
final buildInputBuilder = BuildInputBuilder()
86+
..setupShared(
87+
packageName: name,
88+
packageRoot: tempUri,
89+
outputFile: tempUri.resolve('output.json'),
90+
outputDirectory: tempUri,
91+
outputDirectoryShared: tempUri2,
92+
)
93+
..config.setupBuild(
94+
linkingEnabled: false,
95+
dryRun: false,
96+
)
97+
..config.setupShared(buildAssetTypes: [CodeAsset.type])
98+
..config.setupCode(
99+
targetOS: OS.windows,
100+
targetArchitecture: target,
101+
linkModePreference: linkMode == DynamicLoadingBundled()
102+
? LinkModePreference.dynamic
103+
: LinkModePreference.static,
104+
cCompiler: await (compilers[compiler]!)(),
105+
);
106+
107+
final buildInput = BuildInput(buildInputBuilder.json);
108+
final buildOutput = BuildOutputBuilder();
109+
110+
final cbuilder = CBuilder.library(
111+
name: name,
112+
assetName: name,
113+
sources: [addCUri.toFilePath()],
114+
optimizationLevel: optimizationLevel,
115+
buildMode: BuildMode.release,
116+
);
117+
await cbuilder.run(
118+
input: buildInput,
119+
output: buildOutput,
120+
logger: logger,
84121
);
85122

86-
final buildInput = BuildInput(buildInputBuilder.json);
87-
final buildOutput = BuildOutputBuilder();
88-
89-
final cbuilder = CBuilder.library(
90-
name: name,
91-
assetName: name,
92-
sources: [addCUri.toFilePath()],
93-
optimizationLevel: optimizationLevel,
94-
buildMode: BuildMode.release,
95-
);
96-
await cbuilder.run(
97-
input: buildInput,
98-
output: buildOutput,
99-
logger: logger,
100-
);
101-
102-
final libUri =
103-
tempUri.resolve(OS.windows.libraryFileName(name, linkMode));
104-
expect(await File.fromUri(libUri).exists(), true);
105-
final result = await runProcess(
106-
executable: dumpbinUri,
107-
arguments: ['/HEADERS', libUri.toFilePath()],
108-
logger: logger,
109-
);
110-
expect(result.exitCode, 0);
111-
final machine =
112-
result.stdout.split('\n').firstWhere((e) => e.contains('machine'));
113-
expect(machine, contains(dumpbinMachine[target]));
114-
final fileType = result.stdout
115-
.split('\n')
116-
.firstWhere((e) => e.contains('File Type'));
117-
expect(fileType, contains(dumpbinFileType[linkMode]));
118-
});
123+
final libUri =
124+
tempUri.resolve(OS.windows.libraryFileName(name, linkMode));
125+
expect(await File.fromUri(libUri).exists(), true);
126+
final result = await runProcess(
127+
executable: dumpbinUri,
128+
arguments: ['/HEADERS', libUri.toFilePath()],
129+
logger: logger,
130+
);
131+
expect(result.exitCode, 0);
132+
final machine = result.stdout
133+
.split('\n')
134+
.firstWhere((e) => e.contains('machine'));
135+
expect(machine, contains(dumpbinMachine[target]));
136+
final fileType = result.stdout
137+
.split('\n')
138+
.firstWhere((e) => e.contains('File Type'));
139+
expect(fileType, contains(dumpbinFileType[linkMode]));
140+
});
141+
}
119142
}
120143
}
121144
}

pkgs/native_toolchain_c/test/native_toolchain/clang_test.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ import 'package:test/test.dart';
1616
import '../helpers.dart';
1717

1818
void main() {
19-
if (!Platform.isLinux) {
19+
if (Platform.isMacOS ||
20+
(Platform.isWindows &&
21+
Platform.environment['DART_HOOK_TESTING_C_COMPILER__CC']
22+
?.endsWith('cl.exe') ==
23+
true)) {
2024
// Avoid needing status files on Dart SDK CI.
2125
return;
2226
}

0 commit comments

Comments
 (0)