@@ -238,6 +238,7 @@ pub const Kind = enum {
238
238
exe ,
239
239
lib ,
240
240
obj ,
241
+ pch ,
241
242
@"test" ,
242
243
};
243
244
@@ -263,27 +264,32 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
263
264
.exe = > "zig build-exe" ,
264
265
.lib = > "zig build-lib" ,
265
266
.obj = > "zig build-obj" ,
267
+ .pch = > "zig build-pch" ,
266
268
.@"test" = > "zig test" ,
267
269
},
268
270
name_adjusted ,
269
271
@tagName (options .root_module .optimize orelse .Debug ),
270
272
resolved_target .query .zigTriple (owner .allocator ) catch @panic ("OOM" ),
271
273
});
272
274
273
- const out_filename = std .zig .binNameAlloc (owner .allocator , .{
274
- .root_name = name ,
275
- .target = target ,
276
- .output_mode = switch (options .kind ) {
277
- .lib = > .Lib ,
278
- .obj = > .Obj ,
279
- .exe , .@"test" = > .Exe ,
280
- },
281
- .link_mode = if (options .linkage ) | some | @as (std .builtin .LinkMode , switch (some ) {
282
- .dynamic = > .Dynamic ,
283
- .static = > .Static ,
284
- }) else null ,
285
- .version = options .version ,
286
- }) catch @panic ("OOM" );
275
+ const out_filename = if (options .kind == .pch )
276
+ std .fmt .allocPrint (owner .allocator , "{s}.pch" , .{name }) catch @panic ("OOM" )
277
+ else
278
+ std .zig .binNameAlloc (owner .allocator , .{
279
+ .root_name = name ,
280
+ .target = target ,
281
+ .output_mode = switch (options .kind ) {
282
+ .lib = > .Lib ,
283
+ .obj = > .Obj ,
284
+ .exe , .@"test" = > .Exe ,
285
+ .pch = > unreachable ,
286
+ },
287
+ .link_mode = if (options .linkage ) | some | @as (std .builtin .LinkMode , switch (some ) {
288
+ .dynamic = > .Dynamic ,
289
+ .static = > .Static ,
290
+ }) else null ,
291
+ .version = options .version ,
292
+ }) catch @panic ("OOM" );
287
293
288
294
const self = owner .allocator .create (Compile ) catch @panic ("OOM" );
289
295
self .* = .{
@@ -691,17 +697,20 @@ pub fn linkFrameworkWeak(c: *Compile, name: []const u8) void {
691
697
692
698
/// Handy when you have many C/C++ source files and want them all to have the same flags.
693
699
pub fn addCSourceFiles (self : * Compile , options : Module.AddCSourceFilesOptions ) void {
700
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
694
701
self .root_module .addCSourceFiles (options );
695
702
}
696
703
697
704
pub fn addCSourceFile (self : * Compile , source : Module.CSourceFile ) void {
705
+ assert (self .kind != .pch or self .root_module .link_objects .items .len == 0 ); // pch can only be generated from a single C header file
698
706
self .root_module .addCSourceFile (source );
699
707
}
700
708
701
709
/// Resource files must have the extension `.rc`.
702
710
/// Can be called regardless of target. The .rc file will be ignored
703
711
/// if the target object format does not support embedded resources.
704
712
pub fn addWin32ResourceFile (self : * Compile , source : Module.RcSourceFile ) void {
713
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
705
714
self .root_module .addWin32ResourceFile (source );
706
715
}
707
716
@@ -784,14 +793,17 @@ pub fn getEmittedLlvmBc(self: *Compile) LazyPath {
784
793
}
785
794
786
795
pub fn addAssemblyFile (self : * Compile , source : LazyPath ) void {
796
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
787
797
self .root_module .addAssemblyFile (source );
788
798
}
789
799
790
800
pub fn addObjectFile (self : * Compile , source : LazyPath ) void {
801
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
791
802
self .root_module .addObjectFile (source );
792
803
}
793
804
794
805
pub fn addObject (self : * Compile , object : * Compile ) void {
806
+ assert (self .kind != .pch ); // pch can only be generated from a single C header file
795
807
self .root_module .addObject (object );
796
808
}
797
809
@@ -916,6 +928,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
916
928
.lib = > "build-lib" ,
917
929
.exe = > "build-exe" ,
918
930
.obj = > "build-obj" ,
931
+ .pch = > "build-pch" ,
919
932
.@"test" = > "test" ,
920
933
};
921
934
try zig_args .append (cmd );
@@ -975,6 +988,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
975
988
}
976
989
}
977
990
991
+ if (self .kind == .pch ) {
992
+ // precompiled headers must have a single input header file.
993
+ var it = self .root_module .iterateDependencies (self , false );
994
+ const link_objects = it .next ().? .module .link_objects ;
995
+ assert (link_objects .items .len == 1 and link_objects .items [0 ] == .c_source_file );
996
+ assert (it .next () == null );
997
+ }
998
+
978
999
var cli_named_modules = try CliNamedModules .init (arena , & self .root_module );
979
1000
980
1001
// For this loop, don't chase dynamic libraries because their link
@@ -1076,6 +1097,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1076
1097
switch (other .kind ) {
1077
1098
.exe = > return step .fail ("cannot link with an executable build artifact" , .{}),
1078
1099
.@"test" = > return step .fail ("cannot link with a test" , .{}),
1100
+ .pch = > @panic ("Cannot link with a precompiled header file" ),
1079
1101
.obj = > {
1080
1102
const included_in_lib_or_obj = ! my_responsibility and (compile .kind == .lib or compile .kind == .obj );
1081
1103
if (! already_linked and ! included_in_lib_or_obj ) {
0 commit comments