| author | |
| committer | |
| log | c5ca0fe237e105b95c8edb7f80da899012e573f8 |
| tree | 6f8120d2bb3187a90ba5e855c87332386141bf63 |
| parent | cbc4e59e6805d27f0e889c0a9ff8488376cea5c0 |
| parent | d7968c6d33b054a8293edd89ce248f385e108469 |
| signature |
Closes #44188 files changed, 225 insertions(+), 207 deletions(-)
lib/std/build.zig+7| ... | @@ -1155,6 +1155,9 @@ pub const LibExeObjStep = struct { | ... | @@ -1155,6 +1155,9 @@ pub const LibExeObjStep = struct { |
| 1155 | frameworks: BufSet, | 1155 | frameworks: BufSet, |
| 1156 | verbose_link: bool, | 1156 | verbose_link: bool, |
| 1157 | verbose_cc: bool, | 1157 | verbose_cc: bool, |
| 1158 | emit_llvm_ir: bool = false, | ||
| 1159 | emit_asm: bool = false, | ||
| 1160 | emit_bin: bool = true, | ||
| 1158 | disable_gen_h: bool, | 1161 | disable_gen_h: bool, |
| 1159 | bundle_compiler_rt: bool, | 1162 | bundle_compiler_rt: bool, |
| 1160 | disable_stack_probing: bool, | 1163 | disable_stack_probing: bool, |
| ... | @@ -1941,6 +1944,10 @@ pub const LibExeObjStep = struct { | ... | @@ -1941,6 +1944,10 @@ pub const LibExeObjStep = struct { |
| 1941 | if (builder.verbose_link or self.verbose_link) zig_args.append("--verbose-link") catch unreachable; | 1944 | if (builder.verbose_link or self.verbose_link) zig_args.append("--verbose-link") catch unreachable; |
| 1942 | if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable; | 1945 | if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable; |
| 1943 | 1946 | ||
| 1947 | if (self.emit_llvm_ir) try zig_args.append("-femit-llvm-ir"); | ||
| 1948 | if (self.emit_asm) try zig_args.append("-femit-asm"); | ||
| 1949 | if (!self.emit_bin) try zig_args.append("-fno-emit-bin"); | ||
| 1950 | |||
| 1944 | if (self.strip) { | 1951 | if (self.strip) { |
| 1945 | try zig_args.append("--strip"); | 1952 | try zig_args.append("--strip"); |
| 1946 | } | 1953 | } |
src/all_types.hpp+6-9| ... | @@ -1966,12 +1966,6 @@ enum CodeModel { | ... | @@ -1966,12 +1966,6 @@ enum CodeModel { |
| 1966 | CodeModelLarge, | 1966 | CodeModelLarge, |
| 1967 | }; | 1967 | }; |
| 1968 | 1968 | ||
| 1969 | enum EmitFileType { | ||
| 1970 | EmitFileTypeBinary, | ||
| 1971 | EmitFileTypeAssembly, | ||
| 1972 | EmitFileTypeLLVMIr, | ||
| 1973 | }; | ||
| 1974 | |||
| 1975 | struct LinkLib { | 1969 | struct LinkLib { |
| 1976 | Buf *name; | 1970 | Buf *name; |
| 1977 | Buf *path; | 1971 | Buf *path; |
| ... | @@ -2142,8 +2136,10 @@ struct CodeGen { | ... | @@ -2142,8 +2136,10 @@ struct CodeGen { |
| 2142 | 2136 | ||
| 2143 | Buf llvm_triple_str; | 2137 | Buf llvm_triple_str; |
| 2144 | Buf global_asm; | 2138 | Buf global_asm; |
| 2145 | Buf output_file_path; | ||
| 2146 | Buf o_file_output_path; | 2139 | Buf o_file_output_path; |
| 2140 | Buf bin_file_output_path; | ||
| 2141 | Buf asm_file_output_path; | ||
| 2142 | Buf llvm_ir_file_output_path; | ||
| 2147 | Buf *cache_dir; | 2143 | Buf *cache_dir; |
| 2148 | // As an input parameter, mutually exclusive with enable_cache. But it gets | 2144 | // As an input parameter, mutually exclusive with enable_cache. But it gets |
| 2149 | // populated in codegen_build_and_link. | 2145 | // populated in codegen_build_and_link. |
| ... | @@ -2236,7 +2232,6 @@ struct CodeGen { | ... | @@ -2236,7 +2232,6 @@ struct CodeGen { |
| 2236 | size_t version_patch; | 2232 | size_t version_patch; |
| 2237 | const char *linker_script; | 2233 | const char *linker_script; |
| 2238 | 2234 | ||
| 2239 | EmitFileType emit_file_type; | ||
| 2240 | BuildMode build_mode; | 2235 | BuildMode build_mode; |
| 2241 | OutType out_type; | 2236 | OutType out_type; |
| 2242 | const ZigTarget *zig_target; | 2237 | const ZigTarget *zig_target; |
| ... | @@ -2258,7 +2253,9 @@ struct CodeGen { | ... | @@ -2258,7 +2253,9 @@ struct CodeGen { |
| 2258 | bool function_sections; | 2253 | bool function_sections; |
| 2259 | bool enable_dump_analysis; | 2254 | bool enable_dump_analysis; |
| 2260 | bool enable_doc_generation; | 2255 | bool enable_doc_generation; |
| 2261 | bool disable_bin_generation; | 2256 | bool emit_bin; |
| 2257 | bool emit_asm; | ||
| 2258 | bool emit_llvm_ir; | ||
| 2262 | bool test_is_evented; | 2259 | bool test_is_evented; |
| 2263 | CodeModel code_model; | 2260 | CodeModel code_model; |
| 2264 | 2261 |
src/codegen.cpp+84-95| ... | @@ -121,10 +121,6 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc | ... | @@ -121,10 +121,6 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc |
| 121 | g->version_patch = patch; | 121 | g->version_patch = patch; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type) { | ||
| 125 | g->emit_file_type = emit_file_type; | ||
| 126 | } | ||
| 127 | |||
| 128 | void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) { | 124 | void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) { |
| 129 | g->each_lib_rpath = each_lib_rpath; | 125 | g->each_lib_rpath = each_lib_rpath; |
| 130 | } | 126 | } |
| ... | @@ -7925,50 +7921,44 @@ static void zig_llvm_emit_output(CodeGen *g) { | ... | @@ -7925,50 +7921,44 @@ static void zig_llvm_emit_output(CodeGen *g) { |
| 7925 | 7921 | ||
| 7926 | bool is_small = g->build_mode == BuildModeSmallRelease; | 7922 | bool is_small = g->build_mode == BuildModeSmallRelease; |
| 7927 | 7923 | ||
| 7928 | Buf *output_path = &g->o_file_output_path; | ||
| 7929 | char *err_msg = nullptr; | 7924 | char *err_msg = nullptr; |
| 7930 | switch (g->emit_file_type) { | 7925 | const char *asm_filename = nullptr; |
| 7931 | case EmitFileTypeBinary: | 7926 | const char *bin_filename = nullptr; |
| 7932 | if (g->disable_bin_generation) | 7927 | const char *llvm_ir_filename = nullptr; |
| 7933 | return; | 7928 | |
| 7934 | if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), | 7929 | if (g->emit_bin) bin_filename = buf_ptr(&g->o_file_output_path); |
| 7935 | ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug, is_small, | 7930 | if (g->emit_asm) asm_filename = buf_ptr(&g->asm_file_output_path); |
| 7936 | g->enable_time_report)) | 7931 | if (g->emit_llvm_ir) llvm_ir_filename = buf_ptr(&g->llvm_ir_file_output_path); |
| 7937 | { | 7932 | |
| 7938 | zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg); | 7933 | // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. So we call the entire |
| 7939 | } | 7934 | // pipeline multiple times if this is requested. |
| 7940 | validate_inline_fns(g); | 7935 | if (asm_filename != nullptr && bin_filename != nullptr) { |
| 7941 | g->link_objects.append(output_path); | 7936 | if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug, |
| 7942 | if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || | 7937 | is_small, g->enable_time_report, nullptr, bin_filename, llvm_ir_filename)) |
| 7943 | (g->out_type == OutTypeLib && !g->is_dynamic))) | 7938 | { |
| 7944 | { | 7939 | fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg); |
| 7945 | zig_link_add_compiler_rt(g, g->sub_progress_node); | 7940 | exit(1); |
| 7946 | } | 7941 | } |
| 7947 | break; | 7942 | bin_filename = nullptr; |
| 7943 | llvm_ir_filename = nullptr; | ||
| 7944 | } | ||
| 7948 | 7945 | ||
| 7949 | case EmitFileTypeAssembly: | 7946 | if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug, |
| 7950 | if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), | 7947 | is_small, g->enable_time_report, asm_filename, bin_filename, llvm_ir_filename)) |
| 7951 | ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug, is_small, | 7948 | { |
| 7952 | g->enable_time_report)) | 7949 | fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg); |
| 7953 | { | 7950 | exit(1); |
| 7954 | zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg); | 7951 | } |
| 7955 | } | ||
| 7956 | validate_inline_fns(g); | ||
| 7957 | break; | ||
| 7958 | 7952 | ||
| 7959 | case EmitFileTypeLLVMIr: | 7953 | validate_inline_fns(g); |
| 7960 | if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), | ||
| 7961 | ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug, is_small, | ||
| 7962 | g->enable_time_report)) | ||
| 7963 | { | ||
| 7964 | zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg); | ||
| 7965 | } | ||
| 7966 | validate_inline_fns(g); | ||
| 7967 | break; | ||
| 7968 | 7954 | ||
| 7969 | default: | 7955 | if (g->emit_bin) { |
| 7970 | zig_unreachable(); | 7956 | g->link_objects.append(&g->o_file_output_path); |
| 7957 | if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))) { | ||
| 7958 | zig_link_add_compiler_rt(g, g->sub_progress_node); | ||
| 7959 | } | ||
| 7971 | } | 7960 | } |
| 7961 | |||
| 7972 | LLVMDisposeModule(g->module); | 7962 | LLVMDisposeModule(g->module); |
| 7973 | g->module = nullptr; | 7963 | g->module = nullptr; |
| 7974 | LLVMDisposeTargetData(g->target_data_ref); | 7964 | LLVMDisposeTargetData(g->target_data_ref); |
| ... | @@ -10450,7 +10440,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { | ... | @@ -10450,7 +10440,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 10450 | cache_bool(ch, g->function_sections); | 10440 | cache_bool(ch, g->function_sections); |
| 10451 | cache_bool(ch, g->enable_dump_analysis); | 10441 | cache_bool(ch, g->enable_dump_analysis); |
| 10452 | cache_bool(ch, g->enable_doc_generation); | 10442 | cache_bool(ch, g->enable_doc_generation); |
| 10453 | cache_bool(ch, g->disable_bin_generation); | 10443 | cache_bool(ch, g->emit_bin); |
| 10444 | cache_bool(ch, g->emit_llvm_ir); | ||
| 10445 | cache_bool(ch, g->emit_asm); | ||
| 10454 | cache_buf_opt(ch, g->mmacosx_version_min); | 10446 | cache_buf_opt(ch, g->mmacosx_version_min); |
| 10455 | cache_buf_opt(ch, g->mios_version_min); | 10447 | cache_buf_opt(ch, g->mios_version_min); |
| 10456 | cache_usize(ch, g->version_major); | 10448 | cache_usize(ch, g->version_major); |
| ... | @@ -10495,58 +10487,54 @@ static void resolve_out_paths(CodeGen *g) { | ... | @@ -10495,58 +10487,54 @@ static void resolve_out_paths(CodeGen *g) { |
| 10495 | assert(g->output_dir != nullptr); | 10487 | assert(g->output_dir != nullptr); |
| 10496 | assert(g->root_out_name != nullptr); | 10488 | assert(g->root_out_name != nullptr); |
| 10497 | 10489 | ||
| 10498 | Buf *out_basename = buf_create_from_buf(g->root_out_name); | 10490 | if (g->emit_bin) { |
| 10499 | Buf *o_basename = buf_create_from_buf(g->root_out_name); | 10491 | Buf *out_basename = buf_create_from_buf(g->root_out_name); |
| 10500 | switch (g->emit_file_type) { | 10492 | Buf *o_basename = buf_create_from_buf(g->root_out_name); |
| 10501 | case EmitFileTypeBinary: { | 10493 | switch (g->out_type) { |
| 10502 | switch (g->out_type) { | 10494 | case OutTypeUnknown: |
| 10503 | case OutTypeUnknown: | 10495 | zig_unreachable(); |
| 10504 | zig_unreachable(); | 10496 | case OutTypeObj: |
| 10505 | case OutTypeObj: | 10497 | if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) { |
| 10506 | if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) { | 10498 | buf_init_from_buf(&g->bin_file_output_path, g->link_objects.at(0)); |
| 10507 | buf_init_from_buf(&g->output_file_path, g->link_objects.at(0)); | 10499 | return; |
| 10508 | return; | 10500 | } |
| 10509 | } | 10501 | if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache && |
| 10510 | if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache && | 10502 | buf_eql_buf(o_basename, out_basename)) |
| 10511 | buf_eql_buf(o_basename, out_basename)) | 10503 | { |
| 10512 | { | 10504 | // make it not collide with main output object |
| 10513 | // make it not collide with main output object | 10505 | buf_append_str(o_basename, ".root"); |
| 10514 | buf_append_str(o_basename, ".root"); | 10506 | } |
| 10515 | } | 10507 | buf_append_str(o_basename, target_o_file_ext(g->zig_target)); |
| 10516 | buf_append_str(o_basename, target_o_file_ext(g->zig_target)); | 10508 | buf_append_str(out_basename, target_o_file_ext(g->zig_target)); |
| 10517 | buf_append_str(out_basename, target_o_file_ext(g->zig_target)); | 10509 | break; |
| 10518 | break; | 10510 | case OutTypeExe: |
| 10519 | case OutTypeExe: | 10511 | buf_append_str(o_basename, target_o_file_ext(g->zig_target)); |
| 10520 | buf_append_str(o_basename, target_o_file_ext(g->zig_target)); | 10512 | buf_append_str(out_basename, target_exe_file_ext(g->zig_target)); |
| 10521 | buf_append_str(out_basename, target_exe_file_ext(g->zig_target)); | 10513 | break; |
| 10522 | break; | 10514 | case OutTypeLib: |
| 10523 | case OutTypeLib: | 10515 | buf_append_str(o_basename, target_o_file_ext(g->zig_target)); |
| 10524 | buf_append_str(o_basename, target_o_file_ext(g->zig_target)); | 10516 | buf_resize(out_basename, 0); |
| 10525 | buf_resize(out_basename, 0); | 10517 | buf_append_str(out_basename, target_lib_file_prefix(g->zig_target)); |
| 10526 | buf_append_str(out_basename, target_lib_file_prefix(g->zig_target)); | 10518 | buf_append_buf(out_basename, g->root_out_name); |
| 10527 | buf_append_buf(out_basename, g->root_out_name); | 10519 | buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic, |
| 10528 | buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic, | 10520 | g->version_major, g->version_minor, g->version_patch)); |
| 10529 | g->version_major, g->version_minor, g->version_patch)); | 10521 | break; |
| 10530 | break; | ||
| 10531 | } | ||
| 10532 | break; | ||
| 10533 | } | ||
| 10534 | case EmitFileTypeAssembly: { | ||
| 10535 | const char *asm_ext = target_asm_file_ext(g->zig_target); | ||
| 10536 | buf_append_str(o_basename, asm_ext); | ||
| 10537 | buf_append_str(out_basename, asm_ext); | ||
| 10538 | break; | ||
| 10539 | } | ||
| 10540 | case EmitFileTypeLLVMIr: { | ||
| 10541 | const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target); | ||
| 10542 | buf_append_str(o_basename, llvm_ir_ext); | ||
| 10543 | buf_append_str(out_basename, llvm_ir_ext); | ||
| 10544 | break; | ||
| 10545 | } | 10522 | } |
| 10523 | os_path_join(g->output_dir, o_basename, &g->o_file_output_path); | ||
| 10524 | os_path_join(g->output_dir, out_basename, &g->bin_file_output_path); | ||
| 10525 | } | ||
| 10526 | if (g->emit_asm) { | ||
| 10527 | Buf *asm_basename = buf_create_from_buf(g->root_out_name); | ||
| 10528 | const char *asm_ext = target_asm_file_ext(g->zig_target); | ||
| 10529 | buf_append_str(asm_basename, asm_ext); | ||
| 10530 | os_path_join(g->output_dir, asm_basename, &g->asm_file_output_path); | ||
| 10531 | } | ||
| 10532 | if (g->emit_llvm_ir) { | ||
| 10533 | Buf *llvm_ir_basename = buf_create_from_buf(g->root_out_name); | ||
| 10534 | const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target); | ||
| 10535 | buf_append_str(llvm_ir_basename, llvm_ir_ext); | ||
| 10536 | os_path_join(g->output_dir, llvm_ir_basename, &g->llvm_ir_file_output_path); | ||
| 10546 | } | 10537 | } |
| 10547 | |||
| 10548 | os_path_join(g->output_dir, o_basename, &g->o_file_output_path); | ||
| 10549 | os_path_join(g->output_dir, out_basename, &g->output_file_path); | ||
| 10550 | } | 10538 | } |
| 10551 | 10539 | ||
| 10552 | void codegen_build_and_link(CodeGen *g) { | 10540 | void codegen_build_and_link(CodeGen *g) { |
| ... | @@ -10708,7 +10696,7 @@ void codegen_build_and_link(CodeGen *g) { | ... | @@ -10708,7 +10696,7 @@ void codegen_build_and_link(CodeGen *g) { |
| 10708 | // If there is more than one object, we have to link them (with -r). | 10696 | // If there is more than one object, we have to link them (with -r). |
| 10709 | // Finally, if we didn't make an object from zig source, and we don't have caching enabled, | 10697 | // Finally, if we didn't make an object from zig source, and we don't have caching enabled, |
| 10710 | // then we have an object from C source that we must copy to the output dir which we do with a -r link. | 10698 | // then we have an object from C source that we must copy to the output dir which we do with a -r link. |
| 10711 | if (!g->disable_bin_generation && g->emit_file_type == EmitFileTypeBinary && | 10699 | if (g->emit_bin && |
| 10712 | (g->out_type != OutTypeObj || g->link_objects.length > 1 || | 10700 | (g->out_type != OutTypeObj || g->link_objects.length > 1 || |
| 10713 | (!need_llvm_module(g) && !g->enable_cache))) | 10701 | (!need_llvm_module(g) && !g->enable_cache))) |
| 10714 | { | 10702 | { |
| ... | @@ -10786,6 +10774,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget | ... | @@ -10786,6 +10774,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget |
| 10786 | Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node) | 10774 | Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node) |
| 10787 | { | 10775 | { |
| 10788 | CodeGen *g = heap::c_allocator.create<CodeGen>(); | 10776 | CodeGen *g = heap::c_allocator.create<CodeGen>(); |
| 10777 | g->emit_bin = true; | ||
| 10789 | g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1"); | 10778 | g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1"); |
| 10790 | g->main_progress_node = progress_node; | 10779 | g->main_progress_node = progress_node; |
| 10791 | 10780 |
src/codegen.hpp-1| ... | @@ -26,7 +26,6 @@ void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); | ... | @@ -26,7 +26,6 @@ void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); |
| 26 | void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len); | 26 | void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len); |
| 27 | void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath); | 27 | void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath); |
| 28 | 28 | ||
| 29 | void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type); | ||
| 30 | void codegen_set_strip(CodeGen *codegen, bool strip); | 29 | void codegen_set_strip(CodeGen *codegen, bool strip); |
| 31 | void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color); | 30 | void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color); |
| 32 | void codegen_set_out_name(CodeGen *codegen, Buf *out_name); | 31 | void codegen_set_out_name(CodeGen *codegen, Buf *out_name); |
src/link.cpp+19-19| ... | @@ -605,7 +605,7 @@ static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFil | ... | @@ -605,7 +605,7 @@ static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFil |
| 605 | c_source_files.append(c_file); | 605 | c_source_files.append(c_file); |
| 606 | child_gen->c_source_files = c_source_files; | 606 | child_gen->c_source_files = c_source_files; |
| 607 | codegen_build_and_link(child_gen); | 607 | codegen_build_and_link(child_gen); |
| 608 | return buf_ptr(&child_gen->output_file_path); | 608 | return buf_ptr(&child_gen->bin_file_output_path); |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) { | 611 | static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) { |
| ... | @@ -682,7 +682,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress | ... | @@ -682,7 +682,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress |
| 682 | } | 682 | } |
| 683 | child_gen->c_source_files = c_source_files; | 683 | child_gen->c_source_files = c_source_files; |
| 684 | codegen_build_and_link(child_gen); | 684 | codegen_build_and_link(child_gen); |
| 685 | return buf_ptr(&child_gen->output_file_path); | 685 | return buf_ptr(&child_gen->bin_file_output_path); |
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) { | 688 | static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) { |
| ... | @@ -1123,7 +1123,7 @@ static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node | ... | @@ -1123,7 +1123,7 @@ static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node |
| 1123 | 1123 | ||
| 1124 | child_gen->c_source_files = c_source_files; | 1124 | child_gen->c_source_files = c_source_files; |
| 1125 | codegen_build_and_link(child_gen); | 1125 | codegen_build_and_link(child_gen); |
| 1126 | return buf_ptr(&child_gen->output_file_path); | 1126 | return buf_ptr(&child_gen->bin_file_output_path); |
| 1127 | } | 1127 | } |
| 1128 | 1128 | ||
| 1129 | static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) { | 1129 | static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) { |
| ... | @@ -1253,7 +1253,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr | ... | @@ -1253,7 +1253,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr |
| 1253 | child_gen->c_source_files.append(c_file); | 1253 | child_gen->c_source_files.append(c_file); |
| 1254 | } | 1254 | } |
| 1255 | codegen_build_and_link(child_gen); | 1255 | codegen_build_and_link(child_gen); |
| 1256 | return buf_ptr(&child_gen->output_file_path); | 1256 | return buf_ptr(&child_gen->bin_file_output_path); |
| 1257 | } else if (strcmp(file, "msvcrt-os.lib") == 0) { | 1257 | } else if (strcmp(file, "msvcrt-os.lib") == 0) { |
| 1258 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node); | 1258 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node); |
| 1259 | 1259 | ||
| ... | @@ -1270,7 +1270,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr | ... | @@ -1270,7 +1270,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr |
| 1270 | } | 1270 | } |
| 1271 | } | 1271 | } |
| 1272 | codegen_build_and_link(child_gen); | 1272 | codegen_build_and_link(child_gen); |
| 1273 | return buf_ptr(&child_gen->output_file_path); | 1273 | return buf_ptr(&child_gen->bin_file_output_path); |
| 1274 | } else if (strcmp(file, "mingwex.lib") == 0) { | 1274 | } else if (strcmp(file, "mingwex.lib") == 0) { |
| 1275 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node); | 1275 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node); |
| 1276 | 1276 | ||
| ... | @@ -1295,7 +1295,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr | ... | @@ -1295,7 +1295,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr |
| 1295 | zig_unreachable(); | 1295 | zig_unreachable(); |
| 1296 | } | 1296 | } |
| 1297 | codegen_build_and_link(child_gen); | 1297 | codegen_build_and_link(child_gen); |
| 1298 | return buf_ptr(&child_gen->output_file_path); | 1298 | return buf_ptr(&child_gen->bin_file_output_path); |
| 1299 | } else { | 1299 | } else { |
| 1300 | zig_unreachable(); | 1300 | zig_unreachable(); |
| 1301 | } | 1301 | } |
| ... | @@ -1365,7 +1365,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr | ... | @@ -1365,7 +1365,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr |
| 1365 | codegen_add_object(child_gen, buf_create_from_str(start_os)); | 1365 | codegen_add_object(child_gen, buf_create_from_str(start_os)); |
| 1366 | codegen_add_object(child_gen, buf_create_from_str(abi_note_o)); | 1366 | codegen_add_object(child_gen, buf_create_from_str(abi_note_o)); |
| 1367 | codegen_build_and_link(child_gen); | 1367 | codegen_build_and_link(child_gen); |
| 1368 | return buf_ptr(&child_gen->output_file_path); | 1368 | return buf_ptr(&child_gen->bin_file_output_path); |
| 1369 | } else if (strcmp(file, "libc_nonshared.a") == 0) { | 1369 | } else if (strcmp(file, "libc_nonshared.a") == 0) { |
| 1370 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node); | 1370 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node); |
| 1371 | { | 1371 | { |
| ... | @@ -1445,7 +1445,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr | ... | @@ -1445,7 +1445,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr |
| 1445 | build_libc_object(parent, deps[i].name, c_file, progress_node))); | 1445 | build_libc_object(parent, deps[i].name, c_file, progress_node))); |
| 1446 | } | 1446 | } |
| 1447 | codegen_build_and_link(child_gen); | 1447 | codegen_build_and_link(child_gen); |
| 1448 | return buf_ptr(&child_gen->output_file_path); | 1448 | return buf_ptr(&child_gen->bin_file_output_path); |
| 1449 | } else { | 1449 | } else { |
| 1450 | zig_unreachable(); | 1450 | zig_unreachable(); |
| 1451 | } | 1451 | } |
| ... | @@ -1519,7 +1519,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, | ... | @@ -1519,7 +1519,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, |
| 1519 | child_gen->want_stack_check = WantStackCheckDisabled; | 1519 | child_gen->want_stack_check = WantStackCheckDisabled; |
| 1520 | 1520 | ||
| 1521 | codegen_build_and_link(child_gen); | 1521 | codegen_build_and_link(child_gen); |
| 1522 | return &child_gen->output_file_path; | 1522 | return &child_gen->bin_file_output_path; |
| 1523 | } | 1523 | } |
| 1524 | 1524 | ||
| 1525 | static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) { | 1525 | static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) { |
| ... | @@ -1681,7 +1681,7 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -1681,7 +1681,7 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1681 | } else if (is_dyn_lib) { | 1681 | } else if (is_dyn_lib) { |
| 1682 | lj->args.append("-shared"); | 1682 | lj->args.append("-shared"); |
| 1683 | 1683 | ||
| 1684 | assert(buf_len(&g->output_file_path) != 0); | 1684 | assert(buf_len(&g->bin_file_output_path) != 0); |
| 1685 | soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major); | 1685 | soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major); |
| 1686 | } | 1686 | } |
| 1687 | 1687 | ||
| ... | @@ -1690,7 +1690,7 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -1690,7 +1690,7 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1690 | } | 1690 | } |
| 1691 | 1691 | ||
| 1692 | lj->args.append("-o"); | 1692 | lj->args.append("-o"); |
| 1693 | lj->args.append(buf_ptr(&g->output_file_path)); | 1693 | lj->args.append(buf_ptr(&g->bin_file_output_path)); |
| 1694 | 1694 | ||
| 1695 | if (lj->link_in_crt) { | 1695 | if (lj->link_in_crt) { |
| 1696 | const char *crt1o; | 1696 | const char *crt1o; |
| ... | @@ -1872,7 +1872,7 @@ static void construct_linker_job_wasm(LinkJob *lj) { | ... | @@ -1872,7 +1872,7 @@ static void construct_linker_job_wasm(LinkJob *lj) { |
| 1872 | } | 1872 | } |
| 1873 | lj->args.append("--allow-undefined"); | 1873 | lj->args.append("--allow-undefined"); |
| 1874 | lj->args.append("-o"); | 1874 | lj->args.append("-o"); |
| 1875 | lj->args.append(buf_ptr(&g->output_file_path)); | 1875 | lj->args.append(buf_ptr(&g->bin_file_output_path)); |
| 1876 | 1876 | ||
| 1877 | // .o files | 1877 | // .o files |
| 1878 | for (size_t i = 0; i < g->link_objects.length; i += 1) { | 1878 | for (size_t i = 0; i < g->link_objects.length; i += 1) { |
| ... | @@ -2248,7 +2248,7 @@ static void construct_linker_job_coff(LinkJob *lj) { | ... | @@ -2248,7 +2248,7 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 2248 | lj->args.append("-DLL"); | 2248 | lj->args.append("-DLL"); |
| 2249 | } | 2249 | } |
| 2250 | 2250 | ||
| 2251 | lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); | 2251 | lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->bin_file_output_path)))); |
| 2252 | 2252 | ||
| 2253 | if (g->libc_link_lib != nullptr && g->libc != nullptr) { | 2253 | if (g->libc_link_lib != nullptr && g->libc != nullptr) { |
| 2254 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir))); | 2254 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir))); |
| ... | @@ -2501,7 +2501,7 @@ static void construct_linker_job_macho(LinkJob *lj) { | ... | @@ -2501,7 +2501,7 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 2501 | //lj->args.append("-install_name"); | 2501 | //lj->args.append("-install_name"); |
| 2502 | //lj->args.append(buf_ptr(dylib_install_name)); | 2502 | //lj->args.append(buf_ptr(dylib_install_name)); |
| 2503 | 2503 | ||
| 2504 | assert(buf_len(&g->output_file_path) != 0); | 2504 | assert(buf_len(&g->bin_file_output_path) != 0); |
| 2505 | } | 2505 | } |
| 2506 | 2506 | ||
| 2507 | lj->args.append("-arch"); | 2507 | lj->args.append("-arch"); |
| ... | @@ -2532,14 +2532,14 @@ static void construct_linker_job_macho(LinkJob *lj) { | ... | @@ -2532,14 +2532,14 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 2532 | } | 2532 | } |
| 2533 | 2533 | ||
| 2534 | lj->args.append("-o"); | 2534 | lj->args.append("-o"); |
| 2535 | lj->args.append(buf_ptr(&g->output_file_path)); | 2535 | lj->args.append(buf_ptr(&g->bin_file_output_path)); |
| 2536 | 2536 | ||
| 2537 | for (size_t i = 0; i < g->rpath_list.length; i += 1) { | 2537 | for (size_t i = 0; i < g->rpath_list.length; i += 1) { |
| 2538 | Buf *rpath = g->rpath_list.at(i); | 2538 | Buf *rpath = g->rpath_list.at(i); |
| 2539 | add_rpath(lj, rpath); | 2539 | add_rpath(lj, rpath); |
| 2540 | } | 2540 | } |
| 2541 | if (is_dyn_lib) { | 2541 | if (is_dyn_lib) { |
| 2542 | add_rpath(lj, &g->output_file_path); | 2542 | add_rpath(lj, &g->bin_file_output_path); |
| 2543 | } | 2543 | } |
| 2544 | 2544 | ||
| 2545 | if (is_dyn_lib) { | 2545 | if (is_dyn_lib) { |
| ... | @@ -2659,14 +2659,14 @@ void codegen_link(CodeGen *g) { | ... | @@ -2659,14 +2659,14 @@ void codegen_link(CodeGen *g) { |
| 2659 | progress_name, strlen(progress_name), 0)); | 2659 | progress_name, strlen(progress_name), 0)); |
| 2660 | } | 2660 | } |
| 2661 | if (g->verbose_link) { | 2661 | if (g->verbose_link) { |
| 2662 | fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path)); | 2662 | fprintf(stderr, "ar rcs %s", buf_ptr(&g->bin_file_output_path)); |
| 2663 | for (size_t i = 0; i < file_names.length; i += 1) { | 2663 | for (size_t i = 0; i < file_names.length; i += 1) { |
| 2664 | fprintf(stderr, " %s", file_names.at(i)); | 2664 | fprintf(stderr, " %s", file_names.at(i)); |
| 2665 | } | 2665 | } |
| 2666 | fprintf(stderr, "\n"); | 2666 | fprintf(stderr, "\n"); |
| 2667 | } | 2667 | } |
| 2668 | if (ZigLLVMWriteArchive(buf_ptr(&g->output_file_path), file_names.items, file_names.length, os_type)) { | 2668 | if (ZigLLVMWriteArchive(buf_ptr(&g->bin_file_output_path), file_names.items, file_names.length, os_type)) { |
| 2669 | fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->output_file_path)); | 2669 | fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->bin_file_output_path)); |
| 2670 | exit(1); | 2670 | exit(1); |
| 2671 | } | 2671 | } |
| 2672 | return; | 2672 | return; |
src/main.cpp+47-31| ... | @@ -62,17 +62,21 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { | ... | @@ -62,17 +62,21 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { |
| 62 | " -fno-stack-check disable stack probing in safe builds\n" | 62 | " -fno-stack-check disable stack probing in safe builds\n" |
| 63 | " -fsanitize-c enable C undefined behavior detection in unsafe builds\n" | 63 | " -fsanitize-c enable C undefined behavior detection in unsafe builds\n" |
| 64 | " -fno-sanitize-c disable C undefined behavior detection in safe builds\n" | 64 | " -fno-sanitize-c disable C undefined behavior detection in safe builds\n" |
| 65 | " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" | 65 | " --emit [asm|bin|llvm-ir] (deprecated) emit a specific file format as compilation output\n" |
| 66 | " -fPIC enable Position Independent Code\n" | 66 | " -fPIC enable Position Independent Code\n" |
| 67 | " -fno-PIC disable Position Independent Code\n" | 67 | " -fno-PIC disable Position Independent Code\n" |
| 68 | " -ftime-report print timing diagnostics\n" | 68 | " -ftime-report print timing diagnostics\n" |
| 69 | " -fstack-report print stack size diagnostics\n" | 69 | " -fstack-report print stack size diagnostics\n" |
| 70 | #ifdef ZIG_ENABLE_MEM_PROFILE | ||
| 71 | " -fmem-report print memory usage diagnostics\n" | 70 | " -fmem-report print memory usage diagnostics\n" |
| 72 | #endif | ||
| 73 | " -fdump-analysis write analysis.json file with type information\n" | 71 | " -fdump-analysis write analysis.json file with type information\n" |
| 74 | " -femit-docs create a docs/ dir with html documentation\n" | 72 | " -femit-docs create a docs/ dir with html documentation\n" |
| 75 | " -fno-emit-bin skip emitting machine code\n" | 73 | " -fno-emit-docs do not produce docs/ dir with html documentation\n" |
| 74 | " -femit-bin (default) output machine code\n" | ||
| 75 | " -fno-emit-bin do not output machine code\n" | ||
| 76 | " -femit-asm output .s (assembly code)\n" | ||
| 77 | " -fno-emit-asm (default) do not output .s (assembly code)\n" | ||
| 78 | " -femit-llvm-ir produce a .ll file with LLVM IR\n" | ||
| 79 | " -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n" | ||
| 76 | " --libc [file] Provide a file which specifies libc paths\n" | 80 | " --libc [file] Provide a file which specifies libc paths\n" |
| 77 | " --name [name] override output name\n" | 81 | " --name [name] override output name\n" |
| 78 | " --output-dir [dir] override output directory (defaults to cwd)\n" | 82 | " --output-dir [dir] override output directory (defaults to cwd)\n" |
| ... | @@ -376,7 +380,6 @@ static int main0(int argc, char **argv) { | ... | @@ -376,7 +380,6 @@ static int main0(int argc, char **argv) { |
| 376 | } | 380 | } |
| 377 | 381 | ||
| 378 | Cmd cmd = CmdNone; | 382 | Cmd cmd = CmdNone; |
| 379 | EmitFileType emit_file_type = EmitFileTypeBinary; | ||
| 380 | const char *in_file = nullptr; | 383 | const char *in_file = nullptr; |
| 381 | Buf *output_dir = nullptr; | 384 | Buf *output_dir = nullptr; |
| 382 | bool strip = false; | 385 | bool strip = false; |
| ... | @@ -424,7 +427,9 @@ static int main0(int argc, char **argv) { | ... | @@ -424,7 +427,9 @@ static int main0(int argc, char **argv) { |
| 424 | bool stack_report = false; | 427 | bool stack_report = false; |
| 425 | bool enable_dump_analysis = false; | 428 | bool enable_dump_analysis = false; |
| 426 | bool enable_doc_generation = false; | 429 | bool enable_doc_generation = false; |
| 427 | bool disable_bin_generation = false; | 430 | bool emit_bin = true; |
| 431 | bool emit_asm = false; | ||
| 432 | bool emit_llvm_ir = false; | ||
| 428 | const char *cache_dir = nullptr; | 433 | const char *cache_dir = nullptr; |
| 429 | CliPkg *cur_pkg = heap::c_allocator.create<CliPkg>(); | 434 | CliPkg *cur_pkg = heap::c_allocator.create<CliPkg>(); |
| 430 | BuildMode build_mode = BuildModeDebug; | 435 | BuildMode build_mode = BuildModeDebug; |
| ... | @@ -552,7 +557,7 @@ static int main0(int argc, char **argv) { | ... | @@ -552,7 +557,7 @@ static int main0(int argc, char **argv) { |
| 552 | } | 557 | } |
| 553 | 558 | ||
| 554 | Termination term; | 559 | Termination term; |
| 555 | args.items[0] = buf_ptr(&g->output_file_path); | 560 | args.items[0] = buf_ptr(&g->bin_file_output_path); |
| 556 | os_spawn_process(args, &term); | 561 | os_spawn_process(args, &term); |
| 557 | if (term.how != TerminationIdClean || term.code != 0) { | 562 | if (term.how != TerminationIdClean || term.code != 0) { |
| 558 | fprintf(stderr, "\nBuild failed. The following command failed:\n"); | 563 | fprintf(stderr, "\nBuild failed. The following command failed:\n"); |
| ... | @@ -631,8 +636,6 @@ static int main0(int argc, char **argv) { | ... | @@ -631,8 +636,6 @@ static int main0(int argc, char **argv) { |
| 631 | enable_dump_analysis = true; | 636 | enable_dump_analysis = true; |
| 632 | } else if (strcmp(arg, "-femit-docs") == 0) { | 637 | } else if (strcmp(arg, "-femit-docs") == 0) { |
| 633 | enable_doc_generation = true; | 638 | enable_doc_generation = true; |
| 634 | } else if (strcmp(arg, "-fno-emit-bin") == 0) { | ||
| 635 | disable_bin_generation = true; | ||
| 636 | } else if (strcmp(arg, "--enable-valgrind") == 0) { | 639 | } else if (strcmp(arg, "--enable-valgrind") == 0) { |
| 637 | valgrind_support = ValgrindSupportEnabled; | 640 | valgrind_support = ValgrindSupportEnabled; |
| 638 | } else if (strcmp(arg, "--disable-valgrind") == 0) { | 641 | } else if (strcmp(arg, "--disable-valgrind") == 0) { |
| ... | @@ -701,6 +704,18 @@ static int main0(int argc, char **argv) { | ... | @@ -701,6 +704,18 @@ static int main0(int argc, char **argv) { |
| 701 | function_sections = true; | 704 | function_sections = true; |
| 702 | } else if (strcmp(arg, "--test-evented-io") == 0) { | 705 | } else if (strcmp(arg, "--test-evented-io") == 0) { |
| 703 | test_evented_io = true; | 706 | test_evented_io = true; |
| 707 | } else if (strcmp(arg, "-femit-bin") == 0) { | ||
| 708 | emit_bin = true; | ||
| 709 | } else if (strcmp(arg, "-fno-emit-bin") == 0) { | ||
| 710 | emit_bin = false; | ||
| 711 | } else if (strcmp(arg, "-femit-asm") == 0) { | ||
| 712 | emit_asm = true; | ||
| 713 | } else if (strcmp(arg, "-fno-emit-asm") == 0) { | ||
| 714 | emit_asm = false; | ||
| 715 | } else if (strcmp(arg, "-femit-llvm-ir") == 0) { | ||
| 716 | emit_llvm_ir = true; | ||
| 717 | } else if (strcmp(arg, "-fno-emit-llvm-ir") == 0) { | ||
| 718 | emit_llvm_ir = false; | ||
| 704 | } else if (i + 1 >= argc) { | 719 | } else if (i + 1 >= argc) { |
| 705 | fprintf(stderr, "Expected another argument after %s\n", arg); | 720 | fprintf(stderr, "Expected another argument after %s\n", arg); |
| 706 | return print_error_usage(arg0); | 721 | return print_error_usage(arg0); |
| ... | @@ -732,11 +747,13 @@ static int main0(int argc, char **argv) { | ... | @@ -732,11 +747,13 @@ static int main0(int argc, char **argv) { |
| 732 | } | 747 | } |
| 733 | } else if (strcmp(arg, "--emit") == 0) { | 748 | } else if (strcmp(arg, "--emit") == 0) { |
| 734 | if (strcmp(argv[i], "asm") == 0) { | 749 | if (strcmp(argv[i], "asm") == 0) { |
| 735 | emit_file_type = EmitFileTypeAssembly; | 750 | emit_asm = true; |
| 751 | emit_bin = false; | ||
| 736 | } else if (strcmp(argv[i], "bin") == 0) { | 752 | } else if (strcmp(argv[i], "bin") == 0) { |
| 737 | emit_file_type = EmitFileTypeBinary; | 753 | emit_bin = true; |
| 738 | } else if (strcmp(argv[i], "llvm-ir") == 0) { | 754 | } else if (strcmp(argv[i], "llvm-ir") == 0) { |
| 739 | emit_file_type = EmitFileTypeLLVMIr; | 755 | emit_llvm_ir = true; |
| 756 | emit_bin = false; | ||
| 740 | } else { | 757 | } else { |
| 741 | fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n"); | 758 | fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n"); |
| 742 | return print_error_usage(arg0); | 759 | return print_error_usage(arg0); |
| ... | @@ -1026,8 +1043,8 @@ static int main0(int argc, char **argv) { | ... | @@ -1026,8 +1043,8 @@ static int main0(int argc, char **argv) { |
| 1026 | return print_error_usage(arg0); | 1043 | return print_error_usage(arg0); |
| 1027 | } | 1044 | } |
| 1028 | 1045 | ||
| 1029 | if (emit_file_type != EmitFileTypeBinary && in_file == nullptr) { | 1046 | if ((emit_asm || emit_llvm_ir) && in_file == nullptr) { |
| 1030 | fprintf(stderr, "A root source file is required when using `--emit asm` or `--emit llvm-ir`\n"); | 1047 | fprintf(stderr, "A root source file is required when using `-femit-asm` or `-femit-llvm-ir`\n"); |
| 1031 | return print_error_usage(arg0); | 1048 | return print_error_usage(arg0); |
| 1032 | } | 1049 | } |
| 1033 | 1050 | ||
| ... | @@ -1098,8 +1115,8 @@ static int main0(int argc, char **argv) { | ... | @@ -1098,8 +1115,8 @@ static int main0(int argc, char **argv) { |
| 1098 | { | 1115 | { |
| 1099 | fprintf(stderr, "Expected source file argument.\n"); | 1116 | fprintf(stderr, "Expected source file argument.\n"); |
| 1100 | return print_error_usage(arg0); | 1117 | return print_error_usage(arg0); |
| 1101 | } else if (cmd == CmdRun && emit_file_type != EmitFileTypeBinary) { | 1118 | } else if (cmd == CmdRun && !emit_bin) { |
| 1102 | fprintf(stderr, "Cannot run non-executable file.\n"); | 1119 | fprintf(stderr, "Cannot run without emitting a binary file.\n"); |
| 1103 | return print_error_usage(arg0); | 1120 | return print_error_usage(arg0); |
| 1104 | } | 1121 | } |
| 1105 | 1122 | ||
| ... | @@ -1176,7 +1193,10 @@ static int main0(int argc, char **argv) { | ... | @@ -1176,7 +1193,10 @@ static int main0(int argc, char **argv) { |
| 1176 | g->enable_stack_report = stack_report; | 1193 | g->enable_stack_report = stack_report; |
| 1177 | g->enable_dump_analysis = enable_dump_analysis; | 1194 | g->enable_dump_analysis = enable_dump_analysis; |
| 1178 | g->enable_doc_generation = enable_doc_generation; | 1195 | g->enable_doc_generation = enable_doc_generation; |
| 1179 | g->disable_bin_generation = disable_bin_generation; | 1196 | g->emit_bin = emit_bin; |
| 1197 | g->emit_asm = emit_asm; | ||
| 1198 | g->emit_llvm_ir = emit_llvm_ir; | ||
| 1199 | |||
| 1180 | codegen_set_out_name(g, buf_out_name); | 1200 | codegen_set_out_name(g, buf_out_name); |
| 1181 | codegen_set_lib_version(g, ver_major, ver_minor, ver_patch); | 1201 | codegen_set_lib_version(g, ver_major, ver_minor, ver_patch); |
| 1182 | g->want_single_threaded = want_single_threaded; | 1202 | g->want_single_threaded = want_single_threaded; |
| ... | @@ -1262,8 +1282,6 @@ static int main0(int argc, char **argv) { | ... | @@ -1262,8 +1282,6 @@ static int main0(int argc, char **argv) { |
| 1262 | 1282 | ||
| 1263 | 1283 | ||
| 1264 | if (cmd == CmdBuild || cmd == CmdRun) { | 1284 | if (cmd == CmdBuild || cmd == CmdRun) { |
| 1265 | codegen_set_emit_file_type(g, emit_file_type); | ||
| 1266 | |||
| 1267 | g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun); | 1285 | g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun); |
| 1268 | codegen_build_and_link(g); | 1286 | codegen_build_and_link(g); |
| 1269 | if (root_progress_node != nullptr) { | 1287 | if (root_progress_node != nullptr) { |
| ... | @@ -1281,7 +1299,7 @@ static int main0(int argc, char **argv) { | ... | @@ -1281,7 +1299,7 @@ static int main0(int argc, char **argv) { |
| 1281 | mem::print_report(); | 1299 | mem::print_report(); |
| 1282 | #endif | 1300 | #endif |
| 1283 | 1301 | ||
| 1284 | const char *exec_path = buf_ptr(&g->output_file_path); | 1302 | const char *exec_path = buf_ptr(&g->bin_file_output_path); |
| 1285 | ZigList<const char*> args = {0}; | 1303 | ZigList<const char*> args = {0}; |
| 1286 | 1304 | ||
| 1287 | args.append(exec_path); | 1305 | args.append(exec_path); |
| ... | @@ -1301,21 +1319,21 @@ static int main0(int argc, char **argv) { | ... | @@ -1301,21 +1319,21 @@ static int main0(int argc, char **argv) { |
| 1301 | } else if (cmd == CmdBuild) { | 1319 | } else if (cmd == CmdBuild) { |
| 1302 | if (g->enable_cache) { | 1320 | if (g->enable_cache) { |
| 1303 | #if defined(ZIG_OS_WINDOWS) | 1321 | #if defined(ZIG_OS_WINDOWS) |
| 1304 | buf_replace(&g->output_file_path, '/', '\\'); | 1322 | buf_replace(&g->bin_file_output_path, '/', '\\'); |
| 1305 | #endif | 1323 | #endif |
| 1306 | if (final_output_dir_step != nullptr) { | 1324 | if (final_output_dir_step != nullptr) { |
| 1307 | Buf *dest_basename = buf_alloc(); | 1325 | Buf *dest_basename = buf_alloc(); |
| 1308 | os_path_split(&g->output_file_path, nullptr, dest_basename); | 1326 | os_path_split(&g->bin_file_output_path, nullptr, dest_basename); |
| 1309 | Buf *dest_path = buf_alloc(); | 1327 | Buf *dest_path = buf_alloc(); |
| 1310 | os_path_join(final_output_dir_step, dest_basename, dest_path); | 1328 | os_path_join(final_output_dir_step, dest_basename, dest_path); |
| 1311 | 1329 | ||
| 1312 | if ((err = os_update_file(&g->output_file_path, dest_path))) { | 1330 | if ((err = os_update_file(&g->bin_file_output_path, dest_path))) { |
| 1313 | fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->output_file_path), | 1331 | fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->bin_file_output_path), |
| 1314 | buf_ptr(dest_path), err_str(err)); | 1332 | buf_ptr(dest_path), err_str(err)); |
| 1315 | return main_exit(root_progress_node, EXIT_FAILURE); | 1333 | return main_exit(root_progress_node, EXIT_FAILURE); |
| 1316 | } | 1334 | } |
| 1317 | } else { | 1335 | } else { |
| 1318 | if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0) | 1336 | if (printf("%s\n", buf_ptr(&g->bin_file_output_path)) < 0) |
| 1319 | return main_exit(root_progress_node, EXIT_FAILURE); | 1337 | return main_exit(root_progress_node, EXIT_FAILURE); |
| 1320 | } | 1338 | } |
| 1321 | } | 1339 | } |
| ... | @@ -1330,8 +1348,6 @@ static int main0(int argc, char **argv) { | ... | @@ -1330,8 +1348,6 @@ static int main0(int argc, char **argv) { |
| 1330 | codegen_print_timing_report(g, stderr); | 1348 | codegen_print_timing_report(g, stderr); |
| 1331 | return main_exit(root_progress_node, EXIT_SUCCESS); | 1349 | return main_exit(root_progress_node, EXIT_SUCCESS); |
| 1332 | } else if (cmd == CmdTest) { | 1350 | } else if (cmd == CmdTest) { |
| 1333 | codegen_set_emit_file_type(g, emit_file_type); | ||
| 1334 | |||
| 1335 | ZigTarget native; | 1351 | ZigTarget native; |
| 1336 | get_native_target(&native); | 1352 | get_native_target(&native); |
| 1337 | 1353 | ||
| ... | @@ -1350,17 +1366,17 @@ static int main0(int argc, char **argv) { | ... | @@ -1350,17 +1366,17 @@ static int main0(int argc, char **argv) { |
| 1350 | zig_print_stack_report(g, stdout); | 1366 | zig_print_stack_report(g, stdout); |
| 1351 | } | 1367 | } |
| 1352 | 1368 | ||
| 1353 | if (g->disable_bin_generation) { | 1369 | if (!g->emit_bin) { |
| 1354 | fprintf(stderr, "Semantic analysis complete. No binary produced due to -fno-emit-bin.\n"); | 1370 | fprintf(stderr, "Semantic analysis complete. No binary produced due to -fno-emit-bin.\n"); |
| 1355 | return main_exit(root_progress_node, EXIT_SUCCESS); | 1371 | return main_exit(root_progress_node, EXIT_SUCCESS); |
| 1356 | } | 1372 | } |
| 1357 | 1373 | ||
| 1358 | Buf *test_exe_path_unresolved = &g->output_file_path; | 1374 | Buf *test_exe_path_unresolved = &g->bin_file_output_path; |
| 1359 | Buf *test_exe_path = buf_alloc(); | 1375 | Buf *test_exe_path = buf_alloc(); |
| 1360 | *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1); | 1376 | *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1); |
| 1361 | 1377 | ||
| 1362 | if (emit_file_type != EmitFileTypeBinary) { | 1378 | if (!g->emit_bin) { |
| 1363 | fprintf(stderr, "Created %s but skipping execution because it is non executable.\n", | 1379 | fprintf(stderr, "Created %s but skipping execution because no binary generated.\n", |
| 1364 | buf_ptr(test_exe_path)); | 1380 | buf_ptr(test_exe_path)); |
| 1365 | return main_exit(root_progress_node, EXIT_SUCCESS); | 1381 | return main_exit(root_progress_node, EXIT_SUCCESS); |
| 1366 | } | 1382 | } |
src/zig_llvm.cpp+59-42| ... | @@ -161,17 +161,32 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) { | ... | @@ -161,17 +161,32 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) { |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, | 163 | bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, |
| 164 | const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, | 164 | char **error_message, bool is_debug, |
| 165 | bool is_small, bool time_report) | 165 | bool is_small, bool time_report, |
| 166 | const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename) | ||
| 166 | { | 167 | { |
| 167 | TimePassesIsEnabled = time_report; | 168 | TimePassesIsEnabled = time_report; |
| 168 | 169 | ||
| 169 | std::error_code EC; | 170 | raw_fd_ostream *dest_asm = nullptr; |
| 170 | raw_fd_ostream dest(filename, EC, sys::fs::F_None); | 171 | raw_fd_ostream *dest_bin = nullptr; |
| 171 | if (EC) { | 172 | |
| 172 | *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); | 173 | if (asm_filename) { |
| 173 | return true; | 174 | std::error_code EC; |
| 175 | dest_asm = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None); | ||
| 176 | if (EC) { | ||
| 177 | *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); | ||
| 178 | return true; | ||
| 179 | } | ||
| 174 | } | 180 | } |
| 181 | if (bin_filename) { | ||
| 182 | std::error_code EC; | ||
| 183 | dest_bin = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None); | ||
| 184 | if (EC) { | ||
| 185 | *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); | ||
| 186 | return true; | ||
| 187 | } | ||
| 188 | } | ||
| 189 | |||
| 175 | TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref); | 190 | TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref); |
| 176 | target_machine->setO0WantsFastISel(true); | 191 | target_machine->setO0WantsFastISel(true); |
| 177 | 192 | ||
| ... | @@ -222,49 +237,51 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM | ... | @@ -222,49 +237,51 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 222 | } | 237 | } |
| 223 | PMBuilder->populateFunctionPassManager(FPM); | 238 | PMBuilder->populateFunctionPassManager(FPM); |
| 224 | 239 | ||
| 225 | // Set up the per-module pass manager. | 240 | { |
| 226 | legacy::PassManager MPM; | 241 | // Set up the per-module pass manager. |
| 227 | MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); | 242 | legacy::PassManager MPM; |
| 228 | PMBuilder->populateModulePassManager(MPM); | 243 | MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); |
| 229 | 244 | PMBuilder->populateModulePassManager(MPM); | |
| 230 | // Set output pass. | 245 | |
| 231 | TargetMachine::CodeGenFileType ft; | 246 | // Set output passes. |
| 232 | if (output_type != ZigLLVM_EmitLLVMIr) { | 247 | if (dest_bin) { |
| 233 | switch (output_type) { | 248 | if (target_machine->addPassesToEmitFile(MPM, *dest_bin, nullptr, TargetMachine::CGFT_ObjectFile)) { |
| 234 | case ZigLLVM_EmitAssembly: | 249 | *error_message = strdup("TargetMachine can't emit an object file"); |
| 235 | ft = TargetMachine::CGFT_AssemblyFile; | 250 | return true; |
| 236 | break; | 251 | } |
| 237 | case ZigLLVM_EmitBinary: | ||
| 238 | ft = TargetMachine::CGFT_ObjectFile; | ||
| 239 | break; | ||
| 240 | default: | ||
| 241 | abort(); | ||
| 242 | } | 252 | } |
| 243 | 253 | if (dest_asm) { | |
| 244 | if (target_machine->addPassesToEmitFile(MPM, dest, nullptr, ft)) { | 254 | if (target_machine->addPassesToEmitFile(MPM, *dest_asm, nullptr, TargetMachine::CGFT_AssemblyFile)) { |
| 245 | *error_message = strdup("TargetMachine can't emit a file of this type"); | 255 | *error_message = strdup("TargetMachine can't emit an assembly file"); |
| 246 | return true; | 256 | return true; |
| 257 | } | ||
| 247 | } | 258 | } |
| 248 | } | ||
| 249 | 259 | ||
| 250 | // run per function optimization passes | 260 | // run per function optimization passes |
| 251 | FPM.doInitialization(); | 261 | FPM.doInitialization(); |
| 252 | for (Function &F : *module) | 262 | for (Function &F : *module) |
| 253 | if (!F.isDeclaration()) | 263 | if (!F.isDeclaration()) |
| 254 | FPM.run(F); | 264 | FPM.run(F); |
| 255 | FPM.doFinalization(); | 265 | FPM.doFinalization(); |
| 256 | 266 | ||
| 257 | MPM.run(*module); | 267 | MPM.run(*module); |
| 258 | 268 | ||
| 259 | if (output_type == ZigLLVM_EmitLLVMIr) { | 269 | if (llvm_ir_filename) { |
| 260 | if (LLVMPrintModuleToFile(module_ref, filename, error_message)) { | 270 | if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) { |
| 261 | return true; | 271 | return true; |
| 272 | } | ||
| 262 | } | 273 | } |
| 263 | } | ||
| 264 | 274 | ||
| 265 | if (time_report) { | 275 | if (time_report) { |
| 266 | TimerGroup::printAll(errs()); | 276 | TimerGroup::printAll(errs()); |
| 277 | } | ||
| 278 | |||
| 279 | // MPM goes out of scope and writes to the out streams | ||
| 267 | } | 280 | } |
| 281 | |||
| 282 | delete dest_asm; | ||
| 283 | delete dest_bin; | ||
| 284 | |||
| 268 | return false; | 285 | return false; |
| 269 | } | 286 | } |
| 270 | 287 |
src/zig_llvm.h+3-10| ... | @@ -46,17 +46,10 @@ ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R); | ... | @@ -46,17 +46,10 @@ ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R); |
| 46 | ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void); | 46 | ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void); |
| 47 | ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void); | 47 | ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void); |
| 48 | 48 | ||
| 49 | // We use a custom enum here since LLVM does not expose LLVMIr as an emit | ||
| 50 | // output through the same mechanism as assembly/binary. | ||
| 51 | enum ZigLLVM_EmitOutputType { | ||
| 52 | ZigLLVM_EmitAssembly, | ||
| 53 | ZigLLVM_EmitBinary, | ||
| 54 | ZigLLVM_EmitLLVMIr, | ||
| 55 | }; | ||
| 56 | |||
| 57 | ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, | 49 | ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, |
| 58 | const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, | 50 | char **error_message, bool is_debug, |
| 59 | bool is_small, bool time_report); | 51 | bool is_small, bool time_report, |
| 52 | const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename); | ||
| 60 | 53 | ||
| 61 | ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, | 54 | ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, |
| 62 | const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, | 55 | const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, |