| author | |
| committer | |
| log | 7b0542d08b7e8e5ccbe81f495d641305b3b8a264 |
| tree | 67060c5620c5a36700abfa9c44d3ce31e35f9da4 |
| parent | 09bc4d6ba366c1a642b3c92c7ec554e95a369053 |
* add ability to add assembly files when building an exe, obj, or lib
* add implicit cast from `[N]T` to `?[]const T` (closes #343)
* remove link_exe and link_lib in favor of allowing build_exe and
build_lib support no root zig source file13 files changed, 322 insertions(+), 693 deletions(-)
src/all_types.hpp+2| ... | @@ -1296,6 +1296,7 @@ struct CodeGen { | ... | @@ -1296,6 +1296,7 @@ struct CodeGen { |
| 1296 | LLVMBuilderRef builder; | 1296 | LLVMBuilderRef builder; |
| 1297 | ZigLLVMDIBuilder *dbuilder; | 1297 | ZigLLVMDIBuilder *dbuilder; |
| 1298 | ZigLLVMDICompileUnit *compile_unit; | 1298 | ZigLLVMDICompileUnit *compile_unit; |
| 1299 | ZigLLVMDIFile *compile_unit_file; | ||
| 1299 | 1300 | ||
| 1300 | ZigList<Buf *> link_libs; // non-libc link libs | 1301 | ZigList<Buf *> link_libs; // non-libc link libs |
| 1301 | // add -framework [name] args to linker | 1302 | // add -framework [name] args to linker |
| ... | @@ -1468,6 +1469,7 @@ struct CodeGen { | ... | @@ -1468,6 +1469,7 @@ struct CodeGen { |
| 1468 | 1469 | ||
| 1469 | Buf global_asm; | 1470 | Buf global_asm; |
| 1470 | ZigList<Buf *> link_objects; | 1471 | ZigList<Buf *> link_objects; |
| 1472 | ZigList<Buf *> assembly_files; | ||
| 1471 | 1473 | ||
| 1472 | ZigList<TypeTableEntry *> name_table_enums; | 1474 | ZigList<TypeTableEntry *> name_table_enums; |
| 1473 | 1475 |
src/analyze.cpp+5-4| ... | @@ -2851,9 +2851,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) { | ... | @@ -2851,9 +2851,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) { |
| 2851 | node->data.use.value = result; | 2851 | node->data.use.value = result; |
| 2852 | } | 2852 | } |
| 2853 | 2853 | ||
| 2854 | ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, | 2854 | ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code) { |
| 2855 | Buf *abs_full_path, Buf *src_dirname, Buf *src_basename, Buf *source_code) | ||
| 2856 | { | ||
| 2857 | if (g->verbose) { | 2855 | if (g->verbose) { |
| 2858 | fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(abs_full_path)); | 2856 | fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(abs_full_path)); |
| 2859 | fprintf(stderr, "----------------\n"); | 2857 | fprintf(stderr, "----------------\n"); |
| ... | @@ -2894,7 +2892,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, | ... | @@ -2894,7 +2892,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, |
| 2894 | ast_print(stderr, import_entry->root, 0); | 2892 | ast_print(stderr, import_entry->root, 0); |
| 2895 | } | 2893 | } |
| 2896 | 2894 | ||
| 2897 | // TODO: assert that src_basename has no '/' in it | 2895 | Buf *src_dirname = buf_alloc(); |
| 2896 | Buf *src_basename = buf_alloc(); | ||
| 2897 | os_path_split(abs_full_path, src_dirname, src_basename); | ||
| 2898 | |||
| 2898 | import_entry->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname)); | 2899 | import_entry->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname)); |
| 2899 | g->import_table.put(abs_full_path, import_entry); | 2900 | g->import_table.put(abs_full_path, import_entry); |
| 2900 | g->import_queue.append(import_entry); | 2901 | g->import_queue.append(import_entry); |
src/analyze.hpp+1-2| ... | @@ -40,8 +40,7 @@ void find_libc_lib_path(CodeGen *g); | ... | @@ -40,8 +40,7 @@ void find_libc_lib_path(CodeGen *g); |
| 40 | bool type_has_bits(TypeTableEntry *type_entry); | 40 | bool type_has_bits(TypeTableEntry *type_entry); |
| 41 | 41 | ||
| 42 | 42 | ||
| 43 | ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, | 43 | ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code); |
| 44 | Buf *abs_full_path, Buf *src_dirname, Buf *src_basename, Buf *source_code); | ||
| 45 | 44 | ||
| 46 | 45 | ||
| 47 | // TODO move these over, these used to be static | 46 | // TODO move these over, these used to be static |
src/codegen.cpp+64-39| ... | @@ -55,7 +55,7 @@ PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_pa | ... | @@ -55,7 +55,7 @@ PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_pa |
| 55 | return entry; | 55 | return entry; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { | 58 | CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) { |
| 59 | CodeGen *g = allocate<CodeGen>(1); | 59 | CodeGen *g = allocate<CodeGen>(1); |
| 60 | 60 | ||
| 61 | codegen_add_time_event(g, "Initialize"); | 61 | codegen_add_time_event(g, "Initialize"); |
| ... | @@ -81,9 +81,17 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { | ... | @@ -81,9 +81,17 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { |
| 81 | // reserve index 0 to indicate no error | 81 | // reserve index 0 to indicate no error |
| 82 | g->error_decls.append(nullptr); | 82 | g->error_decls.append(nullptr); |
| 83 | 83 | ||
| 84 | g->root_package = new_package(buf_ptr(root_source_dir), ""); | 84 | if (root_src_path) { |
| 85 | g->std_package = new_package(ZIG_STD_DIR, "index.zig"); | 85 | Buf *src_basename = buf_alloc(); |
| 86 | g->root_package->package_table.put(buf_create_from_str("std"), g->std_package); | 86 | Buf *src_dir = buf_alloc(); |
| 87 | os_path_split(root_src_path, src_dir, src_basename); | ||
| 88 | |||
| 89 | g->root_package = new_package(buf_ptr(src_dir), buf_ptr(src_basename)); | ||
| 90 | g->std_package = new_package(ZIG_STD_DIR, "index.zig"); | ||
| 91 | g->root_package->package_table.put(buf_create_from_str("std"), g->std_package); | ||
| 92 | } else { | ||
| 93 | g->root_package = new_package(".", ""); | ||
| 94 | } | ||
| 87 | g->zig_std_dir = buf_create_from_str(ZIG_STD_DIR); | 95 | g->zig_std_dir = buf_create_from_str(ZIG_STD_DIR); |
| 88 | 96 | ||
| 89 | g->zig_std_special_dir = buf_alloc(); | 97 | g->zig_std_special_dir = buf_alloc(); |
| ... | @@ -757,7 +765,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { | ... | @@ -757,7 +765,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 757 | 765 | ||
| 758 | static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) { | 766 | static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) { |
| 759 | LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g); | 767 | LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g); |
| 760 | LLVMBuildCall(g->builder, safety_crash_err_fn, &err_val, 1, ""); | 768 | ZigLLVMBuildCall(g->builder, safety_crash_err_fn, &err_val, 1, LLVMFastCallConv, false, ""); |
| 761 | LLVMBuildUnreachable(g->builder); | 769 | LLVMBuildUnreachable(g->builder); |
| 762 | } | 770 | } |
| 763 | 771 | ||
| ... | @@ -3655,6 +3663,10 @@ static LLVMValueRef build_alloca(CodeGen *g, TypeTableEntry *type_entry, const c | ... | @@ -3655,6 +3663,10 @@ static LLVMValueRef build_alloca(CodeGen *g, TypeTableEntry *type_entry, const c |
| 3655 | } | 3663 | } |
| 3656 | 3664 | ||
| 3657 | static void do_code_gen(CodeGen *g) { | 3665 | static void do_code_gen(CodeGen *g) { |
| 3666 | if (g->verbose) { | ||
| 3667 | fprintf(stderr, "\nCode Generation:\n"); | ||
| 3668 | fprintf(stderr, "------------------\n"); | ||
| 3669 | } | ||
| 3658 | assert(!g->errors.length); | 3670 | assert(!g->errors.length); |
| 3659 | 3671 | ||
| 3660 | codegen_add_time_event(g, "Code Generation"); | 3672 | codegen_add_time_event(g, "Code Generation"); |
| ... | @@ -4602,8 +4614,9 @@ static void define_builtin_compile_vars(CodeGen *g) { | ... | @@ -4602,8 +4614,9 @@ static void define_builtin_compile_vars(CodeGen *g) { |
| 4602 | add_compile_var(g, "panic_implementation_provided", create_const_bool(g, false)); | 4614 | add_compile_var(g, "panic_implementation_provided", create_const_bool(g, false)); |
| 4603 | } | 4615 | } |
| 4604 | 4616 | ||
| 4605 | static void init(CodeGen *g, Buf *source_path) { | 4617 | static void init(CodeGen *g) { |
| 4606 | g->module = LLVMModuleCreateWithName(buf_ptr(source_path)); | 4618 | assert(g->root_out_name); |
| 4619 | g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name)); | ||
| 4607 | 4620 | ||
| 4608 | get_target_triple(&g->triple_str, &g->zig_target); | 4621 | get_target_triple(&g->triple_str, &g->zig_target); |
| 4609 | 4622 | ||
| ... | @@ -4674,23 +4687,25 @@ static void init(CodeGen *g, Buf *source_path) { | ... | @@ -4674,23 +4687,25 @@ static void init(CodeGen *g, Buf *source_path) { |
| 4674 | g->const_void_val.type = g->builtin_types.entry_void; | 4687 | g->const_void_val.type = g->builtin_types.entry_void; |
| 4675 | } | 4688 | } |
| 4676 | 4689 | ||
| 4677 | void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code) { | 4690 | void codegen_parseh(CodeGen *g, Buf *full_path) { |
| 4678 | find_libc_include_path(g); | 4691 | find_libc_include_path(g); |
| 4679 | Buf *full_path = buf_alloc(); | 4692 | |
| 4680 | os_path_join(src_dirname, src_basename, full_path); | 4693 | Buf *src_basename = buf_alloc(); |
| 4694 | Buf *src_dirname = buf_alloc(); | ||
| 4695 | os_path_split(full_path, src_dirname, src_basename); | ||
| 4681 | 4696 | ||
| 4682 | ImportTableEntry *import = allocate<ImportTableEntry>(1); | 4697 | ImportTableEntry *import = allocate<ImportTableEntry>(1); |
| 4683 | import->source_code = source_code; | 4698 | import->source_code = nullptr; |
| 4684 | import->path = full_path; | 4699 | import->path = full_path; |
| 4685 | g->root_import = import; | 4700 | g->root_import = import; |
| 4686 | import->decls_scope = create_decls_scope(nullptr, nullptr, nullptr, import); | 4701 | import->decls_scope = create_decls_scope(nullptr, nullptr, nullptr, import); |
| 4687 | 4702 | ||
| 4688 | init(g, full_path); | 4703 | init(g); |
| 4689 | 4704 | ||
| 4690 | import->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname)); | 4705 | import->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname)); |
| 4691 | 4706 | ||
| 4692 | ZigList<ErrorMsg *> errors = {0}; | 4707 | ZigList<ErrorMsg *> errors = {0}; |
| 4693 | int err = parse_h_buf(import, &errors, source_code, g, nullptr); | 4708 | int err = parse_h_file(import, &errors, buf_ptr(full_path), g, nullptr); |
| 4694 | if (err) { | 4709 | if (err) { |
| 4695 | fprintf(stderr, "unable to parse .h file: %s\n", err_str(err)); | 4710 | fprintf(stderr, "unable to parse .h file: %s\n", err_str(err)); |
| 4696 | exit(1); | 4711 | exit(1); |
| ... | @@ -4719,7 +4734,7 @@ static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package | ... | @@ -4719,7 +4734,7 @@ static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package |
| 4719 | zig_panic("unable to open '%s': %s", buf_ptr(&path_to_code_src), err_str(err)); | 4734 | zig_panic("unable to open '%s': %s", buf_ptr(&path_to_code_src), err_str(err)); |
| 4720 | } | 4735 | } |
| 4721 | 4736 | ||
| 4722 | return add_source_file(g, package, abs_full_path, g->zig_std_special_dir, code_basename, import_code); | 4737 | return add_source_file(g, package, abs_full_path, import_code); |
| 4723 | } | 4738 | } |
| 4724 | 4739 | ||
| 4725 | static PackageTableEntry *create_bootstrap_pkg(CodeGen *g) { | 4740 | static PackageTableEntry *create_bootstrap_pkg(CodeGen *g) { |
| ... | @@ -4736,23 +4751,27 @@ static PackageTableEntry *create_zigrt_pkg(CodeGen *g) { | ... | @@ -4736,23 +4751,27 @@ static PackageTableEntry *create_zigrt_pkg(CodeGen *g) { |
| 4736 | return package; | 4751 | return package; |
| 4737 | } | 4752 | } |
| 4738 | 4753 | ||
| 4739 | void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *source_code) { | 4754 | static void gen_root_source(CodeGen *g) { |
| 4740 | codegen_add_time_event(g, "Semantic Analysis"); | 4755 | if (buf_len(&g->root_package->root_src_path) == 0) |
| 4741 | 4756 | return; | |
| 4742 | Buf source_path = BUF_INIT; | ||
| 4743 | os_path_join(src_dir, src_basename, &source_path); | ||
| 4744 | 4757 | ||
| 4745 | buf_init_from_buf(&g->root_package->root_src_path, src_basename); | 4758 | codegen_add_time_event(g, "Semantic Analysis"); |
| 4746 | 4759 | ||
| 4747 | init(g, &source_path); | 4760 | Buf *rel_full_path = buf_alloc(); |
| 4761 | os_path_join(&g->root_package->root_src_dir, &g->root_package->root_src_path, rel_full_path); | ||
| 4748 | 4762 | ||
| 4749 | Buf *abs_full_path = buf_alloc(); | 4763 | Buf *abs_full_path = buf_alloc(); |
| 4750 | int err; | 4764 | int err; |
| 4751 | if ((err = os_path_real(&source_path, abs_full_path))) { | 4765 | if ((err = os_path_real(rel_full_path, abs_full_path))) { |
| 4752 | zig_panic("unable to open '%s': %s", buf_ptr(&source_path), err_str(err)); | 4766 | zig_panic("unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err)); |
| 4767 | } | ||
| 4768 | |||
| 4769 | Buf *source_code = buf_alloc(); | ||
| 4770 | if ((err = os_fetch_file_path(rel_full_path, source_code))) { | ||
| 4771 | zig_panic("unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err)); | ||
| 4753 | } | 4772 | } |
| 4754 | 4773 | ||
| 4755 | g->root_import = add_source_file(g, g->root_package, abs_full_path, src_dir, src_basename, source_code); | 4774 | g->root_import = add_source_file(g, g->root_package, abs_full_path, source_code); |
| 4756 | 4775 | ||
| 4757 | assert(g->root_out_name); | 4776 | assert(g->root_out_name); |
| 4758 | assert(g->out_type != OutTypeUnknown); | 4777 | assert(g->out_type != OutTypeUnknown); |
| ... | @@ -4787,27 +4806,33 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou | ... | @@ -4787,27 +4806,33 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou |
| 4787 | exit(1); | 4806 | exit(1); |
| 4788 | } | 4807 | } |
| 4789 | 4808 | ||
| 4790 | if (g->verbose) { | ||
| 4791 | fprintf(stderr, "\nCode Generation:\n"); | ||
| 4792 | fprintf(stderr, "------------------\n"); | ||
| 4793 | |||
| 4794 | } | ||
| 4795 | |||
| 4796 | do_code_gen(g); | ||
| 4797 | } | 4809 | } |
| 4798 | 4810 | ||
| 4799 | void codegen_add_root_assembly(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *source_code) { | 4811 | void codegen_add_assembly(CodeGen *g, Buf *path) { |
| 4800 | Buf source_path = BUF_INIT; | 4812 | g->assembly_files.append(path); |
| 4801 | os_path_join(src_dir, src_basename, &source_path); | 4813 | } |
| 4802 | 4814 | ||
| 4803 | init(g, &source_path); | 4815 | static void gen_global_asm(CodeGen *g) { |
| 4816 | Buf contents = BUF_INIT; | ||
| 4817 | int err; | ||
| 4818 | for (size_t i = 0; i < g->assembly_files.length; i += 1) { | ||
| 4819 | Buf *asm_file = g->assembly_files.at(i); | ||
| 4820 | if ((err = os_fetch_file_path(asm_file, &contents))) { | ||
| 4821 | zig_panic("Unable to read %s: %s", buf_ptr(asm_file), err_str(err)); | ||
| 4822 | } | ||
| 4823 | if (g->zig_target.arch.arch == ZigLLVM_x86 || g->zig_target.arch.arch == ZigLLVM_x86_64) { | ||
| 4824 | buf_append_str(&g->global_asm, ".intel_syntax noprefix\n"); | ||
| 4825 | } | ||
| 4826 | buf_append_buf(&g->global_asm, &contents); | ||
| 4827 | } | ||
| 4828 | } | ||
| 4804 | 4829 | ||
| 4805 | assert(g->root_out_name); | 4830 | void codegen_build(CodeGen *g) { |
| 4806 | assert(g->out_type != OutTypeUnknown); | 4831 | assert(g->out_type != OutTypeUnknown); |
| 4832 | init(g); | ||
| 4807 | 4833 | ||
| 4808 | buf_init_from_str(&g->global_asm, ".intel_syntax noprefix\n"); | 4834 | gen_global_asm(g); |
| 4809 | buf_append_buf(&g->global_asm, source_code); | 4835 | gen_root_source(g); |
| 4810 | |||
| 4811 | do_code_gen(g); | 4836 | do_code_gen(g); |
| 4812 | } | 4837 | } |
| 4813 | 4838 |
src/codegen.hpp+4-4| ... | @@ -14,7 +14,7 @@ | ... | @@ -14,7 +14,7 @@ |
| 14 | 14 | ||
| 15 | #include <stdio.h> | 15 | #include <stdio.h> |
| 16 | 16 | ||
| 17 | CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target); | 17 | CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target); |
| 18 | 18 | ||
| 19 | void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); | 19 | void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); |
| 20 | void codegen_set_is_release(CodeGen *codegen, bool is_release); | 20 | void codegen_set_is_release(CodeGen *codegen, bool is_release); |
| ... | @@ -49,13 +49,13 @@ void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); | ... | @@ -49,13 +49,13 @@ void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); |
| 49 | void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch); | 49 | void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch); |
| 50 | void codegen_add_time_event(CodeGen *g, const char *name); | 50 | void codegen_add_time_event(CodeGen *g, const char *name); |
| 51 | void codegen_print_timing_report(CodeGen *g, FILE *f); | 51 | void codegen_print_timing_report(CodeGen *g, FILE *f); |
| 52 | void codegen_build(CodeGen *g); | ||
| 52 | 53 | ||
| 53 | PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path); | 54 | PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path); |
| 54 | void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code); | 55 | void codegen_add_assembly(CodeGen *g, Buf *path); |
| 55 | void codegen_add_root_assembly(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code); | ||
| 56 | void codegen_add_object(CodeGen *g, Buf *object_path); | 56 | void codegen_add_object(CodeGen *g, Buf *object_path); |
| 57 | 57 | ||
| 58 | void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code); | 58 | void codegen_parseh(CodeGen *g, Buf *path); |
| 59 | void codegen_render_ast(CodeGen *g, FILE *f, int indent_size); | 59 | void codegen_render_ast(CodeGen *g, FILE *f, int indent_size); |
| 60 | 60 | ||
| 61 | void codegen_generate_h_file(CodeGen *g); | 61 | void codegen_generate_h_file(CodeGen *g); |
src/ir.cpp+39-2| ... | @@ -6043,6 +6043,21 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, | ... | @@ -6043,6 +6043,21 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 6043 | } | 6043 | } |
| 6044 | } | 6044 | } |
| 6045 | 6045 | ||
| 6046 | // implicit [N]T to ?[]const N | ||
| 6047 | if (expected_type->id == TypeTableEntryIdMaybe && | ||
| 6048 | is_slice(expected_type->data.maybe.child_type) && | ||
| 6049 | actual_type->id == TypeTableEntryIdArray) | ||
| 6050 | { | ||
| 6051 | TypeTableEntry *ptr_type = | ||
| 6052 | expected_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry; | ||
| 6053 | assert(ptr_type->id == TypeTableEntryIdPointer); | ||
| 6054 | if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && | ||
| 6055 | types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type)) | ||
| 6056 | { | ||
| 6057 | return ImplicitCastMatchResultYes; | ||
| 6058 | } | ||
| 6059 | } | ||
| 6060 | |||
| 6046 | // implicit number literal to typed number | 6061 | // implicit number literal to typed number |
| 6047 | // implicit number literal to &const integer | 6062 | // implicit number literal to &const integer |
| 6048 | if (actual_type->id == TypeTableEntryIdNumLitFloat || | 6063 | if (actual_type->id == TypeTableEntryIdNumLitFloat || |
| ... | @@ -7093,6 +7108,29 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -7093,6 +7108,29 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 7093 | } | 7108 | } |
| 7094 | } | 7109 | } |
| 7095 | 7110 | ||
| 7111 | // explicit cast from [N]T to ?[]const N | ||
| 7112 | if (wanted_type->id == TypeTableEntryIdMaybe && | ||
| 7113 | is_slice(wanted_type->data.maybe.child_type) && | ||
| 7114 | actual_type->id == TypeTableEntryIdArray) | ||
| 7115 | { | ||
| 7116 | TypeTableEntry *ptr_type = | ||
| 7117 | wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry; | ||
| 7118 | assert(ptr_type->id == TypeTableEntryIdPointer); | ||
| 7119 | if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && | ||
| 7120 | types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type)) | ||
| 7121 | { | ||
| 7122 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); | ||
| 7123 | if (type_is_invalid(cast1->value.type)) | ||
| 7124 | return ira->codegen->invalid_instruction; | ||
| 7125 | |||
| 7126 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); | ||
| 7127 | if (type_is_invalid(cast2->value.type)) | ||
| 7128 | return ira->codegen->invalid_instruction; | ||
| 7129 | |||
| 7130 | return cast2; | ||
| 7131 | } | ||
| 7132 | } | ||
| 7133 | |||
| 7096 | // explicit cast from []T to []u8 or []u8 to []T | 7134 | // explicit cast from []T to []u8 or []u8 to []T |
| 7097 | if (is_slice(wanted_type) && is_slice(actual_type) && | 7135 | if (is_slice(wanted_type) && is_slice(actual_type) && |
| 7098 | (is_u8(wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type) || | 7136 | (is_u8(wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type) || |
| ... | @@ -10880,8 +10918,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi | ... | @@ -10880,8 +10918,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi |
| 10880 | return ira->codegen->builtin_types.entry_invalid; | 10918 | return ira->codegen->builtin_types.entry_invalid; |
| 10881 | } | 10919 | } |
| 10882 | } | 10920 | } |
| 10883 | ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, | 10921 | ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, abs_full_path, import_code); |
| 10884 | abs_full_path, search_dir, import_target_path, import_code); | ||
| 10885 | 10922 | ||
| 10886 | scan_decls(ira->codegen, target_import->decls_scope, target_import->root); | 10923 | scan_decls(ira->codegen, target_import->decls_scope, target_import->root); |
| 10887 | 10924 |
src/link.cpp+4-10| ... | @@ -33,9 +33,11 @@ static const char *get_libc_static_file(CodeGen *g, const char *file) { | ... | @@ -33,9 +33,11 @@ static const char *get_libc_static_file(CodeGen *g, const char *file) { |
| 33 | 33 | ||
| 34 | static Buf *build_o(CodeGen *parent_gen, const char *oname) { | 34 | static Buf *build_o(CodeGen *parent_gen, const char *oname) { |
| 35 | Buf *source_basename = buf_sprintf("%s.zig", oname); | 35 | Buf *source_basename = buf_sprintf("%s.zig", oname); |
| 36 | Buf *full_path = buf_alloc(); | ||
| 37 | os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path); | ||
| 36 | 38 | ||
| 37 | ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target; | 39 | ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target; |
| 38 | CodeGen *child_gen = codegen_create(parent_gen->zig_std_special_dir, child_target); | 40 | CodeGen *child_gen = codegen_create(full_path, child_target); |
| 39 | child_gen->link_libc = parent_gen->link_libc; | 41 | child_gen->link_libc = parent_gen->link_libc; |
| 40 | 42 | ||
| 41 | child_gen->link_libs.resize(parent_gen->link_libs.length); | 43 | child_gen->link_libs.resize(parent_gen->link_libs.length); |
| ... | @@ -60,15 +62,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { | ... | @@ -60,15 +62,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { |
| 60 | codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min); | 62 | codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min); |
| 61 | codegen_set_mios_version_min(child_gen, parent_gen->mios_version_min); | 63 | codegen_set_mios_version_min(child_gen, parent_gen->mios_version_min); |
| 62 | 64 | ||
| 63 | Buf *full_path = buf_alloc(); | 65 | codegen_build(child_gen); |
| 64 | os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path); | ||
| 65 | |||
| 66 | Buf source_code = BUF_INIT; | ||
| 67 | if (os_fetch_file_path(full_path, &source_code)) { | ||
| 68 | zig_panic("unable to fetch file: %s\n", buf_ptr(full_path)); | ||
| 69 | } | ||
| 70 | |||
| 71 | codegen_add_root_code(child_gen, parent_gen->zig_std_special_dir, source_basename, &source_code); | ||
| 72 | const char *o_ext = target_o_file_ext(&child_gen->zig_target); | 66 | const char *o_ext = target_o_file_ext(&child_gen->zig_target); |
| 73 | Buf *o_out = buf_sprintf("%s%s", oname, o_ext); | 67 | Buf *o_out = buf_sprintf("%s%s", oname, o_ext); |
| 74 | codegen_link(child_gen, buf_ptr(o_out)); | 68 | codegen_link(child_gen, buf_ptr(o_out)); |
src/main.cpp+64-121| ... | @@ -19,29 +19,19 @@ | ... | @@ -19,29 +19,19 @@ |
| 19 | static int usage(const char *arg0) { | 19 | static int usage(const char *arg0) { |
| 20 | fprintf(stderr, "Usage: %s [command] [options]\n" | 20 | fprintf(stderr, "Usage: %s [command] [options]\n" |
| 21 | "Commands:\n" | 21 | "Commands:\n" |
| 22 | " asm [source] create object from assembly\n" | ||
| 23 | " build build project from build.zig\n" | 22 | " build build project from build.zig\n" |
| 24 | " build_exe [source] create executable from source\n" | 23 | " build_exe [source] create executable from source or object files\n" |
| 25 | " build_lib [source] create library from source\n" | 24 | " build_lib [source] create library from source or object files\n" |
| 26 | " build_obj [source] create object from source\n" | 25 | " build_obj [source] create object from source or assembly\n" |
| 27 | " link_exe [objects] create executable from objects\n" | ||
| 28 | " link_lib [objects] create library from objects\n" | ||
| 29 | " parseh [source] convert a c header file to zig extern declarations\n" | 26 | " parseh [source] convert a c header file to zig extern declarations\n" |
| 30 | " targets list available compilation targets\n" | 27 | " targets list available compilation targets\n" |
| 31 | " test [source] create and run a test build\n" | 28 | " test [source] create and run a test build\n" |
| 32 | " version print version number and exit\n" | 29 | " version print version number and exit\n" |
| 33 | "Options:\n" | 30 | "Compile Options:\n" |
| 34 | " --ar-path [path] set the path to ar\n" | 31 | " --assembly [source] add assembly file to build\n" |
| 35 | " --color [auto|off|on] enable or disable colored error messages\n" | 32 | " --color [auto|off|on] enable or disable colored error messages\n" |
| 36 | " --dynamic-linker [path] set the path to ld.so\n" | 33 | " --enable-timing-info print timing diagnostics\n" |
| 37 | " --each-lib-rpath add rpath for each used dynamic library\n" | ||
| 38 | " --ld-path [path] set the path to the linker\n" | ||
| 39 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" | 34 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" |
| 40 | " --libc-lib-dir [path] directory where libc crt1.o resides\n" | ||
| 41 | " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n" | ||
| 42 | " --library [lib] link against lib\n" | ||
| 43 | " --library-path [dir] add a directory to the library search path\n" | ||
| 44 | " --linker-script [path] use a custom linker script\n" | ||
| 45 | " --name [name] override output name\n" | 35 | " --name [name] override output name\n" |
| 46 | " --output [file] override destination path\n" | 36 | " --output [file] override destination path\n" |
| 47 | " --release build with optimizations on and debug protection off\n" | 37 | " --release build with optimizations on and debug protection off\n" |
| ... | @@ -52,26 +42,34 @@ static int usage(const char *arg0) { | ... | @@ -52,26 +42,34 @@ static int usage(const char *arg0) { |
| 52 | " --target-os [name] specify target operating system\n" | 42 | " --target-os [name] specify target operating system\n" |
| 53 | " --verbose turn on compiler debug output\n" | 43 | " --verbose turn on compiler debug output\n" |
| 54 | " --zig-std-dir [path] directory where zig standard library resides\n" | 44 | " --zig-std-dir [path] directory where zig standard library resides\n" |
| 55 | " -L[dir] alias for --library-path\n" | ||
| 56 | " -dirafter [dir] same as -isystem but do it last\n" | 45 | " -dirafter [dir] same as -isystem but do it last\n" |
| 57 | " -framework [name] (darwin only) link against framework\n" | ||
| 58 | " -isystem [dir] add additional search path for other .h files\n" | 46 | " -isystem [dir] add additional search path for other .h files\n" |
| 59 | " -mconsole (windows only) --subsystem console to the linker\n" | 47 | "Link Options:\n" |
| 60 | " -mios-version-min [ver] (darwin only) set iOS deployment target\n" | 48 | " --ar-path [path] set the path to ar\n" |
| 61 | " -mlinker-version [ver] (darwin only) override linker version\n" | 49 | " --dynamic-linker [path] set the path to ld.so\n" |
| 62 | " -mmacosx-version-min [ver] (darwin only) set Mac OS X deployment target\n" | 50 | " --each-lib-rpath add rpath for each used dynamic library\n" |
| 63 | " -municode (windows only) link with unicode\n" | 51 | " --libc-lib-dir [path] directory where libc crt1.o resides\n" |
| 64 | " -mwindows (windows only) --subsystem windows to the linker\n" | 52 | " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n" |
| 53 | " --library [lib] link against lib\n" | ||
| 54 | " --library-path [dir] add a directory to the library search path\n" | ||
| 55 | " --linker-script [path] use a custom linker script\n" | ||
| 56 | " --object [obj] add object file to build\n" | ||
| 57 | " -L[dir] alias for --library-path\n" | ||
| 65 | " -rdynamic add all symbols to the dynamic symbol table\n" | 58 | " -rdynamic add all symbols to the dynamic symbol table\n" |
| 66 | " -rpath [path] add directory to the runtime library search path\n" | 59 | " -rpath [path] add directory to the runtime library search path\n" |
| 67 | " --enable-timing-info print timing diagnostics\n" | 60 | " -mconsole (windows) --subsystem console to the linker\n" |
| 61 | " -mwindows (windows) --subsystem windows to the linker\n" | ||
| 62 | " -municode (windows) link with unicode\n" | ||
| 63 | " -framework [name] (darwin) link against framework\n" | ||
| 64 | " -mios-version-min [ver] (darwin) set iOS deployment target\n" | ||
| 65 | " -mlinker-version [ver] (darwin) override linker version\n" | ||
| 66 | " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n" | ||
| 67 | " --ver-major [ver] dynamic library semver major version\n" | ||
| 68 | " --ver-minor [ver] dynamic library semver minor version\n" | ||
| 69 | " --ver-patch [ver] dynamic library semver patch version\n" | ||
| 68 | "Test Options:\n" | 70 | "Test Options:\n" |
| 69 | " --test-filter [text] skip tests that do not match filter\n" | 71 | " --test-filter [text] skip tests that do not match filter\n" |
| 70 | " --test-name-prefix [text] add prefix to all tests\n" | 72 | " --test-name-prefix [text] add prefix to all tests\n" |
| 71 | "Dynamic Library Options:\n" | ||
| 72 | " --ver-major [ver] semver major version\n" | ||
| 73 | " --ver-minor [ver] semver minor version\n" | ||
| 74 | " --ver-patch [ver] semver patch version\n" | ||
| 75 | , arg0); | 73 | , arg0); |
| 76 | return EXIT_FAILURE; | 74 | return EXIT_FAILURE; |
| 77 | } | 75 | } |
| ... | @@ -117,8 +115,6 @@ enum Cmd { | ... | @@ -117,8 +115,6 @@ enum Cmd { |
| 117 | CmdVersion, | 115 | CmdVersion, |
| 118 | CmdParseH, | 116 | CmdParseH, |
| 119 | CmdTargets, | 117 | CmdTargets, |
| 120 | CmdAsm, | ||
| 121 | CmdLink, | ||
| 122 | }; | 118 | }; |
| 123 | 119 | ||
| 124 | int main(int argc, char **argv) { | 120 | int main(int argc, char **argv) { |
| ... | @@ -159,6 +155,7 @@ int main(int argc, char **argv) { | ... | @@ -159,6 +155,7 @@ int main(int argc, char **argv) { |
| 159 | ZigList<const char *> rpath_list = {0}; | 155 | ZigList<const char *> rpath_list = {0}; |
| 160 | bool each_lib_rpath = false; | 156 | bool each_lib_rpath = false; |
| 161 | ZigList<const char *> objects = {0}; | 157 | ZigList<const char *> objects = {0}; |
| 158 | ZigList<const char *> asm_files = {0}; | ||
| 162 | const char *test_filter = nullptr; | 159 | const char *test_filter = nullptr; |
| 163 | const char *test_name_prefix = nullptr; | 160 | const char *test_name_prefix = nullptr; |
| 164 | size_t ver_major = 0; | 161 | size_t ver_major = 0; |
| ... | @@ -197,16 +194,7 @@ int main(int argc, char **argv) { | ... | @@ -197,16 +194,7 @@ int main(int argc, char **argv) { |
| 197 | } | 194 | } |
| 198 | } | 195 | } |
| 199 | 196 | ||
| 200 | 197 | CodeGen *g = codegen_create(build_runner_path, nullptr); | |
| 201 | Buf root_source_dir = BUF_INIT; | ||
| 202 | Buf root_source_code = BUF_INIT; | ||
| 203 | Buf root_source_name = BUF_INIT; | ||
| 204 | os_path_split(build_runner_path, &root_source_dir, &root_source_name); | ||
| 205 | if ((err = os_fetch_file_path(build_runner_path, &root_source_code))) { | ||
| 206 | fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(build_runner_path), err_str(err)); | ||
| 207 | return 1; | ||
| 208 | } | ||
| 209 | CodeGen *g = codegen_create(&root_source_dir, nullptr); | ||
| 210 | codegen_set_out_name(g, buf_create_from_str("build")); | 198 | codegen_set_out_name(g, buf_create_from_str("build")); |
| 211 | codegen_set_out_type(g, OutTypeExe); | 199 | codegen_set_out_type(g, OutTypeExe); |
| 212 | codegen_set_verbose(g, verbose); | 200 | codegen_set_verbose(g, verbose); |
| ... | @@ -256,7 +244,7 @@ int main(int argc, char **argv) { | ... | @@ -256,7 +244,7 @@ int main(int argc, char **argv) { |
| 256 | PackageTableEntry *build_pkg = new_package(buf_ptr(&build_file_dirname), buf_ptr(&build_file_basename)); | 244 | PackageTableEntry *build_pkg = new_package(buf_ptr(&build_file_dirname), buf_ptr(&build_file_basename)); |
| 257 | build_pkg->package_table.put(buf_create_from_str("std"), g->std_package); | 245 | build_pkg->package_table.put(buf_create_from_str("std"), g->std_package); |
| 258 | g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg); | 246 | g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg); |
| 259 | codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code); | 247 | codegen_build(g); |
| 260 | codegen_link(g, "build"); | 248 | codegen_link(g, "build"); |
| 261 | 249 | ||
| 262 | Termination term; | 250 | Termination term; |
| ... | @@ -339,6 +327,10 @@ int main(int argc, char **argv) { | ... | @@ -339,6 +327,10 @@ int main(int argc, char **argv) { |
| 339 | lib_dirs.append(argv[i]); | 327 | lib_dirs.append(argv[i]); |
| 340 | } else if (strcmp(arg, "--library") == 0) { | 328 | } else if (strcmp(arg, "--library") == 0) { |
| 341 | link_libs.append(argv[i]); | 329 | link_libs.append(argv[i]); |
| 330 | } else if (strcmp(arg, "--object") == 0) { | ||
| 331 | objects.append(argv[i]); | ||
| 332 | } else if (strcmp(arg, "--assembly") == 0) { | ||
| 333 | asm_files.append(argv[i]); | ||
| 342 | } else if (strcmp(arg, "--target-arch") == 0) { | 334 | } else if (strcmp(arg, "--target-arch") == 0) { |
| 343 | target_arch = argv[i]; | 335 | target_arch = argv[i]; |
| 344 | } else if (strcmp(arg, "--target-os") == 0) { | 336 | } else if (strcmp(arg, "--target-os") == 0) { |
| ... | @@ -382,12 +374,6 @@ int main(int argc, char **argv) { | ... | @@ -382,12 +374,6 @@ int main(int argc, char **argv) { |
| 382 | } else if (strcmp(arg, "build_lib") == 0) { | 374 | } else if (strcmp(arg, "build_lib") == 0) { |
| 383 | cmd = CmdBuild; | 375 | cmd = CmdBuild; |
| 384 | out_type = OutTypeLib; | 376 | out_type = OutTypeLib; |
| 385 | } else if (strcmp(arg, "link_lib") == 0) { | ||
| 386 | cmd = CmdLink; | ||
| 387 | out_type = OutTypeLib; | ||
| 388 | } else if (strcmp(arg, "link_exe") == 0) { | ||
| 389 | cmd = CmdLink; | ||
| 390 | out_type = OutTypeExe; | ||
| 391 | } else if (strcmp(arg, "version") == 0) { | 377 | } else if (strcmp(arg, "version") == 0) { |
| 392 | cmd = CmdVersion; | 378 | cmd = CmdVersion; |
| 393 | } else if (strcmp(arg, "parseh") == 0) { | 379 | } else if (strcmp(arg, "parseh") == 0) { |
| ... | @@ -396,8 +382,6 @@ int main(int argc, char **argv) { | ... | @@ -396,8 +382,6 @@ int main(int argc, char **argv) { |
| 396 | cmd = CmdTest; | 382 | cmd = CmdTest; |
| 397 | } else if (strcmp(arg, "targets") == 0) { | 383 | } else if (strcmp(arg, "targets") == 0) { |
| 398 | cmd = CmdTargets; | 384 | cmd = CmdTargets; |
| 399 | } else if (strcmp(arg, "asm") == 0) { | ||
| 400 | cmd = CmdAsm; | ||
| 401 | } else { | 385 | } else { |
| 402 | fprintf(stderr, "Unrecognized command: %s\n", arg); | 386 | fprintf(stderr, "Unrecognized command: %s\n", arg); |
| 403 | return usage(arg0); | 387 | return usage(arg0); |
| ... | @@ -407,16 +391,12 @@ int main(int argc, char **argv) { | ... | @@ -407,16 +391,12 @@ int main(int argc, char **argv) { |
| 407 | case CmdBuild: | 391 | case CmdBuild: |
| 408 | case CmdParseH: | 392 | case CmdParseH: |
| 409 | case CmdTest: | 393 | case CmdTest: |
| 410 | case CmdAsm: | ||
| 411 | if (!in_file) { | 394 | if (!in_file) { |
| 412 | in_file = arg; | 395 | in_file = arg; |
| 413 | } else { | 396 | } else { |
| 414 | return usage(arg0); | 397 | return usage(arg0); |
| 415 | } | 398 | } |
| 416 | break; | 399 | break; |
| 417 | case CmdLink: | ||
| 418 | objects.append(arg); | ||
| 419 | break; | ||
| 420 | case CmdVersion: | 400 | case CmdVersion: |
| 421 | case CmdTargets: | 401 | case CmdTargets: |
| 422 | return usage(arg0); | 402 | return usage(arg0); |
| ... | @@ -430,25 +410,19 @@ int main(int argc, char **argv) { | ... | @@ -430,25 +410,19 @@ int main(int argc, char **argv) { |
| 430 | case CmdBuild: | 410 | case CmdBuild: |
| 431 | case CmdParseH: | 411 | case CmdParseH: |
| 432 | case CmdTest: | 412 | case CmdTest: |
| 433 | case CmdAsm: | ||
| 434 | case CmdLink: | ||
| 435 | { | 413 | { |
| 436 | bool one_source_input = (cmd == CmdBuild || cmd == CmdParseH || cmd == CmdTest || cmd == CmdAsm); | 414 | if (cmd == CmdBuild && !in_file && objects.length == 0 && asm_files.length == 0) { |
| 437 | if (one_source_input) { | 415 | fprintf(stderr, "Expected source file argument or at least one --object or --assembly argument.\n"); |
| 438 | if (!in_file) { | 416 | return usage(arg0); |
| 439 | fprintf(stderr, "Expected source file argument.\n"); | 417 | } else if ((cmd == CmdParseH || cmd == CmdTest) && !in_file) { |
| 440 | return usage(arg0); | 418 | fprintf(stderr, "Expected source file argument.\n"); |
| 441 | } | 419 | return usage(arg0); |
| 442 | } else if (cmd == CmdLink) { | 420 | } else if (cmd == CmdBuild && out_type == OutTypeObj && objects.length != 0) { |
| 443 | if (objects.length == 0) { | 421 | fprintf(stderr, "When building an object file, --object arguments are invalid.\n"); |
| 444 | fprintf(stderr, "Expected one or more object arguments.\n"); | 422 | return usage(arg0); |
| 445 | return usage(arg0); | ||
| 446 | } | ||
| 447 | } else { | ||
| 448 | zig_unreachable(); | ||
| 449 | } | 423 | } |
| 450 | 424 | ||
| 451 | assert((cmd != CmdBuild && cmd != CmdLink) || out_type != OutTypeUnknown); | 425 | assert(cmd != CmdBuild || out_type != OutTypeUnknown); |
| 452 | 426 | ||
| 453 | init_all_targets(); | 427 | init_all_targets(); |
| 454 | 428 | ||
| ... | @@ -479,45 +453,22 @@ int main(int argc, char **argv) { | ... | @@ -479,45 +453,22 @@ int main(int argc, char **argv) { |
| 479 | } | 453 | } |
| 480 | } | 454 | } |
| 481 | 455 | ||
| 482 | bool need_name = (cmd == CmdBuild || cmd == CmdAsm || cmd == CmdLink || cmd == CmdParseH); | 456 | bool need_name = (cmd == CmdBuild || cmd == CmdParseH); |
| 483 | 457 | ||
| 484 | Buf in_file_buf = BUF_INIT; | 458 | Buf *in_file_buf = nullptr; |
| 485 | |||
| 486 | Buf root_source_dir = BUF_INIT; | ||
| 487 | Buf root_source_code = BUF_INIT; | ||
| 488 | Buf root_source_name = BUF_INIT; | ||
| 489 | 459 | ||
| 490 | Buf *buf_out_name = (cmd == CmdTest) ? buf_create_from_str("test") : | 460 | Buf *buf_out_name = (cmd == CmdTest) ? buf_create_from_str("test") : |
| 491 | (out_name == nullptr) ? nullptr : buf_create_from_str(out_name); | 461 | (out_name == nullptr) ? nullptr : buf_create_from_str(out_name); |
| 492 | 462 | ||
| 493 | if (one_source_input) { | 463 | if (in_file) { |
| 494 | buf_init_from_str(&in_file_buf, in_file); | 464 | in_file_buf = buf_create_from_str(in_file); |
| 495 | |||
| 496 | if (buf_eql_str(&in_file_buf, "-")) { | ||
| 497 | os_get_cwd(&root_source_dir); | ||
| 498 | if ((err = os_fetch_file(stdin, &root_source_code))) { | ||
| 499 | fprintf(stderr, "unable to read stdin: %s\n", err_str(err)); | ||
| 500 | return 1; | ||
| 501 | } | ||
| 502 | buf_init_from_str(&root_source_name, ""); | ||
| 503 | 465 | ||
| 504 | } else { | 466 | if (need_name && buf_out_name == nullptr) { |
| 505 | os_path_split(&in_file_buf, &root_source_dir, &root_source_name); | 467 | Buf basename = BUF_INIT; |
| 506 | if ((err = os_fetch_file_path(buf_create_from_str(in_file), &root_source_code))) { | 468 | os_path_split(in_file_buf, nullptr, &basename); |
| 507 | fprintf(stderr, "unable to open '%s': %s\n", in_file, err_str(err)); | 469 | buf_out_name = buf_alloc(); |
| 508 | return 1; | 470 | os_path_extname(&basename, buf_out_name, nullptr); |
| 509 | } | ||
| 510 | |||
| 511 | if (need_name && buf_out_name == nullptr) { | ||
| 512 | buf_out_name = buf_alloc(); | ||
| 513 | Buf ext_name = BUF_INIT; | ||
| 514 | os_path_extname(&root_source_name, buf_out_name, &ext_name); | ||
| 515 | } | ||
| 516 | } | 471 | } |
| 517 | } else if (cmd == CmdLink) { | ||
| 518 | os_get_cwd(&root_source_dir); | ||
| 519 | } else { | ||
| 520 | zig_unreachable(); | ||
| 521 | } | 472 | } |
| 522 | 473 | ||
| 523 | if (need_name && buf_out_name == nullptr) { | 474 | if (need_name && buf_out_name == nullptr) { |
| ... | @@ -525,7 +476,10 @@ int main(int argc, char **argv) { | ... | @@ -525,7 +476,10 @@ int main(int argc, char **argv) { |
| 525 | return usage(arg0); | 476 | return usage(arg0); |
| 526 | } | 477 | } |
| 527 | 478 | ||
| 528 | CodeGen *g = codegen_create(&root_source_dir, target); | 479 | Buf *zig_root_source_file = (cmd == CmdParseH) ? nullptr : in_file_buf; |
| 480 | |||
| 481 | CodeGen *g = codegen_create(zig_root_source_file, target); | ||
| 482 | codegen_set_out_name(g, buf_out_name); | ||
| 529 | codegen_set_lib_version(g, ver_major, ver_minor, ver_patch); | 483 | codegen_set_lib_version(g, ver_major, ver_minor, ver_patch); |
| 530 | codegen_set_is_release(g, is_release_build); | 484 | codegen_set_is_release(g, is_release_build); |
| 531 | codegen_set_is_test(g, cmd == CmdTest); | 485 | codegen_set_is_test(g, cmd == CmdTest); |
| ... | @@ -536,14 +490,11 @@ int main(int argc, char **argv) { | ... | @@ -536,14 +490,11 @@ int main(int argc, char **argv) { |
| 536 | codegen_set_clang_argv(g, clang_argv.items, clang_argv.length); | 490 | codegen_set_clang_argv(g, clang_argv.items, clang_argv.length); |
| 537 | codegen_set_strip(g, strip); | 491 | codegen_set_strip(g, strip); |
| 538 | codegen_set_is_static(g, is_static); | 492 | codegen_set_is_static(g, is_static); |
| 539 | if (cmd == CmdAsm) { | 493 | if (out_type != OutTypeUnknown) { |
| 540 | codegen_set_out_type(g, OutTypeObj); | ||
| 541 | } else if (out_type != OutTypeUnknown) { | ||
| 542 | codegen_set_out_type(g, out_type); | 494 | codegen_set_out_type(g, out_type); |
| 543 | } else if (cmd == CmdTest) { | 495 | } else if (cmd == CmdTest) { |
| 544 | codegen_set_out_type(g, OutTypeExe); | 496 | codegen_set_out_type(g, OutTypeExe); |
| 545 | } | 497 | } |
| 546 | codegen_set_out_name(g, buf_out_name); | ||
| 547 | if (libc_lib_dir) | 498 | if (libc_lib_dir) |
| 548 | codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir)); | 499 | codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir)); |
| 549 | if (libc_static_lib_dir) | 500 | if (libc_static_lib_dir) |
| ... | @@ -598,33 +549,25 @@ int main(int argc, char **argv) { | ... | @@ -598,33 +549,25 @@ int main(int argc, char **argv) { |
| 598 | } | 549 | } |
| 599 | 550 | ||
| 600 | if (cmd == CmdBuild) { | 551 | if (cmd == CmdBuild) { |
| 601 | codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code); | ||
| 602 | codegen_link(g, out_file); | ||
| 603 | if (timing_info) | ||
| 604 | codegen_print_timing_report(g, stderr); | ||
| 605 | return EXIT_SUCCESS; | ||
| 606 | } else if (cmd == CmdLink) { | ||
| 607 | for (size_t i = 0; i < objects.length; i += 1) { | 552 | for (size_t i = 0; i < objects.length; i += 1) { |
| 608 | codegen_add_object(g, buf_create_from_str(objects.at(i))); | 553 | codegen_add_object(g, buf_create_from_str(objects.at(i))); |
| 609 | } | 554 | } |
| 610 | codegen_link(g, out_file); | 555 | for (size_t i = 0; i < asm_files.length; i += 1) { |
| 611 | if (timing_info) | 556 | codegen_add_assembly(g, buf_create_from_str(asm_files.at(i))); |
| 612 | codegen_print_timing_report(g, stderr); | 557 | } |
| 613 | return EXIT_SUCCESS; | 558 | codegen_build(g); |
| 614 | } else if (cmd == CmdAsm) { | ||
| 615 | codegen_add_root_assembly(g, &root_source_dir, &root_source_name, &root_source_code); | ||
| 616 | codegen_link(g, out_file); | 559 | codegen_link(g, out_file); |
| 617 | if (timing_info) | 560 | if (timing_info) |
| 618 | codegen_print_timing_report(g, stderr); | 561 | codegen_print_timing_report(g, stderr); |
| 619 | return EXIT_SUCCESS; | 562 | return EXIT_SUCCESS; |
| 620 | } else if (cmd == CmdParseH) { | 563 | } else if (cmd == CmdParseH) { |
| 621 | codegen_parseh(g, &root_source_dir, &root_source_name, &root_source_code); | 564 | codegen_parseh(g, in_file_buf); |
| 622 | ast_render_decls(g, stdout, 4, g->root_import); | 565 | ast_render_decls(g, stdout, 4, g->root_import); |
| 623 | if (timing_info) | 566 | if (timing_info) |
| 624 | codegen_print_timing_report(g, stderr); | 567 | codegen_print_timing_report(g, stderr); |
| 625 | return EXIT_SUCCESS; | 568 | return EXIT_SUCCESS; |
| 626 | } else if (cmd == CmdTest) { | 569 | } else if (cmd == CmdTest) { |
| 627 | codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code); | 570 | codegen_build(g); |
| 628 | codegen_link(g, "./test"); | 571 | codegen_link(g, "./test"); |
| 629 | ZigList<const char *> args = {0}; | 572 | ZigList<const char *> args = {0}; |
| 630 | Termination term; | 573 | Termination term; |
src/os.cpp+12-8| ... | @@ -146,24 +146,28 @@ void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename) { | ... | @@ -146,24 +146,28 @@ void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename) { |
| 146 | 146 | ||
| 147 | void os_path_extname(Buf *full_path, Buf *out_basename, Buf *out_extname) { | 147 | void os_path_extname(Buf *full_path, Buf *out_basename, Buf *out_extname) { |
| 148 | if (buf_len(full_path) == 0) { | 148 | if (buf_len(full_path) == 0) { |
| 149 | buf_init_from_str(out_basename, ""); | 149 | if (out_basename) buf_init_from_str(out_basename, ""); |
| 150 | buf_init_from_str(out_extname, ""); | 150 | if (out_extname) buf_init_from_str(out_extname, ""); |
| 151 | return; | 151 | return; |
| 152 | } | 152 | } |
| 153 | size_t i = buf_len(full_path) - 1; | 153 | size_t i = buf_len(full_path) - 1; |
| 154 | while (true) { | 154 | while (true) { |
| 155 | if (buf_ptr(full_path)[i] == '.') { | 155 | if (buf_ptr(full_path)[i] == '.') { |
| 156 | buf_resize(out_basename, 0); | 156 | if (out_basename) { |
| 157 | buf_append_mem(out_basename, buf_ptr(full_path), i); | 157 | buf_resize(out_basename, 0); |
| 158 | buf_append_mem(out_basename, buf_ptr(full_path), i); | ||
| 159 | } | ||
| 158 | 160 | ||
| 159 | buf_resize(out_extname, 0); | 161 | if (out_extname) { |
| 160 | buf_append_mem(out_extname, buf_ptr(full_path) + i, buf_len(full_path) - i); | 162 | buf_resize(out_extname, 0); |
| 163 | buf_append_mem(out_extname, buf_ptr(full_path) + i, buf_len(full_path) - i); | ||
| 164 | } | ||
| 161 | return; | 165 | return; |
| 162 | } | 166 | } |
| 163 | 167 | ||
| 164 | if (i == 0) { | 168 | if (i == 0) { |
| 165 | buf_init_from_buf(out_basename, full_path); | 169 | if (out_basename) buf_init_from_buf(out_basename, full_path); |
| 166 | buf_init_from_str(out_extname, ""); | 170 | if (out_extname) buf_init_from_str(out_extname, ""); |
| 167 | return; | 171 | return; |
| 168 | } | 172 | } |
| 169 | i -= 1; | 173 | i -= 1; |
std/build.zig+109-496| ... | @@ -120,28 +120,22 @@ pub const Builder = struct { | ... | @@ -120,28 +120,22 @@ pub const Builder = struct { |
| 120 | self.lib_dir = %%os.path.join(self.allocator, self.prefix, "lib"); | 120 | self.lib_dir = %%os.path.join(self.allocator, self.prefix, "lib"); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | pub fn addExecutable(self: &Builder, name: []const u8, root_src: []const u8) -> &LibOrExeStep { | 123 | pub fn addExecutable(self: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep { |
| 124 | const exe = %%self.allocator.create(LibOrExeStep); | 124 | return LibExeObjStep.createExecutable(self, name, root_src); |
| 125 | *exe = LibOrExeStep.initExecutable(self, name, root_src); | ||
| 126 | return exe; | ||
| 127 | } | 125 | } |
| 128 | 126 | ||
| 129 | pub fn addObject(self: &Builder, name: []const u8, root_src: []const u8) -> &ObjectStep { | 127 | pub fn addObject(self: &Builder, name: []const u8, root_src: []const u8) -> &LibExeObjStep { |
| 130 | const obj_step = %%self.allocator.create(ObjectStep); | 128 | return LibExeObjStep.createObject(self, name, root_src); |
| 131 | *obj_step = ObjectStep.init(self, name, root_src); | ||
| 132 | return obj_step; | ||
| 133 | } | 129 | } |
| 134 | 130 | ||
| 135 | pub fn addSharedLibrary(self: &Builder, name: []const u8, root_src: []const u8, ver: &const Version) -> &LibOrExeStep { | 131 | pub fn addSharedLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8, |
| 136 | const lib_step = %%self.allocator.create(LibOrExeStep); | 132 | ver: &const Version) -> &LibExeObjStep |
| 137 | *lib_step = LibOrExeStep.initSharedLibrary(self, name, root_src, ver); | 133 | { |
| 138 | return lib_step; | 134 | return LibExeObjStep.createSharedLibrary(self, name, root_src, ver); |
| 139 | } | 135 | } |
| 140 | 136 | ||
| 141 | pub fn addStaticLibrary(self: &Builder, name: []const u8, root_src: []const u8) -> &LibOrExeStep { | 137 | pub fn addStaticLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep { |
| 142 | const lib_step = %%self.allocator.create(LibOrExeStep); | 138 | return LibExeObjStep.createStaticLibrary(self, name, root_src); |
| 143 | *lib_step = LibOrExeStep.initStaticLibrary(self, name, root_src); | ||
| 144 | return lib_step; | ||
| 145 | } | 139 | } |
| 146 | 140 | ||
| 147 | pub fn addTest(self: &Builder, root_src: []const u8) -> &TestStep { | 141 | pub fn addTest(self: &Builder, root_src: []const u8) -> &TestStep { |
| ... | @@ -150,28 +144,10 @@ pub const Builder = struct { | ... | @@ -150,28 +144,10 @@ pub const Builder = struct { |
| 150 | return test_step; | 144 | return test_step; |
| 151 | } | 145 | } |
| 152 | 146 | ||
| 153 | pub fn addAssemble(self: &Builder, name: []const u8, src: []const u8) -> &AsmStep { | 147 | pub fn addAssemble(self: &Builder, name: []const u8, src: []const u8) -> &LibExeObjStep { |
| 154 | const asm_step = %%self.allocator.create(AsmStep); | 148 | const obj_step = LibExeObjStep.createObject(self, name, null); |
| 155 | *asm_step = AsmStep.init(self, name, src); | 149 | obj_step.addAssemblyFile(src); |
| 156 | return asm_step; | 150 | return obj_step; |
| 157 | } | ||
| 158 | |||
| 159 | pub fn addLinkExecutable(self: &Builder, name: []const u8) -> &LinkStep { | ||
| 160 | const exe = %%self.allocator.create(LinkStep); | ||
| 161 | *exe = LinkStep.initExecutable(self, name); | ||
| 162 | return exe; | ||
| 163 | } | ||
| 164 | |||
| 165 | pub fn addLinkStaticLibrary(self: &Builder, name: []const u8) -> &LinkStep { | ||
| 166 | const exe = %%self.allocator.create(LinkStep); | ||
| 167 | *exe = LinkStep.initStaticLibrary(self, name); | ||
| 168 | return exe; | ||
| 169 | } | ||
| 170 | |||
| 171 | pub fn addLinkSharedLibrary(self: &Builder, name: []const u8, ver: &const Version) -> &LinkStep { | ||
| 172 | const exe = %%self.allocator.create(LinkStep); | ||
| 173 | *exe = LinkStep.initSharedLibrary(self, name, ver); | ||
| 174 | return exe; | ||
| 175 | } | 151 | } |
| 176 | 152 | ||
| 177 | pub fn addCStaticLibrary(self: &Builder, name: []const u8) -> &CLibrary { | 153 | pub fn addCStaticLibrary(self: &Builder, name: []const u8) -> &CLibrary { |
| ... | @@ -635,10 +611,10 @@ const LinkerScript = enum { | ... | @@ -635,10 +611,10 @@ const LinkerScript = enum { |
| 635 | Path: []const u8, | 611 | Path: []const u8, |
| 636 | }; | 612 | }; |
| 637 | 613 | ||
| 638 | pub const LibOrExeStep = struct { | 614 | pub const LibExeObjStep = struct { |
| 639 | step: Step, | 615 | step: Step, |
| 640 | builder: &Builder, | 616 | builder: &Builder, |
| 641 | root_src: []const u8, | 617 | root_src: ?[]const u8, |
| 642 | name: []const u8, | 618 | name: []const u8, |
| 643 | target: Target, | 619 | target: Target, |
| 644 | linker_script: LinkerScript, | 620 | linker_script: LinkerScript, |
| ... | @@ -652,30 +628,45 @@ pub const LibOrExeStep = struct { | ... | @@ -652,30 +628,45 @@ pub const LibOrExeStep = struct { |
| 652 | out_filename: []const u8, | 628 | out_filename: []const u8, |
| 653 | out_filename_major_only: []const u8, | 629 | out_filename_major_only: []const u8, |
| 654 | out_filename_name_only: []const u8, | 630 | out_filename_name_only: []const u8, |
| 631 | object_files: List([]const u8), | ||
| 632 | assembly_files: List([]const u8), | ||
| 655 | 633 | ||
| 656 | const Kind = enum { | 634 | const Kind = enum { |
| 657 | Exe, | 635 | Exe, |
| 658 | Lib, | 636 | Lib, |
| 637 | Obj, | ||
| 659 | }; | 638 | }; |
| 660 | 639 | ||
| 661 | pub fn initExecutable(builder: &Builder, name: []const u8, root_src: []const u8) -> LibOrExeStep { | 640 | pub fn createSharedLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8, |
| 662 | return initExtraArgs(builder, name, root_src, Kind.Exe, false, builder.version(0, 0, 0)); | 641 | ver: &const Version) -> &LibExeObjStep |
| 642 | { | ||
| 643 | const self = %%builder.allocator.create(LibExeObjStep); | ||
| 644 | *self = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver); | ||
| 645 | return self; | ||
| 663 | } | 646 | } |
| 664 | 647 | ||
| 665 | pub fn initSharedLibrary(builder: &Builder, name: []const u8, root_src: []const u8, | 648 | pub fn createStaticLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep { |
| 666 | ver: &const Version) -> LibOrExeStep | 649 | const self = %%builder.allocator.create(LibExeObjStep); |
| 667 | { | 650 | *self = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0)); |
| 668 | return initExtraArgs(builder, name, root_src, Kind.Lib, false, ver); | 651 | return self; |
| 669 | } | 652 | } |
| 670 | 653 | ||
| 671 | pub fn initStaticLibrary(builder: &Builder, name: []const u8, root_src: []const u8) -> LibOrExeStep { | 654 | pub fn createObject(builder: &Builder, name: []const u8, root_src: []const u8) -> &LibExeObjStep { |
| 672 | return initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0)); | 655 | const self = %%builder.allocator.create(LibExeObjStep); |
| 656 | *self = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0)); | ||
| 657 | return self; | ||
| 673 | } | 658 | } |
| 674 | 659 | ||
| 675 | fn initExtraArgs(builder: &Builder, name: []const u8, root_src: []const u8, kind: Kind, | 660 | pub fn createExecutable(builder: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep { |
| 676 | static: bool, ver: &const Version) -> LibOrExeStep | 661 | const self = %%builder.allocator.create(LibExeObjStep); |
| 662 | *self = initExtraArgs(builder, name, root_src, Kind.Exe, false, builder.version(0, 0, 0)); | ||
| 663 | return self; | ||
| 664 | } | ||
| 665 | |||
| 666 | fn initExtraArgs(builder: &Builder, name: []const u8, root_src: ?[]const u8, kind: Kind, | ||
| 667 | static: bool, ver: &const Version) -> LibExeObjStep | ||
| 677 | { | 668 | { |
| 678 | var self = LibOrExeStep { | 669 | var self = LibExeObjStep { |
| 679 | .builder = builder, | 670 | .builder = builder, |
| 680 | .verbose = false, | 671 | .verbose = false, |
| 681 | .release = false, | 672 | .release = false, |
| ... | @@ -692,13 +683,18 @@ pub const LibOrExeStep = struct { | ... | @@ -692,13 +683,18 @@ pub const LibOrExeStep = struct { |
| 692 | .out_filename = undefined, | 683 | .out_filename = undefined, |
| 693 | .out_filename_major_only = undefined, | 684 | .out_filename_major_only = undefined, |
| 694 | .out_filename_name_only = undefined, | 685 | .out_filename_name_only = undefined, |
| 686 | .object_files = List([]const u8).init(builder.allocator), | ||
| 687 | .assembly_files = List([]const u8).init(builder.allocator), | ||
| 695 | }; | 688 | }; |
| 696 | self.computeOutFileNames(); | 689 | self.computeOutFileNames(); |
| 697 | return self; | 690 | return self; |
| 698 | } | 691 | } |
| 699 | 692 | ||
| 700 | fn computeOutFileNames(self: &LibOrExeStep) { | 693 | fn computeOutFileNames(self: &LibExeObjStep) { |
| 701 | switch (self.kind) { | 694 | switch (self.kind) { |
| 695 | Kind.Obj => { | ||
| 696 | self.out_filename = self.builder.fmt("{}{}", self.name, self.target.oFileExt()); | ||
| 697 | }, | ||
| 702 | Kind.Exe => { | 698 | Kind.Exe => { |
| 703 | self.out_filename = self.builder.fmt("{}{}", self.name, self.target.exeFileExt()); | 699 | self.out_filename = self.builder.fmt("{}{}", self.name, self.target.exeFileExt()); |
| 704 | }, | 700 | }, |
| ... | @@ -715,7 +711,7 @@ pub const LibOrExeStep = struct { | ... | @@ -715,7 +711,7 @@ pub const LibOrExeStep = struct { |
| 715 | } | 711 | } |
| 716 | } | 712 | } |
| 717 | 713 | ||
| 718 | pub fn setTarget(self: &LibOrExeStep, target_arch: Arch, target_os: Os, target_environ: Environ) { | 714 | pub fn setTarget(self: &LibExeObjStep, target_arch: Arch, target_os: Os, target_environ: Environ) { |
| 719 | self.target = Target.Cross { | 715 | self.target = Target.Cross { |
| 720 | CrossTarget { | 716 | CrossTarget { |
| 721 | .arch = target_arch, | 717 | .arch = target_arch, |
| ... | @@ -723,414 +719,49 @@ pub const LibOrExeStep = struct { | ... | @@ -723,414 +719,49 @@ pub const LibOrExeStep = struct { |
| 723 | .environ = target_environ, | 719 | .environ = target_environ, |
| 724 | } | 720 | } |
| 725 | }; | 721 | }; |
| 722 | self.computeOutFileNames(); | ||
| 726 | } | 723 | } |
| 727 | 724 | ||
| 728 | /// LibOrExeStep keeps a reference to script for its lifetime or until this function | 725 | /// LibExeObjStep keeps a reference to script for its lifetime or until this function |
| 729 | /// is called again. | 726 | /// is called again. |
| 730 | pub fn setLinkerScriptContents(self: &LibOrExeStep, script: []const u8) { | 727 | pub fn setLinkerScriptContents(self: &LibExeObjStep, script: []const u8) { |
| 731 | self.linker_script = LinkerScript.Embed { script }; | 728 | self.linker_script = LinkerScript.Embed { script }; |
| 732 | } | 729 | } |
| 733 | 730 | ||
| 734 | pub fn setLinkerScriptPath(self: &LibOrExeStep, path: []const u8) { | 731 | pub fn setLinkerScriptPath(self: &LibExeObjStep, path: []const u8) { |
| 735 | self.linker_script = LinkerScript.Path { path }; | 732 | self.linker_script = LinkerScript.Path { path }; |
| 736 | } | 733 | } |
| 737 | 734 | ||
| 738 | pub fn linkSystemLibrary(self: &LibOrExeStep, name: []const u8) { | 735 | pub fn linkSystemLibrary(self: &LibExeObjStep, name: []const u8) { |
| 739 | %%self.link_libs.put(name); | 736 | %%self.link_libs.put(name); |
| 740 | } | 737 | } |
| 741 | 738 | ||
| 742 | pub fn setVerbose(self: &LibOrExeStep, value: bool) { | 739 | pub fn setVerbose(self: &LibExeObjStep, value: bool) { |
| 743 | self.verbose = value; | ||
| 744 | } | ||
| 745 | |||
| 746 | pub fn setRelease(self: &LibOrExeStep, value: bool) { | ||
| 747 | self.release = value; | ||
| 748 | } | ||
| 749 | |||
| 750 | pub fn setOutputPath(self: &LibOrExeStep, value: []const u8) { | ||
| 751 | self.output_path = value; | ||
| 752 | } | ||
| 753 | |||
| 754 | fn make(step: &Step) -> %void { | ||
| 755 | const self = @fieldParentPtr(LibOrExeStep, "step", step); | ||
| 756 | const builder = self.builder; | ||
| 757 | |||
| 758 | var zig_args = List([]const u8).init(builder.allocator); | ||
| 759 | defer zig_args.deinit(); | ||
| 760 | |||
| 761 | const cmd = switch (self.kind) { | ||
| 762 | Kind.Lib => "build_lib", | ||
| 763 | Kind.Exe => "build_exe", | ||
| 764 | }; | ||
| 765 | %%zig_args.append(cmd); | ||
| 766 | %%zig_args.append(builder.pathFromRoot(self.root_src)); | ||
| 767 | |||
| 768 | if (self.verbose) { | ||
| 769 | %%zig_args.append("--verbose"); | ||
| 770 | } | ||
| 771 | |||
| 772 | if (self.release) { | ||
| 773 | %%zig_args.append("--release"); | ||
| 774 | } | ||
| 775 | |||
| 776 | test (self.output_path) |output_path| { | ||
| 777 | %%zig_args.append("--output"); | ||
| 778 | %%zig_args.append(builder.pathFromRoot(output_path)); | ||
| 779 | } | ||
| 780 | |||
| 781 | %%zig_args.append("--name"); | ||
| 782 | %%zig_args.append(self.name); | ||
| 783 | |||
| 784 | if (self.kind == Kind.Lib and !self.static) { | ||
| 785 | %%zig_args.append("--ver-major"); | ||
| 786 | %%zig_args.append(builder.fmt("{}", self.version.major)); | ||
| 787 | |||
| 788 | %%zig_args.append("--ver-minor"); | ||
| 789 | %%zig_args.append(builder.fmt("{}", self.version.minor)); | ||
| 790 | |||
| 791 | %%zig_args.append("--ver-patch"); | ||
| 792 | %%zig_args.append(builder.fmt("{}", self.version.patch)); | ||
| 793 | } | ||
| 794 | |||
| 795 | switch (self.target) { | ||
| 796 | Target.Native => {}, | ||
| 797 | Target.Cross => |cross_target| { | ||
| 798 | %%zig_args.append("--target-arch"); | ||
| 799 | %%zig_args.append(@enumTagName(cross_target.arch)); | ||
| 800 | |||
| 801 | %%zig_args.append("--target-os"); | ||
| 802 | %%zig_args.append(@enumTagName(cross_target.os)); | ||
| 803 | |||
| 804 | %%zig_args.append("--target-environ"); | ||
| 805 | %%zig_args.append(@enumTagName(cross_target.environ)); | ||
| 806 | }, | ||
| 807 | } | ||
| 808 | |||
| 809 | switch (self.linker_script) { | ||
| 810 | LinkerScript.None => {}, | ||
| 811 | LinkerScript.Embed => |script| { | ||
| 812 | const tmp_file_name = "linker.ld.tmp"; // TODO issue #298 | ||
| 813 | io.writeFile(tmp_file_name, script, builder.allocator) | ||
| 814 | %% |err| debug.panic("unable to write linker script: {}\n", @errorName(err)); | ||
| 815 | %%zig_args.append("--linker-script"); | ||
| 816 | %%zig_args.append(tmp_file_name); | ||
| 817 | }, | ||
| 818 | LinkerScript.Path => |path| { | ||
| 819 | %%zig_args.append("--linker-script"); | ||
| 820 | %%zig_args.append(path); | ||
| 821 | }, | ||
| 822 | } | ||
| 823 | |||
| 824 | { | ||
| 825 | var it = self.link_libs.iterator(); | ||
| 826 | while (true) { | ||
| 827 | const entry = it.next() ?? break; | ||
| 828 | %%zig_args.append("--library"); | ||
| 829 | %%zig_args.append(entry.key); | ||
| 830 | } | ||
| 831 | } | ||
| 832 | |||
| 833 | for (builder.include_paths.toSliceConst()) |include_path| { | ||
| 834 | %%zig_args.append("-isystem"); | ||
| 835 | %%zig_args.append(include_path); | ||
| 836 | } | ||
| 837 | |||
| 838 | for (builder.rpaths.toSliceConst()) |rpath| { | ||
| 839 | %%zig_args.append("-rpath"); | ||
| 840 | %%zig_args.append(rpath); | ||
| 841 | } | ||
| 842 | |||
| 843 | for (builder.lib_paths.toSliceConst()) |lib_path| { | ||
| 844 | %%zig_args.append("--library-path"); | ||
| 845 | %%zig_args.append(lib_path); | ||
| 846 | } | ||
| 847 | |||
| 848 | %%builder.spawnChild(builder.zig_exe, zig_args.toSliceConst()); | ||
| 849 | |||
| 850 | if (self.kind == Kind.Lib and !self.static) { | ||
| 851 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 | ||
| 852 | %%os.atomicSymLink(builder.allocator, self.out_filename, self.out_filename_major_only); | ||
| 853 | // sym link for libfoo.so to libfoo.so.1 | ||
| 854 | %%os.atomicSymLink(builder.allocator, self.out_filename_major_only, self.out_filename_name_only); | ||
| 855 | } | ||
| 856 | } | ||
| 857 | }; | ||
| 858 | |||
| 859 | pub const ObjectStep = struct { | ||
| 860 | step: Step, | ||
| 861 | builder: &Builder, | ||
| 862 | root_src: []const u8, | ||
| 863 | name: []const u8, | ||
| 864 | target: Target, | ||
| 865 | verbose: bool, | ||
| 866 | release: bool, | ||
| 867 | output_path: ?[]const u8, | ||
| 868 | |||
| 869 | pub fn init(builder: &Builder, name: []const u8, root_src: []const u8) -> ObjectStep { | ||
| 870 | ObjectStep { | ||
| 871 | .builder = builder, | ||
| 872 | .verbose = false, | ||
| 873 | .release = false, | ||
| 874 | .root_src = root_src, | ||
| 875 | .name = name, | ||
| 876 | .target = Target.Native, | ||
| 877 | .step = Step.init(name, builder.allocator, make), | ||
| 878 | .output_path = null, | ||
| 879 | } | ||
| 880 | } | ||
| 881 | |||
| 882 | pub fn setTarget(self: &ObjectStep, target_arch: Arch, target_os: Os, target_environ: Environ) { | ||
| 883 | self.target = Target.Cross { | ||
| 884 | CrossTarget { | ||
| 885 | .arch = target_arch, | ||
| 886 | .os = target_os, | ||
| 887 | .environ = target_environ, | ||
| 888 | } | ||
| 889 | }; | ||
| 890 | } | ||
| 891 | |||
| 892 | pub fn setVerbose(self: &ObjectStep, value: bool) { | ||
| 893 | self.verbose = value; | ||
| 894 | } | ||
| 895 | |||
| 896 | pub fn setRelease(self: &ObjectStep, value: bool) { | ||
| 897 | self.release = value; | ||
| 898 | } | ||
| 899 | |||
| 900 | pub fn setOutputPath(self: &ObjectStep, value: []const u8) { | ||
| 901 | self.output_path = value; | ||
| 902 | } | ||
| 903 | |||
| 904 | fn make(step: &Step) -> %void { | ||
| 905 | const self = @fieldParentPtr(ObjectStep, "step", step); | ||
| 906 | const builder = self.builder; | ||
| 907 | |||
| 908 | var zig_args = List([]const u8).init(builder.allocator); | ||
| 909 | defer zig_args.deinit(); | ||
| 910 | |||
| 911 | %%zig_args.append("build_obj"); | ||
| 912 | %%zig_args.append(builder.pathFromRoot(self.root_src)); | ||
| 913 | |||
| 914 | if (self.verbose) { | ||
| 915 | %%zig_args.append("--verbose"); | ||
| 916 | } | ||
| 917 | |||
| 918 | if (self.release) { | ||
| 919 | %%zig_args.append("--release"); | ||
| 920 | } | ||
| 921 | |||
| 922 | test (self.output_path) |output_path| { | ||
| 923 | %%zig_args.append("--output"); | ||
| 924 | %%zig_args.append(builder.pathFromRoot(output_path)); | ||
| 925 | } | ||
| 926 | |||
| 927 | %%zig_args.append("--name"); | ||
| 928 | %%zig_args.append(self.name); | ||
| 929 | |||
| 930 | switch (self.target) { | ||
| 931 | Target.Native => {}, | ||
| 932 | Target.Cross => |cross_target| { | ||
| 933 | %%zig_args.append("--target-arch"); | ||
| 934 | %%zig_args.append(@enumTagName(cross_target.arch)); | ||
| 935 | |||
| 936 | %%zig_args.append("--target-os"); | ||
| 937 | %%zig_args.append(@enumTagName(cross_target.os)); | ||
| 938 | |||
| 939 | %%zig_args.append("--target-environ"); | ||
| 940 | %%zig_args.append(@enumTagName(cross_target.environ)); | ||
| 941 | }, | ||
| 942 | } | ||
| 943 | |||
| 944 | for (builder.include_paths.toSliceConst()) |include_path| { | ||
| 945 | %%zig_args.append("-isystem"); | ||
| 946 | %%zig_args.append(include_path); | ||
| 947 | } | ||
| 948 | |||
| 949 | for (builder.rpaths.toSliceConst()) |rpath| { | ||
| 950 | %%zig_args.append("-rpath"); | ||
| 951 | %%zig_args.append(rpath); | ||
| 952 | } | ||
| 953 | |||
| 954 | for (builder.lib_paths.toSliceConst()) |lib_path| { | ||
| 955 | %%zig_args.append("--library-path"); | ||
| 956 | %%zig_args.append(lib_path); | ||
| 957 | } | ||
| 958 | |||
| 959 | %%builder.spawnChild(builder.zig_exe, zig_args.toSliceConst()); | ||
| 960 | } | ||
| 961 | }; | ||
| 962 | |||
| 963 | pub const AsmStep = struct { | ||
| 964 | step: Step, | ||
| 965 | builder: &Builder, | ||
| 966 | name: []const u8, | ||
| 967 | target: Target, | ||
| 968 | verbose: bool, | ||
| 969 | release: bool, | ||
| 970 | output_path: ?[]const u8, | ||
| 971 | src_path: []const u8, | ||
| 972 | |||
| 973 | pub fn init(builder: &Builder, name: []const u8, src_path: []const u8) -> AsmStep { | ||
| 974 | var self = AsmStep { | ||
| 975 | .step = Step.init(name, builder.allocator, make), | ||
| 976 | .builder = builder, | ||
| 977 | .name = name, | ||
| 978 | .target = Target.Native, | ||
| 979 | .verbose = false, | ||
| 980 | .release = false, | ||
| 981 | .output_path = null, | ||
| 982 | .src_path = src_path, | ||
| 983 | }; | ||
| 984 | return self; | ||
| 985 | } | ||
| 986 | |||
| 987 | pub fn setTarget(self: &AsmStep, target_arch: Arch, target_os: Os, target_environ: Environ) { | ||
| 988 | self.target = Target.Cross { | ||
| 989 | CrossTarget { | ||
| 990 | .arch = target_arch, | ||
| 991 | .os = target_os, | ||
| 992 | .environ = target_environ, | ||
| 993 | } | ||
| 994 | }; | ||
| 995 | } | ||
| 996 | |||
| 997 | pub fn setVerbose(self: &AsmStep, value: bool) { | ||
| 998 | self.verbose = value; | 740 | self.verbose = value; |
| 999 | } | 741 | } |
| 1000 | 742 | ||
| 1001 | pub fn setRelease(self: &AsmStep, value: bool) { | 743 | pub fn setRelease(self: &LibExeObjStep, value: bool) { |
| 1002 | self.release = value; | 744 | self.release = value; |
| 1003 | } | 745 | } |
| 1004 | 746 | ||
| 1005 | pub fn setOutputPath(self: &AsmStep, value: []const u8) { | 747 | pub fn setOutputPath(self: &LibExeObjStep, value: []const u8) { |
| 1006 | self.output_path = value; | 748 | self.output_path = value; |
| 1007 | } | 749 | } |
| 1008 | 750 | ||
| 1009 | fn make(step: &Step) -> %void { | 751 | pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) { |
| 1010 | const self = @fieldParentPtr(AsmStep, "step", step); | 752 | %%self.assembly_files.append(path); |
| 1011 | const builder = self.builder; | ||
| 1012 | |||
| 1013 | var zig_args = List([]const u8).init(builder.allocator); | ||
| 1014 | defer zig_args.deinit(); | ||
| 1015 | |||
| 1016 | %%zig_args.append("asm"); | ||
| 1017 | %%zig_args.append(builder.pathFromRoot(self.src_path)); | ||
| 1018 | |||
| 1019 | if (self.verbose) { | ||
| 1020 | %%zig_args.append("--verbose"); | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | if (self.release) { | ||
| 1024 | %%zig_args.append("--release"); | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | test (self.output_path) |output_path| { | ||
| 1028 | %%zig_args.append("--output"); | ||
| 1029 | %%zig_args.append(builder.pathFromRoot(output_path)); | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | %%zig_args.append("--name"); | ||
| 1033 | %%zig_args.append(self.name); | ||
| 1034 | |||
| 1035 | switch (self.target) { | ||
| 1036 | Target.Native => {}, | ||
| 1037 | Target.Cross => |cross_target| { | ||
| 1038 | %%zig_args.append("--target-arch"); | ||
| 1039 | %%zig_args.append(@enumTagName(cross_target.arch)); | ||
| 1040 | |||
| 1041 | %%zig_args.append("--target-os"); | ||
| 1042 | %%zig_args.append(@enumTagName(cross_target.os)); | ||
| 1043 | |||
| 1044 | %%zig_args.append("--target-environ"); | ||
| 1045 | %%zig_args.append(@enumTagName(cross_target.environ)); | ||
| 1046 | }, | ||
| 1047 | } | ||
| 1048 | |||
| 1049 | %%builder.spawnChild(builder.zig_exe, zig_args.toSliceConst()); | ||
| 1050 | } | 753 | } |
| 1051 | }; | ||
| 1052 | 754 | ||
| 1053 | pub const LinkStep = struct { | 755 | pub fn addObjectFile(self: &LibExeObjStep, path: []const u8) { |
| 1054 | step: Step, | 756 | assert(self.kind != Kind.Obj); |
| 1055 | builder: &Builder, | ||
| 1056 | name: []const u8, | ||
| 1057 | target: Target, | ||
| 1058 | linker_script: LinkerScript, | ||
| 1059 | link_libs: BufSet, | ||
| 1060 | verbose: bool, | ||
| 1061 | release: bool, | ||
| 1062 | output_path: ?[]const u8, | ||
| 1063 | object_files: List([]const u8), | ||
| 1064 | static: bool, | ||
| 1065 | out_filename: []const u8, | ||
| 1066 | out_type: OutType, | ||
| 1067 | version: Version, | ||
| 1068 | major_only_filename: []const u8, | ||
| 1069 | name_only_filename: []const u8, | ||
| 1070 | |||
| 1071 | const OutType = enum { | ||
| 1072 | Exe, | ||
| 1073 | Lib, | ||
| 1074 | }; | ||
| 1075 | 757 | ||
| 1076 | pub fn initExecutable(builder: &Builder, name: []const u8) -> LinkStep { | 758 | %%self.object_files.append(path); |
| 1077 | return init(builder, name, OutType.Exe, builder.version(0, 0, 0), false) | ||
| 1078 | } | 759 | } |
| 1079 | 760 | ||
| 1080 | pub fn initSharedLibrary(builder: &Builder, name: []const u8, version: &const Version) -> LinkStep { | 761 | pub fn addObject(self: &LibExeObjStep, obj: &LibExeObjStep) { |
| 1081 | return init(builder, name, OutType.Lib, version, false) | 762 | assert(obj.kind == Kind.Obj); |
| 1082 | } | 763 | assert(self.kind != Kind.Obj); |
| 1083 | 764 | ||
| 1084 | pub fn initStaticLibrary(builder: &Builder, name: []const u8) -> LinkStep { | ||
| 1085 | return init(builder, name, OutType.Lib, builder.version(0, 0, 0), true) | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | fn init(builder: &Builder, name: []const u8, out_type: OutType, version: &const Version, static: bool) -> LinkStep { | ||
| 1089 | var self = LinkStep { | ||
| 1090 | .builder = builder, | ||
| 1091 | .verbose = false, | ||
| 1092 | .release = false, | ||
| 1093 | .name = name, | ||
| 1094 | .target = Target.Native, | ||
| 1095 | .linker_script = LinkerScript.None, | ||
| 1096 | .link_libs = BufSet.init(builder.allocator), | ||
| 1097 | .step = Step.init(name, builder.allocator, make), | ||
| 1098 | .output_path = null, | ||
| 1099 | .object_files = List([]const u8).init(builder.allocator), | ||
| 1100 | .out_type = out_type, | ||
| 1101 | .version = *version, | ||
| 1102 | .static = static, | ||
| 1103 | .out_filename = undefined, | ||
| 1104 | .major_only_filename = undefined, | ||
| 1105 | .name_only_filename = undefined, | ||
| 1106 | }; | ||
| 1107 | self.computeOutFileName(); | ||
| 1108 | return self; | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | fn computeOutFileName(self: &LinkStep) { | ||
| 1112 | switch (self.out_type) { | ||
| 1113 | OutType.Exe => { | ||
| 1114 | self.out_filename = self.builder.fmt("{}{}", self.name, self.target.exeFileExt()); | ||
| 1115 | }, | ||
| 1116 | OutType.Lib => { | ||
| 1117 | if (self.static) { | ||
| 1118 | self.out_filename = self.builder.fmt("lib{}.a", self.name); | ||
| 1119 | } else { | ||
| 1120 | self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", | ||
| 1121 | self.name, self.version.major, self.version.minor, self.version.patch); | ||
| 1122 | self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major); | ||
| 1123 | self.name_only_filename = self.builder.fmt("lib{}.so", self.name); | ||
| 1124 | } | ||
| 1125 | }, | ||
| 1126 | } | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | pub fn addObjectFile(self: &LinkStep, file: []const u8) { | ||
| 1130 | %%self.object_files.append(file); | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | pub fn addObject(self: &LinkStep, obj: &ObjectStep) { | ||
| 1134 | self.step.dependOn(&obj.step); | 765 | self.step.dependOn(&obj.step); |
| 1135 | 766 | ||
| 1136 | const path_to_obj = test (obj.output_path) |explicit_out_path| { | 767 | const path_to_obj = test (obj.output_path) |explicit_out_path| { |
| ... | @@ -1143,61 +774,11 @@ pub const LinkStep = struct { | ... | @@ -1143,61 +774,11 @@ pub const LinkStep = struct { |
| 1143 | %%self.object_files.append(path_to_obj); | 774 | %%self.object_files.append(path_to_obj); |
| 1144 | } | 775 | } |
| 1145 | 776 | ||
| 1146 | pub fn addAssembly(self: &LinkStep, assembly: &AsmStep) { | ||
| 1147 | self.step.dependOn(&assembly.step); | ||
| 1148 | |||
| 1149 | const path_to_obj = test (assembly.output_path) |explicit_out_path| { | ||
| 1150 | explicit_out_path | ||
| 1151 | } else { | ||
| 1152 | // TODO make it so we always know where this will be | ||
| 1153 | %%os.path.join(self.builder.allocator, self.builder.out_dir, | ||
| 1154 | self.builder.fmt("{}{}", assembly.name, assembly.target.oFileExt())) | ||
| 1155 | }; | ||
| 1156 | %%self.object_files.append(path_to_obj); | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | pub fn setTarget(self: &LinkStep, target_arch: Arch, target_os: Os, target_environ: Environ) { | ||
| 1160 | self.target = Target.Cross { | ||
| 1161 | CrossTarget { | ||
| 1162 | .arch = target_arch, | ||
| 1163 | .os = target_os, | ||
| 1164 | .environ = target_environ, | ||
| 1165 | } | ||
| 1166 | }; | ||
| 1167 | self.computeOutFileName(); | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | /// LinkStep keeps a reference to script for its lifetime or until this function | ||
| 1171 | /// is called again. | ||
| 1172 | pub fn setLinkerScriptContents(self: &LinkStep, script: []const u8) { | ||
| 1173 | self.linker_script = LinkerScript.Embed { script }; | ||
| 1174 | } | ||
| 1175 | |||
| 1176 | pub fn setLinkerScriptPath(self: &LinkStep, path: []const u8) { | ||
| 1177 | self.linker_script = LinkerScript.Path { path }; | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | pub fn linkSystemLibrary(self: &LinkStep, name: []const u8) { | ||
| 1181 | %%self.link_libs.put(name); | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | pub fn setVerbose(self: &LinkStep, value: bool) { | ||
| 1185 | self.verbose = value; | ||
| 1186 | } | ||
| 1187 | |||
| 1188 | pub fn setRelease(self: &LinkStep, value: bool) { | ||
| 1189 | self.release = value; | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | pub fn setOutputPath(self: &LinkStep, value: []const u8) { | ||
| 1193 | self.output_path = value; | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | fn make(step: &Step) -> %void { | 777 | fn make(step: &Step) -> %void { |
| 1197 | const self = @fieldParentPtr(LinkStep, "step", step); | 778 | const self = @fieldParentPtr(LibExeObjStep, "step", step); |
| 1198 | const builder = self.builder; | 779 | const builder = self.builder; |
| 1199 | 780 | ||
| 1200 | if (self.object_files.len == 0) { | 781 | if (self.root_src == null and self.object_files.len == 0 and self.assembly_files.len == 0) { |
| 1201 | %%io.stderr.printf("{}: linker needs 1 or more objects to link\n", step.name); | 782 | %%io.stderr.printf("{}: linker needs 1 or more objects to link\n", step.name); |
| 1202 | return error.NeedAnObject; | 783 | return error.NeedAnObject; |
| 1203 | } | 784 | } |
| ... | @@ -1205,16 +786,27 @@ pub const LinkStep = struct { | ... | @@ -1205,16 +786,27 @@ pub const LinkStep = struct { |
| 1205 | var zig_args = List([]const u8).init(builder.allocator); | 786 | var zig_args = List([]const u8).init(builder.allocator); |
| 1206 | defer zig_args.deinit(); | 787 | defer zig_args.deinit(); |
| 1207 | 788 | ||
| 1208 | const cmd = switch (self.out_type) { | 789 | const cmd = switch (self.kind) { |
| 1209 | OutType.Exe => "link_exe", | 790 | Kind.Lib => "build_lib", |
| 1210 | OutType.Lib => "link_lib", | 791 | Kind.Exe => "build_exe", |
| 792 | Kind.Obj => "build_obj", | ||
| 1211 | }; | 793 | }; |
| 1212 | %%zig_args.append(cmd); | 794 | %%zig_args.append(cmd); |
| 1213 | 795 | ||
| 796 | test (self.root_src) |root_src| { | ||
| 797 | %%zig_args.append(builder.pathFromRoot(root_src)); | ||
| 798 | } | ||
| 799 | |||
| 1214 | for (self.object_files.toSliceConst()) |object_file| { | 800 | for (self.object_files.toSliceConst()) |object_file| { |
| 801 | %%zig_args.append("--object"); | ||
| 1215 | %%zig_args.append(builder.pathFromRoot(object_file)); | 802 | %%zig_args.append(builder.pathFromRoot(object_file)); |
| 1216 | } | 803 | } |
| 1217 | 804 | ||
| 805 | for (self.assembly_files.toSliceConst()) |asm_file| { | ||
| 806 | %%zig_args.append("--assembly"); | ||
| 807 | %%zig_args.append(builder.pathFromRoot(asm_file)); | ||
| 808 | } | ||
| 809 | |||
| 1218 | if (self.verbose) { | 810 | if (self.verbose) { |
| 1219 | %%zig_args.append("--verbose"); | 811 | %%zig_args.append("--verbose"); |
| 1220 | } | 812 | } |
| ... | @@ -1223,10 +815,6 @@ pub const LinkStep = struct { | ... | @@ -1223,10 +815,6 @@ pub const LinkStep = struct { |
| 1223 | %%zig_args.append("--release"); | 815 | %%zig_args.append("--release"); |
| 1224 | } | 816 | } |
| 1225 | 817 | ||
| 1226 | if (self.static) { | ||
| 1227 | %%zig_args.append("--static"); | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | test (self.output_path) |output_path| { | 818 | test (self.output_path) |output_path| { |
| 1231 | %%zig_args.append("--output"); | 819 | %%zig_args.append("--output"); |
| 1232 | %%zig_args.append(builder.pathFromRoot(output_path)); | 820 | %%zig_args.append(builder.pathFromRoot(output_path)); |
| ... | @@ -1235,6 +823,17 @@ pub const LinkStep = struct { | ... | @@ -1235,6 +823,17 @@ pub const LinkStep = struct { |
| 1235 | %%zig_args.append("--name"); | 823 | %%zig_args.append("--name"); |
| 1236 | %%zig_args.append(self.name); | 824 | %%zig_args.append(self.name); |
| 1237 | 825 | ||
| 826 | if (self.kind == Kind.Lib and !self.static) { | ||
| 827 | %%zig_args.append("--ver-major"); | ||
| 828 | %%zig_args.append(builder.fmt("{}", self.version.major)); | ||
| 829 | |||
| 830 | %%zig_args.append("--ver-minor"); | ||
| 831 | %%zig_args.append(builder.fmt("{}", self.version.minor)); | ||
| 832 | |||
| 833 | %%zig_args.append("--ver-patch"); | ||
| 834 | %%zig_args.append(builder.fmt("{}", self.version.patch)); | ||
| 835 | } | ||
| 836 | |||
| 1238 | switch (self.target) { | 837 | switch (self.target) { |
| 1239 | Target.Native => {}, | 838 | Target.Native => {}, |
| 1240 | Target.Cross => |cross_target| { | 839 | Target.Cross => |cross_target| { |
| ... | @@ -1273,6 +872,11 @@ pub const LinkStep = struct { | ... | @@ -1273,6 +872,11 @@ pub const LinkStep = struct { |
| 1273 | } | 872 | } |
| 1274 | } | 873 | } |
| 1275 | 874 | ||
| 875 | for (builder.include_paths.toSliceConst()) |include_path| { | ||
| 876 | %%zig_args.append("-isystem"); | ||
| 877 | %%zig_args.append(include_path); | ||
| 878 | } | ||
| 879 | |||
| 1276 | for (builder.rpaths.toSliceConst()) |rpath| { | 880 | for (builder.rpaths.toSliceConst()) |rpath| { |
| 1277 | %%zig_args.append("-rpath"); | 881 | %%zig_args.append("-rpath"); |
| 1278 | %%zig_args.append(rpath); | 882 | %%zig_args.append(rpath); |
| ... | @@ -1284,6 +888,13 @@ pub const LinkStep = struct { | ... | @@ -1284,6 +888,13 @@ pub const LinkStep = struct { |
| 1284 | } | 888 | } |
| 1285 | 889 | ||
| 1286 | %%builder.spawnChild(builder.zig_exe, zig_args.toSliceConst()); | 890 | %%builder.spawnChild(builder.zig_exe, zig_args.toSliceConst()); |
| 891 | |||
| 892 | if (self.kind == Kind.Lib and !self.static) { | ||
| 893 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 | ||
| 894 | %%os.atomicSymLink(builder.allocator, self.out_filename, self.out_filename_major_only); | ||
| 895 | // sym link for libfoo.so to libfoo.so.1 | ||
| 896 | %%os.atomicSymLink(builder.allocator, self.out_filename_major_only, self.out_filename_name_only); | ||
| 897 | } | ||
| 1287 | } | 898 | } |
| 1288 | }; | 899 | }; |
| 1289 | 900 | ||
| ... | @@ -1592,15 +1203,17 @@ pub const CExecutable = struct { | ... | @@ -1592,15 +1203,17 @@ pub const CExecutable = struct { |
| 1592 | %%self.full_path_libs.append(clib.out_filename); | 1203 | %%self.full_path_libs.append(clib.out_filename); |
| 1593 | } | 1204 | } |
| 1594 | 1205 | ||
| 1595 | pub fn linkLibrary(self: &CExecutable, lib: &LibOrExeStep) { | 1206 | pub fn linkLibrary(self: &CExecutable, lib: &LibExeObjStep) { |
| 1596 | assert(lib.kind == LibOrExeStep.Kind.Lib); | 1207 | assert(lib.kind == LibExeObjStep.Kind.Lib); |
| 1597 | self.step.dependOn(&lib.step); | 1208 | self.step.dependOn(&lib.step); |
| 1598 | %%self.full_path_libs.append(lib.out_filename); | 1209 | %%self.full_path_libs.append(lib.out_filename); |
| 1599 | // TODO should be some kind of isolated directory that only has this header in it | 1210 | // TODO should be some kind of isolated directory that only has this header in it |
| 1600 | %%self.include_dirs.append(self.builder.out_dir); | 1211 | %%self.include_dirs.append(self.builder.out_dir); |
| 1601 | } | 1212 | } |
| 1602 | 1213 | ||
| 1603 | pub fn addObject(self: &CExecutable, obj: &ObjectStep) { | 1214 | pub fn addObject(self: &CExecutable, obj: &LibExeObjStep) { |
| 1215 | assert(obj.kind == LibExeObjStep.Kind.Obj); | ||
| 1216 | |||
| 1604 | self.step.dependOn(&obj.step); | 1217 | self.step.dependOn(&obj.step); |
| 1605 | 1218 | ||
| 1606 | // TODO make it so we always know where this will be | 1219 | // TODO make it so we always know where this will be |
std/debug.zig+5-1| ... | @@ -90,7 +90,11 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty | ... | @@ -90,7 +90,11 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty |
| 90 | // at compile time. I'll call it issue #313 | 90 | // at compile time. I'll call it issue #313 |
| 91 | const ptr_hex = if (@sizeOf(usize) == 4) "0x{x8}" else "0x{x16}"; | 91 | const ptr_hex = if (@sizeOf(usize) == 4) "0x{x8}" else "0x{x16}"; |
| 92 | 92 | ||
| 93 | const compile_unit = findCompileUnit(st, return_address) ?? return error.MissingDebugInfo; | 93 | const compile_unit = findCompileUnit(st, return_address) ?? { |
| 94 | %return out_stream.print(DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n\n\n", return_address); | ||
| 95 | %return out_stream.flush(); | ||
| 96 | continue; | ||
| 97 | }; | ||
| 94 | const compile_unit_name = %return compile_unit.die.getAttrString(st, DW.AT_name); | 98 | const compile_unit_name = %return compile_unit.die.getAttrString(st, DW.AT_name); |
| 95 | try (getLineNumberInfo(st, compile_unit, usize(return_address) - 1)) |line_info| { | 99 | try (getLineNumberInfo(st, compile_unit, usize(return_address) - 1)) |line_info| { |
| 96 | defer line_info.deinit(); | 100 | defer line_info.deinit(); |
test/cases/cast.zig+9| ... | @@ -150,3 +150,12 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) -> []const u8 { | ... | @@ -150,3 +150,12 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) -> []const u8 { |
| 150 | 150 | ||
| 151 | return slice[0...1]; | 151 | return slice[0...1]; |
| 152 | } | 152 | } |
| 153 | |||
| 154 | test "implicitly cast from [N]T to ?[]const T" { | ||
| 155 | assert(mem.eql(u8, ??castToMaybeSlice(), "hi")); | ||
| 156 | comptime assert(mem.eql(u8, ??castToMaybeSlice(), "hi")); | ||
| 157 | } | ||
| 158 | |||
| 159 | fn castToMaybeSlice() -> ?[]const u8 { | ||
| 160 | return "hi"; | ||
| 161 | } |
test/tests.zig+4-6| ... | @@ -355,18 +355,16 @@ pub const CompareOutputContext = struct { | ... | @@ -355,18 +355,16 @@ pub const CompareOutputContext = struct { |
| 355 | return; | 355 | return; |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | const assembly = b.addAssemble("test", root_src); | 358 | const exe = b.addExecutable("test", null); |
| 359 | exe.addAssemblyFile(root_src); | ||
| 360 | exe.setOutputPath(exe_path); | ||
| 359 | 361 | ||
| 360 | for (case.sources.toSliceConst()) |src_file| { | 362 | for (case.sources.toSliceConst()) |src_file| { |
| 361 | const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename); | 363 | const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename); |
| 362 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); | 364 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); |
| 363 | assembly.step.dependOn(&write_src.step); | 365 | exe.step.dependOn(&write_src.step); |
| 364 | } | 366 | } |
| 365 | 367 | ||
| 366 | const exe = b.addLinkExecutable("test"); | ||
| 367 | exe.addAssembly(assembly); | ||
| 368 | exe.setOutputPath(exe_path); | ||
| 369 | |||
| 370 | const run_and_cmp_output = RunCompareOutputStep.create(self, exe_path, annotated_case_name, | 368 | const run_and_cmp_output = RunCompareOutputStep.create(self, exe_path, annotated_case_name, |
| 371 | case.expected_output); | 369 | case.expected_output); |
| 372 | run_and_cmp_output.step.dependOn(&exe.step); | 370 | run_and_cmp_output.step.dependOn(&exe.step); |