parent
38a04a267c
commit
363d9038c9
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,6 @@
|
||||
zig-cache/
|
||||
build/
|
||||
build-release/
|
||||
/.cproject
|
||||
/.project
|
||||
/.settings/
|
||||
/test_artifacts/
|
||||
|
19
build.zig
19
build.zig
@ -5,19 +5,16 @@ pub fn build(b: &Builder) {
|
||||
const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
|
||||
const test_step = b.step("test", "Run all the tests");
|
||||
|
||||
const cleanup = b.addRemoveDirTree("test_artifacts");
|
||||
test_step.dependOn(&cleanup.step);
|
||||
|
||||
cleanup.step.dependOn(tests.addPkgTests(b, test_filter,
|
||||
test_step.dependOn(tests.addPkgTests(b, test_filter,
|
||||
"test/behavior.zig", "behavior", "Run the behavior tests"));
|
||||
|
||||
cleanup.step.dependOn(tests.addPkgTests(b, test_filter,
|
||||
test_step.dependOn(tests.addPkgTests(b, test_filter,
|
||||
"std/index.zig", "std", "Run the standard library tests"));
|
||||
|
||||
cleanup.step.dependOn(tests.addCompareOutputTests(b, test_filter));
|
||||
cleanup.step.dependOn(tests.addBuildExampleTests(b, test_filter));
|
||||
cleanup.step.dependOn(tests.addCompileErrorTests(b, test_filter));
|
||||
cleanup.step.dependOn(tests.addAssembleAndLinkTests(b, test_filter));
|
||||
cleanup.step.dependOn(tests.addDebugSafetyTests(b, test_filter));
|
||||
cleanup.step.dependOn(tests.addParseHTests(b, test_filter));
|
||||
test_step.dependOn(tests.addCompareOutputTests(b, test_filter));
|
||||
test_step.dependOn(tests.addBuildExampleTests(b, test_filter));
|
||||
test_step.dependOn(tests.addCompileErrorTests(b, test_filter));
|
||||
test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter));
|
||||
test_step.dependOn(tests.addDebugSafetyTests(b, test_filter));
|
||||
test_step.dependOn(tests.addParseHTests(b, test_filter));
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ pub fn build(b: &Builder) {
|
||||
|
||||
b.default_step.dependOn(&exe.step);
|
||||
|
||||
const run_cmd = b.addCommand(b.out_dir, b.env_map, "./test", [][]const u8{});
|
||||
const run_cmd = b.addCommand(b.cache_root, b.env_map, "./test", [][]const u8{});
|
||||
run_cmd.step.dependOn(&exe.step);
|
||||
|
||||
const test_step = b.step("test", "Test the program");
|
||||
|
@ -12,7 +12,7 @@ pub fn build(b: &Builder) {
|
||||
|
||||
b.default_step.dependOn(&exe.step);
|
||||
|
||||
const run_cmd = b.addCommand(b.out_dir, b.env_map, "./test", [][]const u8{});
|
||||
const run_cmd = b.addCommand(b.cache_root, b.env_map, "./test", [][]const u8{});
|
||||
run_cmd.step.dependOn(&exe.step);
|
||||
|
||||
const test_step = b.step("test", "Test the program");
|
||||
|
@ -1488,6 +1488,7 @@ struct CodeGen {
|
||||
ZigList<TimeEvent> timing_events;
|
||||
|
||||
Buf *cache_dir;
|
||||
Buf *out_h_path;
|
||||
};
|
||||
|
||||
enum VarLinkage {
|
||||
|
@ -55,11 +55,12 @@ PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_pa
|
||||
return entry;
|
||||
}
|
||||
|
||||
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) {
|
||||
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type) {
|
||||
CodeGen *g = allocate<CodeGen>(1);
|
||||
|
||||
codegen_add_time_event(g, "Initialize");
|
||||
|
||||
g->out_type = out_type;
|
||||
g->import_table.init(32);
|
||||
g->builtin_fn_table.init(32);
|
||||
g->primitive_type_table.init(32);
|
||||
@ -74,7 +75,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) {
|
||||
g->external_prototypes.init(8);
|
||||
g->is_release_build = false;
|
||||
g->is_test_build = false;
|
||||
g->want_h_file = true;
|
||||
g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib);
|
||||
|
||||
buf_resize(&g->global_asm, 0);
|
||||
|
||||
@ -145,6 +146,10 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) {
|
||||
return g;
|
||||
}
|
||||
|
||||
void codegen_set_output_h_path(CodeGen *g, Buf *h_path) {
|
||||
g->out_h_path = h_path;
|
||||
}
|
||||
|
||||
void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) {
|
||||
g->clang_argv = args;
|
||||
g->clang_argv_len = len;
|
||||
@ -196,10 +201,6 @@ void codegen_set_strip(CodeGen *g, bool strip) {
|
||||
g->strip_debug_symbols = strip;
|
||||
}
|
||||
|
||||
void codegen_set_out_type(CodeGen *g, OutType out_type) {
|
||||
g->out_type = out_type;
|
||||
}
|
||||
|
||||
void codegen_set_out_name(CodeGen *g, Buf *out_name) {
|
||||
g->root_out_name = out_name;
|
||||
}
|
||||
@ -4808,15 +4809,6 @@ static void gen_global_asm(CodeGen *g) {
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_build(CodeGen *g) {
|
||||
assert(g->out_type != OutTypeUnknown);
|
||||
init(g);
|
||||
|
||||
gen_global_asm(g);
|
||||
gen_root_source(g);
|
||||
do_code_gen(g);
|
||||
}
|
||||
|
||||
void codegen_add_object(CodeGen *g, Buf *object_path) {
|
||||
g->link_objects.append(object_path);
|
||||
}
|
||||
@ -4946,13 +4938,21 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_generate_h_file(CodeGen *g) {
|
||||
static void gen_h_file(CodeGen *g) {
|
||||
if (!g->want_h_file)
|
||||
return;
|
||||
|
||||
codegen_add_time_event(g, "Generate .h");
|
||||
|
||||
assert(!g->is_test_build);
|
||||
|
||||
Buf *h_file_out_path = buf_sprintf("%s.h", buf_ptr(g->root_out_name));
|
||||
FILE *out_h = fopen(buf_ptr(h_file_out_path), "wb");
|
||||
if (!g->out_h_path) {
|
||||
g->out_h_path = buf_sprintf("%s.h", buf_ptr(g->root_out_name));
|
||||
}
|
||||
|
||||
FILE *out_h = fopen(buf_ptr(g->out_h_path), "wb");
|
||||
if (!out_h)
|
||||
zig_panic("unable to open %s: %s", buf_ptr(h_file_out_path), strerror(errno));
|
||||
zig_panic("unable to open %s: %s", buf_ptr(g->out_h_path), strerror(errno));
|
||||
|
||||
Buf *export_macro = buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name));
|
||||
buf_upcase(export_macro);
|
||||
@ -5056,3 +5056,13 @@ void codegen_print_timing_report(CodeGen *g, FILE *f) {
|
||||
void codegen_add_time_event(CodeGen *g, const char *name) {
|
||||
g->timing_events.append({os_get_time(), name});
|
||||
}
|
||||
|
||||
void codegen_build(CodeGen *g) {
|
||||
assert(g->out_type != OutTypeUnknown);
|
||||
init(g);
|
||||
|
||||
gen_global_asm(g);
|
||||
gen_root_source(g);
|
||||
do_code_gen(g);
|
||||
gen_h_file(g);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target);
|
||||
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type);
|
||||
|
||||
void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
|
||||
void codegen_set_is_release(CodeGen *codegen, bool is_release);
|
||||
@ -25,7 +25,6 @@ void codegen_set_is_static(CodeGen *codegen, bool is_static);
|
||||
void codegen_set_strip(CodeGen *codegen, bool strip);
|
||||
void codegen_set_verbose(CodeGen *codegen, bool verbose);
|
||||
void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
|
||||
void codegen_set_out_type(CodeGen *codegen, OutType out_type);
|
||||
void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
|
||||
void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir);
|
||||
void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir);
|
||||
@ -48,6 +47,7 @@ void codegen_set_test_filter(CodeGen *g, Buf *filter);
|
||||
void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix);
|
||||
void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch);
|
||||
void codegen_set_cache_dir(CodeGen *g, Buf *cache_dir);
|
||||
void codegen_set_output_h_path(CodeGen *g, Buf *h_path);
|
||||
void codegen_add_time_event(CodeGen *g, const char *name);
|
||||
void codegen_print_timing_report(CodeGen *g, FILE *f);
|
||||
void codegen_build(CodeGen *g);
|
||||
@ -59,6 +59,5 @@ void codegen_add_object(CodeGen *g, Buf *object_path);
|
||||
void codegen_parseh(CodeGen *g, Buf *path);
|
||||
void codegen_render_ast(CodeGen *g, FILE *f, int indent_size);
|
||||
|
||||
void codegen_generate_h_file(CodeGen *g);
|
||||
|
||||
#endif
|
||||
|
20
src/link.cpp
20
src/link.cpp
@ -37,7 +37,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {
|
||||
os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path);
|
||||
|
||||
ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target;
|
||||
CodeGen *child_gen = codegen_create(full_path, child_target);
|
||||
CodeGen *child_gen = codegen_create(full_path, child_target, OutTypeObj);
|
||||
child_gen->link_libc = parent_gen->link_libc;
|
||||
|
||||
child_gen->link_libs.resize(parent_gen->link_libs.length);
|
||||
@ -55,7 +55,6 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {
|
||||
codegen_set_strip(child_gen, parent_gen->strip_debug_symbols);
|
||||
codegen_set_is_static(child_gen, parent_gen->is_static);
|
||||
|
||||
codegen_set_out_type(child_gen, OutTypeObj);
|
||||
codegen_set_out_name(child_gen, buf_create_from_str(oname));
|
||||
|
||||
codegen_set_verbose(child_gen, parent_gen->verbose);
|
||||
@ -186,9 +185,10 @@ static void construct_linker_job_elf(LinkJob *lj) {
|
||||
} else if (shared) {
|
||||
lj->args.append("-shared");
|
||||
|
||||
buf_resize(&lj->out_file, 0);
|
||||
buf_appendf(&lj->out_file, "lib%s.so.%zu.%zu.%zu",
|
||||
buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch);
|
||||
if (buf_len(&lj->out_file) == 0) {
|
||||
buf_appendf(&lj->out_file, "lib%s.so.%zu.%zu.%zu",
|
||||
buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch);
|
||||
}
|
||||
soname = buf_sprintf("lib%s.so.%zu", buf_ptr(g->root_out_name), g->version_major);
|
||||
}
|
||||
|
||||
@ -752,9 +752,6 @@ void codegen_link(CodeGen *g, const char *out_file) {
|
||||
}
|
||||
|
||||
if (g->out_type == OutTypeObj) {
|
||||
if (g->want_h_file) {
|
||||
codegen_generate_h_file(g);
|
||||
}
|
||||
if (override_out_file) {
|
||||
assert(g->link_objects.length == 1);
|
||||
Buf *o_file_path = g->link_objects.at(0);
|
||||
@ -798,13 +795,6 @@ void codegen_link(CodeGen *g, const char *out_file) {
|
||||
fprintf(stderr, "%s\n", buf_ptr(&diag));
|
||||
exit(1);
|
||||
}
|
||||
codegen_add_time_event(g, "Generate .h");
|
||||
|
||||
if (g->out_type == OutTypeLib ||
|
||||
g->out_type == OutTypeObj)
|
||||
{
|
||||
codegen_generate_h_file(g);
|
||||
}
|
||||
|
||||
codegen_add_time_event(g, "Done");
|
||||
|
||||
|
33
src/main.cpp
33
src/main.cpp
@ -35,6 +35,7 @@ static int usage(const char *arg0) {
|
||||
" --libc-include-dir [path] directory where libc stdlib.h resides\n"
|
||||
" --name [name] override output name\n"
|
||||
" --output [file] override destination path\n"
|
||||
" --output-h [file] override generated header file path\n"
|
||||
" --release build with optimizations on and debug protection off\n"
|
||||
" --static output will be statically linked\n"
|
||||
" --strip exclude debug symbols\n"
|
||||
@ -118,6 +119,8 @@ enum Cmd {
|
||||
CmdTargets,
|
||||
};
|
||||
|
||||
static const char *default_zig_cache_name = "zig-cache";
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
os_init();
|
||||
|
||||
@ -125,6 +128,7 @@ int main(int argc, char **argv) {
|
||||
Cmd cmd = CmdInvalid;
|
||||
const char *in_file = nullptr;
|
||||
const char *out_file = nullptr;
|
||||
const char *out_file_h = nullptr;
|
||||
bool is_release_build = false;
|
||||
bool strip = false;
|
||||
bool is_static = false;
|
||||
@ -163,7 +167,7 @@ int main(int argc, char **argv) {
|
||||
size_t ver_minor = 0;
|
||||
size_t ver_patch = 0;
|
||||
bool timing_info = false;
|
||||
const char *cache_dir = "zig-cache";
|
||||
const char *cache_dir = nullptr;
|
||||
|
||||
if (argc >= 2 && strcmp(argv[1], "build") == 0) {
|
||||
const char *zig_exe_path = arg0;
|
||||
@ -200,9 +204,8 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
CodeGen *g = codegen_create(build_runner_path, nullptr);
|
||||
CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe);
|
||||
codegen_set_out_name(g, buf_create_from_str("build"));
|
||||
codegen_set_out_type(g, OutTypeExe);
|
||||
codegen_set_verbose(g, verbose);
|
||||
|
||||
Buf build_file_abs = BUF_INIT;
|
||||
@ -212,7 +215,12 @@ int main(int argc, char **argv) {
|
||||
os_path_split(&build_file_abs, &build_file_dirname, &build_file_basename);
|
||||
|
||||
Buf *full_cache_dir = buf_alloc();
|
||||
os_path_resolve(buf_create_from_str("."), buf_create_from_str(cache_dir), full_cache_dir);
|
||||
if (cache_dir == nullptr) {
|
||||
os_path_join(&build_file_dirname, buf_create_from_str(default_zig_cache_name), full_cache_dir);
|
||||
} else {
|
||||
os_path_resolve(buf_create_from_str("."), buf_create_from_str(cache_dir), full_cache_dir);
|
||||
}
|
||||
|
||||
Buf *path_to_build_exe = buf_alloc();
|
||||
os_path_join(full_cache_dir, buf_create_from_str("build"), path_to_build_exe);
|
||||
codegen_set_cache_dir(g, full_cache_dir);
|
||||
@ -309,6 +317,8 @@ int main(int argc, char **argv) {
|
||||
return usage(arg0);
|
||||
} else if (strcmp(arg, "--output") == 0) {
|
||||
out_file = argv[i];
|
||||
} else if (strcmp(arg, "--output-h") == 0) {
|
||||
out_file_h = argv[i];
|
||||
} else if (strcmp(arg, "--color") == 0) {
|
||||
if (strcmp(argv[i], "auto") == 0) {
|
||||
color = ErrColorAuto;
|
||||
@ -396,6 +406,7 @@ int main(int argc, char **argv) {
|
||||
cmd = CmdParseH;
|
||||
} else if (strcmp(arg, "test") == 0) {
|
||||
cmd = CmdTest;
|
||||
out_type = OutTypeExe;
|
||||
} else if (strcmp(arg, "targets") == 0) {
|
||||
cmd = CmdTargets;
|
||||
} else {
|
||||
@ -495,9 +506,11 @@ int main(int argc, char **argv) {
|
||||
Buf *zig_root_source_file = (cmd == CmdParseH) ? nullptr : in_file_buf;
|
||||
|
||||
Buf *full_cache_dir = buf_alloc();
|
||||
os_path_resolve(buf_create_from_str("."), buf_create_from_str(cache_dir), full_cache_dir);
|
||||
os_path_resolve(buf_create_from_str("."),
|
||||
buf_create_from_str((cache_dir == nullptr) ? default_zig_cache_name : cache_dir),
|
||||
full_cache_dir);
|
||||
|
||||
CodeGen *g = codegen_create(zig_root_source_file, target);
|
||||
CodeGen *g = codegen_create(zig_root_source_file, target, out_type);
|
||||
codegen_set_out_name(g, buf_out_name);
|
||||
codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
|
||||
codegen_set_is_release(g, is_release_build);
|
||||
@ -510,11 +523,6 @@ int main(int argc, char **argv) {
|
||||
codegen_set_clang_argv(g, clang_argv.items, clang_argv.length);
|
||||
codegen_set_strip(g, strip);
|
||||
codegen_set_is_static(g, is_static);
|
||||
if (out_type != OutTypeUnknown) {
|
||||
codegen_set_out_type(g, out_type);
|
||||
} else if (cmd == CmdTest) {
|
||||
codegen_set_out_type(g, OutTypeExe);
|
||||
}
|
||||
if (libc_lib_dir)
|
||||
codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir));
|
||||
if (libc_static_lib_dir)
|
||||
@ -568,6 +576,9 @@ int main(int argc, char **argv) {
|
||||
codegen_set_test_name_prefix(g, buf_create_from_str(test_name_prefix));
|
||||
}
|
||||
|
||||
if (out_file_h)
|
||||
codegen_set_output_h_path(g, buf_create_from_str(out_file_h));
|
||||
|
||||
if (cmd == CmdBuild) {
|
||||
for (size_t i = 0; i < objects.length; i += 1) {
|
||||
codegen_add_object(g, buf_create_from_str(objects.at(i)));
|
||||
|
200
std/build.zig
200
std/build.zig
@ -37,7 +37,6 @@ pub const Builder = struct {
|
||||
top_level_steps: List(&TopLevelStep),
|
||||
prefix: []const u8,
|
||||
lib_dir: []const u8,
|
||||
out_dir: []u8, // TODO get rid of this
|
||||
installed_files: List([]const u8),
|
||||
build_root: []const u8,
|
||||
cache_root: []const u8,
|
||||
@ -97,7 +96,6 @@ pub const Builder = struct {
|
||||
.env_map = %%os.getEnvMap(allocator),
|
||||
.prefix = undefined,
|
||||
.lib_dir = undefined,
|
||||
.out_dir = %%os.getCwd(allocator),
|
||||
.installed_files = List([]const u8).init(allocator),
|
||||
.uninstall_tls = TopLevelStep {
|
||||
.step = Step.init("uninstall", allocator, makeUninstall),
|
||||
@ -111,7 +109,6 @@ pub const Builder = struct {
|
||||
}
|
||||
|
||||
pub fn deinit(self: &Builder) {
|
||||
self.allocator.free(self.out_dir);
|
||||
self.lib_paths.deinit();
|
||||
self.include_paths.deinit();
|
||||
self.rpaths.deinit();
|
||||
@ -172,12 +169,10 @@ pub const Builder = struct {
|
||||
return exe;
|
||||
}
|
||||
|
||||
pub fn addCommand(self: &Builder, cwd: []const u8, env_map: &const BufMap,
|
||||
pub fn addCommand(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
|
||||
path: []const u8, args: []const []const u8) -> &CommandStep
|
||||
{
|
||||
const cmd = %%self.allocator.create(CommandStep);
|
||||
*cmd = CommandStep.init(self, cwd, env_map, path, args);
|
||||
return cmd;
|
||||
return CommandStep.create(self, cwd, env_map, path, args);
|
||||
}
|
||||
|
||||
pub fn addWriteFile(self: &Builder, file_path: []const u8, data: []const u8) -> &WriteFileStep {
|
||||
@ -489,21 +484,22 @@ pub const Builder = struct {
|
||||
}
|
||||
|
||||
fn spawnChild(self: &Builder, exe_path: []const u8, args: []const []const u8) -> %void {
|
||||
return self.spawnChildEnvMap(&self.env_map, exe_path, args);
|
||||
return self.spawnChildEnvMap(null, &self.env_map, exe_path, args);
|
||||
}
|
||||
|
||||
fn spawnChildEnvMap(self: &Builder, env_map: &const BufMap, exe_path: []const u8,
|
||||
args: []const []const u8) -> %void
|
||||
fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
|
||||
exe_path: []const u8, args: []const []const u8) -> %void
|
||||
{
|
||||
if (self.verbose) {
|
||||
%%io.stderr.printf("{}", exe_path);
|
||||
test (cwd) |yes_cwd| %%io.stderr.print("cd {}; ", yes_cwd);
|
||||
%%io.stderr.print("{}", exe_path);
|
||||
for (args) |arg| {
|
||||
%%io.stderr.printf(" {}", arg);
|
||||
%%io.stderr.print(" {}", arg);
|
||||
}
|
||||
%%io.stderr.printf("\n");
|
||||
}
|
||||
|
||||
var child = os.ChildProcess.spawn(exe_path, args, env_map,
|
||||
var child = os.ChildProcess.spawn(exe_path, args, cwd, env_map,
|
||||
StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, self.allocator) %% |err|
|
||||
{
|
||||
%%io.stderr.printf("Unable to spawn {}: {}\n", exe_path, @errorName(err));
|
||||
@ -511,6 +507,7 @@ pub const Builder = struct {
|
||||
};
|
||||
|
||||
const term = child.wait() %% |err| {
|
||||
test (cwd) |yes_cwd| %%io.stderr.printf("cwd: {}\n", yes_cwd);
|
||||
%%io.stderr.printf("Unable to spawn {}: {}\n", exe_path, @errorName(err));
|
||||
return err;
|
||||
};
|
||||
@ -560,11 +557,12 @@ pub const Builder = struct {
|
||||
|
||||
fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) {
|
||||
const dirname = os.path.dirname(dest_path);
|
||||
const abs_source_path = self.pathFromRoot(source_path);
|
||||
os.makePath(self.allocator, dirname) %% |err| {
|
||||
debug.panic("Unable to create path {}: {}", dirname, @errorName(err));
|
||||
};
|
||||
os.copyFile(self.allocator, source_path, dest_path) %% |err| {
|
||||
debug.panic("Unable to copy {} to {}: {}", source_path, dest_path, @errorName(err));
|
||||
os.copyFile(self.allocator, abs_source_path, dest_path) %% |err| {
|
||||
debug.panic("Unable to copy {} to {}: {}", abs_source_path, dest_path, @errorName(err));
|
||||
};
|
||||
}
|
||||
|
||||
@ -628,8 +626,10 @@ pub const LibExeObjStep = struct {
|
||||
release: bool,
|
||||
static: bool,
|
||||
output_path: ?[]const u8,
|
||||
output_h_path: ?[]const u8,
|
||||
kind: Kind,
|
||||
version: Version,
|
||||
out_h_filename: []const u8,
|
||||
out_filename: []const u8,
|
||||
out_filename_major_only: []const u8,
|
||||
out_filename_name_only: []const u8,
|
||||
@ -684,8 +684,10 @@ pub const LibExeObjStep = struct {
|
||||
.link_libs = BufSet.init(builder.allocator),
|
||||
.step = Step.init(name, builder.allocator, make),
|
||||
.output_path = null,
|
||||
.output_h_path = null,
|
||||
.version = *ver,
|
||||
.out_filename = undefined,
|
||||
.out_h_filename = builder.fmt("{}.h", name),
|
||||
.out_filename_major_only = undefined,
|
||||
.out_filename_name_only = undefined,
|
||||
.object_files = List([]const u8).init(builder.allocator),
|
||||
@ -747,6 +749,27 @@ pub const LibExeObjStep = struct {
|
||||
self.output_path = value;
|
||||
}
|
||||
|
||||
pub fn getOutputPath(self: &LibExeObjStep) -> []const u8 {
|
||||
test (self.output_path) |output_path| {
|
||||
output_path
|
||||
} else {
|
||||
const wanted_path = %%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename);
|
||||
%%os.path.relative(self.builder.allocator, self.builder.build_root, wanted_path)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setOutputHPath(self: &LibExeObjStep, value: []const u8) {
|
||||
self.output_h_path = value;
|
||||
}
|
||||
|
||||
pub fn getOutputHPath(self: &LibExeObjStep) -> []const u8 {
|
||||
test (self.output_h_path) |output_h_path| {
|
||||
output_h_path
|
||||
} else {
|
||||
%%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_h_filename)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) {
|
||||
%%self.assembly_files.append(path);
|
||||
}
|
||||
@ -763,14 +786,7 @@ pub const LibExeObjStep = struct {
|
||||
|
||||
self.step.dependOn(&obj.step);
|
||||
|
||||
const path_to_obj = test (obj.output_path) |explicit_out_path| {
|
||||
explicit_out_path
|
||||
} else {
|
||||
// TODO make it so we always know where this will be
|
||||
%%os.path.join(self.builder.allocator, self.builder.cache_root,
|
||||
self.builder.fmt("{}{}", obj.name, obj.target.oFileExt()))
|
||||
};
|
||||
%%self.object_files.append(path_to_obj);
|
||||
%%self.object_files.append(obj.getOutputPath());
|
||||
}
|
||||
|
||||
fn make(step: &Step) -> %void {
|
||||
@ -814,10 +830,16 @@ pub const LibExeObjStep = struct {
|
||||
%%zig_args.append("--release");
|
||||
}
|
||||
|
||||
test (self.output_path) |output_path| {
|
||||
%%zig_args.append("--output");
|
||||
%%zig_args.append(builder.pathFromRoot(output_path));
|
||||
}
|
||||
%%zig_args.append("--cache-dir");
|
||||
%%zig_args.append(builder.cache_root);
|
||||
|
||||
const output_path = builder.pathFromRoot(self.getOutputPath());
|
||||
%%zig_args.append("--output");
|
||||
%%zig_args.append(output_path);
|
||||
|
||||
const output_h_path = self.getOutputHPath();
|
||||
%%zig_args.append("--output-h");
|
||||
%%zig_args.append(builder.pathFromRoot(output_h_path));
|
||||
|
||||
%%zig_args.append("--name");
|
||||
%%zig_args.append(self.name);
|
||||
@ -879,10 +901,8 @@ pub const LibExeObjStep = struct {
|
||||
%return builder.spawnChild(builder.zig_exe, zig_args.toSliceConst());
|
||||
|
||||
if (self.kind == Kind.Lib and !self.static) {
|
||||
// sym link for libfoo.so.1 to libfoo.so.1.2.3
|
||||
%%os.atomicSymLink(builder.allocator, self.out_filename, self.out_filename_major_only);
|
||||
// sym link for libfoo.so to libfoo.so.1
|
||||
%%os.atomicSymLink(builder.allocator, self.out_filename_major_only, self.out_filename_name_only);
|
||||
%return doAtomicSymLinks(builder.allocator, output_path, self.out_filename_major_only,
|
||||
self.out_filename_name_only);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -987,10 +1007,12 @@ pub const TestStep = struct {
|
||||
}
|
||||
};
|
||||
|
||||
// TODO merge with CExecutable
|
||||
pub const CLibrary = struct {
|
||||
step: Step,
|
||||
name: []const u8,
|
||||
out_filename: []const u8,
|
||||
output_path: ?[]const u8,
|
||||
static: bool,
|
||||
version: Version,
|
||||
cflags: List([]const u8),
|
||||
@ -1024,6 +1046,7 @@ pub const CLibrary = struct {
|
||||
.step = Step.init(name, builder.allocator, make),
|
||||
.link_libs = BufSet.init(builder.allocator),
|
||||
.include_dirs = List([]const u8).init(builder.allocator),
|
||||
.output_path = null,
|
||||
.out_filename = undefined,
|
||||
.major_only_filename = undefined,
|
||||
.name_only_filename = undefined,
|
||||
@ -1043,6 +1066,19 @@ pub const CLibrary = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setOutputPath(self: &CLibrary, value: []const u8) {
|
||||
self.output_path = value;
|
||||
}
|
||||
|
||||
pub fn getOutputPath(self: &CLibrary) -> []const u8 {
|
||||
test (self.output_path) |output_path| {
|
||||
output_path
|
||||
} else {
|
||||
const wanted_path = %%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename);
|
||||
%%os.path.relative(self.builder.allocator, self.builder.build_root, wanted_path)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn linkSystemLibrary(self: &CLibrary, name: []const u8) {
|
||||
%%self.link_libs.put(name);
|
||||
}
|
||||
@ -1131,8 +1167,9 @@ pub const CLibrary = struct {
|
||||
defer builder.allocator.free(soname_arg);
|
||||
%%cc_args.append(soname_arg);
|
||||
|
||||
const output_path = builder.pathFromRoot(self.getOutputPath());
|
||||
%%cc_args.append("-o");
|
||||
%%cc_args.append(self.out_filename);
|
||||
%%cc_args.append(output_path);
|
||||
|
||||
for (self.object_files.toSliceConst()) |object_file| {
|
||||
%%cc_args.append(builder.pathFromRoot(object_file));
|
||||
@ -1140,10 +1177,8 @@ pub const CLibrary = struct {
|
||||
|
||||
%return builder.spawnChild(cc, cc_args.toSliceConst());
|
||||
|
||||
// sym link for libfoo.so.1 to libfoo.so.1.2.3
|
||||
%%os.atomicSymLink(builder.allocator, self.out_filename, self.major_only_filename);
|
||||
// sym link for libfoo.so to libfoo.so.1
|
||||
%%os.atomicSymLink(builder.allocator, self.major_only_filename, self.name_only_filename);
|
||||
%return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
|
||||
self.name_only_filename);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1169,9 +1204,11 @@ pub const CExecutable = struct {
|
||||
link_libs: BufSet,
|
||||
target: Target,
|
||||
include_dirs: List([]const u8),
|
||||
output_path: ?[]const u8,
|
||||
out_filename: []const u8,
|
||||
|
||||
pub fn init(builder: &Builder, name: []const u8) -> CExecutable {
|
||||
CExecutable {
|
||||
var self = CExecutable {
|
||||
.builder = builder,
|
||||
.name = name,
|
||||
.target = Target.Native,
|
||||
@ -1182,6 +1219,27 @@ pub const CExecutable = struct {
|
||||
.step = Step.init(name, builder.allocator, make),
|
||||
.link_libs = BufSet.init(builder.allocator),
|
||||
.include_dirs = List([]const u8).init(builder.allocator),
|
||||
.output_path = null,
|
||||
.out_filename = undefined,
|
||||
};
|
||||
self.computeOutFileName();
|
||||
return self;
|
||||
}
|
||||
|
||||
fn computeOutFileName(self: &CExecutable) {
|
||||
self.out_filename = self.builder.fmt("{}{}", self.name, self.target.exeFileExt());
|
||||
}
|
||||
|
||||
pub fn setOutputPath(self: &CExecutable, value: []const u8) {
|
||||
self.output_path = value;
|
||||
}
|
||||
|
||||
pub fn getOutputPath(self: &CExecutable) -> []const u8 {
|
||||
test (self.output_path) |output_path| {
|
||||
self.builder.pathFromRoot(output_path)
|
||||
} else {
|
||||
const wanted_path = %%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename);
|
||||
%%os.path.relative(self.builder.allocator, self.builder.build_root, wanted_path)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1191,15 +1249,15 @@ pub const CExecutable = struct {
|
||||
|
||||
pub fn linkCLibrary(self: &CExecutable, clib: &CLibrary) {
|
||||
self.step.dependOn(&clib.step);
|
||||
%%self.full_path_libs.append(clib.out_filename);
|
||||
%%self.full_path_libs.append(clib.getOutputPath());
|
||||
}
|
||||
|
||||
pub fn linkLibrary(self: &CExecutable, lib: &LibExeObjStep) {
|
||||
assert(lib.kind == LibExeObjStep.Kind.Lib);
|
||||
self.step.dependOn(&lib.step);
|
||||
%%self.full_path_libs.append(lib.out_filename);
|
||||
%%self.full_path_libs.append(lib.getOutputPath());
|
||||
// TODO should be some kind of isolated directory that only has this header in it
|
||||
%%self.include_dirs.append(self.builder.out_dir);
|
||||
%%self.include_dirs.append(self.builder.cache_root);
|
||||
}
|
||||
|
||||
pub fn addObject(self: &CExecutable, obj: &LibExeObjStep) {
|
||||
@ -1207,12 +1265,10 @@ pub const CExecutable = struct {
|
||||
|
||||
self.step.dependOn(&obj.step);
|
||||
|
||||
// TODO make it so we always know where this will be
|
||||
%%self.object_files.append(%%os.path.join(self.builder.allocator, self.builder.cache_root,
|
||||
self.builder.fmt("{}{}", obj.name, obj.target.oFileExt())));
|
||||
%%self.object_files.append(obj.getOutputPath());
|
||||
|
||||
// TODO should be some kind of isolated directory that only has this header in it
|
||||
%%self.include_dirs.append(self.builder.out_dir);
|
||||
%%self.include_dirs.append(self.builder.cache_root);
|
||||
}
|
||||
|
||||
pub fn addSourceFile(self: &CExecutable, file: []const u8) {
|
||||
@ -1256,7 +1312,6 @@ pub const CExecutable = struct {
|
||||
%%cc_args.append("-c");
|
||||
%%cc_args.append(builder.pathFromRoot(source_file));
|
||||
|
||||
// TODO don't dump the .o file in the same place as the source file
|
||||
const rel_src_path = %%os.path.relative(builder.allocator, builder.build_root, source_file);
|
||||
const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, rel_src_path);
|
||||
const cache_o_dir = os.path.dirname(cache_o_src);
|
||||
@ -1276,26 +1331,28 @@ pub const CExecutable = struct {
|
||||
|
||||
%return builder.spawnChild(cc, cc_args.toSliceConst());
|
||||
|
||||
%%self.object_files.append(cache_o_file);
|
||||
%%self.object_files.append(%%os.path.relative(builder.allocator, builder.build_root, cache_o_file));
|
||||
}
|
||||
|
||||
%%cc_args.resize(0);
|
||||
|
||||
for (self.object_files.toSliceConst()) |object_file| {
|
||||
%%cc_args.append(object_file);
|
||||
%%cc_args.append(builder.pathFromRoot(object_file));
|
||||
}
|
||||
|
||||
const output_path = builder.pathFromRoot(self.getOutputPath());
|
||||
%%cc_args.append("-o");
|
||||
%%cc_args.append(self.name);
|
||||
%%cc_args.append(output_path);
|
||||
|
||||
const rpath_arg = builder.fmt("-Wl,-rpath,{}", builder.out_dir);
|
||||
const rpath_arg = builder.fmt("-Wl,-rpath,{}",
|
||||
%%os.path.real(builder.allocator, builder.cache_root));
|
||||
defer builder.allocator.free(rpath_arg);
|
||||
%%cc_args.append(rpath_arg);
|
||||
|
||||
%%cc_args.append("-rdynamic");
|
||||
|
||||
for (self.full_path_libs.toSliceConst()) |full_path_lib| {
|
||||
%%cc_args.append(full_path_lib);
|
||||
%%cc_args.append(builder.pathFromRoot(full_path_lib));
|
||||
}
|
||||
|
||||
%return builder.spawnChild(cc, cc_args.toSliceConst());
|
||||
@ -1317,27 +1374,29 @@ pub const CommandStep = struct {
|
||||
builder: &Builder,
|
||||
exe_path: []const u8,
|
||||
args: []const []const u8,
|
||||
cwd: []const u8,
|
||||
cwd: ?[]const u8,
|
||||
env_map: &const BufMap,
|
||||
|
||||
pub fn init(builder: &Builder, cwd: []const u8, env_map: &const BufMap,
|
||||
exe_path: []const u8, args: []const []const u8) -> CommandStep
|
||||
pub fn create(builder: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
|
||||
exe_path: []const u8, args: []const []const u8) -> &CommandStep
|
||||
{
|
||||
CommandStep {
|
||||
const self = %%builder.allocator.create(CommandStep);
|
||||
*self = CommandStep {
|
||||
.builder = builder,
|
||||
.step = Step.init(exe_path, builder.allocator, make),
|
||||
.exe_path = exe_path,
|
||||
.args = args,
|
||||
.cwd = cwd,
|
||||
.env_map = env_map,
|
||||
}
|
||||
};
|
||||
return self;
|
||||
}
|
||||
|
||||
fn make(step: &Step) -> %void {
|
||||
const self = @fieldParentPtr(CommandStep, "step", step);
|
||||
|
||||
// TODO set cwd
|
||||
return self.builder.spawnChildEnvMap(self.env_map, self.exe_path, self.args);
|
||||
const cwd = test (self.cwd) |cwd| self.builder.pathFromRoot(cwd) else null;
|
||||
return self.builder.spawnChildEnvMap(cwd, self.env_map, self.exe_path, self.args);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1367,12 +1426,10 @@ pub const InstallCLibraryStep = struct {
|
||||
const self = @fieldParentPtr(InstallCLibraryStep, "step", step);
|
||||
const builder = self.builder;
|
||||
|
||||
self.builder.copyFile(self.lib.out_filename, self.dest_file);
|
||||
self.builder.copyFile(self.lib.getOutputPath(), self.dest_file);
|
||||
if (!self.lib.static) {
|
||||
const dest_major_only = %%os.path.join(builder.allocator, builder.lib_dir, self.lib.major_only_filename);
|
||||
const dest_name_only = %%os.path.join(builder.allocator, builder.lib_dir, self.lib.name_only_filename);
|
||||
%%os.atomicSymLink(self.builder.allocator, self.lib.out_filename, dest_major_only);
|
||||
%%os.atomicSymLink(self.builder.allocator, self.lib.major_only_filename, dest_name_only);
|
||||
%return doAtomicSymLinks(self.builder.allocator, self.dest_file, self.lib.major_only_filename,
|
||||
self.lib.name_only_filename);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1506,3 +1563,22 @@ pub const Step = struct {
|
||||
|
||||
fn makeNoOp(self: &Step) -> %void {}
|
||||
};
|
||||
|
||||
fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8,
|
||||
filename_name_only: []const u8) -> %void
|
||||
{
|
||||
const out_dir = os.path.dirname(output_path);
|
||||
const out_basename = os.path.basename(output_path);
|
||||
// sym link for libfoo.so.1 to libfoo.so.1.2.3
|
||||
const major_only_path = %%os.path.join(allocator, out_dir, filename_major_only);
|
||||
os.atomicSymLink(allocator, out_basename, major_only_path) %% |err| {
|
||||
%%io.stderr.printf("Unable to symlink {} -> {}\n", major_only_path, out_basename);
|
||||
return err;
|
||||
};
|
||||
// sym link for libfoo.so to libfoo.so.1
|
||||
const name_only_path = %%os.path.join(allocator, out_dir, filename_name_only);
|
||||
os.atomicSymLink(allocator, filename_major_only, name_only_path) %% |err| {
|
||||
%%io.stderr.printf("Unable to symlink {} -> {}\n", name_only_path, filename_major_only);
|
||||
return err;
|
||||
};
|
||||
}
|
||||
|
@ -345,17 +345,17 @@ fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) {
|
||||
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) -> []u8 {
|
||||
var context = BufPrintContext { .remaining = buf, };
|
||||
_ = format(&context, bufPrintWrite, fmt, args);
|
||||
return buf[0...buf.len - context.remaining.len];
|
||||
}
|
||||
|
||||
pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) -> %[]u8 {
|
||||
var size: usize = 0;
|
||||
_ = format(&size, countSize, fmt, args);
|
||||
const buf = %return allocator.alloc(u8, size);
|
||||
bufPrint(buf, fmt, args);
|
||||
return buf;
|
||||
return bufPrint(buf, fmt, args);
|
||||
}
|
||||
|
||||
fn countSize(size: &usize, bytes: []const u8) -> bool {
|
||||
|
@ -30,12 +30,13 @@ pub const ChildProcess = struct {
|
||||
Close,
|
||||
};
|
||||
|
||||
pub fn spawn(exe_path: []const u8, args: []const []const u8, env_map: &const BufMap,
|
||||
pub fn spawn(exe_path: []const u8, args: []const []const u8,
|
||||
cwd: ?[]const u8, env_map: &const BufMap,
|
||||
stdin: StdIo, stdout: StdIo, stderr: StdIo, allocator: &Allocator) -> %ChildProcess
|
||||
{
|
||||
switch (@compileVar("os")) {
|
||||
Os.linux, Os.macosx, Os.ios, Os.darwin => {
|
||||
return spawnPosix(exe_path, args, env_map, stdin, stdout, stderr, allocator);
|
||||
return spawnPosix(exe_path, args, cwd, env_map, stdin, stdout, stderr, allocator);
|
||||
},
|
||||
else => @compileError("Unsupported OS"),
|
||||
}
|
||||
@ -98,7 +99,8 @@ pub const ChildProcess = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn spawnPosix(exe_path: []const u8, args: []const []const u8, env_map: &const BufMap,
|
||||
fn spawnPosix(exe_path: []const u8, args: []const []const u8,
|
||||
maybe_cwd: ?[]const u8, env_map: &const BufMap,
|
||||
stdin: StdIo, stdout: StdIo, stderr: StdIo, allocator: &Allocator) -> %ChildProcess
|
||||
{
|
||||
// TODO issue #295
|
||||
@ -155,6 +157,11 @@ pub const ChildProcess = struct {
|
||||
setUpChildIo(stderr, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) %%
|
||||
|err| forkChildErrReport(err_pipe[1], err);
|
||||
|
||||
test (maybe_cwd) |cwd| {
|
||||
os.changeCurDir(allocator, cwd) %%
|
||||
|err| forkChildErrReport(err_pipe[1], err);
|
||||
}
|
||||
|
||||
os.posixExecve(exe_path, args, env_map, allocator) %%
|
||||
|err| forkChildErrReport(err_pipe[1], err);
|
||||
}
|
||||
|
@ -780,3 +780,60 @@ pub const Dir = struct {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void {
|
||||
const path_buf = %return allocator.alloc(u8, dir_path.len + 1);
|
||||
defer allocator.free(path_buf);
|
||||
|
||||
mem.copy(u8, path_buf, dir_path);
|
||||
path_buf[dir_path.len] = 0;
|
||||
|
||||
const err = posix.getErrno(posix.chdir(path_buf.ptr));
|
||||
if (err > 0) {
|
||||
return switch (err) {
|
||||
errno.EACCES => error.AccessDenied,
|
||||
errno.EFAULT => unreachable,
|
||||
errno.EIO => error.FileSystem,
|
||||
errno.ELOOP => error.SymLinkLoop,
|
||||
errno.ENAMETOOLONG => error.NameTooLong,
|
||||
errno.ENOENT => error.FileNotFound,
|
||||
errno.ENOMEM => error.SystemResources,
|
||||
errno.ENOTDIR => error.NotDir,
|
||||
else => error.Unexpected,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Read value of a symbolic link.
|
||||
pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
|
||||
const path_buf = %return allocator.alloc(u8, pathname.len + 1);
|
||||
defer allocator.free(path_buf);
|
||||
|
||||
mem.copy(u8, path_buf, pathname);
|
||||
path_buf[pathname.len] = 0;
|
||||
|
||||
var result_buf = %return allocator.alloc(u8, 1024);
|
||||
%defer allocator.free(result_buf);
|
||||
while (true) {
|
||||
const ret_val = posix.readlink(path_buf.ptr, result_buf.ptr, result_buf.len);
|
||||
const err = posix.getErrno(ret_val);
|
||||
if (err > 0) {
|
||||
return switch (err) {
|
||||
errno.EACCES => error.AccessDenied,
|
||||
errno.EFAULT, errno.EINVAL => unreachable,
|
||||
errno.EIO => error.FileSystem,
|
||||
errno.ELOOP => error.SymLinkLoop,
|
||||
errno.ENAMETOOLONG => error.NameTooLong,
|
||||
errno.ENOENT => error.FileNotFound,
|
||||
errno.ENOMEM => error.SystemResources,
|
||||
errno.ENOTDIR => error.NotDir,
|
||||
else => error.Unexpected,
|
||||
};
|
||||
}
|
||||
if (ret_val == result_buf.len) {
|
||||
result_buf = %return allocator.realloc(u8, result_buf, result_buf.len * 2);
|
||||
continue;
|
||||
}
|
||||
return result_buf[0...ret_val];
|
||||
}
|
||||
}
|
||||
|
@ -335,6 +335,10 @@ pub fn dup2(old: i32, new: i32) -> usize {
|
||||
arch.syscall2(arch.SYS_dup2, usize(old), usize(new))
|
||||
}
|
||||
|
||||
pub fn chdir(path: &const u8) -> usize {
|
||||
arch.syscall1(arch.SYS_chdir, usize(path))
|
||||
}
|
||||
|
||||
pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) -> usize {
|
||||
arch.syscall3(arch.SYS_execve, usize(path), usize(argv), usize(envp))
|
||||
}
|
||||
@ -356,6 +360,10 @@ pub fn isatty(fd: i32) -> bool {
|
||||
return arch.syscall3(arch.SYS_ioctl, usize(fd), TIOCGWINSZ, usize(&wsz)) == 0;
|
||||
}
|
||||
|
||||
pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) -> usize {
|
||||
arch.syscall3(arch.SYS_readlink, usize(path), usize(buf_ptr), buf_len)
|
||||
}
|
||||
|
||||
pub fn mkdir(path: &const u8, mode: usize) -> usize {
|
||||
arch.syscall2(arch.SYS_mkdir, usize(path), mode)
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
const debug = @import("../debug.zig");
|
||||
const assert = debug.assert;
|
||||
const mem = @import("../mem.zig");
|
||||
const fmt = @import("../fmt.zig");
|
||||
const Allocator = mem.Allocator;
|
||||
const os = @import("index.zig");
|
||||
const math = @import("../math.zig");
|
||||
const posix = os.posix;
|
||||
|
||||
pub const sep = switch (@compileVar("os")) {
|
||||
Os.windows => '\\',
|
||||
@ -185,6 +187,45 @@ fn testDirname(input: []const u8, expected_output: []const u8) {
|
||||
assert(mem.eql(u8, dirname(input), expected_output));
|
||||
}
|
||||
|
||||
pub fn basename(path: []const u8) -> []const u8 {
|
||||
if (path.len == 0)
|
||||
return []u8{};
|
||||
|
||||
var end_index: usize = path.len - 1;
|
||||
while (path[end_index] == '/') {
|
||||
if (end_index == 0)
|
||||
return []u8{};
|
||||
end_index -= 1;
|
||||
}
|
||||
var start_index: usize = end_index;
|
||||
end_index += 1;
|
||||
while (path[start_index] != '/') {
|
||||
if (start_index == 0)
|
||||
return path[0...end_index];
|
||||
start_index -= 1;
|
||||
}
|
||||
|
||||
return path[start_index + 1...end_index];
|
||||
}
|
||||
|
||||
test "os.path.basename" {
|
||||
testBasename("", "");
|
||||
testBasename("/", "");
|
||||
testBasename("/dir/basename.ext", "basename.ext");
|
||||
testBasename("/basename.ext", "basename.ext");
|
||||
testBasename("basename.ext", "basename.ext");
|
||||
testBasename("basename.ext/", "basename.ext");
|
||||
testBasename("basename.ext//", "basename.ext");
|
||||
testBasename("/aaa/bbb", "bbb");
|
||||
testBasename("/aaa/", "aaa");
|
||||
testBasename("/aaa/b", "b");
|
||||
testBasename("/a/b", "b");
|
||||
testBasename("//a", "a");
|
||||
}
|
||||
fn testBasename(input: []const u8, expected_output: []const u8) {
|
||||
assert(mem.eql(u8, basename(input), expected_output));
|
||||
}
|
||||
|
||||
/// Returns the relative path from ::from to ::to. If ::from and ::to each
|
||||
/// resolve to the same path (after calling ::resolve on each), a zero-length
|
||||
/// string is returned.
|
||||
@ -252,3 +293,17 @@ fn testRelative(from: []const u8, to: []const u8, expected_output: []const u8) {
|
||||
const result = %%relative(&debug.global_allocator, from, to);
|
||||
assert(mem.eql(u8, result, expected_output));
|
||||
}
|
||||
|
||||
/// Return the canonicalized absolute pathname.
|
||||
/// Expands all symbolic links and resolves references to `.`, `..`, and
|
||||
/// extra `/` characters in ::pathname.
|
||||
/// Caller must deallocate result.
|
||||
pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
|
||||
const fd = %return os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator);
|
||||
defer os.posixClose(fd);
|
||||
|
||||
var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined;
|
||||
const proc_path = fmt.bufPrint(buf[0...], "/proc/self/fd/{}", fd);
|
||||
|
||||
return os.readLink(allocator, proc_path);
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ pub const CompareOutputContext = struct {
|
||||
|
||||
%%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
|
||||
|
||||
var child = os.ChildProcess.spawn(full_exe_path, [][]u8{}, &b.env_map,
|
||||
var child = os.ChildProcess.spawn(full_exe_path, [][]u8{}, null, &b.env_map,
|
||||
StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err|
|
||||
{
|
||||
debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));
|
||||
@ -264,7 +264,7 @@ pub const CompareOutputContext = struct {
|
||||
|
||||
%%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
|
||||
|
||||
var child = os.ChildProcess.spawn(full_exe_path, [][]u8{}, &b.env_map,
|
||||
var child = os.ChildProcess.spawn(full_exe_path, [][]u8{}, null, &b.env_map,
|
||||
StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err|
|
||||
{
|
||||
debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));
|
||||
@ -344,8 +344,8 @@ pub const CompareOutputContext = struct {
|
||||
pub fn addCase(self: &CompareOutputContext, case: &const TestCase) {
|
||||
const b = self.b;
|
||||
|
||||
const root_src = %%os.path.join(b.allocator, "test_artifacts", case.sources.items[0].filename);
|
||||
const exe_path = %%os.path.join(b.allocator, "test_artifacts", "test");
|
||||
const root_src = %%os.path.join(b.allocator, b.cache_root, case.sources.items[0].filename);
|
||||
const exe_path = %%os.path.join(b.allocator, b.cache_root, "test");
|
||||
|
||||
switch (case.special) {
|
||||
Special.Asm => {
|
||||
@ -360,7 +360,7 @@ pub const CompareOutputContext = struct {
|
||||
exe.setOutputPath(exe_path);
|
||||
|
||||
for (case.sources.toSliceConst()) |src_file| {
|
||||
const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename);
|
||||
const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename);
|
||||
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
|
||||
exe.step.dependOn(&write_src.step);
|
||||
}
|
||||
@ -388,7 +388,7 @@ pub const CompareOutputContext = struct {
|
||||
}
|
||||
|
||||
for (case.sources.toSliceConst()) |src_file| {
|
||||
const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename);
|
||||
const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename);
|
||||
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
|
||||
exe.step.dependOn(&write_src.step);
|
||||
}
|
||||
@ -401,7 +401,7 @@ pub const CompareOutputContext = struct {
|
||||
}
|
||||
},
|
||||
Special.DebugSafety => {
|
||||
const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o");
|
||||
const obj_path = %%os.path.join(b.allocator, b.cache_root, "test.o");
|
||||
const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "debug-safety {}", case.name);
|
||||
test (self.test_filter) |filter| {
|
||||
if (mem.indexOf(u8, annotated_case_name, filter) == null)
|
||||
@ -415,7 +415,7 @@ pub const CompareOutputContext = struct {
|
||||
}
|
||||
|
||||
for (case.sources.toSliceConst()) |src_file| {
|
||||
const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename);
|
||||
const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename);
|
||||
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
|
||||
exe.step.dependOn(&write_src.step);
|
||||
}
|
||||
@ -488,8 +488,8 @@ pub const CompileErrorContext = struct {
|
||||
const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
|
||||
const b = self.context.b;
|
||||
|
||||
const root_src = %%os.path.join(b.allocator, "test_artifacts", self.case.sources.items[0].filename);
|
||||
const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o");
|
||||
const root_src = %%os.path.join(b.allocator, b.cache_root, self.case.sources.items[0].filename);
|
||||
const obj_path = %%os.path.join(b.allocator, b.cache_root, "test.o");
|
||||
|
||||
var zig_args = List([]const u8).init(b.allocator);
|
||||
%%zig_args.append(if (self.case.is_exe) "build_exe" else "build_obj");
|
||||
@ -511,7 +511,7 @@ pub const CompileErrorContext = struct {
|
||||
printInvocation(b.zig_exe, zig_args.toSliceConst());
|
||||
}
|
||||
|
||||
var child = os.ChildProcess.spawn(b.zig_exe, zig_args.toSliceConst(), &b.env_map,
|
||||
var child = os.ChildProcess.spawn(b.zig_exe, zig_args.toSliceConst(), null, &b.env_map,
|
||||
StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err|
|
||||
{
|
||||
debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err));
|
||||
@ -632,7 +632,7 @@ pub const CompileErrorContext = struct {
|
||||
self.step.dependOn(&compile_and_cmp_errors.step);
|
||||
|
||||
for (case.sources.toSliceConst()) |src_file| {
|
||||
const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename);
|
||||
const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename);
|
||||
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
|
||||
compile_and_cmp_errors.step.dependOn(&write_src.step);
|
||||
}
|
||||
@ -675,7 +675,7 @@ pub const BuildExamplesContext = struct {
|
||||
%%zig_args.append("--verbose");
|
||||
}
|
||||
|
||||
const run_cmd = b.addCommand(b.cache_root, b.env_map, b.zig_exe, zig_args.toSliceConst());
|
||||
const run_cmd = b.addCommand(null, b.env_map, b.zig_exe, zig_args.toSliceConst());
|
||||
|
||||
const log_step = b.addLog("PASS {}\n", annotated_case_name);
|
||||
log_step.step.dependOn(&run_cmd.step);
|
||||
@ -762,7 +762,7 @@ pub const ParseHContext = struct {
|
||||
const self = @fieldParentPtr(ParseHCmpOutputStep, "step", step);
|
||||
const b = self.context.b;
|
||||
|
||||
const root_src = %%os.path.join(b.allocator, "test_artifacts", self.case.sources.items[0].filename);
|
||||
const root_src = %%os.path.join(b.allocator, b.cache_root, self.case.sources.items[0].filename);
|
||||
|
||||
var zig_args = List([]const u8).init(b.allocator);
|
||||
%%zig_args.append("parseh");
|
||||
@ -774,7 +774,7 @@ pub const ParseHContext = struct {
|
||||
printInvocation(b.zig_exe, zig_args.toSliceConst());
|
||||
}
|
||||
|
||||
var child = os.ChildProcess.spawn(b.zig_exe, zig_args.toSliceConst(), &b.env_map,
|
||||
var child = os.ChildProcess.spawn(b.zig_exe, zig_args.toSliceConst(), null, &b.env_map,
|
||||
StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err|
|
||||
{
|
||||
debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err));
|
||||
@ -886,7 +886,7 @@ pub const ParseHContext = struct {
|
||||
self.step.dependOn(&parseh_and_cmp.step);
|
||||
|
||||
for (case.sources.toSliceConst()) |src_file| {
|
||||
const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename);
|
||||
const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename);
|
||||
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
|
||||
parseh_and_cmp.step.dependOn(&write_src.step);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user