@@ -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 ),
@@ -435,6 +436,7 @@ pub const Kind = enum {
435
436
exe ,
436
437
lib ,
437
438
obj ,
439
+ pch ,
438
440
@"test" ,
439
441
};
440
442
@@ -458,6 +460,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
458
460
.exe = > "zig build-exe" ,
459
461
.lib = > "zig build-lib" ,
460
462
.obj = > "zig build-obj" ,
463
+ .pch = > "zig build-pch" ,
461
464
.@"test" = > "zig test" ,
462
465
},
463
466
name_adjusted ,
@@ -467,20 +470,24 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
467
470
468
471
const target_info = NativeTargetInfo .detect (options .target ) catch @panic ("unhandled error" );
469
472
470
- const out_filename = std .zig .binNameAlloc (owner .allocator , .{
471
- .root_name = name ,
472
- .target = target_info .target ,
473
- .output_mode = switch (options .kind ) {
474
- .lib = > .Lib ,
475
- .obj = > .Obj ,
476
- .exe , .@"test" = > .Exe ,
477
- },
478
- .link_mode = if (options .linkage ) | some | @as (std .builtin .LinkMode , switch (some ) {
479
- .dynamic = > .Dynamic ,
480
- .static = > .Static ,
481
- }) else null ,
482
- .version = options .version ,
483
- }) catch @panic ("OOM" );
473
+ const out_filename = if (options .kind == .pch )
474
+ std .fmt .allocPrint (owner .allocator , "{s}.pch" , .{name }) catch @panic ("OOM" )
475
+ else
476
+ std .zig .binNameAlloc (owner .allocator , .{
477
+ .root_name = name ,
478
+ .target = target_info .target ,
479
+ .output_mode = switch (options .kind ) {
480
+ .lib = > .Lib ,
481
+ .obj = > .Obj ,
482
+ .exe , .@"test" = > .Exe ,
483
+ .pch = > unreachable ,
484
+ },
485
+ .link_mode = if (options .linkage ) | some | @as (std .builtin .LinkMode , switch (some ) {
486
+ .dynamic = > .Dynamic ,
487
+ .static = > .Static ,
488
+ }) else null ,
489
+ .version = options .version ,
490
+ }) catch @panic ("OOM" );
484
491
485
492
const self = owner .allocator .create (Compile ) catch @panic ("OOM" );
486
493
self .* = .{
@@ -514,6 +521,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
514
521
.lib_paths = ArrayList (LazyPath ).init (owner .allocator ),
515
522
.rpaths = ArrayList (LazyPath ).init (owner .allocator ),
516
523
.installed_headers = ArrayList (* Step ).init (owner .allocator ),
524
+ .precompiled_header = null ,
517
525
.c_std = std .Build .CStd .C99 ,
518
526
.zig_lib_dir = null ,
519
527
.main_mod_path = null ,
@@ -976,6 +984,8 @@ pub const AddCSourceFilesOptions = struct {
976
984
977
985
/// Handy when you have many C/C++ source files and want them all to have the same flags.
978
986
pub fn addCSourceFiles (self : * Compile , options : AddCSourceFilesOptions ) void {
987
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
988
+
979
989
const b = self .step .owner ;
980
990
const c_source_files = b .allocator .create (CSourceFiles ) catch @panic ("OOM" );
981
991
@@ -991,6 +1001,8 @@ pub fn addCSourceFiles(self: *Compile, options: AddCSourceFilesOptions) void {
991
1001
}
992
1002
993
1003
pub fn addCSourceFile (self : * Compile , source : CSourceFile ) void {
1004
+ assert (self .kind != .pch or self .link_objects .items .len == 0 ); // pch can only be generated from a single C header file
1005
+
994
1006
const b = self .step .owner ;
995
1007
const c_source_file = b .allocator .create (CSourceFile ) catch @panic ("OOM" );
996
1008
c_source_file .* = source .dupe (b );
@@ -1107,23 +1119,39 @@ pub fn getEmittedLlvmBc(self: *Compile) LazyPath {
1107
1119
}
1108
1120
1109
1121
pub fn addAssemblyFile (self : * Compile , source : LazyPath ) void {
1122
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
1123
+
1110
1124
const b = self .step .owner ;
1111
1125
const source_duped = source .dupe (b );
1112
1126
self .link_objects .append (.{ .assembly_file = source_duped }) catch @panic ("OOM" );
1113
1127
source_duped .addStepDependencies (& self .step );
1114
1128
}
1115
1129
1116
1130
pub fn addObjectFile (self : * Compile , source : LazyPath ) void {
1131
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
1132
+
1117
1133
const b = self .step .owner ;
1118
1134
self .link_objects .append (.{ .static_path = source .dupe (b ) }) catch @panic ("OOM" );
1119
1135
source .addStepDependencies (& self .step );
1120
1136
}
1121
1137
1122
1138
pub fn addObject (self : * Compile , obj : * Compile ) void {
1139
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
1140
+
1123
1141
assert (obj .kind == .obj );
1124
1142
self .linkLibraryOrObject (obj );
1125
1143
}
1126
1144
1145
+ pub fn addPrecompiledCHeader (self : * Compile , pch : * Compile ) void {
1146
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
1147
+ assert (pch .kind == .pch );
1148
+
1149
+ if (self .precompiled_header != null ) @panic ("Precompiled header already defined." );
1150
+ self .precompiled_header = pch ;
1151
+
1152
+ pch .getEmittedBin ().addStepDependencies (& self .step );
1153
+ }
1154
+
1127
1155
pub fn addAfterIncludePath (self : * Compile , path : LazyPath ) void {
1128
1156
const b = self .step .owner ;
1129
1157
self .include_dirs .append (IncludeDir { .path_after = path .dupe (b ) }) catch @panic ("OOM" );
@@ -1415,7 +1443,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1415
1443
const cmd = switch (self .kind ) {
1416
1444
.lib = > "build-lib" ,
1417
1445
.exe = > "build-exe" ,
1418
- .obj = > "build-obj" ,
1446
+ .obj , .pch = > "build-obj" ,
1419
1447
.@"test" = > "test" ,
1420
1448
};
1421
1449
try zig_args .append (cmd );
@@ -1431,6 +1459,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1431
1459
try zig_args .append (try std .fmt .allocPrint (b .allocator , "-ofmt={s}" , .{@tagName (ofmt )}));
1432
1460
}
1433
1461
1462
+ if (self .kind == .pch ) {
1463
+ try zig_args .append ("-x" );
1464
+ try zig_args .append (if (self .is_linking_libcpp ) "c++-header" else "c-header" );
1465
+ }
1466
+
1434
1467
switch (self .entry ) {
1435
1468
.default = > {},
1436
1469
.disabled = > try zig_args .append ("-fno-entry" ),
@@ -1482,6 +1515,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1482
1515
.other_step = > | other | switch (other .kind ) {
1483
1516
.exe = > @panic ("Cannot link with an executable build artifact" ),
1484
1517
.@"test" = > @panic ("Cannot link with a test" ),
1518
+ .pch = > @panic ("Cannot link with a precompiled header file" ),
1485
1519
.obj = > {
1486
1520
try zig_args .append (other .getEmittedBin ().getPath (b ));
1487
1521
},
@@ -1578,7 +1612,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1578
1612
},
1579
1613
1580
1614
.c_source_file = > | c_source_file | {
1581
- if (c_source_file .flags .len == 0 ) {
1615
+ if (c_source_file .flags .len == 0 and self . precompiled_header == null ) {
1582
1616
if (prev_has_cflags ) {
1583
1617
try zig_args .append ("-cflags" );
1584
1618
try zig_args .append ("--" );
@@ -1589,14 +1623,18 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1589
1623
for (c_source_file .flags ) | arg | {
1590
1624
try zig_args .append (arg );
1591
1625
}
1626
+ if (self .precompiled_header ) | pch | {
1627
+ try zig_args .append ("-include-pch" );
1628
+ try zig_args .append (pch .getEmittedBin ().getPath (b ));
1629
+ }
1592
1630
try zig_args .append ("--" );
1593
1631
prev_has_cflags = true ;
1594
1632
}
1595
1633
try zig_args .append (c_source_file .file .getPath (b ));
1596
1634
},
1597
1635
1598
1636
.c_source_files = > | c_source_files | {
1599
- if (c_source_files .flags .len == 0 ) {
1637
+ if (c_source_files .flags .len == 0 and self . precompiled_header == null ) {
1600
1638
if (prev_has_cflags ) {
1601
1639
try zig_args .append ("-cflags" );
1602
1640
try zig_args .append ("--" );
@@ -1607,6 +1645,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1607
1645
for (c_source_files .flags ) | flag | {
1608
1646
try zig_args .append (flag );
1609
1647
}
1648
+ if (self .precompiled_header ) | pch | {
1649
+ try zig_args .append ("-include-pch" );
1650
+ try zig_args .append (pch .getEmittedBin ().getPath (b ));
1651
+ }
1610
1652
try zig_args .append ("--" );
1611
1653
prev_has_cflags = true ;
1612
1654
}
0 commit comments