Skip to content

Commit 2156522

Browse files
committed
add std.Build.Module.addForeignSourceFile[s]
1 parent b7e48c6 commit 2156522

File tree

2 files changed

+129
-42
lines changed

2 files changed

+129
-42
lines changed

lib/std/Build/Module.zig

Lines changed: 71 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ pub const LinkObject = union(enum) {
5050
other_step: *Step.Compile,
5151
system_lib: SystemLib,
5252
assembly_file: LazyPath,
53-
c_source_file: *CSourceFile,
54-
c_source_files: *CSourceFiles,
53+
foreign_source_file: *ForeignSourceFile,
54+
foreign_source_files: *ForeignSourceFiles,
5555
win32_resource_file: *RcSourceFile,
5656
};
5757

@@ -77,22 +77,49 @@ pub const SystemLib = struct {
7777
pub const SearchStrategy = enum { paths_first, mode_first, no_fallback };
7878
};
7979

80-
pub const CSourceFiles = struct {
80+
pub const ForeignSourceLanguage = enum {
81+
c,
82+
cpp,
83+
assembly,
84+
assembly_with_cpp,
85+
objc,
86+
objcpp,
87+
88+
find_by_file_extension,
89+
};
90+
91+
pub const ForeignSourceFiles = struct {
8192
root: LazyPath,
8293
/// `files` is relative to `root`, which is
8394
/// the build root by default
8495
files: []const []const u8,
8596
flags: []const []const u8,
97+
language: ForeignSourceLanguage,
8698
};
8799

100+
pub const ForeignSourceFile = struct {
101+
file: LazyPath,
102+
flags: []const []const u8 = &.{},
103+
language: ForeignSourceLanguage,
104+
105+
pub fn dupe(file: ForeignSourceFile, b: *std.Build) ForeignSourceFile {
106+
return .{
107+
.file = file.file.dupe(b),
108+
.flags = b.dupeStrings(file.flags),
109+
.language = file.language,
110+
};
111+
}
112+
};
88113
pub const CSourceFile = struct {
89114
file: LazyPath,
90115
flags: []const []const u8 = &.{},
116+
language: ForeignSourceLanguage = .find_by_file_extension,
91117

92118
pub fn dupe(file: CSourceFile, b: *std.Build) CSourceFile {
93119
return .{
94120
.file = file.file.dupe(b),
95121
.flags = b.dupeStrings(file.flags),
122+
.language = file.language,
96123
};
97124
}
98125
};
@@ -287,10 +314,10 @@ fn addShallowDependencies(m: *Module, dependee: *Module) void {
287314
.assembly_file,
288315
=> |lp| addLazyPathDependencies(m, dependee, lp),
289316

290-
.c_source_file => |x| addLazyPathDependencies(m, dependee, x.file),
317+
.foreign_source_file => |x| addLazyPathDependencies(m, dependee, x.file),
291318
.win32_resource_file => |x| addLazyPathDependencies(m, dependee, x.file),
292319

293-
.c_source_files,
320+
.foreign_source_files,
294321
.system_lib,
295322
=> {},
296323
};
@@ -477,47 +504,75 @@ pub fn linkFramework(m: *Module, name: []const u8, options: LinkFrameworkOptions
477504
m.frameworks.put(b.allocator, b.dupe(name), options) catch @panic("OOM");
478505
}
479506

507+
pub const AddForeignSourceFilesOptions = struct {
508+
/// When provided, `files` are relative to `root` rather than the
509+
/// package that owns the `Compile` step.
510+
root: ?LazyPath = null,
511+
files: []const []const u8,
512+
flags: []const []const u8 = &.{},
513+
language: ForeignSourceLanguage,
514+
};
480515
pub const AddCSourceFilesOptions = struct {
481516
/// When provided, `files` are relative to `root` rather than the
482517
/// package that owns the `Compile` step.
483518
root: ?LazyPath = null,
484519
files: []const []const u8,
485520
flags: []const []const u8 = &.{},
521+
language: ForeignSourceLanguage = .find_by_file_extension,
486522
};
487523

488-
/// Handy when you have many C/C++ source files and want them all to have the same flags.
489-
pub fn addCSourceFiles(m: *Module, options: AddCSourceFilesOptions) void {
524+
/// Handy when you have many non-Zig source files and want them all to have the same flags.
525+
pub fn addForeignSourceFiles(m: *Module, options: AddForeignSourceFilesOptions) void {
490526
const b = m.owner;
491527
const allocator = b.allocator;
492528

493529
for (options.files) |path| {
494530
if (std.fs.path.isAbsolute(path)) {
495531
std.debug.panic(
496-
"file paths added with 'addCSourceFiles' must be relative, found absolute path '{s}'",
532+
"file paths added with 'addForeignSourceFiles' must be relative, found absolute path '{s}'",
497533
.{path},
498534
);
499535
}
500536
}
501537

502-
const c_source_files = allocator.create(CSourceFiles) catch @panic("OOM");
503-
c_source_files.* = .{
538+
const source_files = allocator.create(ForeignSourceFiles) catch @panic("OOM");
539+
source_files.* = .{
504540
.root = options.root orelse b.path(""),
505541
.files = b.dupeStrings(options.files),
506542
.flags = b.dupeStrings(options.flags),
543+
.language = options.language,
507544
};
508-
m.link_objects.append(allocator, .{ .c_source_files = c_source_files }) catch @panic("OOM");
509-
addLazyPathDependenciesOnly(m, c_source_files.root);
545+
m.link_objects.append(allocator, .{ .foreign_source_files = source_files }) catch @panic("OOM");
546+
addLazyPathDependenciesOnly(m, source_files.root);
510547
}
511548

512-
pub fn addCSourceFile(m: *Module, source: CSourceFile) void {
549+
/// Handy when you have many C/C++ source files and want them all to have the same flags.
550+
pub fn addCSourceFiles(m: *Module, options: AddCSourceFilesOptions) void {
551+
addForeignSourceFiles(m, .{
552+
.root = options.root,
553+
.files = options.files,
554+
.flags = options.flags,
555+
.language = options.language,
556+
});
557+
}
558+
559+
pub fn addForeignSourceFile(m: *Module, source: ForeignSourceFile) void {
513560
const b = m.owner;
514561
const allocator = b.allocator;
515-
const c_source_file = allocator.create(CSourceFile) catch @panic("OOM");
516-
c_source_file.* = source.dupe(b);
517-
m.link_objects.append(allocator, .{ .c_source_file = c_source_file }) catch @panic("OOM");
562+
const source_file = allocator.create(ForeignSourceFile) catch @panic("OOM");
563+
source_file.* = source.dupe(b);
564+
m.link_objects.append(allocator, .{ .foreign_source_file = source_file }) catch @panic("OOM");
518565
addLazyPathDependenciesOnly(m, source.file);
519566
}
520567

568+
pub fn addCSourceFile(m: *Module, source: CSourceFile) void {
569+
addForeignSourceFile(m, .{
570+
.file = source.file,
571+
.flags = source.flags,
572+
.language = source.language,
573+
});
574+
}
575+
521576
/// Resource files must have the extension `.rc`.
522577
/// Can be called regardless of target. The .rc file will be ignored
523578
/// if the target object format does not support embedded resources.

lib/std/Build/Step/Compile.zig

Lines changed: 58 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -784,11 +784,18 @@ pub fn linkFrameworkWeak(c: *Compile, name: []const u8) void {
784784
c.root_module.linkFramework(name, .{ .weak = true });
785785
}
786786

787+
/// Handy when you have many non-Zig source files and want them all to have the same flags.
788+
pub fn addForeignSourceFiles(compile: *Compile, options: Module.AddForeignSourceFilesOptions) void {
789+
compile.root_module.addForeignSourceFiles(options);
790+
}
787791
/// Handy when you have many C/C++ source files and want them all to have the same flags.
788792
pub fn addCSourceFiles(compile: *Compile, options: Module.AddCSourceFilesOptions) void {
789793
compile.root_module.addCSourceFiles(options);
790794
}
791795

796+
pub fn addForeignSourceFile(compile: *Compile, source: Module.ForeignSourceFile) void {
797+
compile.root_module.addForeignSourceFile(source);
798+
}
792799
pub fn addCSourceFile(compile: *Compile, source: Module.CSourceFile) void {
793800
compile.root_module.addCSourceFile(source);
794801
}
@@ -1227,51 +1234,76 @@ fn getZigArgs(compile: *Compile) ![][]const u8 {
12271234
total_linker_objects += 1;
12281235
},
12291236

1230-
.c_source_file => |c_source_file| l: {
1237+
.foreign_source_file => |foreign_source_file| l: {
12311238
if (!my_responsibility) break :l;
12321239

1233-
if (c_source_file.flags.len == 0) {
1234-
if (prev_has_cflags) {
1235-
try zig_args.append("-cflags");
1236-
try zig_args.append("--");
1237-
prev_has_cflags = false;
1238-
}
1239-
} else {
1240+
if (prev_has_cflags or foreign_source_file.flags.len != 0) {
12401241
try zig_args.append("-cflags");
1241-
for (c_source_file.flags) |arg| {
1242+
for (foreign_source_file.flags) |arg| {
12421243
try zig_args.append(arg);
12431244
}
12441245
try zig_args.append("--");
1245-
prev_has_cflags = true;
12461246
}
1247-
try zig_args.append(c_source_file.file.getPath2(dep.module.owner, step));
1247+
prev_has_cflags = (foreign_source_file.flags.len != 0);
1248+
1249+
if (foreign_source_file.language != .find_by_file_extension) {
1250+
try zig_args.append("-x");
1251+
try zig_args.append(switch (foreign_source_file.language) {
1252+
.find_by_file_extension => unreachable,
1253+
.c => "c",
1254+
.cpp => "c++",
1255+
.assembly => "assembler",
1256+
.assembly_with_cpp => "assembler-with-cpp",
1257+
.objc => "objective-c",
1258+
.objcpp => "objective-c++",
1259+
});
1260+
}
1261+
1262+
try zig_args.append(foreign_source_file.file.getPath2(dep.module.owner, step));
1263+
1264+
if (foreign_source_file.language != .find_by_file_extension) {
1265+
try zig_args.append("-x");
1266+
try zig_args.append("none");
1267+
}
12481268
total_linker_objects += 1;
12491269
},
12501270

1251-
.c_source_files => |c_source_files| l: {
1271+
.foreign_source_files => |foreign_source_files| l: {
12521272
if (!my_responsibility) break :l;
12531273

1254-
if (c_source_files.flags.len == 0) {
1255-
if (prev_has_cflags) {
1256-
try zig_args.append("-cflags");
1257-
try zig_args.append("--");
1258-
prev_has_cflags = false;
1259-
}
1260-
} else {
1274+
if (prev_has_cflags or foreign_source_files.flags.len != 0) {
12611275
try zig_args.append("-cflags");
1262-
for (c_source_files.flags) |flag| {
1263-
try zig_args.append(flag);
1276+
for (foreign_source_files.flags) |arg| {
1277+
try zig_args.append(arg);
12641278
}
12651279
try zig_args.append("--");
1266-
prev_has_cflags = true;
1280+
}
1281+
prev_has_cflags = (foreign_source_files.flags.len != 0);
1282+
1283+
if (foreign_source_files.language != .find_by_file_extension) {
1284+
try zig_args.append("-x");
1285+
try zig_args.append(switch (foreign_source_files.language) {
1286+
.find_by_file_extension => unreachable,
1287+
.c => "c",
1288+
.cpp => "c++",
1289+
.assembly => "assembler",
1290+
.assembly_with_cpp => "assembler-with-cpp",
1291+
.objc => "objective-c",
1292+
.objcpp => "objective-c++",
1293+
});
12671294
}
12681295

1269-
const root_path = c_source_files.root.getPath2(dep.module.owner, step);
1270-
for (c_source_files.files) |file| {
1296+
const root_path = foreign_source_files.root.getPath2(dep.module.owner, step);
1297+
for (foreign_source_files.files) |file| {
12711298
try zig_args.append(b.pathJoin(&.{ root_path, file }));
12721299
}
12731300

1274-
total_linker_objects += c_source_files.files.len;
1301+
if (foreign_source_files.language != .find_by_file_extension) {
1302+
try zig_args.append("-x");
1303+
try zig_args.append("none");
1304+
}
1305+
1306+
total_linker_objects += foreign_source_files.files.len;
12751307
},
12761308

12771309
.win32_resource_file => |rc_source_file| l: {
@@ -1992,7 +2024,7 @@ pub fn rootModuleTarget(c: *Compile) std.Target {
19922024

19932025
fn moduleNeedsCliArg(mod: *const Module) bool {
19942026
return for (mod.link_objects.items) |o| switch (o) {
1995-
.c_source_file, .c_source_files, .assembly_file, .win32_resource_file => break true,
2027+
.foreign_source_file, .foreign_source_files, .assembly_file, .win32_resource_file => break true,
19962028
else => continue,
19972029
} else false;
19982030
}

0 commit comments

Comments
 (0)