@@ -252,6 +252,7 @@ pub const Kind = enum {
252
252
exe ,
253
253
lib ,
254
254
obj ,
255
+ pch ,
255
256
@"test" ,
256
257
};
257
258
@@ -359,24 +360,29 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
359
360
.exe = > "zig build-exe" ,
360
361
.lib = > "zig build-lib" ,
361
362
.obj = > "zig build-obj" ,
363
+ .pch = > "zig build-pch" ,
362
364
.@"test" = > "zig test" ,
363
365
},
364
366
name_adjusted ,
365
367
@tagName (options .root_module .optimize orelse .Debug ),
366
368
resolved_target .query .zigTriple (owner .allocator ) catch @panic ("OOM" ),
367
369
});
368
370
369
- const out_filename = std .zig .binNameAlloc (owner .allocator , .{
370
- .root_name = name ,
371
- .target = target ,
372
- .output_mode = switch (options .kind ) {
373
- .lib = > .Lib ,
374
- .obj = > .Obj ,
375
- .exe , .@"test" = > .Exe ,
376
- },
377
- .link_mode = options .linkage ,
378
- .version = options .version ,
379
- }) catch @panic ("OOM" );
371
+ const out_filename = if (options .kind == .pch )
372
+ std .fmt .allocPrint (owner .allocator , "{s}.pch" , .{name }) catch @panic ("OOM" )
373
+ else
374
+ std .zig .binNameAlloc (owner .allocator , .{
375
+ .root_name = name ,
376
+ .target = target ,
377
+ .output_mode = switch (options .kind ) {
378
+ .lib = > .Lib ,
379
+ .obj = > .Obj ,
380
+ .exe , .@"test" = > .Exe ,
381
+ .pch = > unreachable ,
382
+ },
383
+ .link_mode = options .linkage ,
384
+ .version = options .version ,
385
+ }) catch @panic ("OOM" );
380
386
381
387
const self = owner .allocator .create (Compile ) catch @panic ("OOM" );
382
388
self .* = .{
@@ -801,17 +807,20 @@ pub fn linkFrameworkWeak(c: *Compile, name: []const u8) void {
801
807
802
808
/// Handy when you have many C/C++ source files and want them all to have the same flags.
803
809
pub fn addCSourceFiles (self : * Compile , options : Module.AddCSourceFilesOptions ) void {
810
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
804
811
self .root_module .addCSourceFiles (options );
805
812
}
806
813
807
814
pub fn addCSourceFile (self : * Compile , source : Module.CSourceFile ) void {
815
+ assert (self .kind != .pch or self .root_module .link_objects .items .len == 0 ); // pch can only be generated from a single C header file
808
816
self .root_module .addCSourceFile (source );
809
817
}
810
818
811
819
/// Resource files must have the extension `.rc`.
812
820
/// Can be called regardless of target. The .rc file will be ignored
813
821
/// if the target object format does not support embedded resources.
814
822
pub fn addWin32ResourceFile (self : * Compile , source : Module.RcSourceFile ) void {
823
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
815
824
self .root_module .addWin32ResourceFile (source );
816
825
}
817
826
@@ -894,14 +903,17 @@ pub fn getEmittedLlvmBc(self: *Compile) LazyPath {
894
903
}
895
904
896
905
pub fn addAssemblyFile (self : * Compile , source : LazyPath ) void {
906
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
897
907
self .root_module .addAssemblyFile (source );
898
908
}
899
909
900
910
pub fn addObjectFile (self : * Compile , source : LazyPath ) void {
911
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
901
912
self .root_module .addObjectFile (source );
902
913
}
903
914
904
915
pub fn addObject (self : * Compile , object : * Compile ) void {
916
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
905
917
self .root_module .addObject (object );
906
918
}
907
919
@@ -1026,6 +1038,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1026
1038
.lib = > "build-lib" ,
1027
1039
.exe = > "build-exe" ,
1028
1040
.obj = > "build-obj" ,
1041
+ .pch = > "build-pch" ,
1029
1042
.@"test" = > "test" ,
1030
1043
};
1031
1044
try zig_args .append (cmd );
@@ -1098,6 +1111,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1098
1111
}
1099
1112
}
1100
1113
1114
+ if (self .kind == .pch ) {
1115
+ // precompiled headers must have a single input header file.
1116
+ var it = self .root_module .iterateDependencies (self , false );
1117
+ const link_objects = it .next ().? .module .link_objects ;
1118
+ assert (link_objects .items .len == 1 and link_objects .items [0 ] == .c_source_file );
1119
+ assert (it .next () == null );
1120
+ }
1121
+
1101
1122
var cli_named_modules = try CliNamedModules .init (arena , & self .root_module );
1102
1123
1103
1124
// For this loop, don't chase dynamic libraries because their link
@@ -1206,6 +1227,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1206
1227
switch (other .kind ) {
1207
1228
.exe = > return step .fail ("cannot link with an executable build artifact" , .{}),
1208
1229
.@"test" = > return step .fail ("cannot link with a test" , .{}),
1230
+ .pch = > @panic ("Cannot link with a precompiled header file" ),
1209
1231
.obj = > {
1210
1232
const included_in_lib_or_obj = ! my_responsibility and (compile .kind == .lib or compile .kind == .obj );
1211
1233
if (! already_linked and ! included_in_lib_or_obj ) {
0 commit comments