mirror of
https://github.com/ziglang/zig.git
synced 2024-11-16 00:57:04 +00:00
parent
458afb0ef9
commit
a147f06585
@ -1486,6 +1486,8 @@ struct CodeGen {
|
||||
Buf *test_name_prefix;
|
||||
|
||||
ZigList<TimeEvent> timing_events;
|
||||
|
||||
Buf *cache_dir;
|
||||
};
|
||||
|
||||
enum VarLinkage {
|
||||
|
@ -204,6 +204,10 @@ void codegen_set_out_name(CodeGen *g, Buf *out_name) {
|
||||
g->root_out_name = out_name;
|
||||
}
|
||||
|
||||
void codegen_set_cache_dir(CodeGen *g, Buf *cache_dir) {
|
||||
g->cache_dir = cache_dir;
|
||||
}
|
||||
|
||||
void codegen_set_libc_lib_dir(CodeGen *g, Buf *libc_lib_dir) {
|
||||
g->libc_lib_dir = libc_lib_dir;
|
||||
}
|
||||
@ -3910,16 +3914,22 @@ static void do_code_gen(CodeGen *g) {
|
||||
codegen_add_time_event(g, "LLVM Emit Object");
|
||||
|
||||
char *err_msg = nullptr;
|
||||
Buf *out_file_o = buf_create_from_buf(g->root_out_name);
|
||||
Buf *o_basename = buf_create_from_buf(g->root_out_name);
|
||||
const char *o_ext = target_o_file_ext(&g->zig_target);
|
||||
buf_append_str(out_file_o, o_ext);
|
||||
if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(out_file_o),
|
||||
buf_append_str(o_basename, o_ext);
|
||||
Buf *output_path = buf_alloc();
|
||||
os_path_join(g->cache_dir, o_basename, output_path);
|
||||
int err;
|
||||
if ((err = os_make_path(g->cache_dir))) {
|
||||
zig_panic("unable to make cache dir: %s", err_str(err));
|
||||
}
|
||||
if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
|
||||
LLVMObjectFile, &err_msg, !g->is_release_build))
|
||||
{
|
||||
zig_panic("unable to write object file: %s", err_msg);
|
||||
}
|
||||
|
||||
g->link_objects.append(out_file_o);
|
||||
g->link_objects.append(output_path);
|
||||
}
|
||||
|
||||
static const uint8_t int_sizes_in_bits[] = {
|
||||
|
@ -47,6 +47,7 @@ void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt);
|
||||
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_add_time_event(CodeGen *g, const char *name);
|
||||
void codegen_print_timing_report(CodeGen *g, FILE *f);
|
||||
void codegen_build(CodeGen *g);
|
||||
|
@ -21,6 +21,8 @@ const char *err_str(int err) {
|
||||
case ErrorFileTooBig: return "file too big";
|
||||
case ErrorDivByZero: return "division by zero";
|
||||
case ErrorOverflow: return "overflow";
|
||||
case ErrorPathAlreadyExists: return "path already exists";
|
||||
case ErrorUnexpected: return "unexpected error";
|
||||
}
|
||||
return "(invalid error)";
|
||||
}
|
||||
|
@ -20,7 +20,9 @@ enum Error {
|
||||
ErrorFileSystem,
|
||||
ErrorFileTooBig,
|
||||
ErrorDivByZero,
|
||||
ErrorOverflow
|
||||
ErrorOverflow,
|
||||
ErrorPathAlreadyExists,
|
||||
ErrorUnexpected,
|
||||
};
|
||||
|
||||
const char *err_str(int err);
|
||||
|
10
src/link.cpp
10
src/link.cpp
@ -48,6 +48,8 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {
|
||||
codegen_set_omit_zigrt(child_gen, true);
|
||||
child_gen->want_h_file = false;
|
||||
|
||||
codegen_set_cache_dir(child_gen, parent_gen->cache_dir);
|
||||
|
||||
codegen_set_is_release(child_gen, parent_gen->is_release_build);
|
||||
|
||||
codegen_set_strip(child_gen, parent_gen->strip_debug_symbols);
|
||||
@ -64,10 +66,12 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {
|
||||
|
||||
codegen_build(child_gen);
|
||||
const char *o_ext = target_o_file_ext(&child_gen->zig_target);
|
||||
Buf *o_out = buf_sprintf("%s%s", oname, o_ext);
|
||||
codegen_link(child_gen, buf_ptr(o_out));
|
||||
Buf *o_out_name = buf_sprintf("%s%s", oname, o_ext);
|
||||
Buf *output_path = buf_alloc();
|
||||
os_path_join(parent_gen->cache_dir, o_out_name, output_path);
|
||||
codegen_link(child_gen, buf_ptr(output_path));
|
||||
|
||||
return o_out;
|
||||
return output_path;
|
||||
}
|
||||
|
||||
static const char *get_exe_file_extension(CodeGen *g) {
|
||||
|
26
src/main.cpp
26
src/main.cpp
@ -29,6 +29,7 @@ static int usage(const char *arg0) {
|
||||
" version print version number and exit\n"
|
||||
"Compile Options:\n"
|
||||
" --assembly [source] add assembly file to build\n"
|
||||
" --cache-dir [path] override the cache directory\n"
|
||||
" --color [auto|off|on] enable or disable colored error messages\n"
|
||||
" --enable-timing-info print timing diagnostics\n"
|
||||
" --libc-include-dir [path] directory where libc stdlib.h resides\n"
|
||||
@ -162,6 +163,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";
|
||||
|
||||
if (argc >= 2 && strcmp(argv[1], "build") == 0) {
|
||||
const char *zig_exe_path = arg0;
|
||||
@ -180,6 +182,7 @@ int main(int argc, char **argv) {
|
||||
ZigList<const char *> args = {0};
|
||||
args.append(zig_exe_path);
|
||||
args.append(NULL); // placeholder
|
||||
args.append(NULL); // placeholder
|
||||
for (int i = 2; i < argc; i += 1) {
|
||||
if (strcmp(argv[i], "--debug-build-verbose") == 0) {
|
||||
verbose = true;
|
||||
@ -189,6 +192,9 @@ int main(int argc, char **argv) {
|
||||
} else if (i + 1 < argc && strcmp(argv[i], "--build-file") == 0) {
|
||||
build_file = argv[i + 1];
|
||||
i += 1;
|
||||
} else if (i + 1 < argc && strcmp(argv[i], "--cache-dir") == 0) {
|
||||
cache_dir = argv[i + 1];
|
||||
i += 1;
|
||||
} else {
|
||||
args.append(argv[i]);
|
||||
}
|
||||
@ -205,7 +211,14 @@ int main(int argc, char **argv) {
|
||||
Buf build_file_dirname = BUF_INIT;
|
||||
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);
|
||||
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);
|
||||
|
||||
args.items[1] = buf_ptr(&build_file_dirname);
|
||||
args.items[2] = buf_ptr(full_cache_dir);
|
||||
|
||||
bool build_file_exists;
|
||||
if ((err = os_file_exists(&build_file_abs, &build_file_exists))) {
|
||||
@ -221,6 +234,7 @@ int main(int argc, char **argv) {
|
||||
"General Options:\n"
|
||||
" --help Print this help and exit\n"
|
||||
" --build-file [file] Override path to build.zig\n"
|
||||
" --cache-dir [path] Override path to cache directory\n"
|
||||
" --verbose Print commands before executing them\n"
|
||||
" --debug-build-verbose Print verbose debugging information for the build system itself\n"
|
||||
" --prefix [prefix] Override default install prefix\n"
|
||||
@ -245,13 +259,13 @@ int main(int argc, char **argv) {
|
||||
build_pkg->package_table.put(buf_create_from_str("std"), g->std_package);
|
||||
g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg);
|
||||
codegen_build(g);
|
||||
codegen_link(g, "build");
|
||||
codegen_link(g, buf_ptr(path_to_build_exe));
|
||||
|
||||
Termination term;
|
||||
os_spawn_process("./build", args, &term);
|
||||
os_spawn_process(buf_ptr(path_to_build_exe), args, &term);
|
||||
if (term.how != TerminationIdClean || term.code != 0) {
|
||||
fprintf(stderr, "\nBuild failed. Use the following command to reproduce the failure:\n");
|
||||
fprintf(stderr, "./build");
|
||||
fprintf(stderr, "%s", buf_ptr(path_to_build_exe));
|
||||
for (size_t i = 0; i < args.length; i += 1) {
|
||||
fprintf(stderr, " %s", args.at(i));
|
||||
}
|
||||
@ -331,6 +345,8 @@ int main(int argc, char **argv) {
|
||||
objects.append(argv[i]);
|
||||
} else if (strcmp(arg, "--assembly") == 0) {
|
||||
asm_files.append(argv[i]);
|
||||
} else if (strcmp(arg, "--cache-dir") == 0) {
|
||||
cache_dir = argv[i];
|
||||
} else if (strcmp(arg, "--target-arch") == 0) {
|
||||
target_arch = argv[i];
|
||||
} else if (strcmp(arg, "--target-os") == 0) {
|
||||
@ -478,12 +494,16 @@ 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);
|
||||
|
||||
CodeGen *g = codegen_create(zig_root_source_file, target);
|
||||
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);
|
||||
codegen_set_is_test(g, cmd == CmdTest);
|
||||
codegen_set_linker_script(g, linker_script);
|
||||
codegen_set_cache_dir(g, full_cache_dir);
|
||||
if (each_lib_rpath)
|
||||
codegen_set_each_lib_rpath(g, each_lib_rpath);
|
||||
|
||||
|
48
src/os.cpp
48
src/os.cpp
@ -723,3 +723,51 @@ double os_get_time(void) {
|
||||
return seconds;
|
||||
#endif
|
||||
}
|
||||
|
||||
int os_make_path(Buf *path) {
|
||||
Buf *resolved_path = buf_alloc();
|
||||
os_path_resolve(buf_create_from_str("."), path, resolved_path);
|
||||
|
||||
size_t end_index = buf_len(resolved_path);
|
||||
int err;
|
||||
while (true) {
|
||||
if ((err = os_make_dir(buf_slice(resolved_path, 0, end_index)))) {
|
||||
if (err == ErrorPathAlreadyExists) {
|
||||
if (end_index == buf_len(resolved_path))
|
||||
return 0;
|
||||
} else if (err == ErrorFileNotFound) {
|
||||
// march end_index backward until next path component
|
||||
while (true) {
|
||||
end_index -= 1;
|
||||
if (buf_ptr(resolved_path)[end_index] == '/')
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
if (end_index == buf_len(resolved_path))
|
||||
return 0;
|
||||
// march end_index forward until next path component
|
||||
while (true) {
|
||||
end_index += 1;
|
||||
if (end_index == buf_len(resolved_path) || buf_ptr(resolved_path)[end_index] == '/')
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int os_make_dir(Buf *path) {
|
||||
if (mkdir(buf_ptr(path), 0755) == -1) {
|
||||
if (errno == EEXIST)
|
||||
return ErrorPathAlreadyExists;
|
||||
if (errno == ENOENT)
|
||||
return ErrorFileNotFound;
|
||||
if (errno == EACCES)
|
||||
return ErrorAccess;
|
||||
return ErrorUnexpected;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -40,6 +40,9 @@ int os_path_real(Buf *rel_path, Buf *out_abs_path);
|
||||
void os_path_resolve(Buf *ref_path, Buf *target_path, Buf *out_abs_path);
|
||||
bool os_path_is_absolute(Buf *path);
|
||||
|
||||
int os_make_path(Buf *path);
|
||||
int os_make_dir(Buf *path);
|
||||
|
||||
void os_write_file(Buf *full_path, Buf *contents);
|
||||
int os_copy_file(Buf *src_path, Buf *dest_path);
|
||||
|
||||
|
@ -37,9 +37,10 @@ pub const Builder = struct {
|
||||
top_level_steps: List(&TopLevelStep),
|
||||
prefix: []const u8,
|
||||
lib_dir: []const u8,
|
||||
out_dir: []u8,
|
||||
out_dir: []u8, // TODO get rid of this
|
||||
installed_files: List([]const u8),
|
||||
build_root: []const u8,
|
||||
cache_root: []const u8,
|
||||
|
||||
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);
|
||||
@ -75,10 +76,13 @@ pub const Builder = struct {
|
||||
description: []const u8,
|
||||
};
|
||||
|
||||
pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8) -> Builder {
|
||||
pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8,
|
||||
cache_root: []const u8) -> Builder
|
||||
{
|
||||
var self = Builder {
|
||||
.zig_exe = zig_exe,
|
||||
.build_root = build_root,
|
||||
.cache_root = cache_root,
|
||||
.verbose = false,
|
||||
.invalid_user_input = false,
|
||||
.allocator = allocator,
|
||||
@ -768,7 +772,7 @@ pub const LibExeObjStep = struct {
|
||||
explicit_out_path
|
||||
} else {
|
||||
// TODO make it so we always know where this will be
|
||||
%%os.path.join(self.builder.allocator, self.builder.out_dir,
|
||||
%%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);
|
||||
@ -1217,7 +1221,7 @@ 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.out_dir,
|
||||
%%self.object_files.append(%%os.path.join(self.builder.allocator, self.builder.cache_root,
|
||||
self.builder.fmt("{}{}", obj.name, obj.target.oFileExt())));
|
||||
|
||||
// TODO should be some kind of isolated directory that only has this header in it
|
||||
|
@ -32,13 +32,23 @@ pub fn main() -> %void {
|
||||
result
|
||||
};
|
||||
|
||||
const cache_root = {
|
||||
if (arg_i >= os.args.count()) {
|
||||
%%io.stderr.printf("Expected third argument to be cache root directory path\n");
|
||||
return error.InvalidArgs;
|
||||
}
|
||||
const result = os.args.at(arg_i);
|
||||
arg_i += 1;
|
||||
result
|
||||
};
|
||||
|
||||
// TODO use a more general purpose allocator here
|
||||
var inc_allocator = %%mem.IncrementingAllocator.init(10 * 1024 * 1024);
|
||||
defer inc_allocator.deinit();
|
||||
|
||||
const allocator = &inc_allocator.allocator;
|
||||
|
||||
var builder = Builder.init(allocator, zig_exe, build_root);
|
||||
var builder = Builder.init(allocator, zig_exe, build_root, cache_root);
|
||||
defer builder.deinit();
|
||||
|
||||
var targets = List([]const u8).init(allocator);
|
||||
@ -113,6 +123,7 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)
|
||||
\\General Options:
|
||||
\\ --help Print this help and exit
|
||||
\\ --build-file [file] Override path to build.zig
|
||||
\\ --cache-dir [path] Override path to cache directory
|
||||
\\ --verbose Print commands before executing them
|
||||
\\ --debug-build-verbose Print verbose debugging information for the build system itself
|
||||
\\ --prefix [prefix] Override default install prefix
|
||||
|
@ -675,7 +675,7 @@ pub const BuildExamplesContext = struct {
|
||||
%%zig_args.append("--verbose");
|
||||
}
|
||||
|
||||
const run_cmd = b.addCommand(b.out_dir, b.env_map, b.zig_exe, zig_args.toSliceConst());
|
||||
const run_cmd = b.addCommand(b.cache_root, 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);
|
||||
|
Loading…
Reference in New Issue
Block a user