| author | |
| committer | |
| log | 2ef68631cb7045c277b348777b1a064845b95cd8 |
| tree | 00e1dca9b53a828a9926cf5b6d2a227dc939375a |
| parent | 333b12a8f9beb5864fa05ce413c5b935e925ec14 |
* move stage2.cpp code into zig0.cpp for simplicity
* add -ftime-report and some more CLI options to stage2
* stage2 compites the llvm cpu features string
* classifyFileExt understands more file extensions
* correction to generateBuiltinZigSource using the wrong allocator
(thanks dbandstra!)
* stage2 is now able to build hello.zig into hello.o using stage1 as a
library however it fails linking due to missing compiler-rt
* remove dead code
* simplify zig0 builtin.zig source
* fix not resolving builtin.zig source path causing duplicate imports
* fix stage1.h not being valid C code
* fix stage2.h not being valid C code17 files changed, 750 insertions(+), 678 deletions(-)
BRANCH_TODO+5-3| ... | @@ -1,3 +1,6 @@ | ... | @@ -1,3 +1,6 @@ |
| 1 | * build & link against compiler-rt | ||
| 2 | * build & link against freestanding libc | ||
| 3 | * Cache integration for stage1 zig code compilation | ||
| 1 | * `zig test` | 4 | * `zig test` |
| 2 | * `zig build` | 5 | * `zig build` |
| 3 | * `-ftime-report` | 6 | * `-ftime-report` |
| ... | @@ -14,10 +17,7 @@ | ... | @@ -14,10 +17,7 @@ |
| 14 | - using it as a preprocessor (-E) | 17 | - using it as a preprocessor (-E) |
| 15 | - try building some software | 18 | - try building some software |
| 16 | * support rpaths in ELF linker code | 19 | * support rpaths in ELF linker code |
| 17 | * build & link against compiler-rt | ||
| 18 | - stage1 C++ code integration | ||
| 19 | * repair @cImport | 20 | * repair @cImport |
| 20 | * build & link against freestanding libc | ||
| 21 | * add CLI support for a way to pass extra flags to c source files | 21 | * add CLI support for a way to pass extra flags to c source files |
| 22 | * capture lld stdout/stderr better | 22 | * capture lld stdout/stderr better |
| 23 | * musl | 23 | * musl |
| ... | @@ -35,10 +35,12 @@ | ... | @@ -35,10 +35,12 @@ |
| 35 | * implement emit-h in stage2 | 35 | * implement emit-h in stage2 |
| 36 | * implement -fno-emit-bin | 36 | * implement -fno-emit-bin |
| 37 | * audit the base cache hash | 37 | * audit the base cache hash |
| 38 | * --main-pkg-path | ||
| 38 | * audit the CLI options for stage2 | 39 | * audit the CLI options for stage2 |
| 39 | * `zig init-lib` | 40 | * `zig init-lib` |
| 40 | * `zig init-exe` | 41 | * `zig init-exe` |
| 41 | * `zig run` | 42 | * `zig run` |
| 43 | * restore error messages for stage2_add_link_lib | ||
| 42 | 44 | ||
| 43 | * implement serialization/deserialization of incremental compilation metadata | 45 | * implement serialization/deserialization of incremental compilation metadata |
| 44 | * incremental compilation - implement detection of which source files changed | 46 | * incremental compilation - implement detection of which source files changed |
CMakeLists.txt-1| ... | @@ -258,7 +258,6 @@ find_package(Threads) | ... | @@ -258,7 +258,6 @@ find_package(Threads) |
| 258 | # This is our shim which will be replaced by stage1.zig. | 258 | # This is our shim which will be replaced by stage1.zig. |
| 259 | set(ZIG0_SOURCES | 259 | set(ZIG0_SOURCES |
| 260 | "${CMAKE_SOURCE_DIR}/src/zig0.cpp" | 260 | "${CMAKE_SOURCE_DIR}/src/zig0.cpp" |
| 261 | "${CMAKE_SOURCE_DIR}/src/stage2.cpp" | ||
| 262 | ) | 261 | ) |
| 263 | 262 | ||
| 264 | set(ZIG_SOURCES | 263 | set(ZIG_SOURCES |
src-self-hosted/Compilation.zig+222-25| ... | @@ -19,6 +19,7 @@ const libunwind = @import("libunwind.zig"); | ... | @@ -19,6 +19,7 @@ const libunwind = @import("libunwind.zig"); |
| 19 | const fatal = @import("main.zig").fatal; | 19 | const fatal = @import("main.zig").fatal; |
| 20 | const Module = @import("Module.zig"); | 20 | const Module = @import("Module.zig"); |
| 21 | const Cache = @import("Cache.zig"); | 21 | const Cache = @import("Cache.zig"); |
| 22 | const stage1 = @import("stage1.zig"); | ||
| 22 | 23 | ||
| 23 | /// General-purpose allocator. Used for both temporary and long-term storage. | 24 | /// General-purpose allocator. Used for both temporary and long-term storage. |
| 24 | gpa: *Allocator, | 25 | gpa: *Allocator, |
| ... | @@ -26,6 +27,7 @@ gpa: *Allocator, | ... | @@ -26,6 +27,7 @@ gpa: *Allocator, |
| 26 | arena_state: std.heap.ArenaAllocator.State, | 27 | arena_state: std.heap.ArenaAllocator.State, |
| 27 | bin_file: *link.File, | 28 | bin_file: *link.File, |
| 28 | c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{}, | 29 | c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{}, |
| 30 | stage1_module: ?*stage1.Module, | ||
| 29 | 31 | ||
| 30 | link_error_flags: link.File.ErrorFlags = .{}, | 32 | link_error_flags: link.File.ErrorFlags = .{}, |
| 31 | 33 | ||
| ... | @@ -122,6 +124,8 @@ const Job = union(enum) { | ... | @@ -122,6 +124,8 @@ const Job = union(enum) { |
| 122 | 124 | ||
| 123 | /// Generate builtin.zig source code and write it into the correct place. | 125 | /// Generate builtin.zig source code and write it into the correct place. |
| 124 | generate_builtin_zig: void, | 126 | generate_builtin_zig: void, |
| 127 | /// Use stage1 C++ code to compile zig code into an object file. | ||
| 128 | stage1_module: void, | ||
| 125 | }; | 129 | }; |
| 126 | 130 | ||
| 127 | pub const CObject = struct { | 131 | pub const CObject = struct { |
| ... | @@ -274,6 +278,7 @@ pub const InitOptions = struct { | ... | @@ -274,6 +278,7 @@ pub const InitOptions = struct { |
| 274 | strip: bool = false, | 278 | strip: bool = false, |
| 275 | single_threaded: bool = false, | 279 | single_threaded: bool = false, |
| 276 | is_native_os: bool, | 280 | is_native_os: bool, |
| 281 | time_report: bool = false, | ||
| 277 | link_eh_frame_hdr: bool = false, | 282 | link_eh_frame_hdr: bool = false, |
| 278 | linker_script: ?[]const u8 = null, | 283 | linker_script: ?[]const u8 = null, |
| 279 | version_script: ?[]const u8 = null, | 284 | version_script: ?[]const u8 = null, |
| ... | @@ -288,12 +293,20 @@ pub const InitOptions = struct { | ... | @@ -288,12 +293,20 @@ pub const InitOptions = struct { |
| 288 | clang_passthrough_mode: bool = false, | 293 | clang_passthrough_mode: bool = false, |
| 289 | verbose_cc: bool = false, | 294 | verbose_cc: bool = false, |
| 290 | verbose_link: bool = false, | 295 | verbose_link: bool = false, |
| 296 | verbose_tokenize: bool = false, | ||
| 297 | verbose_ast: bool = false, | ||
| 298 | verbose_ir: bool = false, | ||
| 299 | verbose_llvm_ir: bool = false, | ||
| 300 | verbose_cimport: bool = false, | ||
| 301 | verbose_llvm_cpu_features: bool = false, | ||
| 291 | is_test: bool = false, | 302 | is_test: bool = false, |
| 292 | stack_size_override: ?u64 = null, | 303 | stack_size_override: ?u64 = null, |
| 293 | self_exe_path: ?[]const u8 = null, | 304 | self_exe_path: ?[]const u8 = null, |
| 294 | version: ?std.builtin.Version = null, | 305 | version: ?std.builtin.Version = null, |
| 295 | libc_installation: ?*const LibCInstallation = null, | 306 | libc_installation: ?*const LibCInstallation = null, |
| 296 | machine_code_model: std.builtin.CodeModel = .default, | 307 | machine_code_model: std.builtin.CodeModel = .default, |
| 308 | /// This is for stage1 and should be deleted upon completion of self-hosting. | ||
| 309 | color: @import("main.zig").Color = .Auto, | ||
| 297 | }; | 310 | }; |
| 298 | 311 | ||
| 299 | pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | 312 | pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| ... | @@ -332,11 +345,27 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -332,11 +345,27 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 332 | { | 345 | { |
| 333 | break :blk true; | 346 | break :blk true; |
| 334 | } | 347 | } |
| 348 | |||
| 349 | if (build_options.is_stage1) { | ||
| 350 | // If stage1 generates an object file, self-hosted linker is not | ||
| 351 | // yet sophisticated enough to handle that. | ||
| 352 | break :blk options.root_pkg != null; | ||
| 353 | } | ||
| 354 | |||
| 335 | break :blk false; | 355 | break :blk false; |
| 336 | }; | 356 | }; |
| 337 | 357 | ||
| 338 | // Make a decision on whether to use LLVM or our own backend. | 358 | // Make a decision on whether to use LLVM or our own backend. |
| 339 | const use_llvm = if (options.use_llvm) |explicit| explicit else blk: { | 359 | const use_llvm = if (options.use_llvm) |explicit| explicit else blk: { |
| 360 | // If we have no zig code to compile, no need for LLVM. | ||
| 361 | if (options.root_pkg == null) | ||
| 362 | break :blk false; | ||
| 363 | |||
| 364 | // If we are the stage1 compiler, we depend on the stage1 c++ llvm backend | ||
| 365 | // to compile zig code. | ||
| 366 | if (build_options.is_stage1) | ||
| 367 | break :blk true; | ||
| 368 | |||
| 340 | // We would want to prefer LLVM for release builds when it is available, however | 369 | // We would want to prefer LLVM for release builds when it is available, however |
| 341 | // we don't have an LLVM backend yet :) | 370 | // we don't have an LLVM backend yet :) |
| 342 | // We would also want to prefer LLVM for architectures that we don't have self-hosted support for too. | 371 | // We would also want to prefer LLVM for architectures that we don't have self-hosted support for too. |
| ... | @@ -580,6 +609,118 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -580,6 +609,118 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 580 | .ReleaseFast, .ReleaseSmall => false, | 609 | .ReleaseFast, .ReleaseSmall => false, |
| 581 | }; | 610 | }; |
| 582 | 611 | ||
| 612 | const llvm_cpu_features: ?[*:0]const u8 = if (build_options.have_llvm and use_llvm) blk: { | ||
| 613 | var buf = std.ArrayList(u8).init(arena); | ||
| 614 | for (options.target.cpu.arch.allFeaturesList()) |feature, index_usize| { | ||
| 615 | const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); | ||
| 616 | const is_enabled = options.target.cpu.features.isEnabled(index); | ||
| 617 | |||
| 618 | if (feature.llvm_name) |llvm_name| { | ||
| 619 | const plus_or_minus = "-+"[@boolToInt(is_enabled)]; | ||
| 620 | try buf.ensureCapacity(buf.items.len + 2 + llvm_name.len); | ||
| 621 | buf.appendAssumeCapacity(plus_or_minus); | ||
| 622 | buf.appendSliceAssumeCapacity(llvm_name); | ||
| 623 | buf.appendSliceAssumeCapacity(","); | ||
| 624 | } | ||
| 625 | } | ||
| 626 | assert(mem.endsWith(u8, buf.items, ",")); | ||
| 627 | buf.items[buf.items.len - 1] = 0; | ||
| 628 | buf.shrink(buf.items.len); | ||
| 629 | break :blk buf.items[0 .. buf.items.len - 1 :0].ptr; | ||
| 630 | } else null; | ||
| 631 | |||
| 632 | const stage1_module: ?*stage1.Module = if (build_options.is_stage1 and use_llvm) blk: { | ||
| 633 | // Here we use the legacy stage1 C++ compiler to compile Zig code. | ||
| 634 | const stage2_target = try arena.create(stage1.Stage2Target); | ||
| 635 | stage2_target.* = .{ | ||
| 636 | .arch = @enumToInt(options.target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch | ||
| 637 | .os = @enumToInt(options.target.os.tag), | ||
| 638 | .abi = @enumToInt(options.target.abi), | ||
| 639 | .is_native_os = options.is_native_os, | ||
| 640 | .is_native_cpu = false, // Only true when bootstrapping the compiler. | ||
| 641 | .llvm_cpu_name = if (options.target.cpu.model.llvm_name) |s| s.ptr else null, | ||
| 642 | .llvm_cpu_features = llvm_cpu_features.?, | ||
| 643 | }; | ||
| 644 | const progress = try arena.create(std.Progress); | ||
| 645 | const main_progress_node = try progress.start("", 100); | ||
| 646 | if (options.color == .Off) progress.terminal = null; | ||
| 647 | |||
| 648 | const mod = module.?; | ||
| 649 | const main_zig_file = mod.root_pkg.root_src_path; | ||
| 650 | const zig_lib_dir = options.zig_lib_directory.path.?; | ||
| 651 | const builtin_sub = &[_][]const u8{"builtin.zig"}; | ||
| 652 | const builtin_zig_path = try mod.zig_cache_artifact_directory.join(arena, builtin_sub); | ||
| 653 | |||
| 654 | const stage1_module = stage1.create( | ||
| 655 | @enumToInt(options.optimize_mode), | ||
| 656 | undefined, | ||
| 657 | 0, // TODO --main-pkg-path | ||
| 658 | main_zig_file.ptr, | ||
| 659 | main_zig_file.len, | ||
| 660 | zig_lib_dir.ptr, | ||
| 661 | zig_lib_dir.len, | ||
| 662 | stage2_target, | ||
| 663 | options.is_test, | ||
| 664 | ) orelse return error.OutOfMemory; | ||
| 665 | |||
| 666 | const output_dir = bin_directory.path orelse "."; | ||
| 667 | |||
| 668 | const stage1_pkg = try arena.create(stage1.Pkg); | ||
| 669 | stage1_pkg.* = .{ | ||
| 670 | .name_ptr = undefined, | ||
| 671 | .name_len = 0, | ||
| 672 | .path_ptr = undefined, | ||
| 673 | .path_len = 0, | ||
| 674 | .children_ptr = undefined, | ||
| 675 | .children_len = 0, | ||
| 676 | .parent = null, | ||
| 677 | }; | ||
| 678 | |||
| 679 | stage1_module.* = .{ | ||
| 680 | .root_name_ptr = root_name.ptr, | ||
| 681 | .root_name_len = root_name.len, | ||
| 682 | .output_dir_ptr = output_dir.ptr, | ||
| 683 | .output_dir_len = output_dir.len, | ||
| 684 | .builtin_zig_path_ptr = builtin_zig_path.ptr, | ||
| 685 | .builtin_zig_path_len = builtin_zig_path.len, | ||
| 686 | .test_filter_ptr = "", | ||
| 687 | .test_filter_len = 0, | ||
| 688 | .test_name_prefix_ptr = "", | ||
| 689 | .test_name_prefix_len = 0, | ||
| 690 | .userdata = @ptrToInt(comp), | ||
| 691 | .root_pkg = stage1_pkg, | ||
| 692 | .code_model = @enumToInt(options.machine_code_model), | ||
| 693 | .subsystem = stage1.TargetSubsystem.Auto, | ||
| 694 | .err_color = @enumToInt(options.color), | ||
| 695 | .pic = pic, | ||
| 696 | .link_libc = options.link_libc, | ||
| 697 | .link_libcpp = options.link_libcpp, | ||
| 698 | .strip = options.strip, | ||
| 699 | .is_single_threaded = single_threaded, | ||
| 700 | .dll_export_fns = dll_export_fns, | ||
| 701 | .link_mode_dynamic = link_mode == .Dynamic, | ||
| 702 | .valgrind_enabled = valgrind, | ||
| 703 | .function_sections = options.function_sections orelse false, | ||
| 704 | .enable_stack_probing = stack_check, | ||
| 705 | .enable_time_report = options.time_report, | ||
| 706 | .enable_stack_report = false, | ||
| 707 | .dump_analysis = false, | ||
| 708 | .enable_doc_generation = false, | ||
| 709 | .emit_bin = true, | ||
| 710 | .emit_asm = false, | ||
| 711 | .emit_llvm_ir = false, | ||
| 712 | .test_is_evented = false, | ||
| 713 | .verbose_tokenize = options.verbose_tokenize, | ||
| 714 | .verbose_ast = options.verbose_ast, | ||
| 715 | .verbose_ir = options.verbose_ir, | ||
| 716 | .verbose_llvm_ir = options.verbose_llvm_ir, | ||
| 717 | .verbose_cimport = options.verbose_cimport, | ||
| 718 | .verbose_llvm_cpu_features = options.verbose_llvm_cpu_features, | ||
| 719 | .main_progress_node = main_progress_node, | ||
| 720 | }; | ||
| 721 | break :blk stage1_module; | ||
| 722 | } else null; | ||
| 723 | |||
| 583 | const bin_file = try link.File.openPath(gpa, .{ | 724 | const bin_file = try link.File.openPath(gpa, .{ |
| 584 | .directory = bin_directory, | 725 | .directory = bin_directory, |
| 585 | .sub_path = emit_bin.basename, | 726 | .sub_path = emit_bin.basename, |
| ... | @@ -626,6 +767,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -626,6 +767,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 626 | .machine_code_model = options.machine_code_model, | 767 | .machine_code_model = options.machine_code_model, |
| 627 | .dll_export_fns = dll_export_fns, | 768 | .dll_export_fns = dll_export_fns, |
| 628 | .error_return_tracing = error_return_tracing, | 769 | .error_return_tracing = error_return_tracing, |
| 770 | .llvm_cpu_features = llvm_cpu_features, | ||
| 629 | }); | 771 | }); |
| 630 | errdefer bin_file.destroy(); | 772 | errdefer bin_file.destroy(); |
| 631 | 773 | ||
| ... | @@ -635,6 +777,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -635,6 +777,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 635 | .zig_lib_directory = options.zig_lib_directory, | 777 | .zig_lib_directory = options.zig_lib_directory, |
| 636 | .zig_cache_directory = options.zig_cache_directory, | 778 | .zig_cache_directory = options.zig_cache_directory, |
| 637 | .bin_file = bin_file, | 779 | .bin_file = bin_file, |
| 780 | .stage1_module = stage1_module, | ||
| 638 | .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa), | 781 | .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa), |
| 639 | .keep_source_files_loaded = options.keep_source_files_loaded, | 782 | .keep_source_files_loaded = options.keep_source_files_loaded, |
| 640 | .use_clang = use_clang, | 783 | .use_clang = use_clang, |
| ... | @@ -681,6 +824,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -681,6 +824,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 681 | try comp.work_queue.writeItem(.{ .libunwind = {} }); | 824 | try comp.work_queue.writeItem(.{ .libunwind = {} }); |
| 682 | } | 825 | } |
| 683 | 826 | ||
| 827 | if (comp.stage1_module) |module| { | ||
| 828 | try comp.work_queue.writeItem(.{ .stage1_module = {} }); | ||
| 829 | } | ||
| 830 | |||
| 684 | return comp; | 831 | return comp; |
| 685 | } | 832 | } |
| 686 | 833 | ||
| ... | @@ -689,6 +836,11 @@ pub fn destroy(self: *Compilation) void { | ... | @@ -689,6 +836,11 @@ pub fn destroy(self: *Compilation) void { |
| 689 | self.bin_file.destroy(); | 836 | self.bin_file.destroy(); |
| 690 | if (optional_module) |module| module.deinit(); | 837 | if (optional_module) |module| module.deinit(); |
| 691 | 838 | ||
| 839 | if (self.stage1_module) |module| { | ||
| 840 | module.main_progress_node.?.end(); | ||
| 841 | module.destroy(); | ||
| 842 | } | ||
| 843 | |||
| 692 | const gpa = self.gpa; | 844 | const gpa = self.gpa; |
| 693 | self.work_queue.deinit(); | 845 | self.work_queue.deinit(); |
| 694 | 846 | ||
| ... | @@ -997,6 +1149,10 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void { | ... | @@ -997,6 +1149,10 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void { |
| 997 | fatal("unable to update builtin.zig file: {}", .{@errorName(err)}); | 1149 | fatal("unable to update builtin.zig file: {}", .{@errorName(err)}); |
| 998 | }; | 1150 | }; |
| 999 | }, | 1151 | }, |
| 1152 | .stage1_module => { | ||
| 1153 | // This Job is only queued up if there is a zig module. | ||
| 1154 | self.stage1_module.?.build_object(); | ||
| 1155 | }, | ||
| 1000 | }; | 1156 | }; |
| 1001 | } | 1157 | } |
| 1002 | 1158 | ||
| ... | @@ -1365,7 +1521,7 @@ pub fn addCCArgs( | ... | @@ -1365,7 +1521,7 @@ pub fn addCCArgs( |
| 1365 | try argv.append("-fPIC"); | 1521 | try argv.append("-fPIC"); |
| 1366 | } | 1522 | } |
| 1367 | }, | 1523 | }, |
| 1368 | .so, .assembly, .ll, .bc, .unknown => {}, | 1524 | .shared_library, .assembly, .ll, .bc, .unknown, .static_library, .object, .zig, .zir => {}, |
| 1369 | } | 1525 | } |
| 1370 | if (out_dep_path) |p| { | 1526 | if (out_dep_path) |p| { |
| 1371 | try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p }); | 1527 | try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p }); |
| ... | @@ -1445,17 +1601,39 @@ pub const FileExt = enum { | ... | @@ -1445,17 +1601,39 @@ pub const FileExt = enum { |
| 1445 | ll, | 1601 | ll, |
| 1446 | bc, | 1602 | bc, |
| 1447 | assembly, | 1603 | assembly, |
| 1448 | so, | 1604 | shared_library, |
| 1605 | object, | ||
| 1606 | static_library, | ||
| 1607 | zig, | ||
| 1608 | zir, | ||
| 1449 | unknown, | 1609 | unknown, |
| 1450 | 1610 | ||
| 1451 | pub fn clangSupportsDepFile(ext: FileExt) bool { | 1611 | pub fn clangSupportsDepFile(ext: FileExt) bool { |
| 1452 | return switch (ext) { | 1612 | return switch (ext) { |
| 1453 | .c, .cpp, .h => true, | 1613 | .c, .cpp, .h => true, |
| 1454 | .ll, .bc, .assembly, .so, .unknown => false, | 1614 | |
| 1615 | .ll, | ||
| 1616 | .bc, | ||
| 1617 | .assembly, | ||
| 1618 | .shared_library, | ||
| 1619 | .object, | ||
| 1620 | .static_library, | ||
| 1621 | .zig, | ||
| 1622 | .zir, | ||
| 1623 | .unknown, | ||
| 1624 | => false, | ||
| 1455 | }; | 1625 | }; |
| 1456 | } | 1626 | } |
| 1457 | }; | 1627 | }; |
| 1458 | 1628 | ||
| 1629 | pub fn hasObjectExt(filename: []const u8) bool { | ||
| 1630 | return mem.endsWith(u8, filename, ".o") or mem.endsWith(u8, filename, ".obj"); | ||
| 1631 | } | ||
| 1632 | |||
| 1633 | pub fn hasStaticLibraryExt(filename: []const u8) bool { | ||
| 1634 | return mem.endsWith(u8, filename, ".a") or mem.endsWith(u8, filename, ".lib"); | ||
| 1635 | } | ||
| 1636 | |||
| 1459 | pub fn hasCExt(filename: []const u8) bool { | 1637 | pub fn hasCExt(filename: []const u8) bool { |
| 1460 | return mem.endsWith(u8, filename, ".c"); | 1638 | return mem.endsWith(u8, filename, ".c"); |
| 1461 | } | 1639 | } |
| ... | @@ -1471,6 +1649,32 @@ pub fn hasAsmExt(filename: []const u8) bool { | ... | @@ -1471,6 +1649,32 @@ pub fn hasAsmExt(filename: []const u8) bool { |
| 1471 | return mem.endsWith(u8, filename, ".s") or mem.endsWith(u8, filename, ".S"); | 1649 | return mem.endsWith(u8, filename, ".s") or mem.endsWith(u8, filename, ".S"); |
| 1472 | } | 1650 | } |
| 1473 | 1651 | ||
| 1652 | pub fn hasSharedLibraryExt(filename: []const u8) bool { | ||
| 1653 | if (mem.endsWith(u8, filename, ".so") or | ||
| 1654 | mem.endsWith(u8, filename, ".dll") or | ||
| 1655 | mem.endsWith(u8, filename, ".dylib")) | ||
| 1656 | { | ||
| 1657 | return true; | ||
| 1658 | } | ||
| 1659 | // Look for .so.X, .so.X.Y, .so.X.Y.Z | ||
| 1660 | var it = mem.split(filename, "."); | ||
| 1661 | _ = it.next().?; | ||
| 1662 | var so_txt = it.next() orelse return false; | ||
| 1663 | while (!mem.eql(u8, so_txt, "so")) { | ||
| 1664 | so_txt = it.next() orelse return false; | ||
| 1665 | } | ||
| 1666 | const n1 = it.next() orelse return false; | ||
| 1667 | const n2 = it.next(); | ||
| 1668 | const n3 = it.next(); | ||
| 1669 | |||
| 1670 | _ = std.fmt.parseInt(u32, n1, 10) catch return false; | ||
| 1671 | if (n2) |x| _ = std.fmt.parseInt(u32, x, 10) catch return false; | ||
| 1672 | if (n3) |x| _ = std.fmt.parseInt(u32, x, 10) catch return false; | ||
| 1673 | if (it.next() != null) return false; | ||
| 1674 | |||
| 1675 | return true; | ||
| 1676 | } | ||
| 1677 | |||
| 1474 | pub fn classifyFileExt(filename: []const u8) FileExt { | 1678 | pub fn classifyFileExt(filename: []const u8) FileExt { |
| 1475 | if (hasCExt(filename)) { | 1679 | if (hasCExt(filename)) { |
| 1476 | return .c; | 1680 | return .c; |
| ... | @@ -1484,26 +1688,19 @@ pub fn classifyFileExt(filename: []const u8) FileExt { | ... | @@ -1484,26 +1688,19 @@ pub fn classifyFileExt(filename: []const u8) FileExt { |
| 1484 | return .assembly; | 1688 | return .assembly; |
| 1485 | } else if (mem.endsWith(u8, filename, ".h")) { | 1689 | } else if (mem.endsWith(u8, filename, ".h")) { |
| 1486 | return .h; | 1690 | return .h; |
| 1487 | } else if (mem.endsWith(u8, filename, ".so")) { | 1691 | } else if (mem.endsWith(u8, filename, ".zig")) { |
| 1488 | return .so; | 1692 | return .zig; |
| 1489 | } | 1693 | } else if (mem.endsWith(u8, filename, ".zir")) { |
| 1490 | // Look for .so.X, .so.X.Y, .so.X.Y.Z | 1694 | return .zig; |
| 1491 | var it = mem.split(filename, "."); | 1695 | } else if (hasSharedLibraryExt(filename)) { |
| 1492 | _ = it.next().?; | 1696 | return .shared_library; |
| 1493 | var so_txt = it.next() orelse return .unknown; | 1697 | } else if (hasStaticLibraryExt(filename)) { |
| 1494 | while (!mem.eql(u8, so_txt, "so")) { | 1698 | return .static_library; |
| 1495 | so_txt = it.next() orelse return .unknown; | 1699 | } else if (hasObjectExt(filename)) { |
| 1700 | return .object; | ||
| 1701 | } else { | ||
| 1702 | return .unknown; | ||
| 1496 | } | 1703 | } |
| 1497 | const n1 = it.next() orelse return .unknown; | ||
| 1498 | const n2 = it.next(); | ||
| 1499 | const n3 = it.next(); | ||
| 1500 | |||
| 1501 | _ = std.fmt.parseInt(u32, n1, 10) catch return .unknown; | ||
| 1502 | if (n2) |x| _ = std.fmt.parseInt(u32, x, 10) catch return .unknown; | ||
| 1503 | if (n3) |x| _ = std.fmt.parseInt(u32, x, 10) catch return .unknown; | ||
| 1504 | if (it.next() != null) return .unknown; | ||
| 1505 | |||
| 1506 | return .so; | ||
| 1507 | } | 1704 | } |
| 1508 | 1705 | ||
| 1509 | test "classifyFileExt" { | 1706 | test "classifyFileExt" { |
| ... | @@ -1681,7 +1878,7 @@ pub fn dump_argv(argv: []const []const u8) void { | ... | @@ -1681,7 +1878,7 @@ pub fn dump_argv(argv: []const []const u8) void { |
| 1681 | } | 1878 | } |
| 1682 | 1879 | ||
| 1683 | pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 { | 1880 | pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 { |
| 1684 | var buffer = std.ArrayList(u8).init(comp.gpa); | 1881 | var buffer = std.ArrayList(u8).init(allocator); |
| 1685 | defer buffer.deinit(); | 1882 | defer buffer.deinit(); |
| 1686 | 1883 | ||
| 1687 | const target = comp.getTarget(); | 1884 | const target = comp.getTarget(); |
| ... | @@ -1691,9 +1888,9 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 | ... | @@ -1691,9 +1888,9 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 |
| 1691 | try buffer.writer().print( | 1888 | try buffer.writer().print( |
| 1692 | \\usingnamespace @import("std").builtin; | 1889 | \\usingnamespace @import("std").builtin; |
| 1693 | \\/// Deprecated | 1890 | \\/// Deprecated |
| 1694 | \\pub const arch = std.Target.current.cpu.arch; | 1891 | \\pub const arch = Target.current.cpu.arch; |
| 1695 | \\/// Deprecated | 1892 | \\/// Deprecated |
| 1696 | \\pub const endian = std.Target.current.cpu.arch.endian(); | 1893 | \\pub const endian = Target.current.cpu.arch.endian(); |
| 1697 | \\pub const output_mode = OutputMode.{}; | 1894 | \\pub const output_mode = OutputMode.{}; |
| 1698 | \\pub const link_mode = LinkMode.{}; | 1895 | \\pub const link_mode = LinkMode.{}; |
| 1699 | \\pub const is_test = {}; | 1896 | \\pub const is_test = {}; |
src-self-hosted/link.zig+13| ... | @@ -69,6 +69,7 @@ pub const Options = struct { | ... | @@ -69,6 +69,7 @@ pub const Options = struct { |
| 69 | linker_script: ?[]const u8 = null, | 69 | linker_script: ?[]const u8 = null, |
| 70 | version_script: ?[]const u8 = null, | 70 | version_script: ?[]const u8 = null, |
| 71 | override_soname: ?[]const u8 = null, | 71 | override_soname: ?[]const u8 = null, |
| 72 | llvm_cpu_features: ?[*:0]const u8 = null, | ||
| 72 | /// Extra args passed directly to LLD. Ignored when not linking with LLD. | 73 | /// Extra args passed directly to LLD. Ignored when not linking with LLD. |
| 73 | extra_lld_args: []const []const u8 = &[0][]const u8, | 74 | extra_lld_args: []const []const u8 = &[0][]const u8, |
| 74 | 75 | ||
| ... | @@ -134,6 +135,18 @@ pub const File = struct { | ... | @@ -134,6 +135,18 @@ pub const File = struct { |
| 134 | /// rewriting it. A malicious file is detected as incremental link failure | 135 | /// rewriting it. A malicious file is detected as incremental link failure |
| 135 | /// and does not cause Illegal Behavior. This operation is not atomic. | 136 | /// and does not cause Illegal Behavior. This operation is not atomic. |
| 136 | pub fn openPath(allocator: *Allocator, options: Options) !*File { | 137 | pub fn openPath(allocator: *Allocator, options: Options) !*File { |
| 138 | const use_stage1 = build_options.is_stage1 and options.use_llvm; | ||
| 139 | if (use_stage1) { | ||
| 140 | return switch (options.object_format) { | ||
| 141 | .coff, .pe => &(try Coff.createEmpty(allocator, options)).base, | ||
| 142 | .elf => &(try Elf.createEmpty(allocator, options)).base, | ||
| 143 | .macho => &(try MachO.createEmpty(allocator, options)).base, | ||
| 144 | .wasm => &(try Wasm.createEmpty(allocator, options)).base, | ||
| 145 | .c => unreachable, // Reported error earlier. | ||
| 146 | .hex => return error.HexObjectFormatUnimplemented, | ||
| 147 | .raw => return error.RawObjectFormatUnimplemented, | ||
| 148 | }; | ||
| 149 | } | ||
| 137 | const use_lld = build_options.have_llvm and options.use_lld; // comptime known false when !have_llvm | 150 | const use_lld = build_options.have_llvm and options.use_lld; // comptime known false when !have_llvm |
| 138 | const sub_path = if (use_lld) blk: { | 151 | const sub_path = if (use_lld) blk: { |
| 139 | if (options.module == null) { | 152 | if (options.module == null) { |
src-self-hosted/link/Elf.zig+9-6| ... | @@ -1222,13 +1222,16 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1222,13 +1222,16 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1222 | // If there is no Zig code to compile, then we should skip flushing the output file because it | 1222 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 1223 | // will not be part of the linker line anyway. | 1223 | // will not be part of the linker line anyway. |
| 1224 | const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: { | 1224 | const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: { |
| 1225 | try self.flushModule(comp); | 1225 | const use_stage1 = build_options.is_stage1 and self.base.options.use_llvm; |
| 1226 | if (use_stage1) { | ||
| 1227 | const obj_basename = try std.fmt.allocPrint(arena, "{}.o", .{self.base.options.root_name}); | ||
| 1228 | const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename}); | ||
| 1229 | break :blk full_obj_path; | ||
| 1230 | } | ||
| 1226 | 1231 | ||
| 1232 | try self.flushModule(comp); | ||
| 1227 | const obj_basename = self.base.intermediary_basename.?; | 1233 | const obj_basename = self.base.intermediary_basename.?; |
| 1228 | const full_obj_path = if (directory.path) |dir_path| | 1234 | const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename}); |
| 1229 | try std.fs.path.join(arena, &[_][]const u8{dir_path, obj_basename}) | ||
| 1230 | else | ||
| 1231 | obj_basename; | ||
| 1232 | break :blk full_obj_path; | 1235 | break :blk full_obj_path; |
| 1233 | } else null; | 1236 | } else null; |
| 1234 | 1237 | ||
| ... | @@ -1504,7 +1507,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1504,7 +1507,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1504 | // (the check for that needs to be earlier), but they could be full paths to .so files, in which | 1507 | // (the check for that needs to be earlier), but they could be full paths to .so files, in which |
| 1505 | // case we want to avoid prepending "-l". | 1508 | // case we want to avoid prepending "-l". |
| 1506 | const ext = Compilation.classifyFileExt(link_lib); | 1509 | const ext = Compilation.classifyFileExt(link_lib); |
| 1507 | const arg = if (ext == .so) link_lib else try std.fmt.allocPrint(arena, "-l{}", .{link_lib}); | 1510 | const arg = if (ext == .shared_library) link_lib else try std.fmt.allocPrint(arena, "-l{}", .{link_lib}); |
| 1508 | argv.appendAssumeCapacity(arg); | 1511 | argv.appendAssumeCapacity(arg); |
| 1509 | } | 1512 | } |
| 1510 | 1513 |
src-self-hosted/main.zig+79-35| ... | @@ -222,21 +222,27 @@ const usage_build_generic = | ... | @@ -222,21 +222,27 @@ const usage_build_generic = |
| 222 | \\ --libc [file] Provide a file which specifies libc paths | 222 | \\ --libc [file] Provide a file which specifies libc paths |
| 223 | \\ | 223 | \\ |
| 224 | \\Link Options: | 224 | \\Link Options: |
| 225 | \\ -l[lib], --library [lib] Link against system library | 225 | \\ -l[lib], --library [lib] Link against system library |
| 226 | \\ -L[d], --library-directory [d] Add a directory to the library search path | 226 | \\ -L[d], --library-directory [d] Add a directory to the library search path |
| 227 | \\ -T[script] Use a custom linker script | 227 | \\ -T[script] Use a custom linker script |
| 228 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) | 228 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) |
| 229 | \\ --version [ver] Dynamic library semver | 229 | \\ --version [ver] Dynamic library semver |
| 230 | \\ -rdynamic Add all symbols to the dynamic symbol table | 230 | \\ -rdynamic Add all symbols to the dynamic symbol table |
| 231 | \\ -rpath [path] Add directory to the runtime library search path | 231 | \\ -rpath [path] Add directory to the runtime library search path |
| 232 | \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker | 232 | \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker |
| 233 | \\ -dynamic Force output to be dynamically linked | 233 | \\ -dynamic Force output to be dynamically linked |
| 234 | \\ -static Force output to be statically linked | 234 | \\ -static Force output to be statically linked |
| 235 | \\ | 235 | \\ |
| 236 | \\Debug Options (Zig Compiler Development): | 236 | \\Debug Options (Zig Compiler Development): |
| 237 | \\ -ftime-report Print timing diagnostics | 237 | \\ -ftime-report Print timing diagnostics |
| 238 | \\ --verbose-link Display linker invocations | 238 | \\ --verbose-link Display linker invocations |
| 239 | \\ --verbose-cc Display C compiler invocations | 239 | \\ --verbose-cc Display C compiler invocations |
| 240 | \\ --verbose-tokenize Enable compiler debug output for tokenization | ||
| 241 | \\ --verbose-ast Enable compiler debug output for AST parsing | ||
| 242 | \\ --verbose-ir Enable compiler debug output for Zig IR | ||
| 243 | \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR | ||
| 244 | \\ --verbose-cimport Enable compiler debug output for C imports | ||
| 245 | \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features | ||
| 240 | \\ | 246 | \\ |
| 241 | ; | 247 | ; |
| 242 | 248 | ||
| ... | @@ -278,6 +284,12 @@ pub fn buildOutputType( | ... | @@ -278,6 +284,12 @@ pub fn buildOutputType( |
| 278 | var watch = false; | 284 | var watch = false; |
| 279 | var verbose_link = false; | 285 | var verbose_link = false; |
| 280 | var verbose_cc = false; | 286 | var verbose_cc = false; |
| 287 | var verbose_tokenize = false; | ||
| 288 | var verbose_ast = false; | ||
| 289 | var verbose_ir = false; | ||
| 290 | var verbose_llvm_ir = false; | ||
| 291 | var verbose_cimport = false; | ||
| 292 | var verbose_llvm_cpu_features = false; | ||
| 281 | var time_report = false; | 293 | var time_report = false; |
| 282 | var show_builtin = false; | 294 | var show_builtin = false; |
| 283 | var emit_bin: Emit = .yes_default_path; | 295 | var emit_bin: Emit = .yes_default_path; |
| ... | @@ -548,6 +560,18 @@ pub fn buildOutputType( | ... | @@ -548,6 +560,18 @@ pub fn buildOutputType( |
| 548 | verbose_link = true; | 560 | verbose_link = true; |
| 549 | } else if (mem.eql(u8, arg, "--verbose-cc")) { | 561 | } else if (mem.eql(u8, arg, "--verbose-cc")) { |
| 550 | verbose_cc = true; | 562 | verbose_cc = true; |
| 563 | } else if (mem.eql(u8, arg, "--verbose-tokenize")) { | ||
| 564 | verbose_tokenize = true; | ||
| 565 | } else if (mem.eql(u8, arg, "--verbose-ast")) { | ||
| 566 | verbose_ast = true; | ||
| 567 | } else if (mem.eql(u8, arg, "--verbose-ir")) { | ||
| 568 | verbose_ir = true; | ||
| 569 | } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) { | ||
| 570 | verbose_llvm_ir = true; | ||
| 571 | } else if (mem.eql(u8, arg, "--verbose-cimport")) { | ||
| 572 | verbose_cimport = true; | ||
| 573 | } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) { | ||
| 574 | verbose_llvm_cpu_features = true; | ||
| 551 | } else if (mem.startsWith(u8, arg, "-T")) { | 575 | } else if (mem.startsWith(u8, arg, "-T")) { |
| 552 | linker_script = arg[2..]; | 576 | linker_script = arg[2..]; |
| 553 | } else if (mem.startsWith(u8, arg, "-L")) { | 577 | } else if (mem.startsWith(u8, arg, "-L")) { |
| ... | @@ -563,28 +587,27 @@ pub fn buildOutputType( | ... | @@ -563,28 +587,27 @@ pub fn buildOutputType( |
| 563 | } else { | 587 | } else { |
| 564 | fatal("unrecognized parameter: '{}'", .{arg}); | 588 | fatal("unrecognized parameter: '{}'", .{arg}); |
| 565 | } | 589 | } |
| 566 | } else if (mem.endsWith(u8, arg, ".o") or | 590 | } else switch (Compilation.classifyFileExt(arg)) { |
| 567 | mem.endsWith(u8, arg, ".obj") or | 591 | .object, .static_library => { |
| 568 | mem.endsWith(u8, arg, ".a") or | 592 | try link_objects.append(arg); |
| 569 | mem.endsWith(u8, arg, ".lib")) | 593 | }, |
| 570 | { | 594 | .assembly, .c, .cpp, .h, .ll, .bc => { |
| 571 | try link_objects.append(arg); | 595 | // TODO a way to pass extra flags on the CLI |
| 572 | } else if (Compilation.hasAsmExt(arg) or Compilation.hasCExt(arg) or Compilation.hasCppExt(arg)) { | 596 | try c_source_files.append(.{ .src_path = arg }); |
| 573 | // TODO a way to pass extra flags on the CLI | 597 | }, |
| 574 | try c_source_files.append(.{ .src_path = arg }); | 598 | .shared_library => { |
| 575 | } else if (mem.endsWith(u8, arg, ".so") or | 599 | fatal("linking against dynamic libraries not yet supported", .{}); |
| 576 | mem.endsWith(u8, arg, ".dylib") or | 600 | }, |
| 577 | mem.endsWith(u8, arg, ".dll")) | 601 | .zig, .zir => { |
| 578 | { | 602 | if (root_src_file) |other| { |
| 579 | fatal("linking against dynamic libraries not yet supported", .{}); | 603 | fatal("found another zig file '{}' after root source file '{}'", .{ arg, other }); |
| 580 | } else if (mem.endsWith(u8, arg, ".zig") or mem.endsWith(u8, arg, ".zir")) { | 604 | } else { |
| 581 | if (root_src_file) |other| { | 605 | root_src_file = arg; |
| 582 | fatal("found another zig file '{}' after root source file '{}'", .{ arg, other }); | 606 | } |
| 583 | } else { | 607 | }, |
| 584 | root_src_file = arg; | 608 | .unknown => { |
| 585 | } | 609 | fatal("unrecognized file extension of parameter '{}'", .{arg}); |
| 586 | } else { | 610 | }, |
| 587 | fatal("unrecognized file extension of parameter '{}'", .{arg}); | ||
| 588 | } | 611 | } |
| 589 | } | 612 | } |
| 590 | } else { | 613 | } else { |
| ... | @@ -617,7 +640,16 @@ pub fn buildOutputType( | ... | @@ -617,7 +640,16 @@ pub fn buildOutputType( |
| 617 | const file_ext = Compilation.classifyFileExt(mem.spanZ(it.only_arg)); | 640 | const file_ext = Compilation.classifyFileExt(mem.spanZ(it.only_arg)); |
| 618 | switch (file_ext) { | 641 | switch (file_ext) { |
| 619 | .assembly, .c, .cpp, .ll, .bc, .h => try c_source_files.append(.{ .src_path = it.only_arg }), | 642 | .assembly, .c, .cpp, .ll, .bc, .h => try c_source_files.append(.{ .src_path = it.only_arg }), |
| 620 | .unknown, .so => try link_objects.append(it.only_arg), | 643 | .unknown, .shared_library, .object, .static_library => { |
| 644 | try link_objects.append(it.only_arg); | ||
| 645 | }, | ||
| 646 | .zig, .zir => { | ||
| 647 | if (root_src_file) |other| { | ||
| 648 | fatal("found another zig file '{}' after root source file '{}'", .{ it.only_arg, other }); | ||
| 649 | } else { | ||
| 650 | root_src_file = it.only_arg; | ||
| 651 | } | ||
| 652 | }, | ||
| 621 | } | 653 | } |
| 622 | }, | 654 | }, |
| 623 | .l => { | 655 | .l => { |
| ... | @@ -1173,7 +1205,15 @@ pub fn buildOutputType( | ... | @@ -1173,7 +1205,15 @@ pub fn buildOutputType( |
| 1173 | .libc_installation = if (libc_installation) |*lci| lci else null, | 1205 | .libc_installation = if (libc_installation) |*lci| lci else null, |
| 1174 | .verbose_cc = verbose_cc, | 1206 | .verbose_cc = verbose_cc, |
| 1175 | .verbose_link = verbose_link, | 1207 | .verbose_link = verbose_link, |
| 1208 | .verbose_tokenize = verbose_tokenize, | ||
| 1209 | .verbose_ast = verbose_ast, | ||
| 1210 | .verbose_ir = verbose_ir, | ||
| 1211 | .verbose_llvm_ir = verbose_llvm_ir, | ||
| 1212 | .verbose_cimport = verbose_cimport, | ||
| 1213 | .verbose_llvm_cpu_features = verbose_llvm_cpu_features, | ||
| 1176 | .machine_code_model = machine_code_model, | 1214 | .machine_code_model = machine_code_model, |
| 1215 | .color = color, | ||
| 1216 | .time_report = time_report, | ||
| 1177 | }) catch |err| { | 1217 | }) catch |err| { |
| 1178 | fatal("unable to create compilation: {}", .{@errorName(err)}); | 1218 | fatal("unable to create compilation: {}", .{@errorName(err)}); |
| 1179 | }; | 1219 | }; |
| ... | @@ -1193,6 +1233,10 @@ pub fn buildOutputType( | ... | @@ -1193,6 +1233,10 @@ pub fn buildOutputType( |
| 1193 | fatal("TODO: implement `zig cc` when using it as a preprocessor", .{}); | 1233 | fatal("TODO: implement `zig cc` when using it as a preprocessor", .{}); |
| 1194 | } | 1234 | } |
| 1195 | 1235 | ||
| 1236 | if (build_options.is_stage1 and comp.stage1_module != null and watch) { | ||
| 1237 | std.log.warn("--watch is not recommended with the stage1 backend; it leaks memory and is not capable of incremental compilation", .{}); | ||
| 1238 | } | ||
| 1239 | |||
| 1196 | const stdin = std.io.getStdIn().inStream(); | 1240 | const stdin = std.io.getStdIn().inStream(); |
| 1197 | const stderr = std.io.getStdErr().outStream(); | 1241 | const stderr = std.io.getStdErr().outStream(); |
| 1198 | var repl_buf: [1024]u8 = undefined; | 1242 | var repl_buf: [1024]u8 = undefined; |
src-self-hosted/stage1.zig+134-278| ... | @@ -10,6 +10,7 @@ const stage2 = @import("main.zig"); | ... | @@ -10,6 +10,7 @@ const stage2 = @import("main.zig"); |
| 10 | const fatal = stage2.fatal; | 10 | const fatal = stage2.fatal; |
| 11 | const CrossTarget = std.zig.CrossTarget; | 11 | const CrossTarget = std.zig.CrossTarget; |
| 12 | const Target = std.Target; | 12 | const Target = std.Target; |
| 13 | const Compilation = @import("Compilation.zig"); | ||
| 13 | 14 | ||
| 14 | comptime { | 15 | comptime { |
| 15 | assert(std.builtin.link_libc); | 16 | assert(std.builtin.link_libc); |
| ... | @@ -23,6 +24,8 @@ pub const log_level = stage2.log_level; | ... | @@ -23,6 +24,8 @@ pub const log_level = stage2.log_level; |
| 23 | pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int { | 24 | pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int { |
| 24 | std.debug.maybeEnableSegfaultHandler(); | 25 | std.debug.maybeEnableSegfaultHandler(); |
| 25 | 26 | ||
| 27 | zig_stage1_os_init(); | ||
| 28 | |||
| 26 | const gpa = std.heap.c_allocator; | 29 | const gpa = std.heap.c_allocator; |
| 27 | var arena_instance = std.heap.ArenaAllocator.init(gpa); | 30 | var arena_instance = std.heap.ArenaAllocator.init(gpa); |
| 28 | defer arena_instance.deinit(); | 31 | defer arena_instance.deinit(); |
| ... | @@ -36,6 +39,106 @@ pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int { | ... | @@ -36,6 +39,106 @@ pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int { |
| 36 | return 0; | 39 | return 0; |
| 37 | } | 40 | } |
| 38 | 41 | ||
| 42 | /// Matches stage2.Color; | ||
| 43 | pub const ErrColor = c_int; | ||
| 44 | /// Matches std.builtin.CodeModel | ||
| 45 | pub const CodeModel = c_int; | ||
| 46 | /// Matches std.Target.Os.Tag | ||
| 47 | pub const OS = c_int; | ||
| 48 | /// Matches std.builtin.BuildMode | ||
| 49 | pub const BuildMode = c_int; | ||
| 50 | |||
| 51 | pub const TargetSubsystem = extern enum(c_int) { | ||
| 52 | Console, | ||
| 53 | Windows, | ||
| 54 | Posix, | ||
| 55 | Native, | ||
| 56 | EfiApplication, | ||
| 57 | EfiBootServiceDriver, | ||
| 58 | EfiRom, | ||
| 59 | EfiRuntimeDriver, | ||
| 60 | Auto, | ||
| 61 | }; | ||
| 62 | |||
| 63 | pub const Pkg = extern struct { | ||
| 64 | name_ptr: [*]const u8, | ||
| 65 | name_len: usize, | ||
| 66 | path_ptr: [*]const u8, | ||
| 67 | path_len: usize, | ||
| 68 | children_ptr: [*]*Pkg, | ||
| 69 | children_len: usize, | ||
| 70 | parent: ?*Pkg, | ||
| 71 | }; | ||
| 72 | |||
| 73 | pub const Module = extern struct { | ||
| 74 | root_name_ptr: [*]const u8, | ||
| 75 | root_name_len: usize, | ||
| 76 | output_dir_ptr: [*]const u8, | ||
| 77 | output_dir_len: usize, | ||
| 78 | builtin_zig_path_ptr: [*]const u8, | ||
| 79 | builtin_zig_path_len: usize, | ||
| 80 | test_filter_ptr: [*]const u8, | ||
| 81 | test_filter_len: usize, | ||
| 82 | test_name_prefix_ptr: [*]const u8, | ||
| 83 | test_name_prefix_len: usize, | ||
| 84 | userdata: usize, | ||
| 85 | root_pkg: *Pkg, | ||
| 86 | main_progress_node: ?*std.Progress.Node, | ||
| 87 | code_model: CodeModel, | ||
| 88 | subsystem: TargetSubsystem, | ||
| 89 | err_color: ErrColor, | ||
| 90 | pic: bool, | ||
| 91 | link_libc: bool, | ||
| 92 | link_libcpp: bool, | ||
| 93 | strip: bool, | ||
| 94 | is_single_threaded: bool, | ||
| 95 | dll_export_fns: bool, | ||
| 96 | link_mode_dynamic: bool, | ||
| 97 | valgrind_enabled: bool, | ||
| 98 | function_sections: bool, | ||
| 99 | enable_stack_probing: bool, | ||
| 100 | enable_time_report: bool, | ||
| 101 | enable_stack_report: bool, | ||
| 102 | dump_analysis: bool, | ||
| 103 | enable_doc_generation: bool, | ||
| 104 | emit_bin: bool, | ||
| 105 | emit_asm: bool, | ||
| 106 | emit_llvm_ir: bool, | ||
| 107 | test_is_evented: bool, | ||
| 108 | verbose_tokenize: bool, | ||
| 109 | verbose_ast: bool, | ||
| 110 | verbose_ir: bool, | ||
| 111 | verbose_llvm_ir: bool, | ||
| 112 | verbose_cimport: bool, | ||
| 113 | verbose_llvm_cpu_features: bool, | ||
| 114 | |||
| 115 | pub fn build_object(mod: *Module) void { | ||
| 116 | zig_stage1_build_object(mod); | ||
| 117 | } | ||
| 118 | |||
| 119 | pub fn destroy(mod: *Module) void { | ||
| 120 | zig_stage1_destroy(mod); | ||
| 121 | } | ||
| 122 | }; | ||
| 123 | |||
| 124 | extern fn zig_stage1_os_init() void; | ||
| 125 | |||
| 126 | pub const create = zig_stage1_create; | ||
| 127 | extern fn zig_stage1_create( | ||
| 128 | optimize_mode: BuildMode, | ||
| 129 | main_pkg_path_ptr: [*]const u8, | ||
| 130 | main_pkg_path_len: usize, | ||
| 131 | root_src_path_ptr: [*]const u8, | ||
| 132 | root_src_path_len: usize, | ||
| 133 | zig_lib_dir_ptr: [*c]const u8, | ||
| 134 | zig_lib_dir_len: usize, | ||
| 135 | target: [*c]const Stage2Target, | ||
| 136 | is_test_build: bool, | ||
| 137 | ) ?*Module; | ||
| 138 | |||
| 139 | extern fn zig_stage1_build_object(*Module) void; | ||
| 140 | extern fn zig_stage1_destroy(*Module) void; | ||
| 141 | |||
| 39 | // ABI warning | 142 | // ABI warning |
| 40 | export fn stage2_panic(ptr: [*]const u8, len: usize) void { | 143 | export fn stage2_panic(ptr: [*]const u8, len: usize) void { |
| 41 | @panic(ptr[0..len]); | 144 | @panic(ptr[0..len]); |
| ... | @@ -199,297 +302,50 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz | ... | @@ -199,297 +302,50 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz |
| 199 | } | 302 | } |
| 200 | 303 | ||
| 201 | // ABI warning | 304 | // ABI warning |
| 202 | const Stage2Target = extern struct { | 305 | pub const Stage2Target = extern struct { |
| 203 | arch: c_int, | 306 | arch: c_int, |
| 204 | vendor: c_int, | 307 | os: OS, |
| 205 | |||
| 206 | abi: c_int, | 308 | abi: c_int, |
| 207 | os: c_int, | ||
| 208 | 309 | ||
| 209 | is_native_os: bool, | 310 | is_native_os: bool, |
| 210 | is_native_cpu: bool, | 311 | is_native_cpu: bool, |
| 211 | 312 | ||
| 212 | llvm_cpu_name: ?[*:0]const u8, | 313 | llvm_cpu_name: ?[*:0]const u8, |
| 213 | llvm_cpu_features: ?[*:0]const u8, | 314 | llvm_cpu_features: ?[*:0]const u8, |
| 214 | cpu_builtin_str: ?[*:0]const u8, | ||
| 215 | os_builtin_str: ?[*:0]const u8, | ||
| 216 | |||
| 217 | dynamic_linker: ?[*:0]const u8, | ||
| 218 | |||
| 219 | llvm_cpu_features_asm_ptr: [*]const [*:0]const u8, | ||
| 220 | llvm_cpu_features_asm_len: usize, | ||
| 221 | |||
| 222 | fn fromTarget(self: *Stage2Target, cross_target: CrossTarget) !void { | ||
| 223 | const allocator = std.heap.c_allocator; | ||
| 224 | |||
| 225 | var dynamic_linker: ?[*:0]u8 = null; | ||
| 226 | const target = try crossTargetToTarget(cross_target, &dynamic_linker); | ||
| 227 | |||
| 228 | const generic_arch_name = target.cpu.arch.genericName(); | ||
| 229 | var cpu_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, | ||
| 230 | \\Cpu{{ | ||
| 231 | \\ .arch = .{}, | ||
| 232 | \\ .model = &Target.{}.cpu.{}, | ||
| 233 | \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ | ||
| 234 | \\ | ||
| 235 | , .{ | ||
| 236 | @tagName(target.cpu.arch), | ||
| 237 | generic_arch_name, | ||
| 238 | target.cpu.model.name, | ||
| 239 | generic_arch_name, | ||
| 240 | generic_arch_name, | ||
| 241 | }); | ||
| 242 | defer cpu_builtin_str_buffer.deinit(); | ||
| 243 | |||
| 244 | var llvm_features_buffer = try std.ArrayListSentineled(u8, 0).initSize(allocator, 0); | ||
| 245 | defer llvm_features_buffer.deinit(); | ||
| 246 | |||
| 247 | // Unfortunately we have to do the work twice, because Clang does not support | ||
| 248 | // the same command line parameters for CPU features when assembling code as it does | ||
| 249 | // when compiling C code. | ||
| 250 | var asm_features_list = std.ArrayList([*:0]const u8).init(allocator); | ||
| 251 | defer asm_features_list.deinit(); | ||
| 252 | |||
| 253 | for (target.cpu.arch.allFeaturesList()) |feature, index_usize| { | ||
| 254 | const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); | ||
| 255 | const is_enabled = target.cpu.features.isEnabled(index); | ||
| 256 | |||
| 257 | if (feature.llvm_name) |llvm_name| { | ||
| 258 | const plus_or_minus = "-+"[@boolToInt(is_enabled)]; | ||
| 259 | try llvm_features_buffer.append(plus_or_minus); | ||
| 260 | try llvm_features_buffer.appendSlice(llvm_name); | ||
| 261 | try llvm_features_buffer.appendSlice(","); | ||
| 262 | } | ||
| 263 | |||
| 264 | if (is_enabled) { | ||
| 265 | // TODO some kind of "zig identifier escape" function rather than | ||
| 266 | // unconditionally using @"" syntax | ||
| 267 | try cpu_builtin_str_buffer.appendSlice(" .@\""); | ||
| 268 | try cpu_builtin_str_buffer.appendSlice(feature.name); | ||
| 269 | try cpu_builtin_str_buffer.appendSlice("\",\n"); | ||
| 270 | } | ||
| 271 | } | ||
| 272 | |||
| 273 | switch (target.cpu.arch) { | ||
| 274 | .riscv32, .riscv64 => { | ||
| 275 | if (Target.riscv.featureSetHas(target.cpu.features, .relax)) { | ||
| 276 | try asm_features_list.append("-mrelax"); | ||
| 277 | } else { | ||
| 278 | try asm_features_list.append("-mno-relax"); | ||
| 279 | } | ||
| 280 | }, | ||
| 281 | else => { | ||
| 282 | // TODO | ||
| 283 | // Argh, why doesn't the assembler accept the list of CPU features?! | ||
| 284 | // I don't see a way to do this other than hard coding everything. | ||
| 285 | }, | ||
| 286 | } | ||
| 287 | |||
| 288 | try cpu_builtin_str_buffer.appendSlice( | ||
| 289 | \\ }), | ||
| 290 | \\}; | ||
| 291 | \\ | ||
| 292 | ); | ||
| 293 | |||
| 294 | assert(mem.endsWith(u8, llvm_features_buffer.span(), ",")); | ||
| 295 | llvm_features_buffer.shrink(llvm_features_buffer.len() - 1); | ||
| 296 | |||
| 297 | var os_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, | ||
| 298 | \\Os{{ | ||
| 299 | \\ .tag = .{}, | ||
| 300 | \\ .version_range = .{{ | ||
| 301 | , .{@tagName(target.os.tag)}); | ||
| 302 | defer os_builtin_str_buffer.deinit(); | ||
| 303 | |||
| 304 | // We'll re-use the OS version range builtin string for the cache hash. | ||
| 305 | const os_builtin_str_ver_start_index = os_builtin_str_buffer.len(); | ||
| 306 | |||
| 307 | @setEvalBranchQuota(2000); | ||
| 308 | switch (target.os.tag) { | ||
| 309 | .freestanding, | ||
| 310 | .ananas, | ||
| 311 | .cloudabi, | ||
| 312 | .dragonfly, | ||
| 313 | .fuchsia, | ||
| 314 | .ios, | ||
| 315 | .kfreebsd, | ||
| 316 | .lv2, | ||
| 317 | .solaris, | ||
| 318 | .haiku, | ||
| 319 | .minix, | ||
| 320 | .rtems, | ||
| 321 | .nacl, | ||
| 322 | .cnk, | ||
| 323 | .aix, | ||
| 324 | .cuda, | ||
| 325 | .nvcl, | ||
| 326 | .amdhsa, | ||
| 327 | .ps4, | ||
| 328 | .elfiamcu, | ||
| 329 | .tvos, | ||
| 330 | .watchos, | ||
| 331 | .mesa3d, | ||
| 332 | .contiki, | ||
| 333 | .amdpal, | ||
| 334 | .hermit, | ||
| 335 | .hurd, | ||
| 336 | .wasi, | ||
| 337 | .emscripten, | ||
| 338 | .uefi, | ||
| 339 | .other, | ||
| 340 | => try os_builtin_str_buffer.appendSlice(" .none = {} }\n"), | ||
| 341 | |||
| 342 | .freebsd, | ||
| 343 | .macosx, | ||
| 344 | .netbsd, | ||
| 345 | .openbsd, | ||
| 346 | => try os_builtin_str_buffer.outStream().print( | ||
| 347 | \\ .semver = .{{ | ||
| 348 | \\ .min = .{{ | ||
| 349 | \\ .major = {}, | ||
| 350 | \\ .minor = {}, | ||
| 351 | \\ .patch = {}, | ||
| 352 | \\ }}, | ||
| 353 | \\ .max = .{{ | ||
| 354 | \\ .major = {}, | ||
| 355 | \\ .minor = {}, | ||
| 356 | \\ .patch = {}, | ||
| 357 | \\ }}, | ||
| 358 | \\ }}}}, | ||
| 359 | \\ | ||
| 360 | , .{ | ||
| 361 | target.os.version_range.semver.min.major, | ||
| 362 | target.os.version_range.semver.min.minor, | ||
| 363 | target.os.version_range.semver.min.patch, | ||
| 364 | |||
| 365 | target.os.version_range.semver.max.major, | ||
| 366 | target.os.version_range.semver.max.minor, | ||
| 367 | target.os.version_range.semver.max.patch, | ||
| 368 | }), | ||
| 369 | |||
| 370 | .linux => try os_builtin_str_buffer.outStream().print( | ||
| 371 | \\ .linux = .{{ | ||
| 372 | \\ .range = .{{ | ||
| 373 | \\ .min = .{{ | ||
| 374 | \\ .major = {}, | ||
| 375 | \\ .minor = {}, | ||
| 376 | \\ .patch = {}, | ||
| 377 | \\ }}, | ||
| 378 | \\ .max = .{{ | ||
| 379 | \\ .major = {}, | ||
| 380 | \\ .minor = {}, | ||
| 381 | \\ .patch = {}, | ||
| 382 | \\ }}, | ||
| 383 | \\ }}, | ||
| 384 | \\ .glibc = .{{ | ||
| 385 | \\ .major = {}, | ||
| 386 | \\ .minor = {}, | ||
| 387 | \\ .patch = {}, | ||
| 388 | \\ }}, | ||
| 389 | \\ }}}}, | ||
| 390 | \\ | ||
| 391 | , .{ | ||
| 392 | target.os.version_range.linux.range.min.major, | ||
| 393 | target.os.version_range.linux.range.min.minor, | ||
| 394 | target.os.version_range.linux.range.min.patch, | ||
| 395 | |||
| 396 | target.os.version_range.linux.range.max.major, | ||
| 397 | target.os.version_range.linux.range.max.minor, | ||
| 398 | target.os.version_range.linux.range.max.patch, | ||
| 399 | |||
| 400 | target.os.version_range.linux.glibc.major, | ||
| 401 | target.os.version_range.linux.glibc.minor, | ||
| 402 | target.os.version_range.linux.glibc.patch, | ||
| 403 | }), | ||
| 404 | |||
| 405 | .windows => try os_builtin_str_buffer.outStream().print( | ||
| 406 | \\ .windows = .{{ | ||
| 407 | \\ .min = {s}, | ||
| 408 | \\ .max = {s}, | ||
| 409 | \\ }}}}, | ||
| 410 | \\ | ||
| 411 | , .{ | ||
| 412 | target.os.version_range.windows.min, | ||
| 413 | target.os.version_range.windows.max, | ||
| 414 | }), | ||
| 415 | } | ||
| 416 | try os_builtin_str_buffer.appendSlice("};\n"); | ||
| 417 | |||
| 418 | const glibc_or_darwin_version = blk: { | ||
| 419 | if (target.isGnuLibC()) { | ||
| 420 | const stage1_glibc = try std.heap.c_allocator.create(Stage2SemVer); | ||
| 421 | const stage2_glibc = target.os.version_range.linux.glibc; | ||
| 422 | stage1_glibc.* = .{ | ||
| 423 | .major = stage2_glibc.major, | ||
| 424 | .minor = stage2_glibc.minor, | ||
| 425 | .patch = stage2_glibc.patch, | ||
| 426 | }; | ||
| 427 | break :blk stage1_glibc; | ||
| 428 | } else if (target.isDarwin()) { | ||
| 429 | const stage1_semver = try std.heap.c_allocator.create(Stage2SemVer); | ||
| 430 | const stage2_semver = target.os.version_range.semver.min; | ||
| 431 | stage1_semver.* = .{ | ||
| 432 | .major = stage2_semver.major, | ||
| 433 | .minor = stage2_semver.minor, | ||
| 434 | .patch = stage2_semver.patch, | ||
| 435 | }; | ||
| 436 | break :blk stage1_semver; | ||
| 437 | } else { | ||
| 438 | break :blk null; | ||
| 439 | } | ||
| 440 | }; | ||
| 441 | |||
| 442 | const std_dl = target.standardDynamicLinkerPath(); | ||
| 443 | const std_dl_z = if (std_dl.get()) |dl| | ||
| 444 | (try mem.dupeZ(std.heap.c_allocator, u8, dl)).ptr | ||
| 445 | else | ||
| 446 | null; | ||
| 447 | |||
| 448 | const asm_features = asm_features_list.toOwnedSlice(); | ||
| 449 | self.* = .{ | ||
| 450 | .arch = @enumToInt(target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch | ||
| 451 | .vendor = 0, | ||
| 452 | .os = @enumToInt(target.os.tag), | ||
| 453 | .abi = @enumToInt(target.abi), | ||
| 454 | .llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null, | ||
| 455 | .llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr, | ||
| 456 | .llvm_cpu_features_asm_ptr = asm_features.ptr, | ||
| 457 | .llvm_cpu_features_asm_len = asm_features.len, | ||
| 458 | .cpu_builtin_str = cpu_builtin_str_buffer.toOwnedSlice().ptr, | ||
| 459 | .os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr, | ||
| 460 | .is_native_os = cross_target.isNativeOs(), | ||
| 461 | .is_native_cpu = cross_target.isNativeCpu(), | ||
| 462 | .glibc_or_darwin_version = glibc_or_darwin_version, | ||
| 463 | .dynamic_linker = dynamic_linker, | ||
| 464 | .standard_dynamic_linker_path = std_dl_z, | ||
| 465 | }; | ||
| 466 | } | ||
| 467 | }; | 315 | }; |
| 468 | 316 | ||
| 469 | fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) !Target { | ||
| 470 | var info = try std.zig.system.NativeTargetInfo.detect(std.heap.c_allocator, cross_target); | ||
| 471 | if (info.cpu_detection_unimplemented) { | ||
| 472 | // TODO We want to just use detected_info.target but implementing | ||
| 473 | // CPU model & feature detection is todo so here we rely on LLVM. | ||
| 474 | const llvm = @import("llvm.zig"); | ||
| 475 | const llvm_cpu_name = llvm.GetHostCPUName(); | ||
| 476 | const llvm_cpu_features = llvm.GetNativeFeatures(); | ||
| 477 | const arch = Target.current.cpu.arch; | ||
| 478 | info.target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features); | ||
| 479 | cross_target.updateCpuFeatures(&info.target.cpu.features); | ||
| 480 | info.target.cpu.arch = cross_target.getCpuArch(); | ||
| 481 | } | ||
| 482 | if (info.dynamic_linker.get()) |dl| { | ||
| 483 | dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl); | ||
| 484 | } else { | ||
| 485 | dynamic_linker_ptr.* = null; | ||
| 486 | } | ||
| 487 | return info.target; | ||
| 488 | } | ||
| 489 | |||
| 490 | // ABI warning | 317 | // ABI warning |
| 491 | const Stage2SemVer = extern struct { | 318 | const Stage2SemVer = extern struct { |
| 492 | major: u32, | 319 | major: u32, |
| 493 | minor: u32, | 320 | minor: u32, |
| 494 | patch: u32, | 321 | patch: u32, |
| 495 | }; | 322 | }; |
| 323 | |||
| 324 | // ABI warning | ||
| 325 | export fn stage2_cimport(stage1: *Module) [*:0]const u8 { | ||
| 326 | @panic("TODO implement stage2_cimport"); | ||
| 327 | } | ||
| 328 | |||
| 329 | export fn stage2_add_link_lib( | ||
| 330 | stage1: *Module, | ||
| 331 | lib_name_ptr: [*c]const u8, | ||
| 332 | lib_name_len: usize, | ||
| 333 | symbol_name_ptr: [*c]const u8, | ||
| 334 | symbol_name_len: usize, | ||
| 335 | ) ?[*:0]const u8 { | ||
| 336 | return null; // no error | ||
| 337 | } | ||
| 338 | |||
| 339 | export fn stage2_fetch_file( | ||
| 340 | stage1: *Module, | ||
| 341 | path_ptr: [*]const u8, | ||
| 342 | path_len: usize, | ||
| 343 | result_len: *usize, | ||
| 344 | ) ?[*]const u8 { | ||
| 345 | const comp = @intToPtr(*Compilation, stage1.userdata); | ||
| 346 | // TODO integrate this with cache hash | ||
| 347 | const file_path = path_ptr[0..path_len]; | ||
| 348 | const contents = std.fs.cwd().readFileAlloc(comp.gpa, file_path, std.math.maxInt(u32)) catch return null; | ||
| 349 | result_len.* = contents.len; | ||
| 350 | return contents.ptr; | ||
| 351 | } |
src/analyze.cpp+1-1| ... | @@ -7987,7 +7987,7 @@ Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents_buf) { | ... | @@ -7987,7 +7987,7 @@ Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents_buf) { |
| 7987 | size_t len; | 7987 | size_t len; |
| 7988 | const char *contents = stage2_fetch_file(&g->stage1, buf_ptr(resolved_path), buf_len(resolved_path), &len); | 7988 | const char *contents = stage2_fetch_file(&g->stage1, buf_ptr(resolved_path), buf_len(resolved_path), &len); |
| 7989 | if (contents == nullptr) | 7989 | if (contents == nullptr) |
| 7990 | return ErrorNoMem; | 7990 | return ErrorFileNotFound; |
| 7991 | buf_init_from_mem(contents_buf, contents, len); | 7991 | buf_init_from_mem(contents_buf, contents, len); |
| 7992 | return ErrorNone; | 7992 | return ErrorNone; |
| 7993 | } | 7993 | } |
src/codegen.cpp+26-35| ... | @@ -8809,33 +8809,18 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { | ... | @@ -8809,33 +8809,18 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 8809 | static_assert(TargetSubsystemEfiBootServiceDriver == 5, ""); | 8809 | static_assert(TargetSubsystemEfiBootServiceDriver == 5, ""); |
| 8810 | static_assert(TargetSubsystemEfiRom == 6, ""); | 8810 | static_assert(TargetSubsystemEfiRom == 6, ""); |
| 8811 | static_assert(TargetSubsystemEfiRuntimeDriver == 7, ""); | 8811 | static_assert(TargetSubsystemEfiRuntimeDriver == 7, ""); |
| 8812 | { | 8812 | |
| 8813 | const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little"; | 8813 | buf_append_str(contents, "/// Deprecated: use `std.Target.current.cpu.arch`\n"); |
| 8814 | buf_appendf(contents, "pub const endian = %s;\n", endian_str); | 8814 | buf_append_str(contents, "pub const arch = Target.current.cpu.arch;\n"); |
| 8815 | } | 8815 | buf_append_str(contents, "/// Deprecated: use `std.Target.current.cpu.arch.endian()`\n"); |
| 8816 | buf_append_str(contents, "pub const endian = Target.current.cpu.arch.endian();\n"); | ||
| 8816 | buf_appendf(contents, "pub const output_mode = OutputMode.Obj;\n"); | 8817 | buf_appendf(contents, "pub const output_mode = OutputMode.Obj;\n"); |
| 8817 | buf_appendf(contents, "pub const link_mode = LinkMode.Static;\n"); | 8818 | buf_appendf(contents, "pub const link_mode = LinkMode.Static;\n"); |
| 8818 | buf_appendf(contents, "pub const is_test = false;\n"); | 8819 | buf_appendf(contents, "pub const is_test = false;\n"); |
| 8819 | buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); | 8820 | buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); |
| 8820 | buf_append_str(contents, "/// Deprecated: use `std.Target.cpu.arch`\n"); | ||
| 8821 | buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch); | ||
| 8822 | buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi); | 8821 | buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi); |
| 8823 | { | 8822 | buf_appendf(contents, "pub const cpu: Cpu = Target.Cpu.baseline(.%s);\n", cur_arch); |
| 8824 | buf_append_str(contents, "pub const cpu: Cpu = "); | 8823 | buf_appendf(contents, "pub const os = Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os); |
| 8825 | if (g->zig_target->cpu_builtin_str != nullptr) { | ||
| 8826 | buf_append_str(contents, g->zig_target->cpu_builtin_str); | ||
| 8827 | } else { | ||
| 8828 | buf_appendf(contents, "Target.Cpu.baseline(.%s);\n", cur_arch); | ||
| 8829 | } | ||
| 8830 | } | ||
| 8831 | { | ||
| 8832 | buf_append_str(contents, "pub const os = "); | ||
| 8833 | if (g->zig_target->os_builtin_str != nullptr) { | ||
| 8834 | buf_append_str(contents, g->zig_target->os_builtin_str); | ||
| 8835 | } else { | ||
| 8836 | buf_appendf(contents, "Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os); | ||
| 8837 | } | ||
| 8838 | } | ||
| 8839 | buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); | 8824 | buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); |
| 8840 | buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); | 8825 | buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); |
| 8841 | buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->link_libc)); | 8826 | buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->link_libc)); |
| ... | @@ -8866,6 +8851,8 @@ static Error define_builtin_compile_vars(CodeGen *g) { | ... | @@ -8866,6 +8851,8 @@ static Error define_builtin_compile_vars(CodeGen *g) { |
| 8866 | if (g->std_package == nullptr) | 8851 | if (g->std_package == nullptr) |
| 8867 | return ErrorNone; | 8852 | return ErrorNone; |
| 8868 | 8853 | ||
| 8854 | assert(g->main_pkg); | ||
| 8855 | |||
| 8869 | const char *builtin_zig_basename = "builtin.zig"; | 8856 | const char *builtin_zig_basename = "builtin.zig"; |
| 8870 | 8857 | ||
| 8871 | Buf *contents; | 8858 | Buf *contents; |
| ... | @@ -8879,17 +8866,22 @@ static Error define_builtin_compile_vars(CodeGen *g) { | ... | @@ -8879,17 +8866,22 @@ static Error define_builtin_compile_vars(CodeGen *g) { |
| 8879 | fprintf(stderr, "Unable to write file '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err)); | 8866 | fprintf(stderr, "Unable to write file '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err)); |
| 8880 | exit(1); | 8867 | exit(1); |
| 8881 | } | 8868 | } |
| 8869 | |||
| 8870 | g->compile_var_package = new_package(buf_ptr(g->output_dir), builtin_zig_basename, "builtin"); | ||
| 8882 | } else { | 8871 | } else { |
| 8872 | Buf *resolve_paths[] = { g->builtin_zig_path, }; | ||
| 8873 | *g->builtin_zig_path = os_path_resolve(resolve_paths, 1); | ||
| 8874 | |||
| 8883 | contents = buf_alloc(); | 8875 | contents = buf_alloc(); |
| 8884 | if ((err = os_fetch_file_path(g->builtin_zig_path, contents))) { | 8876 | if ((err = os_fetch_file_path(g->builtin_zig_path, contents))) { |
| 8885 | fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err)); | 8877 | fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err)); |
| 8886 | exit(1); | 8878 | exit(1); |
| 8887 | } | 8879 | } |
| 8880 | Buf builtin_dirname = BUF_INIT; | ||
| 8881 | os_path_dirname(g->builtin_zig_path, &builtin_dirname); | ||
| 8882 | g->compile_var_package = new_package(buf_ptr(&builtin_dirname), builtin_zig_basename, "builtin"); | ||
| 8888 | } | 8883 | } |
| 8889 | 8884 | ||
| 8890 | assert(g->main_pkg); | ||
| 8891 | assert(g->std_package); | ||
| 8892 | g->compile_var_package = new_package(buf_ptr(g->output_dir), builtin_zig_basename, "builtin"); | ||
| 8893 | if (g->is_test_build) { | 8885 | if (g->is_test_build) { |
| 8894 | if (g->test_runner_package == nullptr) { | 8886 | if (g->test_runner_package == nullptr) { |
| 8895 | g->test_runner_package = create_test_runner_pkg(g); | 8887 | g->test_runner_package = create_test_runner_pkg(g); |
| ... | @@ -8914,6 +8906,13 @@ static void init(CodeGen *g) { | ... | @@ -8914,6 +8906,13 @@ static void init(CodeGen *g) { |
| 8914 | if (g->module) | 8906 | if (g->module) |
| 8915 | return; | 8907 | return; |
| 8916 | 8908 | ||
| 8909 | codegen_add_time_event(g, "Initialize"); | ||
| 8910 | { | ||
| 8911 | const char *progress_name = "Initialize"; | ||
| 8912 | codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, | ||
| 8913 | progress_name, strlen(progress_name), 0)); | ||
| 8914 | } | ||
| 8915 | |||
| 8917 | g->have_err_ret_tracing = detect_err_ret_tracing(g); | 8916 | g->have_err_ret_tracing = detect_err_ret_tracing(g); |
| 8918 | 8917 | ||
| 8919 | assert(g->root_out_name); | 8918 | assert(g->root_out_name); |
| ... | @@ -9374,19 +9373,11 @@ void codegen_destroy(CodeGen *g) { | ... | @@ -9374,19 +9373,11 @@ void codegen_destroy(CodeGen *g) { |
| 9374 | 9373 | ||
| 9375 | CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, | 9374 | CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, |
| 9376 | BuildMode build_mode, Buf *override_lib_dir, | 9375 | BuildMode build_mode, Buf *override_lib_dir, |
| 9377 | bool is_test_build, Stage2ProgressNode *progress_node) | 9376 | bool is_test_build) |
| 9378 | { | 9377 | { |
| 9379 | CodeGen *g = heap::c_allocator.create<CodeGen>(); | 9378 | CodeGen *g = heap::c_allocator.create<CodeGen>(); |
| 9380 | g->emit_bin = true; | 9379 | g->emit_bin = true; |
| 9381 | g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1"); | 9380 | g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1"); |
| 9382 | g->main_progress_node = progress_node; | ||
| 9383 | |||
| 9384 | codegen_add_time_event(g, "Initialize"); | ||
| 9385 | { | ||
| 9386 | const char *progress_name = "Initialize"; | ||
| 9387 | codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, | ||
| 9388 | progress_name, strlen(progress_name), 0)); | ||
| 9389 | } | ||
| 9390 | 9381 | ||
| 9391 | g->subsystem = TargetSubsystemAuto; | 9382 | g->subsystem = TargetSubsystemAuto; |
| 9392 | g->zig_target = target; | 9383 | g->zig_target = target; |
| ... | @@ -9440,7 +9431,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget | ... | @@ -9440,7 +9431,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget |
| 9440 | Buf resolved_main_pkg_path = os_path_resolve(&main_pkg_path, 1); | 9431 | Buf resolved_main_pkg_path = os_path_resolve(&main_pkg_path, 1); |
| 9441 | 9432 | ||
| 9442 | if (!buf_starts_with_buf(&resolved_root_src_path, &resolved_main_pkg_path)) { | 9433 | if (!buf_starts_with_buf(&resolved_root_src_path, &resolved_main_pkg_path)) { |
| 9443 | fprintf(stderr, "Root source path '%s' outside main package path '%s'", | 9434 | fprintf(stderr, "Root source path '%s' outside main package path '%s'\n", |
| 9444 | buf_ptr(root_src_path), buf_ptr(main_pkg_path)); | 9435 | buf_ptr(root_src_path), buf_ptr(main_pkg_path)); |
| 9445 | exit(1); | 9436 | exit(1); |
| 9446 | } | 9437 | } |
src/codegen.hpp+1-2| ... | @@ -16,8 +16,7 @@ | ... | @@ -16,8 +16,7 @@ |
| 16 | #include <stdio.h> | 16 | #include <stdio.h> |
| 17 | 17 | ||
| 18 | CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, | 18 | CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, |
| 19 | BuildMode build_mode, Buf *zig_lib_dir, | 19 | BuildMode build_mode, Buf *zig_lib_dir, bool is_test_build); |
| 20 | bool is_test_build, Stage2ProgressNode *progress_node); | ||
| 21 | 20 | ||
| 22 | void codegen_build_object(CodeGen *g); | 21 | void codegen_build_object(CodeGen *g); |
| 23 | void codegen_destroy(CodeGen *); | 22 | void codegen_destroy(CodeGen *); |
src/stage1.cpp+6-5| ... | @@ -20,13 +20,14 @@ struct ZigStage1 *zig_stage1_create(BuildMode optimize_mode, | ... | @@ -20,13 +20,14 @@ struct ZigStage1 *zig_stage1_create(BuildMode optimize_mode, |
| 20 | const char *main_pkg_path_ptr, size_t main_pkg_path_len, | 20 | const char *main_pkg_path_ptr, size_t main_pkg_path_len, |
| 21 | const char *root_src_path_ptr, size_t root_src_path_len, | 21 | const char *root_src_path_ptr, size_t root_src_path_len, |
| 22 | const char *zig_lib_dir_ptr, size_t zig_lib_dir_len, | 22 | const char *zig_lib_dir_ptr, size_t zig_lib_dir_len, |
| 23 | const ZigTarget *target, bool is_test_build, Stage2ProgressNode *progress_node) | 23 | const ZigTarget *target, bool is_test_build) |
| 24 | { | 24 | { |
| 25 | Buf *main_pkg_path = buf_create_from_mem(main_pkg_path_ptr, main_pkg_path_len); | 25 | Buf *main_pkg_path = (main_pkg_path_len == 0) ? |
| 26 | nullptr : buf_create_from_mem(main_pkg_path_ptr, main_pkg_path_len); | ||
| 26 | Buf *root_src_path = buf_create_from_mem(root_src_path_ptr, root_src_path_len); | 27 | Buf *root_src_path = buf_create_from_mem(root_src_path_ptr, root_src_path_len); |
| 27 | Buf *zig_lib_dir = buf_create_from_mem(zig_lib_dir_ptr, zig_lib_dir_len); | 28 | Buf *zig_lib_dir = buf_create_from_mem(zig_lib_dir_ptr, zig_lib_dir_len); |
| 28 | CodeGen *g = codegen_create(main_pkg_path, root_src_path, target, optimize_mode, | 29 | CodeGen *g = codegen_create(main_pkg_path, root_src_path, target, optimize_mode, |
| 29 | zig_lib_dir, is_test_build, progress_node); | 30 | zig_lib_dir, is_test_build); |
| 30 | return &g->stage1; | 31 | return &g->stage1; |
| 31 | } | 32 | } |
| 32 | 33 | ||
| ... | @@ -68,8 +69,6 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) { | ... | @@ -68,8 +69,6 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) { |
| 68 | CodeGen *g = reinterpret_cast<CodeGen *>(stage1); | 69 | CodeGen *g = reinterpret_cast<CodeGen *>(stage1); |
| 69 | 70 | ||
| 70 | g->root_out_name = buf_create_from_mem(stage1->root_name_ptr, stage1->root_name_len); | 71 | g->root_out_name = buf_create_from_mem(stage1->root_name_ptr, stage1->root_name_len); |
| 71 | g->zig_lib_dir = buf_create_from_mem(stage1->zig_lib_dir_ptr, stage1->zig_lib_dir_len); | ||
| 72 | g->zig_std_dir = buf_create_from_mem(stage1->zig_std_dir_ptr, stage1->zig_std_dir_len); | ||
| 73 | g->output_dir = buf_create_from_mem(stage1->output_dir_ptr, stage1->output_dir_len); | 72 | g->output_dir = buf_create_from_mem(stage1->output_dir_ptr, stage1->output_dir_len); |
| 74 | if (stage1->builtin_zig_path_len != 0) { | 73 | if (stage1->builtin_zig_path_len != 0) { |
| 75 | g->builtin_zig_path = buf_create_from_mem(stage1->builtin_zig_path_ptr, stage1->builtin_zig_path_len); | 74 | g->builtin_zig_path = buf_create_from_mem(stage1->builtin_zig_path_ptr, stage1->builtin_zig_path_len); |
| ... | @@ -119,6 +118,8 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) { | ... | @@ -119,6 +118,8 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) { |
| 119 | } | 118 | } |
| 120 | } | 119 | } |
| 121 | 120 | ||
| 121 | g->main_progress_node = stage1->main_progress_node; | ||
| 122 | |||
| 122 | add_package(g, stage1->root_pkg, g->main_pkg); | 123 | add_package(g, stage1->root_pkg, g->main_pkg); |
| 123 | 124 | ||
| 124 | codegen_build_object(g); | 125 | codegen_build_object(g); |
src/stage1.h+6-19| ... | @@ -100,22 +100,14 @@ enum Os { | ... | @@ -100,22 +100,14 @@ enum Os { |
| 100 | // ABI warning | 100 | // ABI warning |
| 101 | struct ZigTarget { | 101 | struct ZigTarget { |
| 102 | enum ZigLLVM_ArchType arch; | 102 | enum ZigLLVM_ArchType arch; |
| 103 | enum ZigLLVM_VendorType vendor; | 103 | enum Os os; |
| 104 | |||
| 105 | enum ZigLLVM_EnvironmentType abi; | 104 | enum ZigLLVM_EnvironmentType abi; |
| 106 | Os os; | ||
| 107 | 105 | ||
| 108 | bool is_native_os; | 106 | bool is_native_os; |
| 109 | bool is_native_cpu; | 107 | bool is_native_cpu; |
| 110 | 108 | ||
| 111 | const char *llvm_cpu_name; | 109 | const char *llvm_cpu_name; |
| 112 | const char *llvm_cpu_features; | 110 | const char *llvm_cpu_features; |
| 113 | const char *cpu_builtin_str; | ||
| 114 | const char *os_builtin_str; | ||
| 115 | const char *dynamic_linker; | ||
| 116 | |||
| 117 | const char **llvm_cpu_features_asm_ptr; | ||
| 118 | size_t llvm_cpu_features_asm_len; | ||
| 119 | }; | 111 | }; |
| 120 | 112 | ||
| 121 | // ABI warning | 113 | // ABI warning |
| ... | @@ -161,18 +153,13 @@ struct ZigStage1 { | ... | @@ -161,18 +153,13 @@ struct ZigStage1 { |
| 161 | const char *test_name_prefix_ptr; | 153 | const char *test_name_prefix_ptr; |
| 162 | size_t test_name_prefix_len; | 154 | size_t test_name_prefix_len; |
| 163 | 155 | ||
| 164 | const char *zig_lib_dir_ptr; | ||
| 165 | size_t zig_lib_dir_len; | ||
| 166 | |||
| 167 | const char *zig_std_dir_ptr; | ||
| 168 | size_t zig_std_dir_len; | ||
| 169 | |||
| 170 | void *userdata; | 156 | void *userdata; |
| 171 | struct ZigStage1Pkg *root_pkg; | 157 | struct ZigStage1Pkg *root_pkg; |
| 158 | struct Stage2ProgressNode *main_progress_node; | ||
| 172 | 159 | ||
| 173 | CodeModel code_model; | 160 | enum CodeModel code_model; |
| 174 | TargetSubsystem subsystem; | 161 | enum TargetSubsystem subsystem; |
| 175 | ErrColor err_color; | 162 | enum ErrColor err_color; |
| 176 | 163 | ||
| 177 | bool pic; | 164 | bool pic; |
| 178 | bool link_libc; | 165 | bool link_libc; |
| ... | @@ -206,7 +193,7 @@ ZIG_EXTERN_C struct ZigStage1 *zig_stage1_create(enum BuildMode optimize_mode, | ... | @@ -206,7 +193,7 @@ ZIG_EXTERN_C struct ZigStage1 *zig_stage1_create(enum BuildMode optimize_mode, |
| 206 | const char *main_pkg_path_ptr, size_t main_pkg_path_len, | 193 | const char *main_pkg_path_ptr, size_t main_pkg_path_len, |
| 207 | const char *root_src_path_ptr, size_t root_src_path_len, | 194 | const char *root_src_path_ptr, size_t root_src_path_len, |
| 208 | const char *zig_lib_dir_ptr, size_t zig_lib_dir_len, | 195 | const char *zig_lib_dir_ptr, size_t zig_lib_dir_len, |
| 209 | const ZigTarget *target, bool is_test_build, Stage2ProgressNode *progress_node); | 196 | const struct ZigTarget *target, bool is_test_build); |
| 210 | 197 | ||
| 211 | ZIG_EXTERN_C void zig_stage1_build_object(struct ZigStage1 *); | 198 | ZIG_EXTERN_C void zig_stage1_build_object(struct ZigStage1 *); |
| 212 | 199 |
src/stage2.cpp deleted-241| ... | @@ -1,241 +0,0 @@ | ||
| 1 | // This file is a shim for zig1. The real implementations of these are in | ||
| 2 | // src-self-hosted/stage1.zig | ||
| 3 | |||
| 4 | #include "stage2.h" | ||
| 5 | #include "util.hpp" | ||
| 6 | #include "zig_llvm.h" | ||
| 7 | #include "target.hpp" | ||
| 8 | #include "buffer.hpp" | ||
| 9 | #include "os.hpp" | ||
| 10 | #include <stdio.h> | ||
| 11 | #include <stdlib.h> | ||
| 12 | #include <string.h> | ||
| 13 | |||
| 14 | void stage2_panic(const char *ptr, size_t len) { | ||
| 15 | fwrite(ptr, 1, len, stderr); | ||
| 16 | fprintf(stderr, "\n"); | ||
| 17 | fflush(stderr); | ||
| 18 | abort(); | ||
| 19 | } | ||
| 20 | |||
| 21 | struct Stage2Progress { | ||
| 22 | int trash; | ||
| 23 | }; | ||
| 24 | |||
| 25 | struct Stage2ProgressNode { | ||
| 26 | int trash; | ||
| 27 | }; | ||
| 28 | |||
| 29 | Stage2Progress *stage2_progress_create(void) { | ||
| 30 | return nullptr; | ||
| 31 | } | ||
| 32 | |||
| 33 | void stage2_progress_destroy(Stage2Progress *progress) {} | ||
| 34 | |||
| 35 | Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, | ||
| 36 | const char *name_ptr, size_t name_len, size_t estimated_total_items) | ||
| 37 | { | ||
| 38 | return nullptr; | ||
| 39 | } | ||
| 40 | Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, | ||
| 41 | const char *name_ptr, size_t name_len, size_t estimated_total_items) | ||
| 42 | { | ||
| 43 | return nullptr; | ||
| 44 | } | ||
| 45 | void stage2_progress_end(Stage2ProgressNode *node) {} | ||
| 46 | void stage2_progress_complete_one(Stage2ProgressNode *node) {} | ||
| 47 | void stage2_progress_disable_tty(Stage2Progress *progress) {} | ||
| 48 | void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){} | ||
| 49 | |||
| 50 | static Os get_zig_os_type(ZigLLVM_OSType os_type) { | ||
| 51 | switch (os_type) { | ||
| 52 | case ZigLLVM_UnknownOS: | ||
| 53 | return OsFreestanding; | ||
| 54 | case ZigLLVM_Ananas: | ||
| 55 | return OsAnanas; | ||
| 56 | case ZigLLVM_CloudABI: | ||
| 57 | return OsCloudABI; | ||
| 58 | case ZigLLVM_DragonFly: | ||
| 59 | return OsDragonFly; | ||
| 60 | case ZigLLVM_FreeBSD: | ||
| 61 | return OsFreeBSD; | ||
| 62 | case ZigLLVM_Fuchsia: | ||
| 63 | return OsFuchsia; | ||
| 64 | case ZigLLVM_IOS: | ||
| 65 | return OsIOS; | ||
| 66 | case ZigLLVM_KFreeBSD: | ||
| 67 | return OsKFreeBSD; | ||
| 68 | case ZigLLVM_Linux: | ||
| 69 | return OsLinux; | ||
| 70 | case ZigLLVM_Lv2: | ||
| 71 | return OsLv2; | ||
| 72 | case ZigLLVM_Darwin: | ||
| 73 | case ZigLLVM_MacOSX: | ||
| 74 | return OsMacOSX; | ||
| 75 | case ZigLLVM_NetBSD: | ||
| 76 | return OsNetBSD; | ||
| 77 | case ZigLLVM_OpenBSD: | ||
| 78 | return OsOpenBSD; | ||
| 79 | case ZigLLVM_Solaris: | ||
| 80 | return OsSolaris; | ||
| 81 | case ZigLLVM_Win32: | ||
| 82 | return OsWindows; | ||
| 83 | case ZigLLVM_Haiku: | ||
| 84 | return OsHaiku; | ||
| 85 | case ZigLLVM_Minix: | ||
| 86 | return OsMinix; | ||
| 87 | case ZigLLVM_RTEMS: | ||
| 88 | return OsRTEMS; | ||
| 89 | case ZigLLVM_NaCl: | ||
| 90 | return OsNaCl; | ||
| 91 | case ZigLLVM_CNK: | ||
| 92 | return OsCNK; | ||
| 93 | case ZigLLVM_AIX: | ||
| 94 | return OsAIX; | ||
| 95 | case ZigLLVM_CUDA: | ||
| 96 | return OsCUDA; | ||
| 97 | case ZigLLVM_NVCL: | ||
| 98 | return OsNVCL; | ||
| 99 | case ZigLLVM_AMDHSA: | ||
| 100 | return OsAMDHSA; | ||
| 101 | case ZigLLVM_PS4: | ||
| 102 | return OsPS4; | ||
| 103 | case ZigLLVM_ELFIAMCU: | ||
| 104 | return OsELFIAMCU; | ||
| 105 | case ZigLLVM_TvOS: | ||
| 106 | return OsTvOS; | ||
| 107 | case ZigLLVM_WatchOS: | ||
| 108 | return OsWatchOS; | ||
| 109 | case ZigLLVM_Mesa3D: | ||
| 110 | return OsMesa3D; | ||
| 111 | case ZigLLVM_Contiki: | ||
| 112 | return OsContiki; | ||
| 113 | case ZigLLVM_AMDPAL: | ||
| 114 | return OsAMDPAL; | ||
| 115 | case ZigLLVM_HermitCore: | ||
| 116 | return OsHermitCore; | ||
| 117 | case ZigLLVM_Hurd: | ||
| 118 | return OsHurd; | ||
| 119 | case ZigLLVM_WASI: | ||
| 120 | return OsWASI; | ||
| 121 | case ZigLLVM_Emscripten: | ||
| 122 | return OsEmscripten; | ||
| 123 | } | ||
| 124 | zig_unreachable(); | ||
| 125 | } | ||
| 126 | |||
| 127 | static void get_native_target(ZigTarget *target) { | ||
| 128 | // first zero initialize | ||
| 129 | *target = {}; | ||
| 130 | |||
| 131 | ZigLLVM_OSType os_type; | ||
| 132 | ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os | ||
| 133 | ZigLLVMGetNativeTarget( | ||
| 134 | &target->arch, | ||
| 135 | &target->vendor, | ||
| 136 | &os_type, | ||
| 137 | &target->abi, | ||
| 138 | &oformat); | ||
| 139 | target->os = get_zig_os_type(os_type); | ||
| 140 | target->is_native_os = true; | ||
| 141 | target->is_native_cpu = true; | ||
| 142 | if (target->abi == ZigLLVM_UnknownEnvironment) { | ||
| 143 | target->abi = target_default_abi(target->arch, target->os); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, | ||
| 148 | const char *dynamic_linker) | ||
| 149 | { | ||
| 150 | Error err; | ||
| 151 | |||
| 152 | if (zig_triple != nullptr && strcmp(zig_triple, "native") == 0) { | ||
| 153 | zig_triple = nullptr; | ||
| 154 | } | ||
| 155 | |||
| 156 | if (zig_triple == nullptr) { | ||
| 157 | get_native_target(target); | ||
| 158 | |||
| 159 | if (mcpu == nullptr) { | ||
| 160 | target->llvm_cpu_name = ZigLLVMGetHostCPUName(); | ||
| 161 | target->llvm_cpu_features = ZigLLVMGetNativeFeatures(); | ||
| 162 | } else if (strcmp(mcpu, "baseline") == 0) { | ||
| 163 | target->is_native_os = false; | ||
| 164 | target->is_native_cpu = false; | ||
| 165 | target->llvm_cpu_name = ""; | ||
| 166 | target->llvm_cpu_features = ""; | ||
| 167 | } else { | ||
| 168 | const char *msg = "stage0 can't handle CPU/features in the target"; | ||
| 169 | stage2_panic(msg, strlen(msg)); | ||
| 170 | } | ||
| 171 | } else { | ||
| 172 | // first initialize all to zero | ||
| 173 | *target = {}; | ||
| 174 | |||
| 175 | SplitIterator it = memSplit(str(zig_triple), str("-")); | ||
| 176 | |||
| 177 | Optional<Slice<uint8_t>> opt_archsub = SplitIterator_next(&it); | ||
| 178 | Optional<Slice<uint8_t>> opt_os = SplitIterator_next(&it); | ||
| 179 | Optional<Slice<uint8_t>> opt_abi = SplitIterator_next(&it); | ||
| 180 | |||
| 181 | if (!opt_archsub.is_some) | ||
| 182 | return ErrorMissingArchitecture; | ||
| 183 | |||
| 184 | if ((err = target_parse_arch(&target->arch, (char*)opt_archsub.value.ptr, opt_archsub.value.len))) { | ||
| 185 | return err; | ||
| 186 | } | ||
| 187 | |||
| 188 | if (!opt_os.is_some) | ||
| 189 | return ErrorMissingOperatingSystem; | ||
| 190 | |||
| 191 | if ((err = target_parse_os(&target->os, (char*)opt_os.value.ptr, opt_os.value.len))) { | ||
| 192 | return err; | ||
| 193 | } | ||
| 194 | |||
| 195 | if (opt_abi.is_some) { | ||
| 196 | if ((err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len))) { | ||
| 197 | return err; | ||
| 198 | } | ||
| 199 | } else { | ||
| 200 | target->abi = target_default_abi(target->arch, target->os); | ||
| 201 | } | ||
| 202 | |||
| 203 | if (mcpu != nullptr && strcmp(mcpu, "baseline") != 0) { | ||
| 204 | const char *msg = "stage0 can't handle CPU/features in the target"; | ||
| 205 | stage2_panic(msg, strlen(msg)); | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | if (dynamic_linker != nullptr) { | ||
| 210 | target->dynamic_linker = dynamic_linker; | ||
| 211 | } | ||
| 212 | |||
| 213 | return ErrorNone; | ||
| 214 | } | ||
| 215 | |||
| 216 | const char *stage2_fetch_file(struct ZigStage1 *stage1, const char *path_ptr, size_t path_len, | ||
| 217 | size_t *result_len) | ||
| 218 | { | ||
| 219 | Error err; | ||
| 220 | Buf contents_buf = BUF_INIT; | ||
| 221 | Buf path_buf = BUF_INIT; | ||
| 222 | |||
| 223 | buf_init_from_mem(&path_buf, path_ptr, path_len); | ||
| 224 | if ((err = os_fetch_file_path(&path_buf, &contents_buf))) { | ||
| 225 | return nullptr; | ||
| 226 | } | ||
| 227 | *result_len = buf_len(&contents_buf); | ||
| 228 | return buf_ptr(&contents_buf); | ||
| 229 | } | ||
| 230 | |||
| 231 | const char *stage2_cimport(struct ZigStage1 *stage1) { | ||
| 232 | const char *msg = "stage0 called stage2_cimport"; | ||
| 233 | stage2_panic(msg, strlen(msg)); | ||
| 234 | } | ||
| 235 | |||
| 236 | const char *stage2_add_link_lib(struct ZigStage1 *stage1, | ||
| 237 | const char *lib_name_ptr, size_t lib_name_len, | ||
| 238 | const char *symbol_name_ptr, size_t symbol_name_len) | ||
| 239 | { | ||
| 240 | return nullptr; | ||
| 241 | } | ||
src/stage2.h+8-8| ... | @@ -130,23 +130,23 @@ struct Stage2ErrorMsg { | ... | @@ -130,23 +130,23 @@ struct Stage2ErrorMsg { |
| 130 | ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len); | 130 | ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len); |
| 131 | 131 | ||
| 132 | // ABI warning | 132 | // ABI warning |
| 133 | ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void); | 133 | ZIG_EXTERN_C struct Stage2Progress *stage2_progress_create(void); |
| 134 | // ABI warning | 134 | // ABI warning |
| 135 | ZIG_EXTERN_C void stage2_progress_disable_tty(Stage2Progress *progress); | 135 | ZIG_EXTERN_C void stage2_progress_disable_tty(struct Stage2Progress *progress); |
| 136 | // ABI warning | 136 | // ABI warning |
| 137 | ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress); | 137 | ZIG_EXTERN_C void stage2_progress_destroy(struct Stage2Progress *progress); |
| 138 | // ABI warning | 138 | // ABI warning |
| 139 | ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, | 139 | ZIG_EXTERN_C struct Stage2ProgressNode *stage2_progress_start_root(struct Stage2Progress *progress, |
| 140 | const char *name_ptr, size_t name_len, size_t estimated_total_items); | 140 | const char *name_ptr, size_t name_len, size_t estimated_total_items); |
| 141 | // ABI warning | 141 | // ABI warning |
| 142 | ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, | 142 | ZIG_EXTERN_C struct Stage2ProgressNode *stage2_progress_start(struct Stage2ProgressNode *node, |
| 143 | const char *name_ptr, size_t name_len, size_t estimated_total_items); | 143 | const char *name_ptr, size_t name_len, size_t estimated_total_items); |
| 144 | // ABI warning | 144 | // ABI warning |
| 145 | ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node); | 145 | ZIG_EXTERN_C void stage2_progress_end(struct Stage2ProgressNode *node); |
| 146 | // ABI warning | 146 | // ABI warning |
| 147 | ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node); | 147 | ZIG_EXTERN_C void stage2_progress_complete_one(struct Stage2ProgressNode *node); |
| 148 | // ABI warning | 148 | // ABI warning |
| 149 | ZIG_EXTERN_C void stage2_progress_update_node(Stage2ProgressNode *node, | 149 | ZIG_EXTERN_C void stage2_progress_update_node(struct Stage2ProgressNode *node, |
| 150 | size_t completed_count, size_t estimated_total_items); | 150 | size_t completed_count, size_t estimated_total_items); |
| 151 | 151 | ||
| 152 | // ABI warning | 152 | // ABI warning |
src/target.cpp+1-6| ... | @@ -380,10 +380,6 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si | ... | @@ -380,10 +380,6 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si |
| 380 | return ErrorUnknownABI; | 380 | return ErrorUnknownABI; |
| 381 | } | 381 | } |
| 382 | 382 | ||
| 383 | Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker) { | ||
| 384 | return stage2_target_parse(target, triple, mcpu, dynamic_linker); | ||
| 385 | } | ||
| 386 | |||
| 387 | const char *target_arch_name(ZigLLVM_ArchType arch) { | 383 | const char *target_arch_name(ZigLLVM_ArchType arch) { |
| 388 | return ZigLLVMGetArchTypeName(arch); | 384 | return ZigLLVMGetArchTypeName(arch); |
| 389 | } | 385 | } |
| ... | @@ -408,7 +404,7 @@ void target_triple_llvm(Buf *triple, const ZigTarget *target) { | ... | @@ -408,7 +404,7 @@ void target_triple_llvm(Buf *triple, const ZigTarget *target) { |
| 408 | buf_resize(triple, 0); | 404 | buf_resize(triple, 0); |
| 409 | buf_appendf(triple, "%s-%s-%s-%s", | 405 | buf_appendf(triple, "%s-%s-%s-%s", |
| 410 | ZigLLVMGetArchTypeName(target->arch), | 406 | ZigLLVMGetArchTypeName(target->arch), |
| 411 | ZigLLVMGetVendorTypeName(target->vendor), | 407 | ZigLLVMGetVendorTypeName(ZigLLVM_UnknownVendor), |
| 412 | ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)), | 408 | ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)), |
| 413 | ZigLLVMGetEnvironmentTypeName(target->abi)); | 409 | ZigLLVMGetEnvironmentTypeName(target->abi)); |
| 414 | } | 410 | } |
| ... | @@ -1149,7 +1145,6 @@ void target_libc_enum(size_t index, ZigTarget *out_target) { | ... | @@ -1149,7 +1145,6 @@ void target_libc_enum(size_t index, ZigTarget *out_target) { |
| 1149 | out_target->arch = libcs_available[index].arch; | 1145 | out_target->arch = libcs_available[index].arch; |
| 1150 | out_target->os = libcs_available[index].os; | 1146 | out_target->os = libcs_available[index].os; |
| 1151 | out_target->abi = libcs_available[index].abi; | 1147 | out_target->abi = libcs_available[index].abi; |
| 1152 | out_target->vendor = ZigLLVM_UnknownVendor; | ||
| 1153 | out_target->is_native_os = false; | 1148 | out_target->is_native_os = false; |
| 1154 | out_target->is_native_cpu = false; | 1149 | out_target->is_native_cpu = false; |
| 1155 | } | 1150 | } |
src/target.hpp-1| ... | @@ -25,7 +25,6 @@ enum CIntType { | ... | @@ -25,7 +25,6 @@ enum CIntType { |
| 25 | CIntTypeCount, | 25 | CIntTypeCount, |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker); | ||
| 29 | Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len); | 28 | Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len); |
| 30 | Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); | 29 | Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); |
| 31 | Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); | 30 | Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); |
src/zig0.cpp+239-12| ... | @@ -14,6 +14,9 @@ | ... | @@ -14,6 +14,9 @@ |
| 14 | #include "stage2.h" | 14 | #include "stage2.h" |
| 15 | #include "target.hpp" | 15 | #include "target.hpp" |
| 16 | #include "error.hpp" | 16 | #include "error.hpp" |
| 17 | #include "util.hpp" | ||
| 18 | #include "buffer.hpp" | ||
| 19 | #include "os.hpp" | ||
| 17 | 20 | ||
| 18 | #include <stdio.h> | 21 | #include <stdio.h> |
| 19 | #include <string.h> | 22 | #include <string.h> |
| ... | @@ -33,7 +36,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { | ... | @@ -33,7 +36,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { |
| 33 | " --output-dir [dir] override output directory (defaults to cwd)\n" | 36 | " --output-dir [dir] override output directory (defaults to cwd)\n" |
| 34 | " --pkg-begin [name] [path] make pkg available to import and push current pkg\n" | 37 | " --pkg-begin [name] [path] make pkg available to import and push current pkg\n" |
| 35 | " --pkg-end pop current pkg\n" | 38 | " --pkg-end pop current pkg\n" |
| 36 | " --main-pkg-path set the directory of the root package\n" | ||
| 37 | " --release-fast build with optimizations on and safety off\n" | 39 | " --release-fast build with optimizations on and safety off\n" |
| 38 | " --release-safe build with optimizations on and safety on\n" | 40 | " --release-safe build with optimizations on and safety on\n" |
| 39 | " --release-small build with size optimizations on and safety off\n" | 41 | " --release-small build with size optimizations on and safety off\n" |
| ... | @@ -53,6 +55,170 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { | ... | @@ -53,6 +55,170 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { |
| 53 | return return_code; | 55 | return return_code; |
| 54 | } | 56 | } |
| 55 | 57 | ||
| 58 | static Os get_zig_os_type(ZigLLVM_OSType os_type) { | ||
| 59 | switch (os_type) { | ||
| 60 | case ZigLLVM_UnknownOS: | ||
| 61 | return OsFreestanding; | ||
| 62 | case ZigLLVM_Ananas: | ||
| 63 | return OsAnanas; | ||
| 64 | case ZigLLVM_CloudABI: | ||
| 65 | return OsCloudABI; | ||
| 66 | case ZigLLVM_DragonFly: | ||
| 67 | return OsDragonFly; | ||
| 68 | case ZigLLVM_FreeBSD: | ||
| 69 | return OsFreeBSD; | ||
| 70 | case ZigLLVM_Fuchsia: | ||
| 71 | return OsFuchsia; | ||
| 72 | case ZigLLVM_IOS: | ||
| 73 | return OsIOS; | ||
| 74 | case ZigLLVM_KFreeBSD: | ||
| 75 | return OsKFreeBSD; | ||
| 76 | case ZigLLVM_Linux: | ||
| 77 | return OsLinux; | ||
| 78 | case ZigLLVM_Lv2: | ||
| 79 | return OsLv2; | ||
| 80 | case ZigLLVM_Darwin: | ||
| 81 | case ZigLLVM_MacOSX: | ||
| 82 | return OsMacOSX; | ||
| 83 | case ZigLLVM_NetBSD: | ||
| 84 | return OsNetBSD; | ||
| 85 | case ZigLLVM_OpenBSD: | ||
| 86 | return OsOpenBSD; | ||
| 87 | case ZigLLVM_Solaris: | ||
| 88 | return OsSolaris; | ||
| 89 | case ZigLLVM_Win32: | ||
| 90 | return OsWindows; | ||
| 91 | case ZigLLVM_Haiku: | ||
| 92 | return OsHaiku; | ||
| 93 | case ZigLLVM_Minix: | ||
| 94 | return OsMinix; | ||
| 95 | case ZigLLVM_RTEMS: | ||
| 96 | return OsRTEMS; | ||
| 97 | case ZigLLVM_NaCl: | ||
| 98 | return OsNaCl; | ||
| 99 | case ZigLLVM_CNK: | ||
| 100 | return OsCNK; | ||
| 101 | case ZigLLVM_AIX: | ||
| 102 | return OsAIX; | ||
| 103 | case ZigLLVM_CUDA: | ||
| 104 | return OsCUDA; | ||
| 105 | case ZigLLVM_NVCL: | ||
| 106 | return OsNVCL; | ||
| 107 | case ZigLLVM_AMDHSA: | ||
| 108 | return OsAMDHSA; | ||
| 109 | case ZigLLVM_PS4: | ||
| 110 | return OsPS4; | ||
| 111 | case ZigLLVM_ELFIAMCU: | ||
| 112 | return OsELFIAMCU; | ||
| 113 | case ZigLLVM_TvOS: | ||
| 114 | return OsTvOS; | ||
| 115 | case ZigLLVM_WatchOS: | ||
| 116 | return OsWatchOS; | ||
| 117 | case ZigLLVM_Mesa3D: | ||
| 118 | return OsMesa3D; | ||
| 119 | case ZigLLVM_Contiki: | ||
| 120 | return OsContiki; | ||
| 121 | case ZigLLVM_AMDPAL: | ||
| 122 | return OsAMDPAL; | ||
| 123 | case ZigLLVM_HermitCore: | ||
| 124 | return OsHermitCore; | ||
| 125 | case ZigLLVM_Hurd: | ||
| 126 | return OsHurd; | ||
| 127 | case ZigLLVM_WASI: | ||
| 128 | return OsWASI; | ||
| 129 | case ZigLLVM_Emscripten: | ||
| 130 | return OsEmscripten; | ||
| 131 | } | ||
| 132 | zig_unreachable(); | ||
| 133 | } | ||
| 134 | |||
| 135 | static void get_native_target(ZigTarget *target) { | ||
| 136 | // first zero initialize | ||
| 137 | *target = {}; | ||
| 138 | |||
| 139 | ZigLLVM_OSType os_type; | ||
| 140 | ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os | ||
| 141 | ZigLLVM_VendorType trash; | ||
| 142 | ZigLLVMGetNativeTarget( | ||
| 143 | &target->arch, | ||
| 144 | &trash, | ||
| 145 | &os_type, | ||
| 146 | &target->abi, | ||
| 147 | &oformat); | ||
| 148 | target->os = get_zig_os_type(os_type); | ||
| 149 | target->is_native_os = true; | ||
| 150 | target->is_native_cpu = true; | ||
| 151 | if (target->abi == ZigLLVM_UnknownEnvironment) { | ||
| 152 | target->abi = target_default_abi(target->arch, target->os); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | static Error target_parse_triple(struct ZigTarget *target, const char *zig_triple, const char *mcpu, | ||
| 157 | const char *dynamic_linker) | ||
| 158 | { | ||
| 159 | Error err; | ||
| 160 | |||
| 161 | if (zig_triple != nullptr && strcmp(zig_triple, "native") == 0) { | ||
| 162 | zig_triple = nullptr; | ||
| 163 | } | ||
| 164 | |||
| 165 | if (zig_triple == nullptr) { | ||
| 166 | get_native_target(target); | ||
| 167 | |||
| 168 | if (mcpu == nullptr) { | ||
| 169 | target->llvm_cpu_name = ZigLLVMGetHostCPUName(); | ||
| 170 | target->llvm_cpu_features = ZigLLVMGetNativeFeatures(); | ||
| 171 | } else if (strcmp(mcpu, "baseline") == 0) { | ||
| 172 | target->is_native_os = false; | ||
| 173 | target->is_native_cpu = false; | ||
| 174 | target->llvm_cpu_name = ""; | ||
| 175 | target->llvm_cpu_features = ""; | ||
| 176 | } else { | ||
| 177 | const char *msg = "stage0 can't handle CPU/features in the target"; | ||
| 178 | stage2_panic(msg, strlen(msg)); | ||
| 179 | } | ||
| 180 | } else { | ||
| 181 | // first initialize all to zero | ||
| 182 | *target = {}; | ||
| 183 | |||
| 184 | SplitIterator it = memSplit(str(zig_triple), str("-")); | ||
| 185 | |||
| 186 | Optional<Slice<uint8_t>> opt_archsub = SplitIterator_next(&it); | ||
| 187 | Optional<Slice<uint8_t>> opt_os = SplitIterator_next(&it); | ||
| 188 | Optional<Slice<uint8_t>> opt_abi = SplitIterator_next(&it); | ||
| 189 | |||
| 190 | if (!opt_archsub.is_some) | ||
| 191 | return ErrorMissingArchitecture; | ||
| 192 | |||
| 193 | if ((err = target_parse_arch(&target->arch, (char*)opt_archsub.value.ptr, opt_archsub.value.len))) { | ||
| 194 | return err; | ||
| 195 | } | ||
| 196 | |||
| 197 | if (!opt_os.is_some) | ||
| 198 | return ErrorMissingOperatingSystem; | ||
| 199 | |||
| 200 | if ((err = target_parse_os(&target->os, (char*)opt_os.value.ptr, opt_os.value.len))) { | ||
| 201 | return err; | ||
| 202 | } | ||
| 203 | |||
| 204 | if (opt_abi.is_some) { | ||
| 205 | if ((err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len))) { | ||
| 206 | return err; | ||
| 207 | } | ||
| 208 | } else { | ||
| 209 | target->abi = target_default_abi(target->arch, target->os); | ||
| 210 | } | ||
| 211 | |||
| 212 | if (mcpu != nullptr && strcmp(mcpu, "baseline") != 0) { | ||
| 213 | const char *msg = "stage0 can't handle CPU/features in the target"; | ||
| 214 | stage2_panic(msg, strlen(msg)); | ||
| 215 | } | ||
| 216 | } | ||
| 217 | |||
| 218 | return ErrorNone; | ||
| 219 | } | ||
| 220 | |||
| 221 | |||
| 56 | static bool str_starts_with(const char *s1, const char *s2) { | 222 | static bool str_starts_with(const char *s1, const char *s2) { |
| 57 | size_t s2_len = strlen(s2); | 223 | size_t s2_len = strlen(s2); |
| 58 | if (strlen(s1) < s2_len) { | 224 | if (strlen(s1) < s2_len) { |
| ... | @@ -90,10 +256,9 @@ int main(int argc, char **argv) { | ... | @@ -90,10 +256,9 @@ int main(int argc, char **argv) { |
| 90 | bool link_libcpp = false; | 256 | bool link_libcpp = false; |
| 91 | const char *target_string = nullptr; | 257 | const char *target_string = nullptr; |
| 92 | ZigStage1Pkg *cur_pkg = heap::c_allocator.create<ZigStage1Pkg>(); | 258 | ZigStage1Pkg *cur_pkg = heap::c_allocator.create<ZigStage1Pkg>(); |
| 93 | BuildMode build_mode = BuildModeDebug; | 259 | BuildMode optimize_mode = BuildModeDebug; |
| 94 | TargetSubsystem subsystem = TargetSubsystemAuto; | 260 | TargetSubsystem subsystem = TargetSubsystemAuto; |
| 95 | const char *override_lib_dir = nullptr; | 261 | const char *override_lib_dir = nullptr; |
| 96 | const char *main_pkg_path = nullptr; | ||
| 97 | const char *mcpu = nullptr; | 262 | const char *mcpu = nullptr; |
| 98 | 263 | ||
| 99 | for (int i = 1; i < argc; i += 1) { | 264 | for (int i = 1; i < argc; i += 1) { |
| ... | @@ -103,11 +268,11 @@ int main(int argc, char **argv) { | ... | @@ -103,11 +268,11 @@ int main(int argc, char **argv) { |
| 103 | if (strcmp(arg, "--") == 0) { | 268 | if (strcmp(arg, "--") == 0) { |
| 104 | fprintf(stderr, "Unexpected end-of-parameter mark: %s\n", arg); | 269 | fprintf(stderr, "Unexpected end-of-parameter mark: %s\n", arg); |
| 105 | } else if (strcmp(arg, "--release-fast") == 0) { | 270 | } else if (strcmp(arg, "--release-fast") == 0) { |
| 106 | build_mode = BuildModeFastRelease; | 271 | optimize_mode = BuildModeFastRelease; |
| 107 | } else if (strcmp(arg, "--release-safe") == 0) { | 272 | } else if (strcmp(arg, "--release-safe") == 0) { |
| 108 | build_mode = BuildModeSafeRelease; | 273 | optimize_mode = BuildModeSafeRelease; |
| 109 | } else if (strcmp(arg, "--release-small") == 0) { | 274 | } else if (strcmp(arg, "--release-small") == 0) { |
| 110 | build_mode = BuildModeSmallRelease; | 275 | optimize_mode = BuildModeSmallRelease; |
| 111 | } else if (strcmp(arg, "--help") == 0) { | 276 | } else if (strcmp(arg, "--help") == 0) { |
| 112 | return print_full_usage(arg0, stdout, EXIT_SUCCESS); | 277 | return print_full_usage(arg0, stdout, EXIT_SUCCESS); |
| 113 | } else if (strcmp(arg, "--strip") == 0) { | 278 | } else if (strcmp(arg, "--strip") == 0) { |
| ... | @@ -183,8 +348,6 @@ int main(int argc, char **argv) { | ... | @@ -183,8 +348,6 @@ int main(int argc, char **argv) { |
| 183 | dynamic_linker = argv[i]; | 348 | dynamic_linker = argv[i]; |
| 184 | } else if (strcmp(arg, "--override-lib-dir") == 0) { | 349 | } else if (strcmp(arg, "--override-lib-dir") == 0) { |
| 185 | override_lib_dir = argv[i]; | 350 | override_lib_dir = argv[i]; |
| 186 | } else if (strcmp(arg, "--main-pkg-path") == 0) { | ||
| 187 | main_pkg_path = argv[i]; | ||
| 188 | } else if (strcmp(arg, "--library") == 0 || strcmp(arg, "-l") == 0) { | 351 | } else if (strcmp(arg, "--library") == 0 || strcmp(arg, "-l") == 0) { |
| 189 | if (strcmp(argv[i], "c") == 0) { | 352 | if (strcmp(argv[i], "c") == 0) { |
| 190 | link_libc = true; | 353 | link_libc = true; |
| ... | @@ -264,12 +427,13 @@ int main(int argc, char **argv) { | ... | @@ -264,12 +427,13 @@ int main(int argc, char **argv) { |
| 264 | return print_error_usage(arg0); | 427 | return print_error_usage(arg0); |
| 265 | } | 428 | } |
| 266 | 429 | ||
| 267 | ZigStage1 *stage1 = zig_stage1_create(build_mode, | 430 | ZigStage1 *stage1 = zig_stage1_create(optimize_mode, |
| 268 | main_pkg_path, (main_pkg_path == nullptr) ? 0 : strlen(main_pkg_path), | 431 | nullptr, 0, |
| 269 | in_file, strlen(in_file), | 432 | in_file, strlen(in_file), |
| 270 | override_lib_dir, strlen(override_lib_dir), &target, false, | 433 | override_lib_dir, strlen(override_lib_dir), |
| 271 | root_progress_node); | 434 | &target, false); |
| 272 | 435 | ||
| 436 | stage1->main_progress_node = root_progress_node; | ||
| 273 | stage1->root_name_ptr = out_name; | 437 | stage1->root_name_ptr = out_name; |
| 274 | stage1->root_name_len = strlen(out_name); | 438 | stage1->root_name_len = strlen(out_name); |
| 275 | stage1->strip = strip; | 439 | stage1->strip = strip; |
| ... | @@ -295,3 +459,66 @@ int main(int argc, char **argv) { | ... | @@ -295,3 +459,66 @@ int main(int argc, char **argv) { |
| 295 | 459 | ||
| 296 | return main_exit(root_progress_node, EXIT_SUCCESS); | 460 | return main_exit(root_progress_node, EXIT_SUCCESS); |
| 297 | } | 461 | } |
| 462 | |||
| 463 | void stage2_panic(const char *ptr, size_t len) { | ||
| 464 | fwrite(ptr, 1, len, stderr); | ||
| 465 | fprintf(stderr, "\n"); | ||
| 466 | fflush(stderr); | ||
| 467 | abort(); | ||
| 468 | } | ||
| 469 | |||
| 470 | struct Stage2Progress { | ||
| 471 | int trash; | ||
| 472 | }; | ||
| 473 | |||
| 474 | struct Stage2ProgressNode { | ||
| 475 | int trash; | ||
| 476 | }; | ||
| 477 | |||
| 478 | Stage2Progress *stage2_progress_create(void) { | ||
| 479 | return nullptr; | ||
| 480 | } | ||
| 481 | |||
| 482 | void stage2_progress_destroy(Stage2Progress *progress) {} | ||
| 483 | |||
| 484 | Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, | ||
| 485 | const char *name_ptr, size_t name_len, size_t estimated_total_items) | ||
| 486 | { | ||
| 487 | return nullptr; | ||
| 488 | } | ||
| 489 | Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, | ||
| 490 | const char *name_ptr, size_t name_len, size_t estimated_total_items) | ||
| 491 | { | ||
| 492 | return nullptr; | ||
| 493 | } | ||
| 494 | void stage2_progress_end(Stage2ProgressNode *node) {} | ||
| 495 | void stage2_progress_complete_one(Stage2ProgressNode *node) {} | ||
| 496 | void stage2_progress_disable_tty(Stage2Progress *progress) {} | ||
| 497 | void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){} | ||
| 498 | |||
| 499 | const char *stage2_fetch_file(struct ZigStage1 *stage1, const char *path_ptr, size_t path_len, | ||
| 500 | size_t *result_len) | ||
| 501 | { | ||
| 502 | Error err; | ||
| 503 | Buf contents_buf = BUF_INIT; | ||
| 504 | Buf path_buf = BUF_INIT; | ||
| 505 | |||
| 506 | buf_init_from_mem(&path_buf, path_ptr, path_len); | ||
| 507 | if ((err = os_fetch_file_path(&path_buf, &contents_buf))) { | ||
| 508 | return nullptr; | ||
| 509 | } | ||
| 510 | *result_len = buf_len(&contents_buf); | ||
| 511 | return buf_ptr(&contents_buf); | ||
| 512 | } | ||
| 513 | |||
| 514 | const char *stage2_cimport(struct ZigStage1 *stage1) { | ||
| 515 | const char *msg = "stage0 called stage2_cimport"; | ||
| 516 | stage2_panic(msg, strlen(msg)); | ||
| 517 | } | ||
| 518 | |||
| 519 | const char *stage2_add_link_lib(struct ZigStage1 *stage1, | ||
| 520 | const char *lib_name_ptr, size_t lib_name_len, | ||
| 521 | const char *symbol_name_ptr, size_t symbol_name_len) | ||
| 522 | { | ||
| 523 | return nullptr; | ||
| 524 | } |