Skip to content

Commit ed01db0

Browse files
committed
std.Build: add an option to addCSourceFiles() to include a precompiled header
1 parent 4deaef5 commit ed01db0

File tree

8 files changed

+166
-2
lines changed

8 files changed

+166
-2
lines changed

lib/std/Build/Module.zig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,18 +153,21 @@ pub const CSourceFiles = struct {
153153
files: []const []const u8,
154154
lang: ?CSourceLang = null,
155155
flags: []const []const u8,
156+
precompiled_header: ?LazyPath = null,
156157
};
157158

158159
pub const CSourceFile = struct {
159160
file: LazyPath,
160161
lang: ?CSourceLang = null,
161162
flags: []const []const u8 = &.{},
163+
precompiled_header: ?LazyPath = null,
162164

163165
pub fn dupe(file: CSourceFile, b: *std.Build) CSourceFile {
164166
return .{
165167
.file = file.file.dupe(b),
166168
.lang = file.lang,
167169
.flags = b.dupeStrings(file.flags),
170+
.precompiled_header = file.precompiled_header,
168171
};
169172
}
170173
};
@@ -557,6 +560,7 @@ pub const AddCSourceFilesOptions = struct {
557560
files: []const []const u8,
558561
lang: ?CSourceLang = null,
559562
flags: []const []const u8 = &.{},
563+
precompiled_header: ?LazyPath = null,
560564
};
561565

562566
/// Handy when you have many C/C++ source files and want them all to have the same flags.
@@ -579,9 +583,14 @@ pub fn addCSourceFiles(m: *Module, options: AddCSourceFilesOptions) void {
579583
.files = b.dupeStrings(options.files),
580584
.lang = options.lang,
581585
.flags = b.dupeStrings(options.flags),
586+
.precompiled_header = options.precompiled_header,
582587
};
583588
m.link_objects.append(allocator, .{ .c_source_files = c_source_files }) catch @panic("OOM");
584589
addLazyPathDependenciesOnly(m, c_source_files.root);
590+
591+
if (options.precompiled_header) |pch| {
592+
addLazyPathDependenciesOnly(m, pch);
593+
}
585594
}
586595

