Source
pub fn create(owner: *std.Build, options: Options) *Compile {
const name = owner.dupe(options.name);
if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) {
panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name});
}
// Avoid the common case of the step name looking like "zig test test".
const name_adjusted = if (options.kind == .@"test" and mem.eql(u8, name, "test"))
""
else
owner.fmt("{s} ", .{name});
const resolved_target = options.root_module.resolved_target orelse
@panic("the root Module of a Compile step must be created with a known 'target' field");
const target = resolved_target.result;
const step_name = owner.fmt("{s} {s}{s} {s}", .{
switch (options.kind) {
.exe => "zig build-exe",
.lib => "zig build-lib",
.obj => "zig build-obj",
.@"test" => "zig test",
},
name_adjusted,
@tagName(options.root_module.optimize orelse .Debug),
resolved_target.query.zigTriple(owner.allocator) catch @panic("OOM"),
});
const out_filename = std.zig.binNameAlloc(owner.allocator, .{
.root_name = name,
.target = target,
.output_mode = switch (options.kind) {
.lib => .Lib,
.obj => .Obj,
.exe, .@"test" => .Exe,
},
.link_mode = options.linkage,
.version = options.version,
}) catch @panic("OOM");
const compile = owner.allocator.create(Compile) catch @panic("OOM");
compile.* = .{
.root_module = options.root_module,
.verbose_link = false,
.verbose_cc = false,
.linkage = options.linkage,
.kind = options.kind,
.name = name,
.step = Step.init(.{
.id = base_id,
.name = step_name,
.owner = owner,
.makeFn = make,
.max_rss = options.max_rss,
}),
.version = options.version,
.out_filename = out_filename,
.out_lib_filename = undefined,
.major_only_filename = null,
.name_only_filename = null,
.installed_headers = ArrayList(HeaderInstallation).init(owner.allocator),
.zig_lib_dir = null,
.exec_cmd_args = null,
.filters = options.filters,
.test_runner = null, // set below
.rdynamic = false,
.installed_path = null,
.force_undefined_symbols = StringHashMap(void).init(owner.allocator),
.emit_directory = null,
.generated_docs = null,
.generated_asm = null,
.generated_bin = null,
.generated_pdb = null,
.generated_implib = null,
.generated_llvm_bc = null,
.generated_llvm_ir = null,
.generated_h = null,
.use_llvm = options.use_llvm,
.use_lld = options.use_lld,
.zig_process = null,
};
if (options.zig_lib_dir) |lp| {
compile.zig_lib_dir = lp.dupe(compile.step.owner);
lp.addStepDependencies(&compile.step);
}
if (options.test_runner) |runner| {
compile.test_runner = .{
.path = runner.path.dupe(compile.step.owner),
.mode = runner.mode,
};
runner.path.addStepDependencies(&compile.step);
}
// Only the PE/COFF format has a Resource Table which is where the manifest
// gets embedded, so for any other target the manifest file is just ignored.
if (target.ofmt == .coff) {
if (options.win32_manifest) |lp| {
compile.win32_manifest = lp.dupe(compile.step.owner);
lp.addStepDependencies(&compile.step);
}
}
if (compile.kind == .lib) {
if (compile.linkage != null and compile.linkage.? == .static) {
compile.out_lib_filename = compile.out_filename;
} else if (compile.version) |version| {
if (target.os.tag.isDarwin()) {
compile.major_only_filename = owner.fmt("lib{s}.{d}.dylib", .{
compile.name,
version.major,
});
compile.name_only_filename = owner.fmt("lib{s}.dylib", .{compile.name});
compile.out_lib_filename = compile.out_filename;
} else if (target.os.tag == .windows) {
compile.out_lib_filename = owner.fmt("{s}.lib", .{compile.name});
} else {
compile.major_only_filename = owner.fmt("lib{s}.so.{d}", .{ compile.name, version.major });
compile.name_only_filename = owner.fmt("lib{s}.so", .{compile.name});
compile.out_lib_filename = compile.out_filename;
}
} else {
if (target.os.tag.isDarwin()) {
compile.out_lib_filename = compile.out_filename;
} else if (target.os.tag == .windows) {
compile.out_lib_filename = owner.fmt("{s}.lib", .{compile.name});
} else {
compile.out_lib_filename = compile.out_filename;
}
}
}
return compile;
}