@@ -254,6 +254,7 @@ pub const Kind = enum {
254
254
exe ,
255
255
lib ,
256
256
obj ,
257
+ pch ,
257
258
@"test" ,
258
259
};
259
260
@@ -337,24 +338,29 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
337
338
.exe = > "zig build-exe" ,
338
339
.lib = > "zig build-lib" ,
339
340
.obj = > "zig build-obj" ,
341
+ .pch = > "zig build-pch" ,
340
342
.@"test" = > "zig test" ,
341
343
},
342
344
name_adjusted ,
343
345
@tagName (options .root_module .optimize orelse .Debug ),
344
346
resolved_target .query .zigTriple (owner .allocator ) catch @panic ("OOM" ),
345
347
});
346
348
347
- const out_filename = std .zig .binNameAlloc (owner .allocator , .{
348
- .root_name = name ,
349
- .target = target ,
350
- .output_mode = switch (options .kind ) {
351
- .lib = > .Lib ,
352
- .obj = > .Obj ,
353
- .exe , .@"test" = > .Exe ,
354
- },
355
- .link_mode = options .linkage ,
356
- .version = options .version ,
357
- }) catch @panic ("OOM" );
349
+ const out_filename = if (options .kind == .pch )
350
+ std .fmt .allocPrint (owner .allocator , "{s}.pch" , .{name }) catch @panic ("OOM" )
351
+ else
352
+ std .zig .binNameAlloc (owner .allocator , .{
353
+ .root_name = name ,
354
+ .target = target ,
355
+ .output_mode = switch (options .kind ) {
356
+ .lib = > .Lib ,
357
+ .obj = > .Obj ,
358
+ .exe , .@"test" = > .Exe ,
359
+ .pch = > unreachable ,
360
+ },
361
+ .link_mode = options .linkage ,
362
+ .version = options .version ,
363
+ }) catch @panic ("OOM" );
358
364
359
365
const compile = owner .allocator .create (Compile ) catch @panic ("OOM" );
360
366
compile .* = .{
@@ -780,17 +786,20 @@ pub fn linkFrameworkWeak(c: *Compile, name: []const u8) void {
780
786
781
787
/// Handy when you have many C/C++ source files and want them all to have the same flags.
782
788
pub fn addCSourceFiles (compile : * Compile , options : Module.AddCSourceFilesOptions ) void {
789
+ assert (compile .kind != .pch ); // pch can only be generated from a single C header file
783
790
compile .root_module .addCSourceFiles (options );
784
791
}
785
792
786
793
pub fn addCSourceFile (compile : * Compile , source : Module.CSourceFile ) void {
794
+ assert (compile .kind != .pch or compile .root_module .link_objects .items .len == 0 ); // pch can only be generated from a single C header file
787
795
compile .root_module .addCSourceFile (source );
788
796
}
789
797
790
798
/// Resource files must have the extension `.rc`.
791
799
/// Can be called regardless of target. The .rc file will be ignored
792
800
/// if the target object format does not support embedded resources.
793
801
pub fn addWin32ResourceFile (compile : * Compile , source : Module.RcSourceFile ) void {
802
+ assert (compile .kind != .pch ); // pch can only be generated from a single C header file
794
803
compile .root_module .addWin32ResourceFile (source );
795
804
}
796
805
@@ -871,14 +880,17 @@ pub fn getEmittedLlvmBc(compile: *Compile) LazyPath {
871
880
}
872
881
873
882
pub fn addAssemblyFile (compile : * Compile , source : LazyPath ) void {
883
+ assert (compile .kind != .pch ); // pch can only be generated from a single C header file
874
884
compile .root_module .addAssemblyFile (source );
875
885
}
876
886
877
887
pub fn addObjectFile (compile : * Compile , source : LazyPath ) void {
888
+ assert (compile .kind != .pch ); // pch can only be generated from a single C header file
878
889
compile .root_module .addObjectFile (source );
879
890
}
880
891
881
892
pub fn addObject (compile : * Compile , object : * Compile ) void {
893
+ assert (compile .kind != .pch ); // pch can only be generated from a single C header file
882
894
compile .root_module .addObject (object );
883
895
}
884
896
@@ -1003,6 +1015,7 @@ fn getZigArgs(compile: *Compile) ![][]const u8 {
1003
1015
.lib = > "build-lib" ,
1004
1016
.exe = > "build-exe" ,
1005
1017
.obj = > "build-obj" ,
1018
+ .pch = > "build-pch" ,
1006
1019
.@"test" = > "test" ,
1007
1020
};
1008
1021
try zig_args .append (cmd );
@@ -1065,6 +1078,14 @@ fn getZigArgs(compile: *Compile) ![][]const u8 {
1065
1078
}
1066
1079
}
1067
1080
1081
+ if (compile .kind == .pch ) {
1082
+ // precompiled headers must have a single input header file.
1083
+ var it = compile .root_module .iterateDependencies (compile , false );
1084
+ const link_objects = it .next ().? .module .link_objects ;
1085
+ assert (link_objects .items .len == 1 and link_objects .items [0 ] == .c_source_file );
1086
+ assert (it .next () == null );
1087
+ }
1088
+
1068
1089
var cli_named_modules = try CliNamedModules .init (arena , & compile .root_module );
1069
1090
1070
1091
// For this loop, don't chase dynamic libraries because their link
@@ -1170,6 +1191,7 @@ fn getZigArgs(compile: *Compile) ![][]const u8 {
1170
1191
switch (other .kind ) {
1171
1192
.exe = > return step .fail ("cannot link with an executable build artifact" , .{}),
1172
1193
.@"test" = > return step .fail ("cannot link with a test" , .{}),
1194
+ .pch = > @panic ("Cannot link with a precompiled header file" ),
1173
1195
.obj = > {
1174
1196
const included_in_lib_or_obj = ! my_responsibility and
1175
1197
(dep .compile .? .kind == .lib or dep .compile .? .kind == .obj );
0 commit comments