zig/std/build.zig

2315 lines
82 KiB
Zig
Raw Normal View History

2019-03-02 21:46:04 +00:00
const std = @import("std.zig");
const builtin = @import("builtin");
const io = std.io;
2019-05-26 17:17:34 +00:00
const fs = std.fs;
const mem = std.mem;
const debug = std.debug;
const assert = debug.assert;
const warn = std.debug.warn;
const ArrayList = std.ArrayList;
const HashMap = std.HashMap;
const Allocator = mem.Allocator;
2019-05-26 17:17:34 +00:00
const process = std.process;
const BufSet = std.BufSet;
const BufMap = std.BufMap;
const fmt_lib = std.fmt;
2019-05-25 02:52:07 +00:00
const File = std.fs.File;
pub const FmtStep = @import("build/fmt.zig").FmtStep;
pub const Builder = struct {
install_tls: TopLevelStep,
uninstall_tls: TopLevelStep,
allocator: *Allocator,
native_system_lib_paths: ArrayList([]const u8),
native_system_include_dirs: ArrayList([]const u8),
native_system_rpaths: ArrayList([]const u8),
user_input_options: UserInputOptionsMap,
available_options_map: AvailableOptionsMap,
available_options_list: ArrayList(AvailableOption),
verbose: bool,
verbose_tokenize: bool,
verbose_ast: bool,
verbose_link: bool,
verbose_cc: bool,
verbose_ir: bool,
verbose_llvm_ir: bool,
verbose_cimport: bool,
invalid_user_input: bool,
zig_exe: []const u8,
default_step: *Step,
2018-11-08 02:22:42 +00:00
env_map: *BufMap,
top_level_steps: ArrayList(*TopLevelStep),
install_prefix: ?[]const u8,
2017-12-24 01:21:57 +00:00
search_prefixes: ArrayList([]const u8),
lib_dir: ?[]const u8,
exe_dir: ?[]const u8,
installed_files: ArrayList(InstalledFile),
build_root: []const u8,
cache_root: []const u8,
release_mode: ?builtin.Mode,
is_release: bool,
stage1 is now a hybrid of C++ and Zig This modifies the build process of Zig to put all of the source files into libcompiler.a, except main.cpp and userland.cpp. Next, the build process links main.cpp, userland.cpp, and libcompiler.a into zig1. userland.cpp is a shim for functions that will later be replaced with self-hosted implementations. Next, the build process uses zig1 to build src-self-hosted/stage1.zig into libuserland.a, which does not depend on any of the things that are shimmed in userland.cpp, such as translate-c. Finally, the build process re-links main.cpp and libcompiler.a, except with libuserland.a instead of userland.cpp. Now the shims are replaced with .zig code. This provides all of the Zig standard library to the stage1 C++ compiler, and enables us to move certain things to userland, such as translate-c. As a proof of concept I have made the `zig zen` command use text defined in userland. I added `zig translate-c-2` which is a work-in-progress reimplementation of translate-c in userland, which currently calls `std.debug.panic("unimplemented")` and you can see the stack trace makes it all the way back into the C++ main() function (Thanks LemonBoy for improving that!). This could potentially let us move other things into userland, such as hashing algorithms, the entire cache system, .d file parsing, pretty much anything that libuserland.a itself doesn't need to depend on. This can also let us have `zig fmt` in stage1 without the overhead of child process execution, and without the initial compilation delay before it gets cached. See #1964
2019-04-16 20:47:47 +00:00
override_std_dir: ?[]const u8,
override_lib_dir: ?[]const u8,
pub const CStd = enum {
2018-09-06 20:29:35 +00:00
C89,
C99,
C11,
};
const UserInputOptionsMap = HashMap([]const u8, UserInputOption, mem.hash_slice_u8, mem.eql_slice_u8);
const AvailableOptionsMap = HashMap([]const u8, AvailableOption, mem.hash_slice_u8, mem.eql_slice_u8);
const AvailableOption = struct {
name: []const u8,
type_id: TypeId,
description: []const u8,
};
const UserInputOption = struct {
name: []const u8,
value: UserValue,
used: bool,
};
const UserValue = union(enum) {
Flag: void,
Scalar: []const u8,
List: ArrayList([]const u8),
};
const TypeId = enum {
Bool,
Int,
Float,
String,
List,
};
const TopLevelStep = struct {
step: Step,
description: []const u8,
};
pub fn create(
allocator: *Allocator,
zig_exe: []const u8,
build_root: []const u8,
cache_root: []const u8,
) !*Builder {
const env_map = try allocator.create(BufMap);
env_map.* = try process.getEnvMap(allocator);
const self = try allocator.create(Builder);
self.* = Builder{
.zig_exe = zig_exe,
.build_root = build_root,
.cache_root = try fs.path.relative(allocator, build_root, cache_root),
.verbose = false,
.verbose_tokenize = false,
.verbose_ast = false,
.verbose_link = false,
.verbose_cc = false,
.verbose_ir = false,
.verbose_llvm_ir = false,
.verbose_cimport = false,
.invalid_user_input = false,
.allocator = allocator,
.native_system_lib_paths = ArrayList([]const u8).init(allocator),
.native_system_include_dirs = ArrayList([]const u8).init(allocator),
.native_system_rpaths = ArrayList([]const u8).init(allocator),
.user_input_options = UserInputOptionsMap.init(allocator),
.available_options_map = AvailableOptionsMap.init(allocator),
.available_options_list = ArrayList(AvailableOption).init(allocator),
.top_level_steps = ArrayList(*TopLevelStep).init(allocator),
.default_step = undefined,
.env_map = env_map,
.install_prefix = null,
2017-12-24 01:21:57 +00:00
.search_prefixes = ArrayList([]const u8).init(allocator),
.lib_dir = null,
.exe_dir = null,
.installed_files = ArrayList(InstalledFile).init(allocator),
.install_tls = TopLevelStep{
.step = Step.initNoOp("install", allocator),
.description = "Copy build artifacts to prefix path",
},
.uninstall_tls = TopLevelStep{
.step = Step.init("uninstall", allocator, makeUninstall),
.description = "Remove build artifacts from prefix path",
},
.release_mode = null,
.is_release = false,
stage1 is now a hybrid of C++ and Zig This modifies the build process of Zig to put all of the source files into libcompiler.a, except main.cpp and userland.cpp. Next, the build process links main.cpp, userland.cpp, and libcompiler.a into zig1. userland.cpp is a shim for functions that will later be replaced with self-hosted implementations. Next, the build process uses zig1 to build src-self-hosted/stage1.zig into libuserland.a, which does not depend on any of the things that are shimmed in userland.cpp, such as translate-c. Finally, the build process re-links main.cpp and libcompiler.a, except with libuserland.a instead of userland.cpp. Now the shims are replaced with .zig code. This provides all of the Zig standard library to the stage1 C++ compiler, and enables us to move certain things to userland, such as translate-c. As a proof of concept I have made the `zig zen` command use text defined in userland. I added `zig translate-c-2` which is a work-in-progress reimplementation of translate-c in userland, which currently calls `std.debug.panic("unimplemented")` and you can see the stack trace makes it all the way back into the C++ main() function (Thanks LemonBoy for improving that!). This could potentially let us move other things into userland, such as hashing algorithms, the entire cache system, .d file parsing, pretty much anything that libuserland.a itself doesn't need to depend on. This can also let us have `zig fmt` in stage1 without the overhead of child process execution, and without the initial compilation delay before it gets cached. See #1964
2019-04-16 20:47:47 +00:00
.override_std_dir = null,
.override_lib_dir = null,
};
try self.top_level_steps.append(&self.install_tls);
try self.top_level_steps.append(&self.uninstall_tls);
self.detectNativeSystemPaths();
self.default_step = &self.install_tls.step;
return self;
}
pub fn destroy(self: *Builder) void {
self.native_system_lib_paths.deinit();
self.native_system_include_dirs.deinit();
self.native_system_rpaths.deinit();
self.env_map.deinit();
self.top_level_steps.deinit();
self.allocator.destroy(self);
}
pub fn setInstallPrefix(self: *Builder, optional_prefix: ?[]const u8) void {
self.install_prefix = optional_prefix;
}
fn resolveInstallPrefix(self: *Builder) void {
const prefix = if (self.install_prefix) |prefix| prefix else blk: {
const prefix = self.cache_root;
self.install_prefix = prefix;
break :blk prefix;
};
self.lib_dir = fs.path.join(self.allocator, [_][]const u8{ prefix, "lib" }) catch unreachable;
self.exe_dir = fs.path.join(self.allocator, [_][]const u8{ prefix, "bin" }) catch unreachable;
}
pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
2018-12-01 06:21:59 +00:00
return LibExeObjStep.createExecutable(self, name, root_src, false);
}
pub fn addObject(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
return LibExeObjStep.createObject(self, name, root_src);
}
pub fn addSharedLibrary(self: *Builder, name: []const u8, root_src: ?[]const u8, ver: Version) *LibExeObjStep {
return LibExeObjStep.createSharedLibrary(self, name, root_src, ver);
}
pub fn addStaticLibrary(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
return LibExeObjStep.createStaticLibrary(self, name, root_src);
}
pub fn addTest(self: *Builder, root_src: []const u8) *LibExeObjStep {
return LibExeObjStep.createTest(self, "test", root_src);
}
pub fn addAssemble(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep {
const obj_step = LibExeObjStep.createObject(self, name, null);
obj_step.addAssemblyFile(src);
return obj_step;
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
/// Initializes a RunStep with argv, which must at least have the path to the
/// executable. More command line arguments can be added with `addArg`,
/// `addArgs`, and `addArtifactArg`.
/// Be careful using this function, as it introduces a system dependency.
/// To run an executable built with zig build, see `LibExeObjStep.run`.
pub fn addSystemCommand(self: *Builder, argv: []const []const u8) *RunStep {
assert(argv.len >= 1);
const run_step = RunStep.create(self, self.fmt("run {}", argv[0]));
run_step.addArgs(argv);
return run_step;
}
fn dupe(self: *Builder, bytes: []const u8) []u8 {
return mem.dupe(self.allocator, u8, bytes) catch unreachable;
}
pub fn addWriteFile(self: *Builder, file_path: []const u8, data: []const u8) *WriteFileStep {
const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;
write_file_step.* = WriteFileStep.init(self, file_path, data);
return write_file_step;
}
pub fn addLog(self: *Builder, comptime format: []const u8, args: ...) *LogStep {
const data = self.fmt(format, args);
const log_step = self.allocator.create(LogStep) catch unreachable;
log_step.* = LogStep.init(self, data);
return log_step;
}
pub fn addRemoveDirTree(self: *Builder, dir_path: []const u8) *RemoveDirStep {
const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;
remove_dir_step.* = RemoveDirStep.init(self, dir_path);
return remove_dir_step;
}
pub fn addFmt(self: *Builder, paths: []const []const u8) *FmtStep {
return FmtStep.create(self, paths);
}
pub fn version(self: *const Builder, major: u32, minor: u32, patch: u32) Version {
return Version{
.major = major,
.minor = minor,
.patch = patch,
};
}
pub fn addNativeSystemIncludeDir(self: *Builder, path: []const u8) void {
self.native_system_include_dirs.append(path) catch unreachable;
}
pub fn addNativeSystemRPath(self: *Builder, path: []const u8) void {
self.native_system_rpaths.append(path) catch unreachable;
}
pub fn addNativeSystemLibPath(self: *Builder, path: []const u8) void {
self.native_system_lib_paths.append(path) catch unreachable;
}
pub fn make(self: *Builder, step_names: []const []const u8) !void {
try self.makePath(self.cache_root);
var wanted_steps = ArrayList(*Step).init(self.allocator);
defer wanted_steps.deinit();
if (step_names.len == 0) {
try wanted_steps.append(self.default_step);
} else {
for (step_names) |step_name| {
const s = try self.getTopLevelStepByName(step_name);
try wanted_steps.append(s);
}
}
for (wanted_steps.toSliceConst()) |s| {
try self.makeOneStep(s);
}
}
pub fn getInstallStep(self: *Builder) *Step {
return &self.install_tls.step;
}
pub fn getUninstallStep(self: *Builder) *Step {
return &self.uninstall_tls.step;
}
fn makeUninstall(uninstall_step: *Step) anyerror!void {
const uninstall_tls = @fieldParentPtr(TopLevelStep, "step", uninstall_step);
const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls);
for (self.installed_files.toSliceConst()) |installed_file| {
const full_path = self.getInstallPath(installed_file.dir, installed_file.path);
if (self.verbose) {
warn("rm {}\n", full_path);
}
fs.deleteTree(self.allocator, full_path) catch {};
}
// TODO remove empty directories
}
fn makeOneStep(self: *Builder, s: *Step) anyerror!void {
if (s.loop_flag) {
warn("Dependency loop detected:\n {}\n", s.name);
return error.DependencyLoopDetected;
}
s.loop_flag = true;
for (s.dependencies.toSlice()) |dep| {
self.makeOneStep(dep) catch |err| {
if (err == error.DependencyLoopDetected) {
warn(" {}\n", s.name);
}
return err;
};
}
s.loop_flag = false;
try s.make();
}
fn getTopLevelStepByName(self: *Builder, name: []const u8) !*Step {
for (self.top_level_steps.toSliceConst()) |top_level_step| {
if (mem.eql(u8, top_level_step.step.name, name)) {
return &top_level_step.step;
}
}
warn("Cannot run step '{}' because it does not exist\n", name);
return error.InvalidStepName;
}
fn detectNativeSystemPaths(self: *Builder) void {
var is_nixos = false;
2019-05-26 17:17:34 +00:00
if (process.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
is_nixos = true;
var it = mem.tokenize(nix_cflags_compile, " ");
while (true) {
const word = it.next() orelse break;
if (mem.eql(u8, word, "-isystem")) {
const include_path = it.next() orelse {
warn("Expected argument after -isystem in NIX_CFLAGS_COMPILE\n");
break;
};
self.addNativeSystemIncludeDir(include_path);
} else {
warn("Unrecognized C flag from NIX_CFLAGS_COMPILE: {}\n", word);
break;
}
}
} else |err| {
assert(err == error.EnvironmentVariableNotFound);
}
2019-05-26 17:17:34 +00:00
if (process.getEnvVarOwned(self.allocator, "NIX_LDFLAGS")) |nix_ldflags| {
is_nixos = true;
var it = mem.tokenize(nix_ldflags, " ");
while (true) {
const word = it.next() orelse break;
if (mem.eql(u8, word, "-rpath")) {
const rpath = it.next() orelse {
warn("Expected argument after -rpath in NIX_LDFLAGS\n");
break;
};
self.addNativeSystemRPath(rpath);
} else if (word.len > 2 and word[0] == '-' and word[1] == 'L') {
const lib_path = word[2..];
self.addNativeSystemLibPath(lib_path);
} else {
warn("Unrecognized C flag from NIX_LDFLAGS: {}\n", word);
break;
}
}
} else |err| {
assert(err == error.EnvironmentVariableNotFound);
}
if (is_nixos) return;
switch (builtin.os) {
2019-05-26 17:17:34 +00:00
.windows => {},
else => {
const triple = (Target{
.Cross = CrossTarget{
.arch = builtin.arch,
.os = builtin.os,
.abi = builtin.abi,
},
}).linuxTriple(self.allocator);
// TODO: $ ld --verbose | grep SEARCH_DIR
// the output contains some paths that end with lib64, maybe include them too?
// also, what is the best possible order of things?
self.addNativeSystemIncludeDir("/usr/local/include");
self.addNativeSystemLibPath("/usr/local/lib");
self.addNativeSystemIncludeDir(self.fmt("/usr/include/{}", triple));
self.addNativeSystemLibPath(self.fmt("/usr/lib/{}", triple));
self.addNativeSystemIncludeDir("/usr/include");
self.addNativeSystemLibPath("/usr/lib");
// example: on a 64-bit debian-based linux distro, with zlib installed from apt:
// zlib.h is in /usr/include (added above)
// libz.so.1 is in /lib/x86_64-linux-gnu (added here)
self.addNativeSystemLibPath(self.fmt("/lib/{}", triple));
},
}
}
pub fn option(self: *Builder, comptime T: type, name: []const u8, description: []const u8) ?T {
const type_id = comptime typeToEnum(T);
const available_option = AvailableOption{
.name = name,
.type_id = type_id,
.description = description,
};
if ((self.available_options_map.put(name, available_option) catch unreachable) != null) {
debug.panic("Option '{}' declared twice", name);
}
self.available_options_list.append(available_option) catch unreachable;
const entry = self.user_input_options.get(name) orelse return null;
entry.value.used = true;
switch (type_id) {
TypeId.Bool => switch (entry.value.value) {
UserValue.Flag => return true,
UserValue.Scalar => |s| {
if (mem.eql(u8, s, "true")) {
return true;
} else if (mem.eql(u8, s, "false")) {
return false;
} else {
warn("Expected -D{} to be a boolean, but received '{}'\n", name, s);
self.markInvalidUserInput();
return null;
}
},
UserValue.List => {
warn("Expected -D{} to be a boolean, but received a list.\n", name);
self.markInvalidUserInput();
return null;
},
},
TypeId.Int => debug.panic("TODO integer options to build script"),
TypeId.Float => debug.panic("TODO float options to build script"),
TypeId.String => switch (entry.value.value) {
UserValue.Flag => {
warn("Expected -D{} to be a string, but received a boolean.\n", name);
self.markInvalidUserInput();
return null;
},
UserValue.List => {
warn("Expected -D{} to be a string, but received a list.\n", name);
self.markInvalidUserInput();
return null;
},
UserValue.Scalar => |s| return s,
},
TypeId.List => debug.panic("TODO list options to build script"),
}
}
pub fn step(self: *Builder, name: []const u8, description: []const u8) *Step {
const step_info = self.allocator.create(TopLevelStep) catch unreachable;
step_info.* = TopLevelStep{
.step = Step.initNoOp(name, self.allocator),
.description = description,
};
self.top_level_steps.append(step_info) catch unreachable;
return &step_info.step;
}
/// This provides the -Drelease option to the build user and does not give them the choice.
pub fn setPreferredReleaseMode(self: *Builder, mode: builtin.Mode) void {
if (self.release_mode != null) {
@panic("setPreferredReleaseMode must be called before standardReleaseOptions and may not be called twice");
}
const description = self.fmt("create a release build ({})", @tagName(mode));
self.is_release = self.option(bool, "release", description) orelse false;
self.release_mode = if (self.is_release) mode else builtin.Mode.Debug;
}
/// If you call this without first calling `setPreferredReleaseMode` then it gives the build user
/// the choice of what kind of release.
pub fn standardReleaseOptions(self: *Builder) builtin.Mode {
if (self.release_mode) |mode| return mode;
const release_safe = self.option(bool, "release-safe", "optimizations on and safety on") orelse false;
const release_fast = self.option(bool, "release-fast", "optimizations on and safety off") orelse false;
const release_small = self.option(bool, "release-small", "size optimizations on and safety off") orelse false;
const mode = if (release_safe and !release_fast and !release_small)
builtin.Mode.ReleaseSafe
else if (release_fast and !release_safe and !release_small)
builtin.Mode.ReleaseFast
else if (release_small and !release_fast and !release_safe)
builtin.Mode.ReleaseSmall
else if (!release_fast and !release_safe and !release_small)
builtin.Mode.Debug
else x: {
2018-04-16 00:26:10 +00:00
warn("Multiple release modes (of -Drelease-safe, -Drelease-fast and -Drelease-small)");
self.markInvalidUserInput();
break :x builtin.Mode.Debug;
};
self.is_release = mode != .Debug;
self.release_mode = mode;
return mode;
}
/// Exposes standard `zig build` options for choosing a target. Pass `null` to support all targets.
pub fn standardTargetOptions(self: *Builder, supported_targets: ?[]const Target) Target {
if (supported_targets) |target_list| {
// TODO detect multiple args and emit an error message
// there's probably a better way to collect the target
for (target_list) |targ| {
const targ_str = targ.zigTriple(self.allocator) catch unreachable;
const targ_desc = targ.allocDescription(self.allocator) catch unreachable;
const this_targ_opt = self.option(bool, targ_str, targ_desc) orelse false;
if (this_targ_opt) {
return targ;
}
}
return Target.Native;
} else {
const target_str = self.option([]const u8, "target", "the target to build for") orelse return Target.Native;
return Target.parse(target_str) catch unreachable; // TODO better error message for bad target
}
}
pub fn addUserInputOption(self: *Builder, name: []const u8, value: []const u8) !bool {
const gop = try self.user_input_options.getOrPut(name);
if (!gop.found_existing) {
gop.kv.value = UserInputOption{
.name = name,
.value = UserValue{ .Scalar = value },
.used = false,
};
return false;
}
// option already exists
switch (gop.kv.value.value) {
UserValue.Scalar => |s| {
// turn it into a list
var list = ArrayList([]const u8).init(self.allocator);
list.append(s) catch unreachable;
list.append(value) catch unreachable;
_ = self.user_input_options.put(name, UserInputOption{
.name = name,
.value = UserValue{ .List = list },
.used = false,
}) catch unreachable;
},
UserValue.List => |*list| {
// append to the list
list.append(value) catch unreachable;
_ = self.user_input_options.put(name, UserInputOption{
.name = name,
.value = UserValue{ .List = list.* },
.used = false,
}) catch unreachable;
},
UserValue.Flag => {
warn("Option '-D{}={}' conflicts with flag '-D{}'.\n", name, value, name);
return true;
},
}
return false;
}
pub fn addUserInputFlag(self: *Builder, name: []const u8) !bool {
const gop = try self.user_input_options.getOrPut(name);
if (!gop.found_existing) {
gop.kv.value = UserInputOption{
.name = name,
.value = UserValue{ .Flag = {} },
.used = false,
};
return false;
}
// option already exists
switch (gop.kv.value.value) {
UserValue.Scalar => |s| {
warn("Flag '-D{}' conflicts with option '-D{}={}'.\n", name, name, s);
return true;
},
UserValue.List => {
warn("Flag '-D{}' conflicts with multiple options of the same name.\n", name);
return true;
},
UserValue.Flag => {},
}
return false;
}
fn typeToEnum(comptime T: type) TypeId {
return switch (@typeId(T)) {
builtin.TypeId.Int => TypeId.Int,
builtin.TypeId.Float => TypeId.Float,
builtin.TypeId.Bool => TypeId.Bool,
else => switch (T) {
[]const u8 => TypeId.String,
[]const []const u8 => TypeId.List,
else => @compileError("Unsupported type: " ++ @typeName(T)),
},
};
}
fn markInvalidUserInput(self: *Builder) void {
self.invalid_user_input = true;
}
pub fn typeIdName(id: TypeId) []const u8 {
return switch (id) {
TypeId.Bool => "bool",
TypeId.Int => "int",
TypeId.Float => "float",
TypeId.String => "string",
TypeId.List => "list",
};
}
pub fn validateUserInputDidItFail(self: *Builder) bool {
self.resolveInstallPrefix();
// make sure all args are used
var it = self.user_input_options.iterator();
while (true) {
const entry = it.next() orelse break;
if (!entry.value.used) {
warn("Invalid option: -D{}\n\n", entry.key);
self.markInvalidUserInput();
}
}
return self.invalid_user_input;
}
fn spawnChild(self: *Builder, argv: []const []const u8) !void {
return self.spawnChildEnvMap(null, self.env_map, argv);
}
fn printCmd(cwd: ?[]const u8, argv: []const []const u8) void {
if (cwd) |yes_cwd| warn("cd {} && ", yes_cwd);
for (argv) |arg| {
warn("{} ", arg);
}
warn("\n");
}
fn spawnChildEnvMap(self: *Builder, cwd: ?[]const u8, env_map: *const BufMap, argv: []const []const u8) !void {
if (self.verbose) {
printCmd(cwd, argv);
}
2019-05-26 17:17:34 +00:00
const child = std.ChildProcess.init(argv, self.allocator) catch unreachable;
defer child.deinit();
child.cwd = cwd;
child.env_map = env_map;
const term = child.spawnAndWait() catch |err| {
warn("Unable to spawn {}: {}\n", argv[0], @errorName(err));
return err;
};
switch (term) {
2019-05-26 17:17:34 +00:00
.Exited => |code| {
if (code != 0) {
warn("The following command exited with error code {}:\n", code);
printCmd(cwd, argv);
return error.UncleanExit;
}
},
else => {
warn("The following command terminated unexpectedly:\n");
printCmd(cwd, argv);
return error.UncleanExit;
},
}
}
pub fn makePath(self: *Builder, path: []const u8) !void {
2019-05-26 17:17:34 +00:00
fs.makePath(self.allocator, self.pathFromRoot(path)) catch |err| {
warn("Unable to create path {}: {}\n", path, @errorName(err));
return err;
};
}
pub fn installArtifact(self: *Builder, artifact: *LibExeObjStep) void {
self.getInstallStep().dependOn(&self.addInstallArtifact(artifact).step);
}
pub fn addInstallArtifact(self: *Builder, artifact: *LibExeObjStep) *InstallArtifactStep {
return InstallArtifactStep.create(self, artifact);
}
///`dest_rel_path` is relative to prefix path
pub fn installFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void {
self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Prefix, dest_rel_path).step);
}
pub fn installDirectory(self: *Builder, options: InstallDirectoryOptions) void {
self.getInstallStep().dependOn(&self.addInstallDirectory(options).step);
}
///`dest_rel_path` is relative to bin path
pub fn installBinFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void {
self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Bin, dest_rel_path).step);
}
///`dest_rel_path` is relative to lib path
pub fn installLibFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void {
self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Lib, dest_rel_path).step);
}
///`dest_rel_path` is relative to install prefix path
pub fn addInstallFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep {
return self.addInstallFileWithDir(src_path, .Prefix, dest_rel_path);
}
///`dest_rel_path` is relative to bin path
pub fn addInstallBinFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep {
return self.addInstallFileWithDir(src_path, .Bin, dest_rel_path);
}
///`dest_rel_path` is relative to lib path
pub fn addInstallLibFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep {
return self.addInstallFileWithDir(src_path, .Lib, dest_rel_path);
}
pub fn addInstallFileWithDir(
self: *Builder,
src_path: []const u8,
install_dir: InstallDir,
dest_rel_path: []const u8,
) *InstallFileStep {
const install_step = self.allocator.create(InstallFileStep) catch unreachable;
install_step.* = InstallFileStep.init(self, src_path, install_dir, dest_rel_path);
return install_step;
}
pub fn addInstallDirectory(self: *Builder, options: InstallDirectoryOptions) *InstallDirStep {
const install_step = self.allocator.create(InstallDirStep) catch unreachable;
install_step.* = InstallDirStep.init(self, options);
return install_step;
}
pub fn pushInstalledFile(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) void {
self.installed_files.append(InstalledFile{
.dir = dir,
.path = dest_rel_path,
}) catch unreachable;
}
fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void {
if (self.verbose) {
warn("cp {} {} ", source_path, dest_path);
}
const prev_status = try fs.updateFile(source_path, dest_path);
if (self.verbose) switch (prev_status) {
.stale => warn("# installed\n"),
.fresh => warn("# up-to-date\n"),
};
}
fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 {
return fs.path.resolve(self.allocator, [_][]const u8{ self.build_root, rel_path }) catch unreachable;
}
pub fn fmt(self: *Builder, comptime format: []const u8, args: ...) []u8 {
return fmt_lib.allocPrint(self.allocator, format, args) catch unreachable;
}
2017-10-16 05:14:28 +00:00
pub fn findProgram(self: *Builder, names: []const []const u8, paths: []const []const u8) ![]const u8 {
2017-12-24 01:21:57 +00:00
// TODO report error for ambiguous situations
const exe_extension = (Target{ .Native = {} }).exeFileExt();
2017-12-24 01:21:57 +00:00
for (self.search_prefixes.toSliceConst()) |search_prefix| {
for (names) |name| {
2019-05-26 17:17:34 +00:00
if (fs.path.isAbsolute(name)) {
2017-12-24 01:21:57 +00:00
return name;
}
const full_path = try fs.path.join(self.allocator, [_][]const u8{ search_prefix, "bin", self.fmt("{}{}", name, exe_extension) });
2019-05-26 17:17:34 +00:00
if (fs.path.real(self.allocator, full_path)) |real_path| {
2017-12-24 01:21:57 +00:00
return real_path;
} else |_| {
continue;
}
}
}
if (self.env_map.get("PATH")) |PATH| {
for (names) |name| {
2019-05-26 17:17:34 +00:00
if (fs.path.isAbsolute(name)) {
return name;
}
2019-05-26 17:17:34 +00:00
var it = mem.tokenize(PATH, []u8{fs.path.delimiter});
while (it.next()) |path| {
const full_path = try fs.path.join(self.allocator, [_][]const u8{ path, self.fmt("{}{}", name, exe_extension) });
2019-05-26 17:17:34 +00:00
if (fs.path.real(self.allocator, full_path)) |real_path| {
return real_path;
} else |_| {
continue;
}
}
}
}
for (names) |name| {
2019-05-26 17:17:34 +00:00
if (fs.path.isAbsolute(name)) {
return name;
}
for (paths) |path| {
const full_path = try fs.path.join(self.allocator, [_][]const u8{ path, self.fmt("{}{}", name, exe_extension) });
2019-05-26 17:17:34 +00:00
if (fs.path.real(self.allocator, full_path)) |real_path| {
return real_path;
} else |_| {
continue;
}
}
}
return error.FileNotFound;
}
pub fn exec(self: *Builder, argv: []const []const u8) ![]u8 {
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
assert(argv.len != 0);
if (self.verbose) {
printCmd(null, argv);
}
const max_output_size = 100 * 1024;
2019-05-26 17:17:34 +00:00
const child = try std.ChildProcess.init(argv, self.allocator);
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
defer child.deinit();
2019-05-26 17:17:34 +00:00
child.stdin_behavior = .Ignore;
child.stdout_behavior = .Pipe;
child.stderr_behavior = .Inherit;
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
try child.spawn();
var stdout = std.Buffer.initNull(self.allocator);
defer std.Buffer.deinit(&stdout);
var stdout_file_in_stream = child.stdout.?.inStream();
try stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size);
const term = child.wait() catch |err| std.debug.panic("unable to spawn {}: {}", argv[0], err);
switch (term) {
2019-05-26 17:17:34 +00:00
.Exited => |code| {
if (code != 0) {
warn("The following command exited with error code {}:\n", code);
printCmd(null, argv);
2019-06-28 22:16:22 +00:00
std.os.exit(@truncate(u8, code));
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
return stdout.toOwnedSlice();
},
2019-07-03 18:17:43 +00:00
.Signal, .Stopped, .Unknown => |code| {
warn("The following command terminated unexpectedly:\n");
printCmd(null, argv);
2019-07-03 18:17:43 +00:00
std.os.exit(@truncate(u8, code));
},
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
return stdout.toOwnedSlice();
}
2017-12-24 01:21:57 +00:00
pub fn addSearchPrefix(self: *Builder, search_prefix: []const u8) void {
self.search_prefixes.append(search_prefix) catch unreachable;
2017-12-24 01:21:57 +00:00
}
fn getInstallPath(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) []const u8 {
const base_dir = switch (dir) {
.Prefix => self.install_prefix.?,
.Bin => self.exe_dir.?,
.Lib => self.lib_dir.?,
};
return fs.path.resolve(
self.allocator,
[_][]const u8{ base_dir, dest_rel_path },
) catch unreachable;
}
};
pub const Version = struct {
major: u32,
minor: u32,
patch: u32,
};
pub const CrossTarget = struct {
arch: builtin.Arch,
os: builtin.Os,
abi: builtin.Abi,
};
pub const Target = union(enum) {
Native: void,
Cross: CrossTarget,
pub fn zigTriple(self: Target, allocator: *Allocator) ![]u8 {
return std.fmt.allocPrint(
allocator,
"{}{}-{}-{}",
@tagName(self.getArch()),
Target.archSubArchName(self.getArch()),
@tagName(self.getOs()),
@tagName(self.getAbi()),
);
}
pub fn allocDescription(self: Target, allocator: *Allocator) ![]u8 {
// TODO is there anything else worthy of the description that is not
// already captured in the triple?
return self.zigTriple(allocator);
}
pub fn zigTripleNoSubArch(self: Target, allocator: *Allocator) ![]u8 {
return std.fmt.allocPrint(
allocator,
"{}-{}-{}",
@tagName(self.getArch()),
@tagName(self.getOs()),
@tagName(self.getAbi()),
);
}
pub fn linuxTriple(self: Target, allocator: *Allocator) ![]u8 {
return std.fmt.allocPrint(
allocator,
"{}-{}-{}",
@tagName(self.getArch()),
@tagName(self.getOs()),
@tagName(self.getAbi()),
);
}
pub fn parse(text: []const u8) !Target {
var it = mem.separate(text, "-");
const arch_name = it.next() orelse return error.MissingArchitecture;
const os_name = it.next() orelse return error.MissingOperatingSystem;
const abi_name = it.next();
var cross = CrossTarget{
.arch = try parseArchSub(arch_name),
.os = try parseOs(os_name),
.abi = undefined,
};
cross.abi = if (abi_name) |n| try parseAbi(n) else defaultAbi(cross.arch, cross.os);
return Target{ .Cross = cross };
}
pub fn defaultAbi(arch: builtin.Arch, target_os: builtin.Os) builtin.Abi {
switch (arch) {
.wasm32, .wasm64 => return .musl,
else => {},
}
switch (target_os) {
.freestanding,
.ananas,
.cloudabi,
.dragonfly,
.lv2,
.solaris,
.haiku,
.minix,
.rtems,
.nacl,
.cnk,
.aix,
.cuda,
.nvcl,
.amdhsa,
.ps4,
.elfiamcu,
.mesa3d,
.contiki,
.amdpal,
.zen,
.hermit,
=> return .eabi,
.openbsd,
.macosx,
.freebsd,
.ios,
.tvos,
.watchos,
.fuchsia,
.kfreebsd,
.netbsd,
.hurd,
=> return .gnu,
.windows,
.uefi,
=> return .msvc,
.linux,
.wasi,
=> return .musl,
}
}
pub const ParseArchSubError = error{
UnknownArchitecture,
UnknownSubArchitecture,
};
pub fn parseArchSub(text: []const u8) ParseArchSubError!builtin.Arch {
const info = @typeInfo(builtin.Arch);
inline for (info.Union.fields) |field| {
if (mem.eql(u8, text, field.name)) {
if (field.field_type == void) {
return (builtin.Arch)(@field(builtin.Arch, field.name));
} else {
const sub_info = @typeInfo(field.field_type);
inline for (sub_info.Enum.fields) |sub_field| {
const combined = field.name ++ sub_field.name;
if (mem.eql(u8, text, combined)) {
return @unionInit(builtin.Arch, field.name, @field(field.field_type, sub_field.name));
}
}
return error.UnknownSubArchitecture;
}
}
}
return error.UnknownArchitecture;
}
pub fn parseOs(text: []const u8) !builtin.Os {
const info = @typeInfo(builtin.Os);
inline for (info.Enum.fields) |field| {
if (mem.eql(u8, text, field.name)) {
return @field(builtin.Os, field.name);
}
}
return error.UnknownOperatingSystem;
}
pub fn parseAbi(text: []const u8) !builtin.Abi {
const info = @typeInfo(builtin.Abi);
inline for (info.Enum.fields) |field| {
if (mem.eql(u8, text, field.name)) {
return @field(builtin.Abi, field.name);
}
}
return error.UnknownApplicationBinaryInterface;
}
fn archSubArchName(arch: builtin.Arch) []const u8 {
return switch (arch) {
.arm => |sub| @tagName(sub),
.armeb => |sub| @tagName(sub),
.thumb => |sub| @tagName(sub),
.thumbeb => |sub| @tagName(sub),
.aarch64 => |sub| @tagName(sub),
.aarch64_be => |sub| @tagName(sub),
.kalimba => |sub| @tagName(sub),
else => "",
};
}
pub fn subArchName(self: Target) []const u8 {
switch (self) {
.Native => return archSubArchName(builtin.arch),
.Cross => |cross| return archSubArchName(cross.arch),
}
}
2019-05-26 17:17:34 +00:00
pub fn oFileExt(self: Target) []const u8 {
return switch (self.getAbi()) {
builtin.Abi.msvc => ".obj",
else => ".o",
};
}
2019-05-26 17:17:34 +00:00
pub fn exeFileExt(self: Target) []const u8 {
2017-09-23 21:59:30 +00:00
return switch (self.getOs()) {
2019-05-26 17:17:34 +00:00
.windows => ".exe",
2017-09-23 21:59:30 +00:00
else => "",
};
}
pub fn staticLibSuffix(self: Target) []const u8 {
if (self.isWasm()) {
return ".wasm";
}
switch (self.getAbi()) {
.msvc => return ".lib",
else => return ".a",
}
}
pub fn dynamicLibSuffix(self: Target) []const u8 {
if (self.isDarwin()) {
return ".dylib";
}
switch (self.getOs()) {
.windows => return ".dll",
else => return ".so",
}
}
pub fn libPrefix(self: Target) []const u8 {
switch (self.getAbi()) {
.msvc => return "",
else => return "lib",
}
2017-09-23 21:59:30 +00:00
}
2019-05-26 17:17:34 +00:00
pub fn getOs(self: Target) builtin.Os {
return switch (self) {
.Native => builtin.os,
.Cross => |t| t.os,
};
2017-09-23 21:59:30 +00:00
}
pub fn getArch(self: Target) builtin.Arch {
switch (self) {
.Native => return builtin.arch,
.Cross => |t| return t.arch,
}
}
pub fn getAbi(self: Target) builtin.Abi {
switch (self) {
.Native => return builtin.abi,
.Cross => |t| return t.abi,
}
}
pub fn isMinGW(self: Target) bool {
return self.isWindows() and self.isGnu();
}
pub fn isGnu(self: Target) bool {
return switch (self.getAbi()) {
.gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true,
else => false,
};
}
2019-05-26 17:17:34 +00:00
pub fn isDarwin(self: Target) bool {
2017-09-23 21:59:30 +00:00
return switch (self.getOs()) {
2019-05-26 17:17:34 +00:00
.ios, .macosx, .watchos, .tvos => true,
2017-09-23 21:59:30 +00:00
else => false,
};
}
2017-10-16 05:14:28 +00:00
2019-05-26 17:17:34 +00:00
pub fn isWindows(self: Target) bool {
2017-10-16 05:14:28 +00:00
return switch (self.getOs()) {
2019-05-26 17:17:34 +00:00
.windows => true,
2017-10-16 05:14:28 +00:00
else => false,
};
}
pub fn isWasm(self: Target) bool {
return switch (self.getArch()) {
.wasm32, .wasm64 => true,
else => false,
};
}
2019-05-26 17:17:34 +00:00
pub fn isFreeBSD(self: Target) bool {
return switch (self.getOs()) {
2019-05-26 17:17:34 +00:00
.freebsd => true,
else => false,
};
}
2019-05-26 17:17:34 +00:00
pub fn wantSharedLibSymLinks(self: Target) bool {
2017-10-16 05:14:28 +00:00
return !self.isWindows();
}
};
2018-12-05 13:10:09 +00:00
const Pkg = struct {
name: []const u8,
path: []const u8,
};
const CSourceFile = struct {
source_path: []const u8,
args: []const []const u8,
};
fn isLibCLibrary(name: []const u8) bool {
const libc_libraries = [_][]const u8{ "c", "m", "dl", "rt", "pthread" };
for (libc_libraries) |libc_lib_name| {
if (mem.eql(u8, name, libc_lib_name))
return true;
}
return false;
}
pub const LibExeObjStep = struct {
step: Step,
builder: *Builder,
name: []const u8,
target: Target,
2019-07-07 21:55:25 +00:00
linker_script: ?[]const u8 = null,
version_script: ?[]const u8 = null,
out_filename: []const u8,
is_dynamic: bool,
version: Version,
build_mode: builtin.Mode,
kind: Kind,
major_only_filename: []const u8,
name_only_filename: []const u8,
strip: bool,
2017-12-12 04:34:59 +00:00
lib_paths: ArrayList([]const u8),
2017-09-23 21:59:30 +00:00
frameworks: BufSet,
verbose_link: bool,
verbose_cc: bool,
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
disable_gen_h: bool,
bundle_compiler_rt: bool,
disable_stack_probing: bool,
2018-09-06 20:29:35 +00:00
c_std: Builder.CStd,
override_std_dir: ?[]const u8,
stage1 is now a hybrid of C++ and Zig This modifies the build process of Zig to put all of the source files into libcompiler.a, except main.cpp and userland.cpp. Next, the build process links main.cpp, userland.cpp, and libcompiler.a into zig1. userland.cpp is a shim for functions that will later be replaced with self-hosted implementations. Next, the build process uses zig1 to build src-self-hosted/stage1.zig into libuserland.a, which does not depend on any of the things that are shimmed in userland.cpp, such as translate-c. Finally, the build process re-links main.cpp and libcompiler.a, except with libuserland.a instead of userland.cpp. Now the shims are replaced with .zig code. This provides all of the Zig standard library to the stage1 C++ compiler, and enables us to move certain things to userland, such as translate-c. As a proof of concept I have made the `zig zen` command use text defined in userland. I added `zig translate-c-2` which is a work-in-progress reimplementation of translate-c in userland, which currently calls `std.debug.panic("unimplemented")` and you can see the stack trace makes it all the way back into the C++ main() function (Thanks LemonBoy for improving that!). This could potentially let us move other things into userland, such as hashing algorithms, the entire cache system, .d file parsing, pretty much anything that libuserland.a itself doesn't need to depend on. This can also let us have `zig fmt` in stage1 without the overhead of child process execution, and without the initial compilation delay before it gets cached. See #1964
2019-04-16 20:47:47 +00:00
override_lib_dir: ?[]const u8,
main_pkg_path: ?[]const u8,
exec_cmd_args: ?[]const ?[]const u8,
name_prefix: []const u8,
filter: ?[]const u8,
single_threaded: bool,
root_src: ?[]const u8,
out_h_filename: []const u8,
2019-02-25 18:34:25 +00:00
out_lib_filename: []const u8,
out_pdb_filename: []const u8,
packages: ArrayList(Pkg),
2018-07-08 04:00:05 +00:00
build_options_contents: std.Buffer,
system_linker_hack: bool,
object_src: []const u8,
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
link_objects: ArrayList(LinkObject),
include_dirs: ArrayList(IncludeDir),
output_dir: ?[]const u8,
need_system_paths: bool,
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
installed_path: ?[]const u8,
install_step: ?*InstallArtifactStep,
libc_file: ?[]const u8 = null,
target_glibc: ?Version = null,
2019-07-07 15:31:07 +00:00
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
const LinkObject = union(enum) {
StaticPath: []const u8,
OtherStep: *LibExeObjStep,
SystemLib: []const u8,
AssemblyFile: []const u8,
CSourceFile: *CSourceFile,
};
const IncludeDir = union(enum) {
RawPath: []const u8,
OtherStep: *LibExeObjStep,
};
const Kind = enum {
Exe,
Lib,
Obj,
Test,
};
pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8, ver: Version) *LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, ver);
return self;
}
pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, builder.version(0, 0, 0));
return self;
}
pub fn createObject(builder: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
return self;
}
pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?[]const u8, is_dynamic: bool) *LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Exe, is_dynamic, builder.version(0, 0, 0));
return self;
}
pub fn createTest(builder: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Test, false, builder.version(0, 0, 0));
return self;
}
fn initExtraArgs(builder: *Builder, name: []const u8, root_src: ?[]const u8, kind: Kind, is_dynamic: bool, ver: Version) LibExeObjStep {
var self = LibExeObjStep{
.strip = false,
.builder = builder,
.verbose_link = false,
.verbose_cc = false,
.build_mode = builtin.Mode.Debug,
.is_dynamic = is_dynamic,
.kind = kind,
.root_src = root_src,
.name = name,
.target = Target.Native,
2017-09-23 21:59:30 +00:00
.frameworks = BufSet.init(builder.allocator),
.step = Step.init(name, builder.allocator, make),
.version = ver,
.out_filename = undefined,
.out_h_filename = builder.fmt("{}.h", name),
2019-02-25 18:34:25 +00:00
.out_lib_filename = undefined,
.out_pdb_filename = builder.fmt("{}.pdb", name),
.major_only_filename = undefined,
.name_only_filename = undefined,
.packages = ArrayList(Pkg).init(builder.allocator),
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
.include_dirs = ArrayList(IncludeDir).init(builder.allocator),
.link_objects = ArrayList(LinkObject).init(builder.allocator),
2017-12-12 04:34:59 +00:00
.lib_paths = ArrayList([]const u8).init(builder.allocator),
.object_src = undefined,
2018-07-08 04:00:05 +00:00
.build_options_contents = std.Buffer.initSize(builder.allocator, 0) catch unreachable,
2018-09-06 20:29:35 +00:00
.c_std = Builder.CStd.C99,
.system_linker_hack = false,
.override_std_dir = null,
stage1 is now a hybrid of C++ and Zig This modifies the build process of Zig to put all of the source files into libcompiler.a, except main.cpp and userland.cpp. Next, the build process links main.cpp, userland.cpp, and libcompiler.a into zig1. userland.cpp is a shim for functions that will later be replaced with self-hosted implementations. Next, the build process uses zig1 to build src-self-hosted/stage1.zig into libuserland.a, which does not depend on any of the things that are shimmed in userland.cpp, such as translate-c. Finally, the build process re-links main.cpp and libcompiler.a, except with libuserland.a instead of userland.cpp. Now the shims are replaced with .zig code. This provides all of the Zig standard library to the stage1 C++ compiler, and enables us to move certain things to userland, such as translate-c. As a proof of concept I have made the `zig zen` command use text defined in userland. I added `zig translate-c-2` which is a work-in-progress reimplementation of translate-c in userland, which currently calls `std.debug.panic("unimplemented")` and you can see the stack trace makes it all the way back into the C++ main() function (Thanks LemonBoy for improving that!). This could potentially let us move other things into userland, such as hashing algorithms, the entire cache system, .d file parsing, pretty much anything that libuserland.a itself doesn't need to depend on. This can also let us have `zig fmt` in stage1 without the overhead of child process execution, and without the initial compilation delay before it gets cached. See #1964
2019-04-16 20:47:47 +00:00
.override_lib_dir = null,
.main_pkg_path = null,
.exec_cmd_args = null,
.name_prefix = "",
.filter = null,
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
.disable_gen_h = false,
.bundle_compiler_rt = false,
.disable_stack_probing = false,
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
.output_dir = null,
.need_system_paths = false,
.single_threaded = false,
.installed_path = null,
.install_step = null,
};
self.computeOutFileNames();
return self;
}
fn computeOutFileNames(self: *LibExeObjStep) void {
switch (self.kind) {
2019-05-26 17:17:34 +00:00
.Obj => {
self.out_filename = self.builder.fmt("{}{}", self.name, self.target.oFileExt());
},
2019-05-26 17:17:34 +00:00
.Exe => {
self.out_filename = self.builder.fmt("{}{}", self.name, self.target.exeFileExt());
},
2019-05-26 17:17:34 +00:00
.Test => {
self.out_filename = self.builder.fmt("test{}", self.target.exeFileExt());
},
2019-05-26 17:17:34 +00:00
.Lib => {
if (!self.is_dynamic) {
self.out_filename = self.builder.fmt(
"{}{}{}",
self.target.libPrefix(),
self.name,
self.target.staticLibSuffix(),
);
2019-02-25 18:34:25 +00:00
self.out_lib_filename = self.out_filename;
} else {
if (self.target.isDarwin()) {
self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", self.name, self.version.major, self.version.minor, self.version.patch);
self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major);
self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);
self.out_lib_filename = self.out_filename;
} else if (self.target.isWindows()) {
self.out_filename = self.builder.fmt("{}.dll", self.name);
self.out_lib_filename = self.builder.fmt("{}.lib", self.name);
} else {
self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", self.name, self.version.major, self.version.minor, self.version.patch);
self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major);
self.name_only_filename = self.builder.fmt("lib{}.so", self.name);
self.out_lib_filename = self.out_filename;
}
}
},
}
}
/// Deprecated. Use `setTheTarget`.
pub fn setTarget(
self: *LibExeObjStep,
target_arch: builtin.Arch,
target_os: builtin.Os,
target_abi: builtin.Abi,
) void {
return self.setTheTarget(Target{
.Cross = CrossTarget{
.arch = target_arch,
.os = target_os,
.abi = target_abi,
},
});
}
pub fn setTheTarget(self: *LibExeObjStep, target: Target) void {
self.target = target;
self.computeOutFileNames();
}
pub fn setTargetGLibC(self: *LibExeObjStep, major: u32, minor: u32, patch: u32) void {
self.target_glibc = Version{
.major = major,
.minor = minor,
.patch = patch,
};
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
pub fn setOutputDir(self: *LibExeObjStep, dir: []const u8) void {
self.output_dir = self.builder.dupe(dir);
}
pub fn install(self: *LibExeObjStep) void {
self.builder.installArtifact(self);
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
/// Creates a `RunStep` with an executable built with `addExecutable`.
/// Add command line arguments with `addArg`.
pub fn run(exe: *LibExeObjStep) *RunStep {
assert(exe.kind == Kind.Exe);
// It doesn't have to be native. We catch that if you actually try to run it.
// Consider that this is declarative; the run step may not be run unless a user
// option is supplied.
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {}", exe.step.name));
run_step.addArtifactArg(exe);
return run_step;
}
pub fn setLinkerScriptPath(self: *LibExeObjStep, path: []const u8) void {
self.linker_script = path;
}
pub fn linkFramework(self: *LibExeObjStep, framework_name: []const u8) void {
2017-09-23 21:59:30 +00:00
assert(self.target.isDarwin());
self.frameworks.put(framework_name) catch unreachable;
2017-09-23 21:59:30 +00:00
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
/// Returns whether the library, executable, or object depends on a particular system library.
pub fn dependsOnSystemLibrary(self: LibExeObjStep, name: []const u8) bool {
for (self.link_objects.toSliceConst()) |link_object| {
switch (link_object) {
LinkObject.SystemLib => |n| if (mem.eql(u8, n, name)) return true,
else => continue,
}
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
return false;
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
pub fn linkLibrary(self: *LibExeObjStep, lib: *LibExeObjStep) void {
assert(lib.kind == Kind.Lib);
self.linkLibraryOrObject(lib);
}
2017-09-23 21:59:30 +00:00
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
pub fn isDynamicLibrary(self: *LibExeObjStep) bool {
return self.kind == Kind.Lib and self.is_dynamic;
}
2019-07-10 23:40:46 +00:00
pub fn producesPdbFile(self: *LibExeObjStep) bool {
if (!self.target.isWindows()) return false;
if (self.strip) return false;
return self.isDynamicLibrary() or self.kind == .Exe;
}
pub fn linkSystemLibrary(self: *LibExeObjStep, name: []const u8) void {
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
self.link_objects.append(LinkObject{ .SystemLib = self.builder.dupe(name) }) catch unreachable;
if (!isLibCLibrary(name)) {
self.need_system_paths = true;
}
}
pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void {
assert(self.kind == Kind.Test);
self.name_prefix = text;
}
pub fn setFilter(self: *LibExeObjStep, text: ?[]const u8) void {
assert(self.kind == Kind.Test);
self.filter = text;
}
pub fn addCSourceFile(self: *LibExeObjStep, file: []const u8, args: []const []const u8) void {
const c_source_file = self.builder.allocator.create(CSourceFile) catch unreachable;
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
const args_copy = self.builder.allocator.alloc([]u8, args.len) catch unreachable;
for (args) |arg, i| {
args_copy[i] = self.builder.dupe(arg);
}
c_source_file.* = CSourceFile{
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
.source_path = self.builder.dupe(file),
.args = args_copy,
};
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
self.link_objects.append(LinkObject{ .CSourceFile = c_source_file }) catch unreachable;
}
pub fn setVerboseLink(self: *LibExeObjStep, value: bool) void {
self.verbose_link = value;
}
pub fn setVerboseCC(self: *LibExeObjStep, value: bool) void {
self.verbose_cc = value;
}
pub fn setBuildMode(self: *LibExeObjStep, mode: builtin.Mode) void {
self.build_mode = mode;
}
pub fn overrideStdDir(self: *LibExeObjStep, dir_path: []const u8) void {
self.override_std_dir = dir_path;
}
pub fn setMainPkgPath(self: *LibExeObjStep, dir_path: []const u8) void {
self.main_pkg_path = dir_path;
}
pub fn setDisableGenH(self: *LibExeObjStep, value: bool) void {
self.disable_gen_h = value;
}
2019-07-07 15:31:07 +00:00
pub fn setLibCFile(self: *LibExeObjStep, libc_file: ?[]const u8) void {
self.libc_file = libc_file;
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
/// Unless setOutputDir was called, this function must be called only in
/// the make step, from a step that has declared a dependency on this one.
/// To run an executable built with zig build, use `run`, or create an install step and invoke it.
pub fn getOutputPath(self: *LibExeObjStep) []const u8 {
2019-05-26 17:17:34 +00:00
return fs.path.join(
self.builder.allocator,
[_][]const u8{ self.output_dir.?, self.out_filename },
) catch unreachable;
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
/// Unless setOutputDir was called, this function must be called only in
/// the make step, from a step that has declared a dependency on this one.
2019-02-25 18:34:25 +00:00
pub fn getOutputLibPath(self: *LibExeObjStep) []const u8 {
assert(self.kind == Kind.Lib);
2019-05-26 17:17:34 +00:00
return fs.path.join(
2019-02-25 18:34:25 +00:00
self.builder.allocator,
[_][]const u8{ self.output_dir.?, self.out_lib_filename },
2019-02-25 18:34:25 +00:00
) catch unreachable;
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
/// Unless setOutputDir was called, this function must be called only in
/// the make step, from a step that has declared a dependency on this one.
pub fn getOutputHPath(self: *LibExeObjStep) []const u8 {
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
assert(self.kind != Kind.Exe);
assert(!self.disable_gen_h);
2019-05-26 17:17:34 +00:00
return fs.path.join(
self.builder.allocator,
[_][]const u8{ self.output_dir.?, self.out_h_filename },
) catch unreachable;
}
/// Unless setOutputDir was called, this function must be called only in
/// the make step, from a step that has declared a dependency on this one.
pub fn getOutputPdbPath(self: *LibExeObjStep) []const u8 {
assert(self.target.isWindows());
return fs.path.join(
self.builder.allocator,
[_][]const u8{ self.output_dir.?, self.out_pdb_filename },
) catch unreachable;
}
pub fn addAssemblyFile(self: *LibExeObjStep, path: []const u8) void {
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
self.link_objects.append(LinkObject{ .AssemblyFile = self.builder.dupe(path) }) catch unreachable;
}
pub fn addObjectFile(self: *LibExeObjStep, path: []const u8) void {
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
self.link_objects.append(LinkObject{ .StaticPath = self.builder.dupe(path) }) catch unreachable;
}
pub fn addObject(self: *LibExeObjStep, obj: *LibExeObjStep) void {
assert(obj.kind == Kind.Obj);
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
self.linkLibraryOrObject(obj);
}
2018-07-08 04:00:05 +00:00
pub fn addBuildOption(self: *LibExeObjStep, comptime T: type, name: []const u8, value: T) void {
const out = &std.io.BufferOutStream.init(&self.build_options_contents).stream;
out.print("pub const {} = {};\n", name, value) catch unreachable;
}
pub fn addIncludeDir(self: *LibExeObjStep, path: []const u8) void {
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
self.include_dirs.append(IncludeDir{ .RawPath = self.builder.dupe(path) }) catch unreachable;
}
pub fn addLibPath(self: *LibExeObjStep, path: []const u8) void {
self.lib_paths.append(path) catch unreachable;
2017-12-12 04:34:59 +00:00
}
pub fn addPackagePath(self: *LibExeObjStep, name: []const u8, pkg_index_path: []const u8) void {
self.packages.append(Pkg{
.name = name,
.path = pkg_index_path,
}) catch unreachable;
}
pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void {
assert(self.kind == Kind.Test);
self.exec_cmd_args = args;
}
pub fn enableSystemLinkerHack(self: *LibExeObjStep) void {
self.system_linker_hack = true;
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
fn linkLibraryOrObject(self: *LibExeObjStep, other: *LibExeObjStep) void {
self.step.dependOn(&other.step);
self.link_objects.append(LinkObject{ .OtherStep = other }) catch unreachable;
self.include_dirs.append(IncludeDir{ .OtherStep = other }) catch unreachable;
// Inherit dependency on system libraries
for (other.link_objects.toSliceConst()) |link_object| {
switch (link_object) {
.SystemLib => |name| self.linkSystemLibrary(name),
else => continue,
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
}
// Inherit dependencies on darwin frameworks
if (self.target.isDarwin() and !other.isDynamicLibrary()) {
var it = other.frameworks.iterator();
while (it.next()) |entry| {
self.frameworks.put(entry.key) catch unreachable;
}
}
}
fn make(step: *Step) !void {
const self = @fieldParentPtr(LibExeObjStep, "step", step);
const builder = self.builder;
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
if (self.root_src == null and self.link_objects.len == 0) {
warn("{}: linker needs 1 or more objects to link\n", self.step.name);
return error.NeedAnObject;
}
var zig_args = ArrayList([]const u8).init(builder.allocator);
defer zig_args.deinit();
zig_args.append(builder.zig_exe) catch unreachable;
const cmd = switch (self.kind) {
2017-09-16 05:00:59 +00:00
Kind.Lib => "build-lib",
Kind.Exe => "build-exe",
Kind.Obj => "build-obj",
Kind.Test => "test",
};
zig_args.append(cmd) catch unreachable;
if (self.root_src) |root_src| {
zig_args.append(builder.pathFromRoot(root_src)) catch unreachable;
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
for (self.link_objects.toSlice()) |link_object| {
switch (link_object) {
LinkObject.StaticPath => |static_path| {
try zig_args.append("--object");
try zig_args.append(builder.pathFromRoot(static_path));
},
LinkObject.OtherStep => |other| switch (other.kind) {
LibExeObjStep.Kind.Exe => unreachable,
LibExeObjStep.Kind.Test => unreachable,
LibExeObjStep.Kind.Obj => {
try zig_args.append("--object");
try zig_args.append(other.getOutputPath());
},
LibExeObjStep.Kind.Lib => {
if (!other.is_dynamic or self.target.isWindows()) {
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
try zig_args.append("--object");
try zig_args.append(other.getOutputLibPath());
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
} else {
const full_path_lib = other.getOutputPath();
try zig_args.append("--library");
try zig_args.append(full_path_lib);
2019-05-26 17:17:34 +00:00
if (fs.path.dirname(full_path_lib)) |dirname| {
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
try zig_args.append("-rpath");
try zig_args.append(dirname);
}
}
},
},
LinkObject.SystemLib => |name| {
try zig_args.append("--library");
try zig_args.append(name);
},
LinkObject.AssemblyFile => |asm_file| {
try zig_args.append("--c-source");
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
try zig_args.append(builder.pathFromRoot(asm_file));
},
LinkObject.CSourceFile => |c_source_file| {
try zig_args.append("--c-source");
for (c_source_file.args) |arg| {
try zig_args.append(arg);
}
try zig_args.append(self.builder.pathFromRoot(c_source_file.source_path));
},
}
}
2018-07-08 04:00:05 +00:00
if (self.build_options_contents.len() > 0) {
2019-05-26 17:17:34 +00:00
const build_options_file = try fs.path.join(
builder.allocator,
[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", self.name) },
);
2018-08-21 20:07:28 +00:00
try std.io.writeFile(build_options_file, self.build_options_contents.toSliceConst());
2018-07-08 04:00:05 +00:00
try zig_args.append("--pkg-begin");
try zig_args.append("build_options");
try zig_args.append(builder.pathFromRoot(build_options_file));
try zig_args.append("--pkg-end");
}
if (self.filter) |filter| {
try zig_args.append("--test-filter");
try zig_args.append(filter);
}
if (self.name_prefix.len != 0) {
try zig_args.append("--test-name-prefix");
try zig_args.append(self.name_prefix);
}
if (builder.verbose_tokenize) zig_args.append("--verbose-tokenize") catch unreachable;
if (builder.verbose_ast) zig_args.append("--verbose-ast") catch unreachable;
if (builder.verbose_cimport) zig_args.append("--verbose-cimport") catch unreachable;
if (builder.verbose_ir) zig_args.append("--verbose-ir") catch unreachable;
if (builder.verbose_llvm_ir) zig_args.append("--verbose-llvm-ir") catch unreachable;
if (builder.verbose_link or self.verbose_link) zig_args.append("--verbose-link") catch unreachable;
if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable;
if (self.strip) {
zig_args.append("--strip") catch unreachable;
}
if (self.single_threaded) {
try zig_args.append("--single-threaded");
}
2019-07-07 15:31:07 +00:00
if (self.libc_file) |libc_file| {
try zig_args.append("--libc");
try zig_args.append(builder.pathFromRoot(libc_file));
}
switch (self.build_mode) {
builtin.Mode.Debug => {},
builtin.Mode.ReleaseSafe => zig_args.append("--release-safe") catch unreachable,
builtin.Mode.ReleaseFast => zig_args.append("--release-fast") catch unreachable,
2018-04-16 00:26:10 +00:00
builtin.Mode.ReleaseSmall => zig_args.append("--release-small") catch unreachable,
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
try zig_args.append("--cache-dir");
try zig_args.append(builder.pathFromRoot(builder.cache_root));
zig_args.append("--name") catch unreachable;
zig_args.append(self.name) catch unreachable;
if (self.kind == Kind.Lib and self.is_dynamic) {
zig_args.append("--ver-major") catch unreachable;
zig_args.append(builder.fmt("{}", self.version.major)) catch unreachable;
zig_args.append("--ver-minor") catch unreachable;
zig_args.append(builder.fmt("{}", self.version.minor)) catch unreachable;
zig_args.append("--ver-patch") catch unreachable;
zig_args.append(builder.fmt("{}", self.version.patch)) catch unreachable;
}
if (self.is_dynamic) {
try zig_args.append("-dynamic");
2018-12-01 06:21:59 +00:00
}
if (self.disable_gen_h) {
try zig_args.append("--disable-gen-h");
}
if (self.bundle_compiler_rt) {
try zig_args.append("--bundle-compiler-rt");
}
if (self.disable_stack_probing) {
try zig_args.append("--disable-stack-probing");
}
switch (self.target) {
Target.Native => {},
Target.Cross => {
try zig_args.append("-target");
try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);
},
}
if (self.target_glibc) |ver| {
try zig_args.append("-target-glibc");
try zig_args.append(builder.fmt("{}.{}.{}", ver.major, ver.minor, ver.patch));
}
if (self.linker_script) |linker_script| {
zig_args.append("--linker-script") catch unreachable;
2019-07-07 21:55:25 +00:00
zig_args.append(builder.pathFromRoot(linker_script)) catch unreachable;
}
if (self.version_script) |version_script| {
try zig_args.append("--version-script");
try zig_args.append(builder.pathFromRoot(version_script));
}
if (self.exec_cmd_args) |exec_cmd_args| {
for (exec_cmd_args) |cmd_arg| {
if (cmd_arg) |arg| {
try zig_args.append("--test-cmd");
try zig_args.append(arg);
} else {
try zig_args.append("--test-cmd-bin");
}
}
}
for (self.packages.toSliceConst()) |pkg| {
zig_args.append("--pkg-begin") catch unreachable;
zig_args.append(pkg.name) catch unreachable;
zig_args.append(builder.pathFromRoot(pkg.path)) catch unreachable;
zig_args.append("--pkg-end") catch unreachable;
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
for (self.include_dirs.toSliceConst()) |include_dir| {
switch (include_dir) {
IncludeDir.RawPath => |include_path| {
try zig_args.append("-isystem");
try zig_args.append(self.builder.pathFromRoot(include_path));
},
IncludeDir.OtherStep => |other| {
const h_path = other.getOutputHPath();
try zig_args.append("-isystem");
2019-05-26 17:17:34 +00:00
try zig_args.append(fs.path.dirname(h_path).?);
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
},
}
2017-12-12 04:34:59 +00:00
}
for (self.lib_paths.toSliceConst()) |lib_path| {
zig_args.append("--library-path") catch unreachable;
zig_args.append(lib_path) catch unreachable;
2017-12-12 04:34:59 +00:00
}
if (self.need_system_paths and self.target == Target.Native) {
for (builder.native_system_include_dirs.toSliceConst()) |include_path| {
zig_args.append("-isystem") catch unreachable;
zig_args.append(builder.pathFromRoot(include_path)) catch unreachable;
}
for (builder.native_system_rpaths.toSliceConst()) |rpath| {
zig_args.append("-rpath") catch unreachable;
zig_args.append(rpath) catch unreachable;
}
for (builder.native_system_lib_paths.toSliceConst()) |lib_path| {
zig_args.append("--library-path") catch unreachable;
zig_args.append(lib_path) catch unreachable;
}
}
2017-09-23 21:59:30 +00:00
if (self.target.isDarwin()) {
var it = self.frameworks.iterator();
while (it.next()) |entry| {
zig_args.append("-framework") catch unreachable;
zig_args.append(entry.key) catch unreachable;
2017-09-23 21:59:30 +00:00
}
}
if (self.system_linker_hack) {
try zig_args.append("--system-linker-hack");
}
if (self.override_std_dir) |dir| {
try zig_args.append("--override-std-dir");
try zig_args.append(builder.pathFromRoot(dir));
stage1 is now a hybrid of C++ and Zig This modifies the build process of Zig to put all of the source files into libcompiler.a, except main.cpp and userland.cpp. Next, the build process links main.cpp, userland.cpp, and libcompiler.a into zig1. userland.cpp is a shim for functions that will later be replaced with self-hosted implementations. Next, the build process uses zig1 to build src-self-hosted/stage1.zig into libuserland.a, which does not depend on any of the things that are shimmed in userland.cpp, such as translate-c. Finally, the build process re-links main.cpp and libcompiler.a, except with libuserland.a instead of userland.cpp. Now the shims are replaced with .zig code. This provides all of the Zig standard library to the stage1 C++ compiler, and enables us to move certain things to userland, such as translate-c. As a proof of concept I have made the `zig zen` command use text defined in userland. I added `zig translate-c-2` which is a work-in-progress reimplementation of translate-c in userland, which currently calls `std.debug.panic("unimplemented")` and you can see the stack trace makes it all the way back into the C++ main() function (Thanks LemonBoy for improving that!). This could potentially let us move other things into userland, such as hashing algorithms, the entire cache system, .d file parsing, pretty much anything that libuserland.a itself doesn't need to depend on. This can also let us have `zig fmt` in stage1 without the overhead of child process execution, and without the initial compilation delay before it gets cached. See #1964
2019-04-16 20:47:47 +00:00
} else if (self.builder.override_std_dir) |dir| {
try zig_args.append("--override-std-dir");
try zig_args.append(builder.pathFromRoot(dir));
}
if (self.override_lib_dir) |dir| {
try zig_args.append("--override-lib-dir");
try zig_args.append(builder.pathFromRoot(dir));
} else if (self.builder.override_lib_dir) |dir| {
try zig_args.append("--override-lib-dir");
try zig_args.append(builder.pathFromRoot(dir));
}
if (self.main_pkg_path) |dir| {
try zig_args.append("--main-pkg-path");
try zig_args.append(builder.pathFromRoot(dir));
}
if (self.kind == Kind.Test) {
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
try builder.spawnChild(zig_args.toSliceConst());
} else {
try zig_args.append("--cache");
try zig_args.append("on");
const output_path_nl = try builder.exec(zig_args.toSliceConst());
const output_path = mem.trimRight(u8, output_path_nl, "\r\n");
if (self.output_dir) |output_dir| {
const full_dest = try fs.path.join(builder.allocator, [_][]const u8{
output_dir,
fs.path.basename(output_path),
});
try builder.updateFile(output_path, full_dest);
} else {
self.output_dir = fs.path.dirname(output_path).?;
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
}
if (self.kind == Kind.Lib and self.is_dynamic and self.target.wantSharedLibSymLinks()) {
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
try doAtomicSymLinks(builder.allocator, self.getOutputPath(), self.major_only_filename, self.name_only_filename);
}
}
};
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
pub const RunStep = struct {
step: Step,
builder: *Builder,
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
/// See also addArg and addArgs to modifying this directly
argv: ArrayList(Arg),
/// Set this to modify the current working directory
cwd: ?[]const u8,
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
/// Override this field to modify the environment, or use setEnvironmentVariable
env_map: ?*BufMap,
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
pub const Arg = union(enum) {
Artifact: *LibExeObjStep,
Bytes: []u8,
};
pub fn create(builder: *Builder, name: []const u8) *RunStep {
const self = builder.allocator.create(RunStep) catch unreachable;
self.* = RunStep{
.builder = builder,
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
.step = Step.init(name, builder.allocator, make),
.argv = ArrayList(Arg).init(builder.allocator),
.cwd = null,
.env_map = null,
};
return self;
}
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
pub fn addArtifactArg(self: *RunStep, artifact: *LibExeObjStep) void {
self.argv.append(Arg{ .Artifact = artifact }) catch unreachable;
self.step.dependOn(&artifact.step);
}
pub fn addArg(self: *RunStep, arg: []const u8) void {
self.argv.append(Arg{ .Bytes = self.builder.dupe(arg) }) catch unreachable;
}
pub fn addArgs(self: *RunStep, args: []const []const u8) void {
for (args) |arg| {
self.addArg(arg);
}
}
pub fn clearEnvironment(self: *RunStep) void {
const new_env_map = self.builder.allocator.create(BufMap) catch unreachable;
new_env_map.* = BufMap.init(self.builder.allocator);
self.env_map = new_env_map;
}
pub fn addPathDir(self: *RunStep, search_path: []const u8) void {
2019-05-26 17:17:34 +00:00
const PATH = if (std.os.windows.is_the_target) "Path" else "PATH";
const env_map = self.getEnvMap();
const prev_path = env_map.get(PATH) orelse {
env_map.set(PATH, search_path) catch unreachable;
return;
};
2019-05-26 17:17:34 +00:00
const new_path = self.builder.fmt("{}" ++ [1]u8{fs.path.delimiter} ++ "{}", prev_path, search_path);
env_map.set(PATH, new_path) catch unreachable;
}
pub fn getEnvMap(self: *RunStep) *BufMap {
return self.env_map orelse {
const env_map = self.builder.allocator.create(BufMap) catch unreachable;
2019-05-26 17:17:34 +00:00
env_map.* = process.getEnvMap(self.builder.allocator) catch unreachable;
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
self.env_map = env_map;
return env_map;
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
};
}
pub fn setEnvironmentVariable(self: *RunStep, key: []const u8, value: []const u8) void {
const env_map = self.getEnvMap();
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
env_map.set(key, value) catch unreachable;
}
fn make(step: *Step) !void {
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
const self = @fieldParentPtr(RunStep, "step", step);
const cwd = if (self.cwd) |cwd| self.builder.pathFromRoot(cwd) else self.builder.build_root;
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
var argv = ArrayList([]const u8).init(self.builder.allocator);
for (self.argv.toSlice()) |arg| {
switch (arg) {
Arg.Bytes => |bytes| try argv.append(bytes),
Arg.Artifact => |artifact| {
if (artifact.target.isWindows()) {
// On Windows we don't have rpaths so we have to add .dll search paths to PATH
self.addPathForDynLibs(artifact);
}
const executable_path = artifact.installed_path orelse artifact.getOutputPath();
try argv.append(executable_path);
},
breaking changes to zig build API and improved caching * in Zig build scripts, getOutputPath() is no longer a valid function to call, unless setOutputDir() was used, or within a custom make() function. Instead there is more convenient API to use which takes advantage of the caching system. Search this commit diff for `exe.run()` for an example. * Zig build by default enables caching. All build artifacts will go into zig-cache. If you want to access build artifacts in a convenient location, it is recommended to add an `install` step. Otherwise you can use the `run()` API mentioned above to execute programs directly from their location in the cache. Closes #330. `addSystemCommand` is available for programs not built with Zig build. * Please note that Zig does no cache evicting yet. You may have to manually delete zig-cache directories periodically to keep disk usage down. It's planned for this to be a simple Least Recently Used eviction system eventually. * `--output`, `--output-lib`, and `--output-h` are removed. Instead, use `--output-dir` which defaults to the current working directory. Or take advantage of `--cache on`, which will print the main output path to stdout, and the other artifacts will be in the same directory with predictable file names. `--disable-gen-h` is available when one wants to prevent .h file generation. * `@cImport` is always independently cached now. Closes #2015. It always writes the generated Zig code to disk which makes debug info and compile errors better. No more "TODO: remember C source location to display here" * Fix .d file parsing. (Fixes the MacOS CI failure) * Zig no longer creates "temporary files" other than inside a zig-cache directory. This breaks the CLI API that Godbolt uses. The suggested new invocation can be found in this commit diff, in the changes to `test/cli.zig`.
2019-03-09 03:53:35 +00:00
}
}
return self.builder.spawnChildEnvMap(cwd, self.env_map orelse self.builder.env_map, argv.toSliceConst());
}
fn addPathForDynLibs(self: *RunStep, artifact: *LibExeObjStep) void {
for (artifact.link_objects.toSliceConst()) |link_object| {
switch (link_object) {
LibExeObjStep.LinkObject.OtherStep => |other| {
if (other.target.isWindows() and other.isDynamicLibrary()) {
2019-05-26 17:17:34 +00:00
self.addPathDir(fs.path.dirname(other.getOutputPath()).?);
self.addPathForDynLibs(other);
}
},
else => {},
}
}
}
};
const InstallArtifactStep = struct {
step: Step,
builder: *Builder,
artifact: *LibExeObjStep,
dest_dir: InstallDir,
pdb_dir: ?InstallDir,
const Self = @This();
pub fn create(builder: *Builder, artifact: *LibExeObjStep) *Self {
if (artifact.install_step) |s| return s;
const self = builder.allocator.create(Self) catch unreachable;
self.* = Self{
.builder = builder,
.step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),
.artifact = artifact,
.dest_dir = switch (artifact.kind) {
.Obj => unreachable,
.Test => unreachable,
.Exe => InstallDir.Bin,
.Lib => InstallDir.Lib,
},
2019-07-10 23:40:46 +00:00
.pdb_dir = if (artifact.producesPdbFile()) blk: {
if (artifact.kind == .Exe) {
break :blk InstallDir.Bin;
} else {
break :blk InstallDir.Lib;
}
} else null,
};
self.step.dependOn(&artifact.step);
artifact.install_step = self;
builder.pushInstalledFile(self.dest_dir, artifact.out_filename);
if (self.artifact.isDynamicLibrary()) {
builder.pushInstalledFile(.Lib, artifact.major_only_filename);
builder.pushInstalledFile(.Lib, artifact.name_only_filename);
}
if (self.pdb_dir) |pdb_dir| {
builder.pushInstalledFile(pdb_dir, artifact.out_pdb_filename);
}
return self;
}
fn make(step: *Step) !void {
const self = @fieldParentPtr(Self, "step", step);
const builder = self.builder;
const full_dest_path = builder.getInstallPath(self.dest_dir, self.artifact.out_filename);
try builder.updateFile(self.artifact.getOutputPath(), full_dest_path);
if (self.artifact.isDynamicLibrary()) {
try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename, self.artifact.name_only_filename);
}
if (self.pdb_dir) |pdb_dir| {
const full_pdb_path = builder.getInstallPath(pdb_dir, self.artifact.out_pdb_filename);
try builder.updateFile(self.artifact.getOutputPdbPath(), full_pdb_path);
}
self.artifact.installed_path = full_dest_path;
}
};
pub const InstallFileStep = struct {
step: Step,
builder: *Builder,
src_path: []const u8,
dir: InstallDir,
dest_rel_path: []const u8,
pub fn init(
builder: *Builder,
src_path: []const u8,
dir: InstallDir,
dest_rel_path: []const u8,
) InstallFileStep {
builder.pushInstalledFile(dir, dest_rel_path);
return InstallFileStep{
.builder = builder,
.step = Step.init(builder.fmt("install {}", src_path), builder.allocator, make),
.src_path = src_path,
.dir = dir,
.dest_rel_path = dest_rel_path,
};
}
fn make(step: *Step) !void {
const self = @fieldParentPtr(InstallFileStep, "step", step);
const full_dest_path = self.builder.getInstallPath(self.dir, self.dest_rel_path);
const full_src_path = self.builder.pathFromRoot(self.src_path);
try self.builder.updateFile(full_src_path, full_dest_path);
}
};
pub const InstallDirectoryOptions = struct {
source_dir: []const u8,
install_dir: InstallDir,
install_subdir: []const u8,
exclude_extensions: ?[]const []const u8 = null,
};
pub const InstallDirStep = struct {
step: Step,
builder: *Builder,
options: InstallDirectoryOptions,
pub fn init(
builder: *Builder,
options: InstallDirectoryOptions,
) InstallDirStep {
builder.pushInstalledFile(options.install_dir, options.install_subdir);
return InstallDirStep{
.builder = builder,
.step = Step.init(builder.fmt("install {}/", options.source_dir), builder.allocator, make),
.options = options,
};
}
fn make(step: *Step) !void {
const self = @fieldParentPtr(InstallDirStep, "step", step);
const dest_prefix = self.builder.getInstallPath(self.options.install_dir, self.options.install_subdir);
const full_src_dir = self.builder.pathFromRoot(self.options.source_dir);
var it = try fs.walkPath(self.builder.allocator, full_src_dir);
next_entry: while (try it.next()) |entry| {
if (self.options.exclude_extensions) |ext_list| for (ext_list) |ext| {
if (mem.endsWith(u8, entry.path, ext)) {
continue :next_entry;
}
};
const rel_path = entry.path[full_src_dir.len + 1 ..];
const dest_path = try fs.path.join(self.builder.allocator, [_][]const u8{ dest_prefix, rel_path });
switch (entry.kind) {
.Directory => try fs.makePath(self.builder.allocator, dest_path),
.File => try self.builder.updateFile(entry.path, dest_path),
else => continue,
}
}
}
};
pub const WriteFileStep = struct {
step: Step,
builder: *Builder,
file_path: []const u8,
data: []const u8,
pub fn init(builder: *Builder, file_path: []const u8, data: []const u8) WriteFileStep {
return WriteFileStep{
.builder = builder,
.step = Step.init(builder.fmt("writefile {}", file_path), builder.allocator, make),
.file_path = file_path,
.data = data,
};
}
fn make(step: *Step) !void {
const self = @fieldParentPtr(WriteFileStep, "step", step);
const full_path = self.builder.pathFromRoot(self.file_path);
2019-05-26 17:17:34 +00:00
const full_path_dir = fs.path.dirname(full_path) orelse ".";
fs.makePath(self.builder.allocator, full_path_dir) catch |err| {
warn("unable to make path {}: {}\n", full_path_dir, @errorName(err));
return err;
};
2018-08-21 20:07:28 +00:00
io.writeFile(full_path, self.data) catch |err| {
warn("unable to write {}: {}\n", full_path, @errorName(err));
return err;
};
}
};
pub const LogStep = struct {
step: Step,
builder: *Builder,
data: []const u8,
pub fn init(builder: *Builder, data: []const u8) LogStep {
return LogStep{
.builder = builder,
.step = Step.init(builder.fmt("log {}", data), builder.allocator, make),
.data = data,
};
}
fn make(step: *Step) anyerror!void {
const self = @fieldParentPtr(LogStep, "step", step);
warn("{}", self.data);
}
};
pub const RemoveDirStep = struct {
step: Step,
builder: *Builder,
dir_path: []const u8,
pub fn init(builder: *Builder, dir_path: []const u8) RemoveDirStep {
return RemoveDirStep{
.builder = builder,
.step = Step.init(builder.fmt("RemoveDir {}", dir_path), builder.allocator, make),
.dir_path = dir_path,
};
}
fn make(step: *Step) !void {
const self = @fieldParentPtr(RemoveDirStep, "step", step);
const full_path = self.builder.pathFromRoot(self.dir_path);
2019-05-26 17:17:34 +00:00
fs.deleteTree(self.builder.allocator, full_path) catch |err| {
warn("Unable to remove {}: {}\n", full_path, @errorName(err));
return err;
};
}
};
pub const Step = struct {
name: []const u8,
makeFn: fn (self: *Step) anyerror!void,
dependencies: ArrayList(*Step),
loop_flag: bool,
done_flag: bool,
pub fn init(name: []const u8, allocator: *Allocator, makeFn: fn (*Step) anyerror!void) Step {
return Step{
.name = name,
.makeFn = makeFn,
.dependencies = ArrayList(*Step).init(allocator),
.loop_flag = false,
.done_flag = false,
};
}
pub fn initNoOp(name: []const u8, allocator: *Allocator) Step {
return init(name, allocator, makeNoOp);
}
pub fn make(self: *Step) !void {
if (self.done_flag) return;
try self.makeFn(self);
self.done_flag = true;
}
pub fn dependOn(self: *Step, other: *Step) void {
self.dependencies.append(other) catch unreachable;
}
fn makeNoOp(self: *Step) anyerror!void {}
};
fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_major_only: []const u8, filename_name_only: []const u8) !void {
2019-05-26 17:17:34 +00:00
const out_dir = fs.path.dirname(output_path) orelse ".";
const out_basename = fs.path.basename(output_path);
// sym link for libfoo.so.1 to libfoo.so.1.2.3
2019-05-26 17:17:34 +00:00
const major_only_path = fs.path.join(
allocator,
[_][]const u8{ out_dir, filename_major_only },
) catch unreachable;
2019-05-26 17:17:34 +00:00
fs.atomicSymLink(allocator, out_basename, major_only_path) catch |err| {
warn("Unable to symlink {} -> {}\n", major_only_path, out_basename);
return err;
};
// sym link for libfoo.so to libfoo.so.1
2019-05-26 17:17:34 +00:00
const name_only_path = fs.path.join(
allocator,
[_][]const u8{ out_dir, filename_name_only },
) catch unreachable;
2019-05-26 17:17:34 +00:00
fs.atomicSymLink(allocator, filename_major_only, name_only_path) catch |err| {
warn("Unable to symlink {} -> {}\n", name_only_path, filename_major_only);
return err;
};
}
pub const InstallDir = enum {
Prefix,
Lib,
Bin,
};
pub const InstalledFile = struct {
dir: InstallDir,
path: []const u8,
};