-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add precompiled c/c++ header support to zig build #17956
base: master
Are you sure you want to change the base?
Changes from all commits
0f87959
a6b7560
761cb7d
f434e49
a863f5f
47d9aef
1dbc006
0bd9380
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,11 +46,39 @@ pub const RPath = union(enum) { | |
special: []const u8, | ||
}; | ||
|
||
// subset of Compilation.FileExt | ||
pub const AsmSourceLang = enum { | ||
assembly, | ||
assembly_with_cpp, | ||
|
||
pub fn getName(lang: @This()) []const u8 { | ||
return switch (lang) { | ||
.assembly => "assembler", | ||
.assembly_with_cpp => "assembler-with-cpp", | ||
}; | ||
} | ||
}; | ||
|
||
pub const AsmSourceFile = struct { | ||
file: LazyPath, | ||
/// if null, deduce the language from the file extension | ||
lang: ?AsmSourceLang = null, | ||
flags: []const []const u8 = &.{}, | ||
|
||
pub fn dupe(file: AsmSourceFile, b: *std.Build) AsmSourceFile { | ||
return .{ | ||
.file = file.file.dupe(b), | ||
.flags = b.dupeStrings(file.flags), | ||
.lang = file.lang, | ||
}; | ||
} | ||
}; | ||
|
||
pub const LinkObject = union(enum) { | ||
static_path: LazyPath, | ||
other_step: *Step.Compile, | ||
system_lib: SystemLib, | ||
assembly_file: LazyPath, | ||
assembly_file: *AsmSourceFile, | ||
c_source_file: *CSourceFile, | ||
c_source_files: *CSourceFiles, | ||
win32_resource_file: *RcSourceFile, | ||
|
@@ -78,22 +106,88 @@ pub const SystemLib = struct { | |
pub const SearchStrategy = enum { paths_first, mode_first, no_fallback }; | ||
}; | ||
|
||
/// Supported languages for "zig clang -x <lang>". | ||
// subset of Compilation.FileExt | ||
pub const CSourceLang = enum { | ||
/// "c" | ||
c, | ||
/// "c-header" | ||
h, | ||
/// "c++" | ||
cpp, | ||
/// "c++-header" | ||
hpp, | ||
/// "objective-c" | ||
m, | ||
/// "objective-c-header" | ||
hm, | ||
/// "objective-c++" | ||
mm, | ||
/// "objective-c++-header" | ||
hmm, | ||
/// "assembler" | ||
assembly, | ||
/// "assembler-with-cpp" | ||
assembly_with_cpp, | ||
Comment on lines
+128
to
+131
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there is already an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, as I said I'm more drawn to removing it. and maybe finding a better name for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Relevant comment about the name: #20655 (comment) Zig primarily has built-in first-class support for the C and C-like languages, and I don't believe there is intention to have that kind of support for other languages, so addCSourceFile may be fine. |
||
/// "cuda" | ||
cu, | ||
|
||
pub fn getName(lang: @This()) []const u8 { | ||
return switch (lang) { | ||
.assembly => "assembler", | ||
.assembly_with_cpp => "assembler-with-cpp", | ||
.c => "c", | ||
.cpp => "c++", | ||
.h => "c-header", | ||
.hpp => "c++-header", | ||
.hm => "objective-c-header", | ||
.hmm => "objective-c++-header", | ||
.cu => "cuda", | ||
.m => "objective-c", | ||
.mm => "objective-c++", | ||
}; | ||
} | ||
}; | ||
|
||
pub const PrecompiledHeader = union(enum) { | ||
/// automatically create the PCH compile step for the source header file, | ||
/// inheriting the options from the parent compile step. | ||
source_header: struct { path: LazyPath, lang: ?CSourceLang = null }, | ||
|
||
/// final PCH compile step, | ||
/// can be provided by the user or else will be created from the `source_header` field during step finalization. | ||
pch_step: *Step.Compile, | ||
|
||
pub fn getPath(pch: PrecompiledHeader, b: *std.Build) []const u8 { | ||
switch (pch) { | ||
.source_header => unreachable, | ||
.pch_step => |pch_step| return pch_step.getEmittedBin().getPath(b), | ||
} | ||
} | ||
}; | ||
pub const CSourceFiles = struct { | ||
root: LazyPath, | ||
/// `files` is relative to `root`, which is | ||
/// the build root by default | ||
files: []const []const u8, | ||
/// if null, deduce the language from the file extension | ||
lang: ?CSourceLang = null, | ||
xxxbxxx marked this conversation as resolved.
Show resolved
Hide resolved
|
||
flags: []const []const u8, | ||
precompiled_header: ?PrecompiledHeader = null, | ||
}; | ||
|
||
pub const CSourceFile = struct { | ||
file: LazyPath, | ||
lang: ?CSourceLang = null, | ||
flags: []const []const u8 = &.{}, | ||
precompiled_header: ?PrecompiledHeader = null, | ||
|
||
pub fn dupe(file: CSourceFile, b: *std.Build) CSourceFile { | ||
return .{ | ||
.file = file.file.dupe(b), | ||
.lang = file.lang, | ||
.flags = b.dupeStrings(file.flags), | ||
.precompiled_header = file.precompiled_header, | ||
}; | ||
} | ||
}; | ||
|
@@ -377,7 +471,9 @@ pub const AddCSourceFilesOptions = struct { | |
/// package that owns the `Compile` step. | ||
root: ?LazyPath = null, | ||
files: []const []const u8, | ||
lang: ?CSourceLang = null, | ||
flags: []const []const u8 = &.{}, | ||
precompiled_header: ?PrecompiledHeader = null, | ||
}; | ||
|
||
/// Handy when you have many C/C++ source files and want them all to have the same flags. | ||
|
@@ -398,9 +494,18 @@ pub fn addCSourceFiles(m: *Module, options: AddCSourceFilesOptions) void { | |
c_source_files.* = .{ | ||
.root = options.root orelse b.path(""), | ||
.files = b.dupeStrings(options.files), | ||
.lang = options.lang, | ||
.flags = b.dupeStrings(options.flags), | ||
.precompiled_header = options.precompiled_header, | ||
}; | ||
m.link_objects.append(allocator, .{ .c_source_files = c_source_files }) catch @panic("OOM"); | ||
|
||
if (options.precompiled_header) |pch| { | ||
switch (pch) { | ||
.source_header => {}, | ||
.pch_step => |step| _ = step.getEmittedBin(), // Indicate there is a dependency on the outputted binary. | ||
} | ||
} | ||
} | ||
|
||
pub fn addCSourceFile(m: *Module, source: CSourceFile) void { | ||
|
@@ -409,6 +514,13 @@ pub fn addCSourceFile(m: *Module, source: CSourceFile) void { | |
const c_source_file = allocator.create(CSourceFile) catch @panic("OOM"); | ||
c_source_file.* = source.dupe(b); | ||
m.link_objects.append(allocator, .{ .c_source_file = c_source_file }) catch @panic("OOM"); | ||
|
||
if (source.precompiled_header) |pch| { | ||
switch (pch) { | ||
.source_header => {}, | ||
.pch_step => |step| _ = step.getEmittedBin(), // Indicate there is a dependency on the outputted binary. | ||
} | ||
} | ||
} | ||
|
||
/// Resource files must have the extension `.rc`. | ||
|
@@ -427,9 +539,11 @@ pub fn addWin32ResourceFile(m: *Module, source: RcSourceFile) void { | |
m.link_objects.append(allocator, .{ .win32_resource_file = rc_source_file }) catch @panic("OOM"); | ||
} | ||
|
||
pub fn addAssemblyFile(m: *Module, source: LazyPath) void { | ||
pub fn addAssemblyFile(m: *Module, source: AsmSourceFile) void { | ||
const b = m.owner; | ||
m.link_objects.append(b.allocator, .{ .assembly_file = source.dupe(b) }) catch @panic("OOM"); | ||
const source_file = b.allocator.create(AsmSourceFile) catch @panic("OOM"); | ||
source_file.* = source.dupe(b); | ||
m.link_objects.append(b.allocator, .{ .assembly_file = source_file }) catch @panic("OOM"); | ||
} | ||
|
||
pub fn addObjectFile(m: *Module, object: LazyPath) void { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a way to specify defines and/or flags? When using assembly with the C preprocessor, defines are definitely important; I'm not sure if general purpose flags would be of any use though, and defines are only used in assembly with the C preprocessor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess so, but I never used
addAssemblyFile()
myself so I don't know how it is used by people. And I don't know if there is a reason to have it separate fromaddCSourceFile()
- which coincidentally also allows for asm files with defines and all.maybe it should just be removed?
Altough I don't want to include unrelated changes to the pull request, looks like I still felt compelled to add
AsmSourceFile
to make the API ofaddAssemblyFile()
more similar toaddCSourceFile()
for some reason, maybe I shouldn't have or I should go all the way. (but that looks like wasted effort if it is to be deleted)