Skip to content

Commit 47611ae

Browse files
authored
[native_toolchain_c] Forced includes (#2096)
1 parent 0cd2e55 commit 47611ae

File tree

7 files changed

+43
-0
lines changed

7 files changed

+43
-0
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class CBuilder extends CTool implements Builder {
5555
super.assetName,
5656
super.sources = const [],
5757
super.includes = const [],
58+
super.forcedIncludes = const [],
5859
super.frameworks = CTool.defaultFrameworks,
5960
super.libraries = const [],
6061
super.libraryDirectories = CTool.defaultLibraryDirectories,
@@ -81,6 +82,7 @@ class CBuilder extends CTool implements Builder {
8182
required super.name,
8283
super.sources = const [],
8384
super.includes = const [],
85+
super.forcedIncludes = const [],
8486
super.frameworks = CTool.defaultFrameworks,
8587
super.libraries = const [],
8688
super.libraryDirectories = CTool.defaultLibraryDirectories,
@@ -149,6 +151,10 @@ class CBuilder extends CTool implements Builder {
149151
for (final directory in this.includes)
150152
packageRoot.resolveUri(Uri.file(directory)),
151153
];
154+
final forcedIncludes = [
155+
for (final file in this.forcedIncludes)
156+
packageRoot.resolveUri(Uri.file(file)),
157+
];
152158
final dartBuildFiles = [
153159
// ignore: deprecated_member_use_from_same_package
154160
for (final source in this.dartBuildFiles) packageRoot.resolve(source),
@@ -164,6 +170,7 @@ class CBuilder extends CTool implements Builder {
164170
logger: logger,
165171
sources: sources,
166172
includes: includes,
173+
forcedIncludes: forcedIncludes,
167174
frameworks: frameworks,
168175
libraries: libraries,
169176
libraryDirectories: libraryDirectories,
@@ -220,6 +227,7 @@ class CBuilder extends CTool implements Builder {
220227
// Note: We use a Set here to deduplicate the dependencies.
221228
...sources,
222229
...includeFiles,
230+
...forcedIncludes,
223231
...dartBuildFiles,
224232
});
225233
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class CLinker extends CTool implements Linker {
2828
required this.linkerOptions,
2929
super.sources = const [],
3030
super.includes = const [],
31+
super.forcedIncludes = const [],
3132
super.frameworks = CTool.defaultFrameworks,
3233
super.libraries = const [],
3334
super.libraryDirectories = CTool.defaultLibraryDirectories,

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ abstract class CTool {
4646
/// The sources will be reported as dependencies of the hook.
4747
final List<String> includes;
4848

49+
/// Files passed to the compiler that will be included before all source
50+
/// files.
51+
///
52+
/// Resolved against [LinkInput.packageRoot].
53+
///
54+
/// The sources will be reported as dependencies of the hook.
55+
/// For clang, each of the files are added as an `-include` flag.
56+
/// see: https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Preprocessor-Options.html#index-include
57+
/// For MSVC, each of the files are added as an `/FI` flag.
58+
/// see: https://learn.microsoft.com/en-us/cpp/build/reference/fi-name-forced-include-file
59+
final List<String> forcedIncludes;
60+
4961
/// Frameworks to link.
5062
///
5163
/// Only effective if [language] is [Language.objectiveC].
@@ -154,6 +166,7 @@ abstract class CTool {
154166
required this.assetName,
155167
required this.sources,
156168
required this.includes,
169+
required this.forcedIncludes,
157170
required this.frameworks,
158171
required this.libraries,
159172
required this.libraryDirectories,

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class RunCBuilder {
2626
final Logger? logger;
2727
final List<Uri> sources;
2828
final List<Uri> includes;
29+
final List<Uri> forcedIncludes;
2930
final List<String> frameworks;
3031
final List<String> libraries;
3132
final List<Uri> libraryDirectories;
@@ -56,6 +57,7 @@ class RunCBuilder {
5657
this.logger,
5758
this.sources = const [],
5859
this.includes = const [],
60+
this.forcedIncludes = const [],
5961
required this.frameworks,
6062
this.libraries = const [],
6163
this.libraryDirectories = const [],
@@ -301,6 +303,8 @@ class RunCBuilder {
301303
for (final MapEntry(key: name, :value) in defines.entries)
302304
if (value == null) '-D$name' else '-D$name=$value',
303305
for (final include in includes) '-I${include.toFilePath()}',
306+
for (final forcedInclude in forcedIncludes)
307+
'-include${forcedInclude.toFilePath()}',
304308
...sourceFiles,
305309
if (language == Language.objectiveC) ...[
306310
for (final framework in frameworks) ...['-framework', framework],
@@ -359,6 +363,8 @@ class RunCBuilder {
359363
for (final MapEntry(key: name, :value) in defines.entries)
360364
if (value == null) '/D$name' else '/D$name=$value',
361365
for (final directory in includes) '/I${directory.toFilePath()}',
366+
for (final forcedInclude in forcedIncludes)
367+
'/FI${forcedInclude.toFilePath()}',
362368
if (executable != null) ...[
363369
...sources.map((e) => e.toFilePath()),
364370
'/link',

pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ void main() {
233233
if (!await File.fromUri(definesCUri).exists()) {
234234
throw Exception('Run the test from the root directory.');
235235
}
236+
final forcedIncludeCUri = packageUri.resolve(
237+
'test/cbuilder/testfiles/defines/src/forcedInclude.c',
238+
);
236239
const name = 'defines';
237240

238241
final logMessages = <String>[];
@@ -268,6 +271,7 @@ void main() {
268271
final cbuilder = CBuilder.executable(
269272
name: name,
270273
sources: [definesCUri.toFilePath()],
274+
forcedIncludes: [forcedIncludeCUri.toFilePath()],
271275
flags: [flag],
272276
buildMode: BuildMode.release,
273277
);
@@ -278,6 +282,8 @@ void main() {
278282
final result = await runProcess(executable: executableUri, logger: logger);
279283
expect(result.exitCode, 0);
280284
expect(result.stdout, contains('Macro FOO is defined: USER_FLAG'));
285+
// Check the forced include is added.
286+
expect(result.stdout, contains('Macro FIFOO is defined: "QuotedFIFOO"'));
281287

282288
final compilerInvocation = logMessages.singleWhere(
283289
(message) => message.contains(definesCUri.toFilePath()),

pkgs/native_toolchain_c/test/cbuilder/testfiles/defines/src/defines.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,11 @@ int main() {
3434
MACRO_IS_UNDEFINED(FOO);
3535
#endif
3636

37+
#ifdef FIFOO
38+
MACRO_IS_DEFINED(FIFOO);
39+
#else
40+
MACRO_IS_UNDEFINED(FIFOO);
41+
#endif
42+
3743
return 0;
3844
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#ifndef FIFOO
2+
#define FIFOO "QuotedFIFOO"
3+
#endif

0 commit comments

Comments
 (0)