587596
pub fn addCSourceFile(m: *Module, source: CSourceFile) void {
@@ -591,6 +600,10 @@ pub fn addCSourceFile(m: *Module, source: CSourceFile) void {
591600
c_source_file.* = source.dupe(b);
592601
m.link_objects.append(allocator, .{ .c_source_file = c_source_file }) catch @panic("OOM");
593602
addLazyPathDependenciesOnly(m, source.file);
603+
604+
if (source.precompiled_header) |pch| {
605+
addLazyPathDependenciesOnly(m, pch);
606+
}
594607
}
595608

596609
/// Resource files must have the extension `.rc`.

lib/std/Build/Step/Compile.zig

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,7 @@ fn getZigArgs(compile: *Compile) ![][]const u8 {
12721272
.c_source_file => |c_source_file| l: {
12731273
if (!my_responsibility) break :l;
12741274

1275-
if (c_source_file.flags.len == 0) {
1275+
if (c_source_file.flags.len == 0 and c_source_file.precompiled_header == null) {
12761276
if (prev_has_cflags) {
12771277
try zig_args.append("-cflags");
12781278
try zig_args.append("--");
@@ -1283,6 +1283,11 @@ fn getZigArgs(compile: *Compile) ![][]const u8 {
12831283
for (c_source_file.flags) |arg| {
12841284
try zig_args.append(arg);
12851285
}
1286+
if (c_source_file.precompiled_header) |pch| {
1287+
try zig_args.append("-include-pch");
1288+
try zig_args.append(pch.getPath(b));
1289+
try zig_args.append("-fpch-validate-input-files-content");
1290+
}
12861291
try zig_args.append("--");
12871292
prev_has_cflags = true;
12881293
}
@@ -1304,7 +1309,7 @@ fn getZigArgs(compile: *Compile) ![][]const u8 {
13041309
.c_source_files => |c_source_files| l: {
13051310
if (!my_responsibility) break :l;
13061311

1307-
if (c_source_files.flags.len == 0) {
1312+
if (c_source_files.flags.len == 0 and c_source_files.precompiled_header == null) {
13081313
if (prev_has_cflags) {
13091314
try zig_args.append("-cflags");
13101315
try zig_args.append("--");
@@ -1315,6 +1320,13 @@ fn getZigArgs(compile: *Compile) ![][]const u8 {
13151320
for (c_source_files.flags) |flag| {
13161321
try zig_args.append(flag);
13171322
}
1323+
1324+
if (c_source_files.precompiled_header) |pch| {
1325+
try zig_args.append("-include-pch");
1326+
try zig_args.append(pch.getPath(b));
1327+
try zig_args.append("-fpch-validate-input-files-content");
1328+
}
1329+
13181330
try zig_args.append("--");
13191331
prev_has_cflags = true;
13201332
}

test/standalone/build.zig.zon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@
173173
.dependencyFromBuildZig = .{
174174
.path = "dependencyFromBuildZig",
175175
},
176+
.precompiled_c_headers = .{
177+
.path = "pch",
178+
},
176179
.run_output_paths = .{
177180
.path = "run_output_paths",
178181
},

test/standalone/pch/build.zig

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
const std = @import("std");
2+
3+
pub fn build(b: *std.Build) void {
4+
const test_step = b.step("test", "Test it");
5+
b.default_step = test_step;
6+
7+
const target = b.standardTargetOptions(.{});
8+
const optimize = b.standardOptimizeOption(.{});
9+
10+
// c-header
11+
{
12+
const exe = b.addExecutable(.{
13+
.name = "pchtest",
14+
.target = target,
15+
.optimize = optimize,
16+
.link_libc = true,
17+
});
18+
19+
const pch = b.addPrecompiledCHeader(.{
20+
.name = "pch_c",
21+
.target = target,
22+
.optimize = optimize,
23+
.link_libc = true,
24+
}, .{
25+
.file = b.path("include_a.h"),
26+
.flags = &[_][]const u8{},
27+
.lang = .h,
28+
});
29+
30+
exe.addCSourceFiles(.{
31+
.files = &.{"test.c"},
32+
.flags = &[_][]const u8{},
33+
.lang = .c,
34+
.precompiled_header = pch.getEmittedBin(),
35+
});
36+
37+
test_step.dependOn(&b.addRunArtifact(exe).step);
38+
}
39+
40+
// c++-header
41+
{
42+
const exe = b.addExecutable(.{
43+
.name = "pchtest++",
44+
.target = target,
45+
.optimize = optimize,
46+
.link_libc = true,
47+
});
48+
exe.linkLibCpp();
49+
50+
const pch = b.addPrecompiledCHeader(.{
51+
.name = "pch_c++",
52+
.target = target,
53+
.optimize = optimize,
54+
.link_libcpp = true,
55+
}, .{
56+
.file = b.path("include_a.h"),
57+
.flags = &[_][]const u8{},
58+
.lang = .hpp,
59+
});
60+
61+
exe.addCSourceFile(.{
62+
.file = b.path("test.cpp"),
63+
.flags = &[_][]const u8{},
64+
.precompiled_header = pch.getEmittedBin(),
65+
});
66+
67+
test_step.dependOn(&b.addRunArtifact(exe).step);
68+
}
69+
}

test/standalone/pch/include_a.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include "include_b.h"
4+
5+
#include <string.h>
6+
#include <stdlib.h>
7+
8+
#if defined(__cplusplus)
9+
#include <iostream>
10+
#else
11+
#include <stdio.h>
12+
#endif
13+
14+
#define A_INCLUDED 1
15+

test/standalone/pch/include_b.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include <math.h>
4+
5+
typedef double real;
6+
7+
#define B_INCLUDED 1

test/standalone/pch/test.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
// includes commented out to make sure the symbols come from the precompiled header.
3+
//#include "include_a.h"
4+
//#include "include_b.h"
5+
6+
#ifndef A_INCLUDED
7+
#error "pch not included"
8+
#endif
9+
#ifndef B_INCLUDED
10+
#error "pch not included"
11+
#endif
12+
13+
int main(int argc, char *argv[])
14+
{
15+
real a = 0.123;
16+
17+
if (argc > 1) {
18+
fprintf(stdout, "abs(%g)=%g\n", a, fabs(a));
19+
}
20+
21+
return EXIT_SUCCESS;
22+
}

test/standalone/pch/test.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
// includes commented out to make sure the symbols come from the precompiled header.
3+
//#include "includeA.h"
4+
//#include "includeB.h"
5+
6+
#ifndef A_INCLUDED
7+
#error "pch not included"
8+
#endif
9+
#ifndef B_INCLUDED
10+
#error "pch not included"
11+
#endif
12+
13+
int main(int argc, char *argv[])
14+
{
15+
real a = -0.123;
16+
17+
if (argc > 1) {
18+
std::cout << "abs(" << a << ")=" << fabs(a) << "\n";
19+
}
20+
21+
return EXIT_SUCCESS;
22+
}
23+

0 commit comments

Comments
 (0)