From 2864359950f8ebd9eca70a94801b78c4a0ed9955 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 11 Apr 2017 06:14:46 -0400 Subject: [PATCH] zig build system writes template build.zig file when none exists see #204 --- CMakeLists.txt | 1 + src/main.cpp | 46 ++++++++++++++++++++++++- src/os.cpp | 52 +++++++++++++++++++++++++++++ src/os.hpp | 1 + std/special/build_file_template.zig | 8 +++++ std/special/build_runner.zig | 2 ++ 6 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 std/special/build_file_template.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index a2800e59ad..b4a5494ad7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,6 +238,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/rand_test.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special") +install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special") install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special") install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special") diff --git a/src/main.cpp b/src/main.cpp index 48ddb5b95c..05576099f2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -154,6 +154,8 @@ int main(int argc, char **argv) { if (argc >= 2 && strcmp(argv[1], "build") == 0) { const char *zig_exe_path = arg0; + const char *build_file = "build.zig"; + bool asked_for_help = false; init_all_targets(); @@ -169,6 +171,12 @@ int main(int argc, char **argv) { for (int i = 2; i < argc; i += 1) { if (strcmp(argv[i], "--debug-build-verbose") == 0) { verbose = true; + } else if (strcmp(argv[i], "--help") == 0) { + asked_for_help = true; + args.append(argv[i]); + } else if (i + 1 < argc && strcmp(argv[i], "--build-file") == 0) { + build_file = argv[i + 1]; + i += 1; } else { args.append(argv[i]); } @@ -188,7 +196,43 @@ int main(int argc, char **argv) { codegen_set_out_type(g, OutTypeExe); codegen_set_verbose(g, verbose); - PackageTableEntry *build_pkg = new_package(".", "build.zig"); + Buf build_file_abs = BUF_INIT; + os_path_resolve(buf_create_from_str("."), buf_create_from_str(build_file), &build_file_abs); + Buf build_file_basename = BUF_INIT; + Buf build_file_dirname = BUF_INIT; + os_path_split(&build_file_abs, &build_file_dirname, &build_file_basename); + + bool build_file_exists; + if ((err = os_file_exists(&build_file_abs, &build_file_exists))) { + fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(&build_file_abs), err_str(err)); + return 1; + } + if (!build_file_exists) { + if (asked_for_help) { + // This usage text has to be synchronized with std/special/build_runner.zig + fprintf(stdout, + "Usage: %s build [options]\n" + "\n" + "General Options:\n" + " --help Print this help and exit.\n" + " --build-file [file] Override path to build.zig.\n" + " --verbose Print commands before executing them.\n" + " --debug-build-verbose Print verbose debugging information for the build system itself.\n" + , zig_exe_path); + return 0; + } + Buf *build_template_path = buf_alloc(); + os_path_join(special_dir, buf_create_from_str("build_file_template.zig"), build_template_path); + + if ((err = os_copy_file(build_template_path, &build_file_abs))) { + fprintf(stderr, "Unable to write build.zig template: %s\n", err_str(err)); + } else { + fprintf(stderr, "Wrote build.zig template\n"); + } + return 1; + } + + PackageTableEntry *build_pkg = new_package(buf_ptr(&build_file_dirname), buf_ptr(&build_file_basename)); 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_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code); diff --git a/src/os.cpp b/src/os.cpp index 9abff77477..de0df92714 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -490,6 +490,58 @@ void os_write_file(Buf *full_path, Buf *contents) { zig_panic("close failed"); } +int os_copy_file(Buf *src_path, Buf *dest_path) { + FILE *src_f = fopen(buf_ptr(src_path), "rb"); + if (!src_f) { + int err = errno; + if (err == ENOENT) { + return ErrorFileNotFound; + } else if (err == EACCES || err == EPERM) { + return ErrorAccess; + } else { + return ErrorFileSystem; + } + } + FILE *dest_f = fopen(buf_ptr(dest_path), "wb"); + if (!dest_f) { + int err = errno; + if (err == ENOENT) { + fclose(src_f); + return ErrorFileNotFound; + } else if (err == EACCES || err == EPERM) { + fclose(src_f); + return ErrorAccess; + } else { + fclose(src_f); + return ErrorFileSystem; + } + } + + static const size_t buf_size = 2048; + char buf[buf_size]; + for (;;) { + size_t amt_read = fread(buf, 1, buf_size, src_f); + if (amt_read != buf_size) { + if (ferror(src_f)) { + fclose(src_f); + fclose(dest_f); + return ErrorFileSystem; + } + } + size_t amt_written = fwrite(buf, 1, amt_read, dest_f); + if (amt_written != amt_read) { + fclose(src_f); + fclose(dest_f); + return ErrorFileSystem; + } + if (feof(src_f)) { + fclose(src_f); + fclose(dest_f); + return 0; + } + } +} + int os_fetch_file_path(Buf *full_path, Buf *out_contents) { FILE *f = fopen(buf_ptr(full_path), "rb"); if (!f) { diff --git a/src/os.hpp b/src/os.hpp index 339f1c8ae9..bec2766893 100644 --- a/src/os.hpp +++ b/src/os.hpp @@ -41,6 +41,7 @@ void os_path_resolve(Buf *ref_path, Buf *target_path, Buf *out_abs_path); bool os_path_is_absolute(Buf *path); void os_write_file(Buf *full_path, Buf *contents); +int os_copy_file(Buf *src_path, Buf *dest_path); int os_fetch_file(FILE *file, Buf *out_contents); int os_fetch_file_path(Buf *full_path, Buf *out_contents); diff --git a/std/special/build_file_template.zig b/std/special/build_file_template.zig new file mode 100644 index 0000000000..ea91ebb4cd --- /dev/null +++ b/std/special/build_file_template.zig @@ -0,0 +1,8 @@ +const Builder = @import("std").build.Builder; + +pub fn build(b: &Builder) { + const release = b.option(bool, "release", "optimizations on and safety off") ?? false; + + var exe = b.addExe("src/main.zig", "YOUR_NAME_HERE"); + exe.setRelease(release); +} diff --git a/std/special/build_runner.zig b/std/special/build_runner.zig index 5f24bc5924..385c398124 100644 --- a/std/special/build_runner.zig +++ b/std/special/build_runner.zig @@ -77,11 +77,13 @@ fn usage(builder: &Builder, maybe_zig_exe: ?[]const u8, already_ran_build: bool, root.build(builder); } + // This usage text has to be synchronized with src/main.cpp %%out_stream.printf( \\Usage: {} build [options] \\ \\General Options: \\ --help Print this help and exit. + \\ --build-file [file] Override path to build.zig. \\ --verbose Print commands before executing them. \\ --debug-build-verbose Print verbose debugging information for the build system itself. \\