Skip to content

Commit 3707eed

Browse files
committed
Add includes, flags, std, cpp, cppLinkStdLib options
1 parent d215feb commit 3707eed

File tree

8 files changed

+344
-22
lines changed

8 files changed

+344
-22
lines changed

pkgs/native_toolchain_c/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 0.2.3
2+
3+
- Added `includes` for specifying include directories.
4+
- Added `flags` for specifying arbitrary compiler flags.
5+
- Added `std` for specifying a language standard.
6+
- Added `cpp` for enabling C++ compilation.
7+
- Added `cppLinkStdLib` for specifying the C++ standard library to link against.
8+
19
## 0.2.2
210

311
- Generate position independent code for libraries by default and add

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

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,33 @@ class CBuilder implements Builder {
105105
/// Defaults to `true` for libraries and `false` for executables.
106106
final bool? pic;
107107

108+
/// The language standard to use.
109+
///
110+
/// When set to `null`, the default behavior of the compiler will be used.
111+
final String? std;
112+
113+
/// Whether to compile sources as C++.
114+
///
115+
/// [cppLinkStdLib] only has an effect when this is `true`.
116+
final bool cpp;
117+
118+
/// The C++ standard library to link against.
119+
///
120+
/// This option has no effect when [cpp] is `false` or when compiling for
121+
/// Windows.
122+
///
123+
/// When set to `null`, the following defaults will be used, based on the
124+
/// target OS:
125+
///
126+
/// | OS | Library |
127+
/// | :------ | :----------- |
128+
/// | Android | `c++_shared` |
129+
/// | iOS | `c++` |
130+
/// | Linux | `stdc++` |
131+
/// | macOS | `c++` |
132+
/// | Fuchsia | `c++` |
133+
final String? cppLinkStdLib;
134+
108135
CBuilder.library({
109136
required this.name,
110137
required this.assetId,
@@ -117,6 +144,9 @@ class CBuilder implements Builder {
117144
this.buildModeDefine = true,
118145
this.ndebugDefine = true,
119146
this.pic = true,
147+
this.std,
148+
this.cpp = false,
149+
this.cppLinkStdLib,
120150
}) : _type = _CBuilderType.library;
121151

122152
CBuilder.executable({
@@ -129,6 +159,9 @@ class CBuilder implements Builder {
129159
this.buildModeDefine = true,
130160
this.ndebugDefine = true,
131161
bool? pie = false,
162+
this.std,
163+
this.cpp = false,
164+
this.cppLinkStdLib,
132165
}) : _type = _CBuilderType.executable,
133166
assetId = null,
134167
installName = null,
@@ -185,6 +218,9 @@ class CBuilder implements Builder {
185218
'NDEBUG': null,
186219
},
187220
pic: pic,
221+
std: std,
222+
cpp: cpp,
223+
cppLinkStdLib: cppLinkStdLib,
188224
);
189225
await task.run();
190226
}
@@ -207,11 +243,21 @@ class CBuilder implements Builder {
207243
}
208244
}
209245
if (!buildConfig.dryRun) {
210-
buildOutput.dependencies.dependencies.addAll([
246+
final includeFiles = await Stream.fromIterable(includes)
247+
.asyncExpand(
248+
(include) => Directory(include.toFilePath())
249+
.list(recursive: true)
250+
.where((entry) => entry is File)
251+
.map((file) => file.uri),
252+
)
253+
.toList();
254+
255+
buildOutput.dependencies.dependencies.addAll({
256+
// Note: We use a Set here to deduplicate the dependencies.
211257
...sources,
212-
...includes,
258+
...includeFiles,
213259
...dartBuildFiles,
214-
]);
260+
});
215261
}
216262
}
217263
}

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

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ class RunCBuilder {
3636
final List<String> flags;
3737
final Map<String, String?> defines;
3838
final bool? pic;
39+
final String? std;
40+
final bool cpp;
41+
final String? cppLinkStdLib;
3942

4043
RunCBuilder({
4144
required this.buildConfig,
@@ -49,6 +52,9 @@ class RunCBuilder {
4952
this.flags = const [],
5053
this.defines = const {},
5154
this.pic,
55+
this.std,
56+
this.cpp = false,
57+
this.cppLinkStdLib,
5258
}) : outDir = buildConfig.outDir,
5359
target = buildConfig.target,
5460
assert([executable, dynamicLibrary, staticLibrary]
@@ -137,21 +143,6 @@ class RunCBuilder {
137143
'-install_name',
138144
installName!.toFilePath(),
139145
],
140-
...sources.map((e) => e.toFilePath()),
141-
if (executable != null) ...[
142-
'-o',
143-
outDir.resolveUri(executable!).toFilePath(),
144-
],
145-
if (dynamicLibrary != null) ...[
146-
'--shared',
147-
'-o',
148-
outDir.resolveUri(dynamicLibrary!).toFilePath(),
149-
] else if (staticLibrary != null) ...[
150-
'-c',
151-
'-o',
152-
outDir.resolve('out.o').toFilePath(),
153-
],
154-
for (final include in includes) '-I${include.toFilePath()}',
155146
if (pic != null)
156147
if (pic!) ...[
157148
if (dynamicLibrary != null) '-fPIC',
@@ -166,9 +157,31 @@ class RunCBuilder {
166157
'-fno-PIC',
167158
'-fno-PIE',
168159
],
160+
if (std != null) '-std=$std',
161+
if (cpp) ...[
162+
'-x',
163+
'c++',
164+
'-l',
165+
cppLinkStdLib ?? defaultCppLinkStdLib[target.os]!
166+
],
167+
...flags,
169168
for (final MapEntry(key: name, :value) in defines.entries)
170169
if (value == null) '-D$name' else '-D$name=$value',
171-
...flags,
170+
for (final include in includes) '-I${include.toFilePath()}',
171+
...sources.map((e) => e.toFilePath()),
172+
if (executable != null) ...[
173+
'-o',
174+
outDir.resolveUri(executable!).toFilePath(),
175+
],
176+
if (dynamicLibrary != null) ...[
177+
'--shared',
178+
'-o',
179+
outDir.resolveUri(dynamicLibrary!).toFilePath(),
180+
] else if (staticLibrary != null) ...[
181+
'-c',
182+
'-o',
183+
outDir.resolve('out.o').toFilePath(),
184+
],
172185
],
173186
logger: logger,
174187
captureOutput: false,
@@ -203,10 +216,12 @@ class RunCBuilder {
203216
final result = await runProcess(
204217
executable: compiler.uri,
205218
arguments: [
206-
for (final include in includes) '/I${include.toFilePath()}',
219+
if (std != null) '/std:$std',
220+
if (cpp) '/TP',
221+
...flags,
207222
for (final MapEntry(key: name, :value) in defines.entries)
208223
if (value == null) '/D$name' else '/D$name=$value',
209-
...flags,
224+
for (final include in includes) '/I${include.toFilePath()}',
210225
if (executable != null) ...[
211226
...sources.map((e) => e.toFilePath()),
212227
'/link',
@@ -269,4 +284,12 @@ class RunCBuilder {
269284
IOSSdk.iPhoneSimulator: 'x86_64-apple-ios-simulator',
270285
},
271286
};
287+
288+
static const defaultCppLinkStdLib = {
289+
OS.android: 'c++_shared',
290+
OS.fuchsia: 'c++',
291+
OS.iOS: 'c++',
292+
OS.linux: 'stdc++',
293+
OS.macOS: 'c++',
294+
};
272295
}

pkgs/native_toolchain_c/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: native_toolchain_c
22
description: >-
33
A library to invoke the native C compiler installed on the host machine.
4-
version: 0.2.2
4+
version: 0.2.3
55
repository: https://github.com/dart-lang/native/tree/main/pkgs/native_toolchain_c
66

77
topics:

0 commit comments

Comments
 (0)