@@ -83,6 +83,7 @@ root_src: ?LazyPath,
83
83
out_lib_filename : []const u8 ,
84
84
modules : std .StringArrayHashMap (* Module ),
85
85
86
+ precompiled_header : ? * Compile ,
86
87
link_objects : ArrayList (LinkObject ),
87
88
include_dirs : ArrayList (IncludeDir ),
88
89
c_macros : ArrayList ([]const u8 ),
@@ -439,6 +440,7 @@ pub const Kind = enum {
439
440
exe ,
440
441
lib ,
441
442
obj ,
443
+ pch ,
442
444
@"test" ,
443
445
};
444
446
@@ -462,6 +464,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
462
464
.exe = > "zig build-exe" ,
463
465
.lib = > "zig build-lib" ,
464
466
.obj = > "zig build-obj" ,
467
+ .pch = > "zig build-pch" ,
465
468
.@"test" = > "zig test" ,
466
469
},
467
470
name_adjusted ,
@@ -471,20 +474,24 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
471
474
472
475
const target_info = NativeTargetInfo .detect (options .target ) catch @panic ("unhandled error" );
473
476
474
- const out_filename = std .zig .binNameAlloc (owner .allocator , .{
475
- .root_name = name ,
476
- .target = target_info .target ,
477
- .output_mode = switch (options .kind ) {
478
- .lib = > .Lib ,
479
- .obj = > .Obj ,
480
- .exe , .@"test" = > .Exe ,
481
- },
482
- .link_mode = if (options .linkage ) | some | @as (std .builtin .LinkMode , switch (some ) {
483
- .dynamic = > .Dynamic ,
484
- .static = > .Static ,
485
- }) else null ,
486
- .version = options .version ,
487
- }) catch @panic ("OOM" );
477
+ const out_filename = if (options .kind == .pch )
478
+ std .fmt .allocPrint (owner .allocator , "{s}.pch" , .{name }) catch @panic ("OOM" )
479
+ else
480
+ std .zig .binNameAlloc (owner .allocator , .{
481
+ .root_name = name ,
482
+ .target = target_info .target ,
483
+ .output_mode = switch (options .kind ) {
484
+ .lib = > .Lib ,
485
+ .obj = > .Obj ,
486
+ .exe , .@"test" = > .Exe ,
487
+ .pch = > unreachable ,
488
+ },
489
+ .link_mode = if (options .linkage ) | some | @as (std .builtin .LinkMode , switch (some ) {
490
+ .dynamic = > .Dynamic ,
491
+ .static = > .Static ,
492
+ }) else null ,
493
+ .version = options .version ,
494
+ }) catch @panic ("OOM" );
488
495
489
496
const self = owner .allocator .create (Compile ) catch @panic ("OOM" );
490
497
self .* = .{
@@ -518,6 +525,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
518
525
.lib_paths = ArrayList (LazyPath ).init (owner .allocator ),
519
526
.rpaths = ArrayList (LazyPath ).init (owner .allocator ),
520
527
.installed_headers = ArrayList (* Step ).init (owner .allocator ),
528
+ .precompiled_header = null ,
521
529
.c_std = std .Build .CStd .C99 ,
522
530
.zig_lib_dir = null ,
523
531
.main_mod_path = null ,
@@ -980,6 +988,8 @@ pub const AddCSourceFilesOptions = struct {
980
988
981
989
/// Handy when you have many C/C++ source files and want them all to have the same flags.
982
990
pub fn addCSourceFiles (self : * Compile , options : AddCSourceFilesOptions ) void {
991
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
992
+
983
993
const b = self .step .owner ;
984
994
const c_source_files = b .allocator .create (CSourceFiles ) catch @panic ("OOM" );
985
995
@@ -995,6 +1005,8 @@ pub fn addCSourceFiles(self: *Compile, options: AddCSourceFilesOptions) void {
995
1005
}
996
1006
997
1007
pub fn addCSourceFile (self : * Compile , source : CSourceFile ) void {
1008
+ assert (self .kind != .pch or self .link_objects .items .len == 0 ); // pch can only be generated from a single C header file
1009
+
998
1010
const b = self .step .owner ;
999
1011
const c_source_file = b .allocator .create (CSourceFile ) catch @panic ("OOM" );
1000
1012
c_source_file .* = source .dupe (b );
@@ -1111,23 +1123,39 @@ pub fn getEmittedLlvmBc(self: *Compile) LazyPath {
1111
1123
}
1112
1124
1113
1125
pub fn addAssemblyFile (self : * Compile , source : LazyPath ) void {
1126
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
1127
+
1114
1128
const b = self .step .owner ;
1115
1129
const source_duped = source .dupe (b );
1116
1130
self .link_objects .append (.{ .assembly_file = source_duped }) catch @panic ("OOM" );
1117
1131
source_duped .addStepDependencies (& self .step );
1118
1132
}
1119
1133
1120
1134
pub fn addObjectFile (self : * Compile , source : LazyPath ) void {
1135
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
1136
+
1121
1137
const b = self .step .owner ;
1122
1138
self .link_objects .append (.{ .static_path = source .dupe (b ) }) catch @panic ("OOM" );
1123
1139
source .addStepDependencies (& self .step );
1124
1140
}
1125
1141
1126
1142
pub fn addObject (self : * Compile , obj : * Compile ) void {
1143
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
1144
+
1127
1145
assert (obj .kind == .obj );
1128
1146
self .linkLibraryOrObject (obj );
1129
1147
}
1130
1148
1149
+ pub fn addPrecompiledCHeader (self : * Compile , pch : * Compile ) void {
1150
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
1151
+ assert (pch .kind == .pch );
1152
+
1153
+ if (self .precompiled_header != null ) @panic ("Precompiled header already defined." );
1154
+ self .precompiled_header = pch ;
1155
+
1156
+ pch .getEmittedBin ().addStepDependencies (& self .step );
1157
+ }
1158
+
1131
1159
pub fn addAfterIncludePath (self : * Compile , path : LazyPath ) void {
1132
1160
const b = self .step .owner ;
1133
1161
self .include_dirs .append (IncludeDir { .path_after = path .dupe (b ) }) catch @panic ("OOM" );
@@ -1419,7 +1447,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1419
1447
const cmd = switch (self .kind ) {
1420
1448
.lib = > "build-lib" ,
1421
1449
.exe = > "build-exe" ,
1422
- .obj = > "build-obj" ,
1450
+ .obj , .pch = > "build-obj" ,
1423
1451
.@"test" = > "test" ,
1424
1452
};
1425
1453
try zig_args .append (cmd );
@@ -1435,6 +1463,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1435
1463
try zig_args .append (try std .fmt .allocPrint (b .allocator , "-ofmt={s}" , .{@tagName (ofmt )}));
1436
1464
}
1437
1465
1466
+ if (self .kind == .pch ) {
1467
+ try zig_args .append ("-x" );
1468
+ try zig_args .append (if (self .is_linking_libcpp ) "c++-header" else "c-header" );
1469
+ }
1470
+
1438
1471
switch (self .entry ) {
1439
1472
.default = > {},
1440
1473
.disabled = > try zig_args .append ("-fno-entry" ),
@@ -1486,6 +1519,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1486
1519
.other_step = > | other | switch (other .kind ) {
1487
1520
.exe = > @panic ("Cannot link with an executable build artifact" ),
1488
1521
.@"test" = > @panic ("Cannot link with a test" ),
1522
+ .pch = > @panic ("Cannot link with a precompiled header file" ),
1489
1523
.obj = > {
1490
1524
try zig_args .append (other .getEmittedBin ().getPath (b ));
1491
1525
},
@@ -1582,7 +1616,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1582
1616
},
1583
1617
1584
1618
.c_source_file = > | c_source_file | {
1585
- if (c_source_file .flags .len == 0 ) {
1619
+ if (c_source_file .flags .len == 0 and self . precompiled_header == null ) {
1586
1620
if (prev_has_cflags ) {
1587
1621
try zig_args .append ("-cflags" );
1588
1622
try zig_args .append ("--" );
@@ -1593,14 +1627,19 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1593
1627
for (c_source_file .flags ) | arg | {
1594
1628
try zig_args .append (arg );
1595
1629
}
1630
+ if (self .precompiled_header ) | pch | {
1631
+ try zig_args .append ("-include-pch" );
1632
+ try zig_args .append (pch .getEmittedBin ().getPath (b ));
1633
+ try zig_args .append ("-fpch-validate-input-files-content" );
1634
+ }
1596
1635
try zig_args .append ("--" );
1597
1636
prev_has_cflags = true ;
1598
1637
}
1599
1638
try zig_args .append (c_source_file .file .getPath (b ));
1600
1639
},
1601
1640
1602
1641
.c_source_files = > | c_source_files | {
1603
- if (c_source_files .flags .len == 0 ) {
1642
+ if (c_source_files .flags .len == 0 and self . precompiled_header == null ) {
1604
1643
if (prev_has_cflags ) {
1605
1644
try zig_args .append ("-cflags" );
1606
1645
try zig_args .append ("--" );
@@ -1611,6 +1650,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1611
1650
for (c_source_files .flags ) | flag | {
1612
1651
try zig_args .append (flag );
1613
1652
}
1653
+ if (self .precompiled_header ) | pch | {
1654
+ try zig_args .append ("-include-pch" );
1655
+ try zig_args .append (pch .getEmittedBin ().getPath (b ));
1656
+ try zig_args .append ("-fpch-validate-input-files-content" );
1657
+ }
1614
1658
try zig_args .append ("--" );
1615
1659
prev_has_cflags = true ;
1616
1660
}
0 commit comments