diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-07-22 16:37:38 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-07-22 19:51:32 -0700 |
| commit | 7c25390c957273ff43927608a45e257c4ed73549 (patch) | |
| tree | 411809c36b20d2575816bcf726330413c3624398 /src/Compilation.zig | |
| parent | a5fb28070f37c2cad92ac8805bcc704e872fc538 (diff) | |
| download | zig-7c25390c957273ff43927608a45e257c4ed73549.tar.gz zig-7c25390c957273ff43927608a45e257c4ed73549.zip | |
support -fcompiler-rt in conjunction with build-obj
When using `build-exe` or `build-lib -dynamic`, `-fcompiler-rt` means building
compiler-rt into a static library and then linking it into the executable.
When using `build-lib`, `-fcompiler-rt` means building compiler-rt into an
object file and then adding it into the static archive.
Before this commit, when using `build-obj`, zig would build compiler-rt
into an object file, and then on ELF, use `lld -r` to merge it into the
main object file. Other linker backends of LLD do not support `-r` to
merge objects, so this failed with error messages for those targets.
Now, `-fcompiler-rt` when used with `build-obj` acts as if the user puts
`_ = @import("compiler_rt");` inside their root source file. The symbols
of compiler-rt go into the same compilation unit as the root source file.
This is hooked up for stage1 only for now. Once stage2 is capable of
building compiler-rt, it should be hooked up there as well.
Diffstat (limited to 'src/Compilation.zig')
| -rw-r--r-- | src/Compilation.zig | 32 |
1 files changed, 13 insertions, 19 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index fb35f5153f..8fb86916e6 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -826,6 +826,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { const ofmt = options.object_format orelse options.target.getObjectFormat(); const use_stage1 = options.use_stage1 orelse blk: { + // Even though we may have no Zig code to compile (depending on `options.root_pkg`), + // we may need to use stage1 for building compiler-rt and other dependencies. + if (build_options.omit_stage2) break :blk true; if (options.use_llvm) |use_llvm| { @@ -833,9 +836,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { break :blk false; } } - // If we have no zig code to compile, no need for stage1 backend. - if (options.root_pkg == null) - break :blk false; break :blk build_options.is_stage1; }; @@ -878,9 +878,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { if (options.emit_llvm_ir != null or options.emit_llvm_bc != null) { return error.EmittingLlvmModuleRequiresUsingLlvmBackend; } - if (use_stage1) { - return error.@"stage1 only supports LLVM backend"; - } } const tsan = options.want_tsan orelse false; @@ -1542,24 +1539,19 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { } // The `use_stage1` condition is here only because stage2 cannot yet build compiler-rt. - // Once it is capable this condition should be removed. + // Once it is capable this condition should be removed. When removing this condition, + // also test the use case of `build-obj -fcompiler-rt` with the self-hosted compiler + // and make sure the compiler-rt symbols are emitted. Currently this is hooked up for + // stage1 but not stage2. if (comp.bin_file.options.use_stage1) { if (comp.bin_file.options.include_compiler_rt) { if (is_exe_or_dyn_lib) { try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} }); - } else { + } else if (options.output_mode != .Obj) { + // If build-obj with -fcompiler-rt is requested, that is handled specially + // elsewhere. In this case we are making a static library, so we ask + // for a compiler-rt object to put in it. try comp.work_queue.writeItem(.{ .compiler_rt_obj = {} }); - if (comp.bin_file.options.object_format != .elf and - comp.bin_file.options.output_mode == .Obj) - { - // For ELF we can rely on using -r to link multiple objects together into one, - // but to truly support `build-obj -fcompiler-rt` will require virtually - // injecting `_ = @import("compiler_rt.zig")` into the root source file of - // the compilation. - fatal("Embedding compiler-rt into {s} objects is not yet implemented.", .{ - @tagName(comp.bin_file.options.object_format), - }); - } } } if (needs_c_symbols) { @@ -4002,6 +3994,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node man.hash.add(target.os.getVersionRange()); man.hash.add(comp.bin_file.options.dll_export_fns); man.hash.add(comp.bin_file.options.function_sections); + man.hash.add(comp.bin_file.options.include_compiler_rt); man.hash.add(comp.bin_file.options.is_test); man.hash.add(comp.bin_file.options.emit != null); man.hash.add(mod.emit_h != null); @@ -4182,6 +4175,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node .valgrind_enabled = comp.bin_file.options.valgrind, .tsan_enabled = comp.bin_file.options.tsan, .function_sections = comp.bin_file.options.function_sections, + .include_compiler_rt = comp.bin_file.options.include_compiler_rt, .enable_stack_probing = comp.bin_file.options.stack_check, .red_zone = comp.bin_file.options.red_zone, .enable_time_report = comp.time_report, |
