@@ -273,6 +273,7 @@ pub const Kind = enum {
273
273
exe ,
274
274
lib ,
275
275
obj ,
276
+ pch ,
276
277
@"test" ,
277
278
};
278
279
@@ -356,24 +357,29 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
356
357
.exe = > "zig build-exe" ,
357
358
.lib = > "zig build-lib" ,
358
359
.obj = > "zig build-obj" ,
360
+ .pch = > "zig build-pch" ,
359
361
.@"test" = > "zig test" ,
360
362
},
361
363
name_adjusted ,
362
364
@tagName (options .root_module .optimize orelse .Debug ),
363
365
resolved_target .query .zigTriple (owner .allocator ) catch @panic ("OOM" ),
364
366
});
365
367
366
- const out_filename = std .zig .binNameAlloc (owner .allocator , .{
367
- .root_name = name ,
368
- .target = target ,
369
- .output_mode = switch (options .kind ) {
370
- .lib = > .Lib ,
371
- .obj = > .Obj ,
372
- .exe , .@"test" = > .Exe ,
373
- },
374
- .link_mode = options .linkage ,
375
- .version = options .version ,
376
- }) catch @panic ("OOM" );
368
+ const out_filename = if (options .kind == .pch )
369
+ std .fmt .allocPrint (owner .allocator , "{s}.pch" , .{name }) catch @panic ("OOM" )
370
+ else
371
+ std .zig .binNameAlloc (owner .allocator , .{
372
+ .root_name = name ,
373
+ .target = target ,
374
+ .output_mode = switch (options .kind ) {
375
+ .lib = > .Lib ,
376
+ .obj = > .Obj ,
377
+ .exe , .@"test" = > .Exe ,
378
+ .pch = > unreachable ,
379
+ },
380
+ .link_mode = options .linkage ,
381
+ .version = options .version ,
382
+ }) catch @panic ("OOM" );
377
383
378
384
const compile = owner .allocator .create (Compile ) catch @panic ("OOM" );
379
385
compile .* = .{
@@ -802,17 +808,20 @@ pub fn linkFrameworkWeak(c: *Compile, name: []const u8) void {
802
808
803
809
/// Handy when you have many C/C++ source files and want them all to have the same flags.
804
810
pub fn addCSourceFiles (compile : * Compile , options : Module.AddCSourceFilesOptions ) void {
811
+ assert (compile .kind != .pch ); // pch can only be generated from a single C header file
805
812
compile .root_module .addCSourceFiles (options );
806
813
}
807
814
808
815
pub fn addCSourceFile (compile : * Compile , source : Module.CSourceFile ) void {
816
+ assert (compile .kind != .pch or compile .root_module .link_objects .items .len == 0 ); // pch can only be generated from a single C header file
809
817
compile .root_module .addCSourceFile (source );
810
818
}
811
819
812
820
/// Resource files must have the extension `.rc`.
813
821
/// Can be called regardless of target. The .rc file will be ignored
814
822
/// if the target object format does not support embedded resources.
815
823
pub fn addWin32ResourceFile (compile : * Compile , source : Module.RcSourceFile ) void {
824
+ assert (compile .kind != .pch ); // pch can only be generated from a single C header file
816
825
compile .root_module .addWin32ResourceFile (source );
817
826
}
818
827
@@ -893,14 +902,17 @@ pub fn getEmittedLlvmBc(compile: *Compile) LazyPath {
893
902
}
894
903
895
904
pub fn addAssemblyFile (compile : * Compile , source : Module.AsmSourceFile ) void {
905
+ assert (compile .kind != .pch ); // pch can only be generated from a single C header file
896
906
compile .root_module .addAssemblyFile (source );
897
907
}
898
908
899
909
pub fn addObjectFile (compile : * Compile , source : LazyPath ) void {
910
+ assert (compile .kind != .pch ); // pch can only be generated from a single C header file
900
911
compile .root_module .addObjectFile (source );
901
912
}
902
913
903
914
pub fn addObject (compile : * Compile , object : * Compile ) void {
915
+ assert (compile .kind != .pch ); // pch can only be generated from a single C header file
904
916
compile .root_module .addObject (object );
905
917
}
906
918
@@ -1025,6 +1037,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
1025
1037
.lib = > "build-lib" ,
1026
1038
.exe = > "build-exe" ,
1027
1039
.obj = > "build-obj" ,
1040
+ .pch = > "build-pch" ,
1028
1041
.@"test" = > "test" ,
1029
1042
};
1030
1043
try zig_args .append (cmd );
@@ -1092,6 +1105,14 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
1092
1105
}
1093
1106
}
1094
1107
1108
+ if (compile .kind == .pch ) {
1109
+ // precompiled headers must have a single input header file.
1110
+ var it = compile .root_module .iterateDependencies (compile , false );
1111
+ const link_objects = it .next ().? .module .link_objects ;
1112
+ assert (link_objects .items .len == 1 and link_objects .items [0 ] == .c_source_file );
1113
+ assert (it .next () == null );
1114
+ }
1115
+
1095
1116
var cli_named_modules = try CliNamedModules .init (arena , & compile .root_module );
1096
1117
1097
1118
// For this loop, don't chase dynamic libraries because their link
@@ -1203,6 +1224,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
1203
1224
switch (other .kind ) {
1204
1225
.exe = > return step .fail ("cannot link with an executable build artifact" , .{}),
1205
1226
.@"test" = > return step .fail ("cannot link with a test" , .{}),
1227
+ .pch = > @panic ("Cannot link with a precompiled header file" ),
1206
1228
.obj = > {
1207
1229
const included_in_lib_or_obj = ! my_responsibility and
1208
1230
(dep .compile .? .kind == .lib or dep .compile .? .kind == .obj );
0 commit comments