From 503ba7b27c6e8e248d271aec936623853cd8fcd1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 3 Sep 2020 20:23:00 -0700 Subject: start moving `zig cc` to stage2 * build.zig: repair the ability to link against llvm, clang, and lld * move the zig cc arg parsing logic to stage2 - the preprocessor flag is still TODO - the clang arg iterator code is improved to use slices instead of raw pointers because it no longer has to deal with an extern struct. * clean up error printing with a `fatal` function and use log API for messages rather than std.debug.print * add support for more CLI options to stage2 & update usage text - hooking up most of these new options is TODO * clean up the way libc and libc++ are detected via command line options. target information is used to determine if any of the libc candidate names are chosen. * add native library directory detection * implement the ability to invoke clang from stage2 * introduce a build_options.have_llvm so we can comptime branch on whether LLVM is linked in or not. --- src/stage2.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'src/stage2.cpp') diff --git a/src/stage2.cpp b/src/stage2.cpp index 6c010de84f..ad6a9f9d97 100644 --- a/src/stage2.cpp +++ b/src/stage2.cpp @@ -32,6 +32,11 @@ int stage2_env(int argc, char** argv) { stage2_panic(msg, strlen(msg)); } +int stage2_cc(int argc, char** argv, bool is_cpp) { + const char *msg = "stage0 called stage2_cc"; + stage2_panic(msg, strlen(msg)); +} + void stage2_attach_segfault_handler(void) { } void stage2_panic(const char *ptr, size_t len) { @@ -316,16 +321,4 @@ enum Error stage2_detect_native_paths(struct Stage2NativePaths *native_paths) { return ErrorNone; } -void stage2_clang_arg_iterator(struct Stage2ClangArgIterator *it, - size_t argc, char **argv) -{ - const char *msg = "stage0 called stage2_clang_arg_iterator"; - stage2_panic(msg, strlen(msg)); -} - -enum Error stage2_clang_arg_next(struct Stage2ClangArgIterator *it) { - const char *msg = "stage0 called stage2_clang_arg_next"; - stage2_panic(msg, strlen(msg)); -} - const bool stage2_is_zig0 = true; -- cgit v1.2.3 From dc478687d95ee0d495cd26182edae78a01db59af Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 17 Sep 2020 18:29:38 -0700 Subject: delete all stage1 c++ code not directly related to compiling stage2 Deleted 16,000+ lines of c++ code, including: * an implementation of blake hashing * the cache hash system * compiler.cpp * all the linking code, and everything having to do with building glibc, musl, and mingw-w64 * much of the stage1 compiler internals got slimmed down since it now assumes it is always outputting an object file. More stuff: * stage1 is now built with a different strategy: we have a tiny zig0.cpp which is a slimmed down version of what stage1 main.cpp used to be. Its only purpose is to build stage2 zig code into an object file, which is then linked by the host build system (cmake) into stage1. zig0.cpp uses the same C API that stage2 now has access to, so that stage2 zig code can call into stage1 c++ code. - stage1.h is - stage2.h is - stage1.zig is the main entry point for the Zig/C++ hybrid compiler. It has the functions exported from Zig, called in C++, and bindings for the functions exported from C++, called from Zig. * removed the memory profiling instrumentation from stage1. Abandon ship! * Re-added the sections to the README about how to build stage2 and stage3. * stage2 now knows as a comptime boolean whether it is being compiled as part of stage1 or as stage2. - TODO use this flag to call into stage1 for compiling zig code. * introduce -fdll-export-fns and -fno-dll-export-fns and clarify its relationship to link_mode (static/dynamic) * implement depending on LLVM to detect native target cpu features when LLVM extensions are enabled and zig lacks CPU feature detection for that target architecture. * C importing is broken, will need some stage2 support to function again. --- BRANCH_TODO | 24 +- CMakeLists.txt | 71 +- README.md | 37 + build.zig | 2 + src-self-hosted/Compilation.zig | 18 +- src-self-hosted/libcxx.zig | 66 + src-self-hosted/link.zig | 1 + src-self-hosted/main.zig | 112 +- src-self-hosted/musl.zig | 1843 ++++++++++++++++++++++++ src-self-hosted/stage1.zig | 495 +++++++ src-self-hosted/stage2.zig | 1054 -------------- src/all_types.hpp | 135 +- src/analyze.cpp | 49 +- src/analyze.hpp | 3 - src/blake2.h | 196 --- src/blake2b.c | 539 ------- src/cache_hash.cpp | 595 -------- src/cache_hash.hpp | 83 -- src/codegen.cpp | 2231 +++-------------------------- src/codegen.hpp | 35 +- src/compiler.cpp | 196 --- src/compiler.hpp | 24 - src/config.h.in | 2 - src/config.zig.in | 1 + src/dump_analysis.cpp | 12 +- src/empty.cpp | 0 src/errmsg.hpp | 7 +- src/glibc.cpp | 392 ----- src/glibc.hpp | 50 - src/heap.cpp | 66 +- src/heap.hpp | 19 - src/install_files.h | 1907 ------------------------- src/ir.cpp | 181 +-- src/link.cpp | 2985 --------------------------------------- src/main.cpp | 1474 ------------------- src/mem.cpp | 13 - src/mem.hpp | 9 - src/mem_profile.cpp | 181 --- src/mem_profile.hpp | 71 - src/mem_type_info.hpp | 109 -- src/stage1.cpp | 127 ++ src/stage1.h | 217 +++ src/stage2.cpp | 125 +- src/stage2.h | 182 +-- src/target.cpp | 127 -- src/target.hpp | 30 - src/zig0.cpp | 307 ++++ 47 files changed, 3526 insertions(+), 12877 deletions(-) create mode 100644 src-self-hosted/libcxx.zig create mode 100644 src-self-hosted/musl.zig create mode 100644 src-self-hosted/stage1.zig delete mode 100644 src-self-hosted/stage2.zig delete mode 100644 src/blake2.h delete mode 100644 src/blake2b.c delete mode 100644 src/cache_hash.cpp delete mode 100644 src/cache_hash.hpp delete mode 100644 src/compiler.cpp delete mode 100644 src/compiler.hpp create mode 100644 src/empty.cpp delete mode 100644 src/glibc.cpp delete mode 100644 src/glibc.hpp delete mode 100644 src/install_files.h delete mode 100644 src/link.cpp delete mode 100644 src/main.cpp delete mode 100644 src/mem_profile.cpp delete mode 100644 src/mem_profile.hpp create mode 100644 src/stage1.cpp create mode 100644 src/stage1.h create mode 100644 src/zig0.cpp (limited to 'src/stage2.cpp') diff --git a/BRANCH_TODO b/BRANCH_TODO index 1934cfd02d..56f4661259 100644 --- a/BRANCH_TODO +++ b/BRANCH_TODO @@ -1,3 +1,21 @@ + * `zig builtin` + * `zig translate-c` + * `zig test` + * `zig run` + * `zig init-lib` + * `zig init-exe` + * `zig build` + * `-ftime-report` + * -fstack-report print stack size diagnostics\n" + * -fdump-analysis write analysis.json file with type information\n" + * -femit-docs create a docs/ dir with html documentation\n" + * -fno-emit-docs do not produce docs/ dir with html documentation\n" + * -femit-asm output .s (assembly code)\n" + * -fno-emit-asm (default) do not output .s (assembly code)\n" + * -femit-llvm-ir produce a .ll file with LLVM IR\n" + * -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n" + * --cache-dir [path] override the local cache directory\n" + * move main.cpp to stage2 * make sure zig cc works - using it as a preprocessor (-E) - try building some software @@ -6,26 +24,24 @@ - stage1 C++ code integration * build & link againstn freestanding libc * add CLI support for a way to pass extra flags to c source files - * implement the workaround for using LLVM to detect native CPU features - * self-host main.cpp * capture lld stdout/stderr better * musl * mingw-w64 * use global zig-cache dir for crt files - * `zig translate-c` * MachO LLD linking * COFF LLD linking * WASM LLD linking * implement proper parsing of LLD stderr/stdout and exposing compile errors * implement proper parsing of clang stderr/stdout and exposing compile errors * implement proper compile errors for failing to build glibc crt files and shared libs - * self-host link.cpp and building libcs (#4313 and #4314). using the `zig cc` command will set a flag indicating a preference for the llvm backend, which will include linking with LLD. At least for now. If zig's self-hosted linker ever gets on par with the likes of ld and lld, we can make it always be used even for zig cc. * improve the stage2 tests to support testing with LLVM extensions enabled * multi-thread building C objects * support cross compiling stage2 with `zig build` * implement emit-h in stage2 * implement -fno-emit-bin * audit the base cache hash + * audit the CLI options for stage2 + * implement serialization/deserialization of incremental compilation metadata * incremental compilation - implement detection of which source files changed * improve the cache hash logic for c objects with respect to extra flags and file parameters diff --git a/CMakeLists.txt b/CMakeLists.txt index ceaecf5552..c8746338d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,6 @@ message("Configuring zig version ${ZIG_VERSION}") set(ZIG_STATIC off CACHE BOOL "Attempt to build a static zig executable (not compatible with glibc)") set(ZIG_STATIC_LLVM off CACHE BOOL "Prefer linking against static LLVM libraries") -set(ZIG_ENABLE_MEM_PROFILE off CACHE BOOL "Activate memory usage instrumentation") set(ZIG_PREFER_CLANG_CPP_DYLIB off CACHE BOOL "Try to link against -lclang-cpp") set(ZIG_WORKAROUND_4799 off CACHE BOOL "workaround for https://github.com/ziglang/zig/issues/4799") set(ZIG_WORKAROUND_POLLY_SO off CACHE STRING "workaround for https://github.com/ziglang/zig/issues/4799") @@ -71,11 +70,6 @@ string(REGEX REPLACE "\\\\" "\\\\\\\\" ZIG_LIBC_INCLUDE_DIR_ESCAPED "${ZIG_LIBC_ option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF) -# Zig no longer has embedded LLD. This option is kept for package maintainers -# so that they don't have to update their scripts in case we ever re-introduce -# LLD to the tree. This option does nothing. -option(ZIG_FORCE_EXTERNAL_LLD "does nothing" OFF) - set(ZIG_TARGET_TRIPLE "native" CACHE STRING "arch-os-abi to output binaries for") set(ZIG_TARGET_MCPU "baseline" CACHE STRING "-mcpu parameter to output binaries for") set(ZIG_EXECUTABLE "" CACHE STRING "(when cross compiling) path to already-built zig binary") @@ -261,15 +255,11 @@ include_directories("${CMAKE_SOURCE_DIR}/deps/dbg-macro") find_package(Threads) -# CMake doesn't let us create an empty executable, so we hang on to this one separately. -set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp") - -# This is our shim which will be replaced by libstage2 written in Zig. -set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/stage2.cpp") - -if(ZIG_ENABLE_MEM_PROFILE) - set(ZIG_SOURCES_MEM_PROFILE "${CMAKE_SOURCE_DIR}/src/mem_profile.cpp") -endif() +# This is our shim which will be replaced by stage1.zig. +set(ZIG0_SOURCES + "${CMAKE_SOURCE_DIR}/src/zig0.cpp" + "${CMAKE_SOURCE_DIR}/src/stage2.cpp" +) set(ZIG_SOURCES "${CMAKE_SOURCE_DIR}/src/analyze.cpp" @@ -277,37 +267,34 @@ set(ZIG_SOURCES "${CMAKE_SOURCE_DIR}/src/bigfloat.cpp" "${CMAKE_SOURCE_DIR}/src/bigint.cpp" "${CMAKE_SOURCE_DIR}/src/buffer.cpp" - "${CMAKE_SOURCE_DIR}/src/cache_hash.cpp" "${CMAKE_SOURCE_DIR}/src/codegen.cpp" - "${CMAKE_SOURCE_DIR}/src/compiler.cpp" "${CMAKE_SOURCE_DIR}/src/dump_analysis.cpp" "${CMAKE_SOURCE_DIR}/src/errmsg.cpp" "${CMAKE_SOURCE_DIR}/src/error.cpp" - "${CMAKE_SOURCE_DIR}/src/glibc.cpp" "${CMAKE_SOURCE_DIR}/src/heap.cpp" "${CMAKE_SOURCE_DIR}/src/ir.cpp" "${CMAKE_SOURCE_DIR}/src/ir_print.cpp" - "${CMAKE_SOURCE_DIR}/src/link.cpp" "${CMAKE_SOURCE_DIR}/src/mem.cpp" "${CMAKE_SOURCE_DIR}/src/os.cpp" "${CMAKE_SOURCE_DIR}/src/parser.cpp" "${CMAKE_SOURCE_DIR}/src/range_set.cpp" + "${CMAKE_SOURCE_DIR}/src/stage1.cpp" "${CMAKE_SOURCE_DIR}/src/target.cpp" "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp" "${CMAKE_SOURCE_DIR}/src/util.cpp" "${CMAKE_SOURCE_DIR}/src/softfloat_ext.cpp" - "${ZIG_SOURCES_MEM_PROFILE}" ) set(OPTIMIZED_C_SOURCES - "${CMAKE_SOURCE_DIR}/src/blake2b.c" "${CMAKE_SOURCE_DIR}/src/parse_f128.c" ) set(ZIG_CPP_SOURCES + # These are planned to stay even when we are self-hosted. "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp" "${CMAKE_SOURCE_DIR}/src/zig_clang.cpp" "${CMAKE_SOURCE_DIR}/src/zig_clang_driver.cpp" "${CMAKE_SOURCE_DIR}/src/zig_clang_cc1_main.cpp" "${CMAKE_SOURCE_DIR}/src/zig_clang_cc1as_main.cpp" + # https://github.com/ziglang/zig/issues/6363 "${CMAKE_SOURCE_DIR}/src/windows_sdk.cpp" ) @@ -447,7 +434,7 @@ if(MSVC OR MINGW) target_link_libraries(zigcompiler LINK_PUBLIC version) endif() -add_executable(zig0 "${ZIG_MAIN_SRC}" "${ZIG0_SHIM_SRC}") +add_executable(zig0 ${ZIG0_SOURCES}) set_target_properties(zig0 PROPERTIES COMPILE_FLAGS ${EXE_CFLAGS} LINK_FLAGS ${EXE_LDFLAGS} @@ -455,37 +442,36 @@ set_target_properties(zig0 PROPERTIES target_link_libraries(zig0 zigcompiler) if(MSVC) - set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/zigstage2.lib") + set(ZIG1_OBJECT "${CMAKE_BINARY_DIR}/zig1.obj") else() - set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/libzigstage2.a") + set(ZIG1_OBJECT "${CMAKE_BINARY_DIR}/zig1.o") endif() if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - set(LIBSTAGE2_RELEASE_ARG "") + set(ZIG1_RELEASE_ARG "") else() - set(LIBSTAGE2_RELEASE_ARG --release-fast --strip) + set(ZIG1_RELEASE_ARG --release-fast --strip) endif() -set(BUILD_LIBSTAGE2_ARGS "build-lib" - "src-self-hosted/stage2.zig" +set(BUILD_ZIG1_ARGS + "src-self-hosted/stage1.zig" -target "${ZIG_TARGET_TRIPLE}" "-mcpu=${ZIG_TARGET_MCPU}" - --name zigstage2 + --name zig1 --override-lib-dir "${CMAKE_SOURCE_DIR}/lib" - --cache on --output-dir "${CMAKE_BINARY_DIR}" - ${LIBSTAGE2_RELEASE_ARG} - --bundle-compiler-rt - -fPIC + ${ZIG1_RELEASE_ARG} -lc --pkg-begin build_options "${ZIG_CONFIG_ZIG_OUT}" --pkg-end + --pkg-begin compiler_rt "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt.zig" + --pkg-end ) if("${ZIG_TARGET_TRIPLE}" STREQUAL "native") - add_custom_target(zig_build_libstage2 ALL - COMMAND zig0 ${BUILD_LIBSTAGE2_ARGS} + add_custom_target(zig_build_zig1 ALL + COMMAND zig0 ${BUILD_ZIG1_ARGS} DEPENDS zig0 - BYPRODUCTS "${LIBSTAGE2}" + BYPRODUCTS "${ZIG1_OBJECT}" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" ) set(ZIG_EXECUTABLE "${zig_BINARY_DIR}/zig") @@ -493,26 +479,27 @@ if("${ZIG_TARGET_TRIPLE}" STREQUAL "native") set(ZIG_EXECUTABLE "${ZIG_EXECUTABLE}.exe") endif() else() - add_custom_target(zig_build_libstage2 ALL - COMMAND "${ZIG_EXECUTABLE}" ${BUILD_LIBSTAGE2_ARGS} - BYPRODUCTS "${LIBSTAGE2}" + add_custom_target(zig_build_zig1 ALL + COMMAND "${ZIG_EXECUTABLE}" ${BUILD_ZIG1_ARGS} + BYPRODUCTS "${ZIG1_OBJECT}" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" ) endif() -add_executable(zig "${ZIG_MAIN_SRC}") +# cmake won't let us configure an executable without C sources. +add_executable(zig "${CMAKE_SOURCE_DIR}/src/empty.cpp") set_target_properties(zig PROPERTIES COMPILE_FLAGS ${EXE_CFLAGS} LINK_FLAGS ${EXE_LDFLAGS} ) -target_link_libraries(zig zigcompiler "${LIBSTAGE2}") +target_link_libraries(zig zigcompiler "${ZIG1_OBJECT}") if(MSVC) target_link_libraries(zig ntdll.lib) elseif(MINGW) target_link_libraries(zig ntdll) endif() -add_dependencies(zig zig_build_libstage2) +add_dependencies(zig zig_build_zig1) install(TARGETS zig DESTINATION bin) diff --git a/README.md b/README.md index 8031aa790e..242f78d59e 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ Note that you can ### Stage 1: Build Zig from C++ Source Code +This step must be repeated when you make changes to any of the C++ source code. + #### Dependencies ##### POSIX @@ -77,6 +79,41 @@ Hopefully this will be fixed upstream with LLVM 10.0.1. See https://github.com/ziglang/zig/wiki/Building-Zig-on-Windows +### Stage 2: Build Self-Hosted Zig from Zig Source Code + +Now we use the stage1 binary: + +``` +zig build --prefix $(pwd)/stage2 -Denable-llvm +``` + +This produces `stage2/bin/zig` which can be used for testing and development. +Once it is feature complete, it will be used to build stage 3 - the final compiler +binary. + +### Stage 3: Rebuild Self-Hosted Zig Using the Self-Hosted Compiler + +*Note: Stage 2 compiler is not yet able to build Stage 3. Building Stage 3 is +not yet supported.* + +Once the self-hosted compiler can build itself, this will be the actual +compiler binary that we will install to the system. Until then, users should +use stage 1. + +#### Debug / Development Build + +``` +stage2/bin/zig build +``` + +This produces `zig-cache/bin/zig`. + +#### Release / Install Build + +``` +stage2/bin/zig build install -Drelease +``` + ## License The ultimate goal of the Zig project is to serve users. As a first-order diff --git a/build.zig b/build.zig index 17ee040e8f..9e5f2425c2 100644 --- a/build.zig +++ b/build.zig @@ -145,6 +145,7 @@ pub fn build(b: *Builder) !void { exe.addBuildOption([]const []const u8, "log_scopes", log_scopes); exe.addBuildOption([]const []const u8, "zir_dumps", zir_dumps); exe.addBuildOption(bool, "enable_tracy", tracy != null); + exe.addBuildOption(bool, "is_stage1", false); if (tracy) |tracy_path| { const client_cpp = fs.path.join( b.allocator, @@ -165,6 +166,7 @@ pub fn build(b: *Builder) !void { const is_wasmtime_enabled = b.option(bool, "enable-wasmtime", "Use Wasmtime to enable and run WASI libstd tests") orelse false; const glibc_multi_dir = b.option([]const u8, "enable-foreign-glibc", "Provide directory with glibc installations to run cross compiled tests that link glibc"); + test_stage2.addBuildOption(bool, "is_stage1", false); test_stage2.addBuildOption(bool, "have_llvm", enable_llvm); test_stage2.addBuildOption(bool, "enable_qemu", is_qemu_enabled); test_stage2.addBuildOption(bool, "enable_wine", is_wine_enabled); diff --git a/src-self-hosted/Compilation.zig b/src-self-hosted/Compilation.zig index 8e18e7fffc..05f76f08f3 100644 --- a/src-self-hosted/Compilation.zig +++ b/src-self-hosted/Compilation.zig @@ -244,6 +244,7 @@ pub const InitOptions = struct { /// `null` means to not emit a C header file. emit_h: ?EmitLoc = null, link_mode: ?std.builtin.LinkMode = null, + dll_export_fns: ?bool = false, object_format: ?std.builtin.ObjectFormat = null, optimize_mode: std.builtin.Mode = .Debug, keep_source_files_loaded: bool = false, @@ -340,9 +341,13 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { return error.MachineCodeModelNotSupported; } + const is_dyn_lib = switch (options.output_mode) { + .Obj, .Exe => false, + .Lib => (options.link_mode orelse .Static) == .Dynamic, + }; const is_exe_or_dyn_lib = switch (options.output_mode) { .Obj => false, - .Lib => (options.link_mode orelse .Static) == .Dynamic, + .Lib => is_dyn_lib, .Exe => true, }; const must_dynamic_link = dl: { @@ -365,6 +370,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { break :blk lm; } else default_link_mode; + const dll_export_fns = if (options.dll_export_fns) |explicit| explicit else is_dyn_lib; + const libc_dirs = try detectLibCIncludeDirs( arena, options.zig_lib_directory.path.?, @@ -379,7 +386,12 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { break :b true; break :b link_mode == .Dynamic; }; - const pic = options.want_pic orelse must_pic; + const pic = if (options.want_pic) |explicit| pic: { + if (!explicit and must_pic) { + return error.TargetRequiresPIC; + } + break :pic explicit; + } else must_pic; if (options.emit_h != null) fatal("-femit-h not supported yet", .{}); // TODO @@ -464,6 +476,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { hash.add(valgrind); hash.add(single_threaded); hash.add(options.target.os.getVersionRange()); + hash.add(dll_export_fns); const digest = hash.final(); const artifact_sub_dir = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); @@ -601,6 +614,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .single_threaded = single_threaded, .debug_link = options.debug_link, .machine_code_model = options.machine_code_model, + .dll_export_fns = dll_export_fns, }); errdefer bin_file.destroy(); diff --git a/src-self-hosted/libcxx.zig b/src-self-hosted/libcxx.zig new file mode 100644 index 0000000000..c7dc24ae9f --- /dev/null +++ b/src-self-hosted/libcxx.zig @@ -0,0 +1,66 @@ +//! TODO build libcxx and libcxxabi from source + +pub const libcxxabi_files = [_][]const u8{ + "src/abort_message.cpp", + "src/cxa_aux_runtime.cpp", + "src/cxa_default_handlers.cpp", + "src/cxa_demangle.cpp", + "src/cxa_exception.cpp", + "src/cxa_exception_storage.cpp", + "src/cxa_guard.cpp", + "src/cxa_handlers.cpp", + "src/cxa_noexception.cpp", + "src/cxa_personality.cpp", + "src/cxa_thread_atexit.cpp", + "src/cxa_unexpected.cpp", + "src/cxa_vector.cpp", + "src/cxa_virtual.cpp", + "src/fallback_malloc.cpp", + "src/private_typeinfo.cpp", + "src/stdlib_exception.cpp", + "src/stdlib_stdexcept.cpp", + "src/stdlib_typeinfo.cpp", +}; + +pub const libcxx_files = [_][]const u8{ + "src/algorithm.cpp", + "src/any.cpp", + "src/bind.cpp", + "src/charconv.cpp", + "src/chrono.cpp", + "src/condition_variable.cpp", + "src/condition_variable_destructor.cpp", + "src/debug.cpp", + "src/exception.cpp", + "src/experimental/memory_resource.cpp", + "src/filesystem/directory_iterator.cpp", + "src/filesystem/operations.cpp", + "src/functional.cpp", + "src/future.cpp", + "src/hash.cpp", + "src/ios.cpp", + "src/iostream.cpp", + "src/locale.cpp", + "src/memory.cpp", + "src/mutex.cpp", + "src/mutex_destructor.cpp", + "src/new.cpp", + "src/optional.cpp", + "src/random.cpp", + "src/regex.cpp", + "src/shared_mutex.cpp", + "src/stdexcept.cpp", + "src/string.cpp", + "src/strstream.cpp", + "src/support/solaris/xlocale.cpp", + "src/support/win32/locale_win32.cpp", + "src/support/win32/support.cpp", + "src/support/win32/thread_win32.cpp", + "src/system_error.cpp", + "src/thread.cpp", + "src/typeinfo.cpp", + "src/utility.cpp", + "src/valarray.cpp", + "src/variant.cpp", + "src/vector.cpp", +}; diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig index cdeb2b5e5c..069a90872e 100644 --- a/src-self-hosted/link.zig +++ b/src-self-hosted/link.zig @@ -62,6 +62,7 @@ pub const Options = struct { stack_check: bool, single_threaded: bool, debug_link: bool = false, + dll_export_fns: bool, gc_sections: ?bool = null, allow_shlib_undefined: ?bool = null, linker_script: ?[]const u8 = null, diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index c9b872cc7e..db68c867b2 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -92,7 +92,7 @@ pub fn log( var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){}; -pub fn main() !void { +pub fn main() anyerror!void { const gpa = if (std.builtin.link_libc) std.heap.c_allocator else &general_purpose_allocator.allocator; defer if (!std.builtin.link_libc) { _ = general_purpose_allocator.deinit(); @@ -102,7 +102,10 @@ pub fn main() !void { const arena = &arena_instance.allocator; const args = try process.argsAlloc(arena); + return mainArgs(gpa, arena, args); +} +pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !void { if (args.len <= 1) { std.log.info("{}", .{usage}); fatal("expected command argument", .{}); @@ -131,7 +134,7 @@ pub fn main() !void { } else if (mem.eql(u8, cmd, "libc")) { return cmdLibC(gpa, cmd_args); } else if (mem.eql(u8, cmd, "targets")) { - const info = try std.zig.system.NativeTargetInfo.detect(arena, .{}); + const info = try detectNativeTargetInfo(arena, .{}); const stdout = io.getStdOut().outStream(); return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, info.target); } else if (mem.eql(u8, cmd, "version")) { @@ -183,7 +186,7 @@ const usage_build_generic = \\ -mcmodel=[default|tiny| Limit range of code and data virtual addresses \\ small|kernel| \\ medium|large] - \\ --name [name] Override output name + \\ --name [name] Override root name (not a file path) \\ --mode [mode] Set the build mode \\ Debug (default) optimizations off, safety on \\ ReleaseFast Optimizations on, safety off @@ -197,7 +200,9 @@ const usage_build_generic = \\ -fno-sanitize-c Disable C undefined behavior detection in safe builds \\ -fvalgrind Include valgrind client requests in release builds \\ -fno-valgrind Omit valgrind client requests in debug builds - \\ --strip Exclude debug symbols + \\ -fdll-export-fns Mark exported functions as DLL exports (Windows) + \\ -fno-dll-export-fns Force-disable marking exported functions as DLL exports + \\ --strip Omit debug symbols \\ --single-threaded Code assumes it is only used single-threaded \\ -ofmt=[mode] Override target object format \\ elf Executable and Linking Format @@ -262,6 +267,7 @@ pub fn buildOutputType( var build_mode: std.builtin.Mode = .Debug; var provided_name: ?[]const u8 = null; var link_mode: ?std.builtin.LinkMode = null; + var dll_export_fns: ?bool = null; var root_src_file: ?[]const u8 = null; var version: std.builtin.Version = .{ .major = 0, .minor = 0, .patch = 0 }; var have_version = false; @@ -521,6 +527,10 @@ pub fn buildOutputType( link_mode = .Dynamic; } else if (mem.eql(u8, arg, "-static")) { link_mode = .Static; + } else if (mem.eql(u8, arg, "-fdll-export-fns")) { + dll_export_fns = true; + } else if (mem.eql(u8, arg, "-fno-dll-export-fns")) { + dll_export_fns = false; } else if (mem.eql(u8, arg, "--strip")) { strip = true; } else if (mem.eql(u8, arg, "--single-threaded")) { @@ -902,14 +912,7 @@ pub fn buildOutputType( else => |e| return e, }; - const target_info = try std.zig.system.NativeTargetInfo.detect(gpa, cross_target); - if (target_info.cpu_detection_unimplemented) { - // TODO We want to just use detected_info.target but implementing - // CPU model & feature detection is todo so here we rely on LLVM. - // TODO The workaround to use LLVM to detect features needs to be used for - // `zig targets` as well. - fatal("CPU features detection is not yet available for this system without LLVM extensions", .{}); - } + const target_info = try detectNativeTargetInfo(gpa, cross_target); if (target_info.target.os.tag != .freestanding) { if (ensure_libc_on_non_freestanding) @@ -1116,6 +1119,7 @@ pub fn buildOutputType( .emit_bin = emit_bin_loc, .emit_h = emit_h_loc, .link_mode = link_mode, + .dll_export_fns = dll_export_fns, .object_format = object_format, .optimize_mode = build_mode, .keep_source_files_loaded = zir_out_path != null, @@ -1974,3 +1978,87 @@ fn gimmeMoreOfThoseSweetSweetFileDescriptors() void { test "fds" { gimmeMoreOfThoseSweetSweetFileDescriptors(); } + +fn detectNativeCpuWithLLVM( + arch: std.Target.Cpu.Arch, + llvm_cpu_name_z: ?[*:0]const u8, + llvm_cpu_features_opt: ?[*:0]const u8, +) !std.Target.Cpu { + var result = std.Target.Cpu.baseline(arch); + + if (llvm_cpu_name_z) |cpu_name_z| { + const llvm_cpu_name = mem.spanZ(cpu_name_z); + + for (arch.allCpuModels()) |model| { + const this_llvm_name = model.llvm_name orelse continue; + if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) { + // Here we use the non-dependencies-populated set, + // so that subtracting features later in this function + // affect the prepopulated set. + result = std.Target.Cpu{ + .arch = arch, + .model = model, + .features = model.features, + }; + break; + } + } + } + + const all_features = arch.allFeaturesList(); + + if (llvm_cpu_features_opt) |llvm_cpu_features| { + var it = mem.tokenize(mem.spanZ(llvm_cpu_features), ","); + while (it.next()) |decorated_llvm_feat| { + var op: enum { + add, + sub, + } = undefined; + var llvm_feat: []const u8 = undefined; + if (mem.startsWith(u8, decorated_llvm_feat, "+")) { + op = .add; + llvm_feat = decorated_llvm_feat[1..]; + } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) { + op = .sub; + llvm_feat = decorated_llvm_feat[1..]; + } else { + return error.InvalidLlvmCpuFeaturesFormat; + } + for (all_features) |feature, index_usize| { + const this_llvm_name = feature.llvm_name orelse continue; + if (mem.eql(u8, llvm_feat, this_llvm_name)) { + const index = @intCast(std.Target.Cpu.Feature.Set.Index, index_usize); + switch (op) { + .add => result.features.addFeature(index), + .sub => result.features.removeFeature(index), + } + break; + } + } + } + } + + result.features.populateDependencies(all_features); + return result; +} + +fn detectNativeTargetInfo(gpa: *Allocator, cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo { + var info = try std.zig.system.NativeTargetInfo.detect(gpa, cross_target); + if (info.cpu_detection_unimplemented) { + const arch = std.Target.current.cpu.arch; + + // We want to just use detected_info.target but implementing + // CPU model & feature detection is todo so here we rely on LLVM. + // https://github.com/ziglang/zig/issues/4591 + if (!build_options.have_llvm) + fatal("CPU features detection is not yet available for {} without LLVM extensions", .{@tagName(arch)}); + + const llvm = @import("llvm.zig"); + const llvm_cpu_name = llvm.GetHostCPUName(); + const llvm_cpu_features = llvm.GetNativeFeatures(); + info.target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features); + cross_target.updateCpuFeatures(&info.target.cpu.features); + info.target.cpu.arch = cross_target.getCpuArch(); + } + return info; +} diff --git a/src-self-hosted/musl.zig b/src-self-hosted/musl.zig new file mode 100644 index 0000000000..88536b90fd --- /dev/null +++ b/src-self-hosted/musl.zig @@ -0,0 +1,1843 @@ +//! TODO build musl libc from source + +pub const src_files = [_][]const u8{ + "musl/src/aio/aio.c", + "musl/src/aio/aio_suspend.c", + "musl/src/aio/lio_listio.c", + "musl/src/complex/__cexp.c", + "musl/src/complex/__cexpf.c", + "musl/src/complex/cabs.c", + "musl/src/complex/cabsf.c", + "musl/src/complex/cabsl.c", + "musl/src/complex/cacos.c", + "musl/src/complex/cacosf.c", + "musl/src/complex/cacosh.c", + "musl/src/complex/cacoshf.c", + "musl/src/complex/cacoshl.c", + "musl/src/complex/cacosl.c", + "musl/src/complex/carg.c", + "musl/src/complex/cargf.c", + "musl/src/complex/cargl.c", + "musl/src/complex/casin.c", + "musl/src/complex/casinf.c", + "musl/src/complex/casinh.c", + "musl/src/complex/casinhf.c", + "musl/src/complex/casinhl.c", + "musl/src/complex/casinl.c", + "musl/src/complex/catan.c", + "musl/src/complex/catanf.c", + "musl/src/complex/catanh.c", + "musl/src/complex/catanhf.c", + "musl/src/complex/catanhl.c", + "musl/src/complex/catanl.c", + "musl/src/complex/ccos.c", + "musl/src/complex/ccosf.c", + "musl/src/complex/ccosh.c", + "musl/src/complex/ccoshf.c", + "musl/src/complex/ccoshl.c", + "musl/src/complex/ccosl.c", + "musl/src/complex/cexp.c", + "musl/src/complex/cexpf.c", + "musl/src/complex/cexpl.c", + "musl/src/complex/cimag.c", + "musl/src/complex/cimagf.c", + "musl/src/complex/cimagl.c", + "musl/src/complex/clog.c", + "musl/src/complex/clogf.c", + "musl/src/complex/clogl.c", + "musl/src/complex/conj.c", + "musl/src/complex/conjf.c", + "musl/src/complex/conjl.c", + "musl/src/complex/cpow.c", + "musl/src/complex/cpowf.c", + "musl/src/complex/cpowl.c", + "musl/src/complex/cproj.c", + "musl/src/complex/cprojf.c", + "musl/src/complex/cprojl.c", + "musl/src/complex/creal.c", + "musl/src/complex/crealf.c", + "musl/src/complex/creall.c", + "musl/src/complex/csin.c", + "musl/src/complex/csinf.c", + "musl/src/complex/csinh.c", + "musl/src/complex/csinhf.c", + "musl/src/complex/csinhl.c", + "musl/src/complex/csinl.c", + "musl/src/complex/csqrt.c", + "musl/src/complex/csqrtf.c", + "musl/src/complex/csqrtl.c", + "musl/src/complex/ctan.c", + "musl/src/complex/ctanf.c", + "musl/src/complex/ctanh.c", + "musl/src/complex/ctanhf.c", + "musl/src/complex/ctanhl.c", + "musl/src/complex/ctanl.c", + "musl/src/conf/confstr.c", + "musl/src/conf/fpathconf.c", + "musl/src/conf/legacy.c", + "musl/src/conf/pathconf.c", + "musl/src/conf/sysconf.c", + "musl/src/crypt/crypt.c", + "musl/src/crypt/crypt_blowfish.c", + "musl/src/crypt/crypt_des.c", + "musl/src/crypt/crypt_md5.c", + "musl/src/crypt/crypt_r.c", + "musl/src/crypt/crypt_sha256.c", + "musl/src/crypt/crypt_sha512.c", + "musl/src/crypt/encrypt.c", + "musl/src/ctype/__ctype_b_loc.c", + "musl/src/ctype/__ctype_get_mb_cur_max.c", + "musl/src/ctype/__ctype_tolower_loc.c", + "musl/src/ctype/__ctype_toupper_loc.c", + "musl/src/ctype/isalnum.c", + "musl/src/ctype/isalpha.c", + "musl/src/ctype/isascii.c", + "musl/src/ctype/isblank.c", + "musl/src/ctype/iscntrl.c", + "musl/src/ctype/isdigit.c", + "musl/src/ctype/isgraph.c", + "musl/src/ctype/islower.c", + "musl/src/ctype/isprint.c", + "musl/src/ctype/ispunct.c", + "musl/src/ctype/isspace.c", + "musl/src/ctype/isupper.c", + "musl/src/ctype/iswalnum.c", + "musl/src/ctype/iswalpha.c", + "musl/src/ctype/iswblank.c", + "musl/src/ctype/iswcntrl.c", + "musl/src/ctype/iswctype.c", + "musl/src/ctype/iswdigit.c", + "musl/src/ctype/iswgraph.c", + "musl/src/ctype/iswlower.c", + "musl/src/ctype/iswprint.c", + "musl/src/ctype/iswpunct.c", + "musl/src/ctype/iswspace.c", + "musl/src/ctype/iswupper.c", + "musl/src/ctype/iswxdigit.c", + "musl/src/ctype/isxdigit.c", + "musl/src/ctype/toascii.c", + "musl/src/ctype/tolower.c", + "musl/src/ctype/toupper.c", + "musl/src/ctype/towctrans.c", + "musl/src/ctype/wcswidth.c", + "musl/src/ctype/wctrans.c", + "musl/src/ctype/wcwidth.c", + "musl/src/dirent/alphasort.c", + "musl/src/dirent/closedir.c", + "musl/src/dirent/dirfd.c", + "musl/src/dirent/fdopendir.c", + "musl/src/dirent/opendir.c", + "musl/src/dirent/readdir.c", + "musl/src/dirent/readdir_r.c", + "musl/src/dirent/rewinddir.c", + "musl/src/dirent/scandir.c", + "musl/src/dirent/seekdir.c", + "musl/src/dirent/telldir.c", + "musl/src/dirent/versionsort.c", + "musl/src/env/__environ.c", + "musl/src/env/__init_tls.c", + "musl/src/env/__libc_start_main.c", + "musl/src/env/__reset_tls.c", + "musl/src/env/__stack_chk_fail.c", + "musl/src/env/clearenv.c", + "musl/src/env/getenv.c", + "musl/src/env/putenv.c", + "musl/src/env/secure_getenv.c", + "musl/src/env/setenv.c", + "musl/src/env/unsetenv.c", + "musl/src/errno/__errno_location.c", + "musl/src/errno/strerror.c", + "musl/src/exit/_Exit.c", + "musl/src/exit/abort.c", + "musl/src/exit/arm/__aeabi_atexit.c", + "musl/src/exit/assert.c", + "musl/src/exit/at_quick_exit.c", + "musl/src/exit/atexit.c", + "musl/src/exit/exit.c", + "musl/src/exit/quick_exit.c", + "musl/src/fcntl/creat.c", + "musl/src/fcntl/fcntl.c", + "musl/src/fcntl/open.c", + "musl/src/fcntl/openat.c", + "musl/src/fcntl/posix_fadvise.c", + "musl/src/fcntl/posix_fallocate.c", + "musl/src/fenv/__flt_rounds.c", + "musl/src/fenv/aarch64/fenv.s", + "musl/src/fenv/arm/fenv-hf.S", + "musl/src/fenv/arm/fenv.c", + "musl/src/fenv/fegetexceptflag.c", + "musl/src/fenv/feholdexcept.c", + "musl/src/fenv/fenv.c", + "musl/src/fenv/fesetexceptflag.c", + "musl/src/fenv/fesetround.c", + "musl/src/fenv/feupdateenv.c", + "musl/src/fenv/i386/fenv.s", + "musl/src/fenv/m68k/fenv.c", + "musl/src/fenv/mips/fenv-sf.c", + "musl/src/fenv/mips/fenv.S", + "musl/src/fenv/mips64/fenv-sf.c", + "musl/src/fenv/mips64/fenv.S", + "musl/src/fenv/mipsn32/fenv-sf.c", + "musl/src/fenv/mipsn32/fenv.S", + "musl/src/fenv/powerpc/fenv-sf.c", + "musl/src/fenv/powerpc/fenv.S", + "musl/src/fenv/powerpc64/fenv.c", + "musl/src/fenv/riscv64/fenv-sf.c", + "musl/src/fenv/riscv64/fenv.S", + "musl/src/fenv/s390x/fenv.c", + "musl/src/fenv/sh/fenv-nofpu.c", + "musl/src/fenv/sh/fenv.S", + "musl/src/fenv/x32/fenv.s", + "musl/src/fenv/x86_64/fenv.s", + "musl/src/internal/defsysinfo.c", + "musl/src/internal/floatscan.c", + "musl/src/internal/i386/defsysinfo.s", + "musl/src/internal/intscan.c", + "musl/src/internal/libc.c", + "musl/src/internal/procfdname.c", + "musl/src/internal/sh/__shcall.c", + "musl/src/internal/shgetc.c", + "musl/src/internal/syscall_ret.c", + "musl/src/internal/vdso.c", + "musl/src/internal/version.c", + "musl/src/ipc/ftok.c", + "musl/src/ipc/msgctl.c", + "musl/src/ipc/msgget.c", + "musl/src/ipc/msgrcv.c", + "musl/src/ipc/msgsnd.c", + "musl/src/ipc/semctl.c", + "musl/src/ipc/semget.c", + "musl/src/ipc/semop.c", + "musl/src/ipc/semtimedop.c", + "musl/src/ipc/shmat.c", + "musl/src/ipc/shmctl.c", + "musl/src/ipc/shmdt.c", + "musl/src/ipc/shmget.c", + "musl/src/ldso/__dlsym.c", + "musl/src/ldso/aarch64/dlsym.s", + "musl/src/ldso/aarch64/tlsdesc.s", + "musl/src/ldso/arm/dlsym.s", + "musl/src/ldso/arm/dlsym_time64.S", + "musl/src/ldso/arm/find_exidx.c", + "musl/src/ldso/arm/tlsdesc.S", + "musl/src/ldso/dl_iterate_phdr.c", + "musl/src/ldso/dladdr.c", + "musl/src/ldso/dlclose.c", + "musl/src/ldso/dlerror.c", + "musl/src/ldso/dlinfo.c", + "musl/src/ldso/dlopen.c", + "musl/src/ldso/dlsym.c", + "musl/src/ldso/i386/dlsym.s", + "musl/src/ldso/i386/dlsym_time64.S", + "musl/src/ldso/i386/tlsdesc.s", + "musl/src/ldso/m68k/dlsym.s", + "musl/src/ldso/m68k/dlsym_time64.S", + "musl/src/ldso/microblaze/dlsym.s", + "musl/src/ldso/microblaze/dlsym_time64.S", + "musl/src/ldso/mips/dlsym.s", + "musl/src/ldso/mips/dlsym_time64.S", + "musl/src/ldso/mips64/dlsym.s", + "musl/src/ldso/mipsn32/dlsym.s", + "musl/src/ldso/mipsn32/dlsym_time64.S", + "musl/src/ldso/or1k/dlsym.s", + "musl/src/ldso/or1k/dlsym_time64.S", + "musl/src/ldso/powerpc/dlsym.s", + "musl/src/ldso/powerpc/dlsym_time64.S", + "musl/src/ldso/powerpc64/dlsym.s", + "musl/src/ldso/riscv64/dlsym.s", + "musl/src/ldso/s390x/dlsym.s", + "musl/src/ldso/sh/dlsym.s", + "musl/src/ldso/sh/dlsym_time64.S", + "musl/src/ldso/tlsdesc.c", + "musl/src/ldso/x32/dlsym.s", + "musl/src/ldso/x86_64/dlsym.s", + "musl/src/ldso/x86_64/tlsdesc.s", + "musl/src/legacy/cuserid.c", + "musl/src/legacy/daemon.c", + "musl/src/legacy/err.c", + "musl/src/legacy/euidaccess.c", + "musl/src/legacy/ftw.c", + "musl/src/legacy/futimes.c", + "musl/src/legacy/getdtablesize.c", + "musl/src/legacy/getloadavg.c", + "musl/src/legacy/getpagesize.c", + "musl/src/legacy/getpass.c", + "musl/src/legacy/getusershell.c", + "musl/src/legacy/isastream.c", + "musl/src/legacy/lutimes.c", + "musl/src/legacy/ulimit.c", + "musl/src/legacy/utmpx.c", + "musl/src/legacy/valloc.c", + "musl/src/linux/adjtime.c", + "musl/src/linux/adjtimex.c", + "musl/src/linux/arch_prctl.c", + "musl/src/linux/brk.c", + "musl/src/linux/cache.c", + "musl/src/linux/cap.c", + "musl/src/linux/chroot.c", + "musl/src/linux/clock_adjtime.c", + "musl/src/linux/clone.c", + "musl/src/linux/copy_file_range.c", + "musl/src/linux/epoll.c", + "musl/src/linux/eventfd.c", + "musl/src/linux/fallocate.c", + "musl/src/linux/fanotify.c", + "musl/src/linux/flock.c", + "musl/src/linux/getdents.c", + "musl/src/linux/getrandom.c", + "musl/src/linux/inotify.c", + "musl/src/linux/ioperm.c", + "musl/src/linux/iopl.c", + "musl/src/linux/klogctl.c", + "musl/src/linux/membarrier.c", + "musl/src/linux/memfd_create.c", + "musl/src/linux/mlock2.c", + "musl/src/linux/module.c", + "musl/src/linux/mount.c", + "musl/src/linux/name_to_handle_at.c", + "musl/src/linux/open_by_handle_at.c", + "musl/src/linux/personality.c", + "musl/src/linux/pivot_root.c", + "musl/src/linux/ppoll.c", + "musl/src/linux/prctl.c", + "musl/src/linux/prlimit.c", + "musl/src/linux/process_vm.c", + "musl/src/linux/ptrace.c", + "musl/src/linux/quotactl.c", + "musl/src/linux/readahead.c", + "musl/src/linux/reboot.c", + "musl/src/linux/remap_file_pages.c", + "musl/src/linux/sbrk.c", + "musl/src/linux/sendfile.c", + "musl/src/linux/setfsgid.c", + "musl/src/linux/setfsuid.c", + "musl/src/linux/setgroups.c", + "musl/src/linux/sethostname.c", + "musl/src/linux/setns.c", + "musl/src/linux/settimeofday.c", + "musl/src/linux/signalfd.c", + "musl/src/linux/splice.c", + "musl/src/linux/stime.c", + "musl/src/linux/swap.c", + "musl/src/linux/sync_file_range.c", + "musl/src/linux/syncfs.c", + "musl/src/linux/sysinfo.c", + "musl/src/linux/tee.c", + "musl/src/linux/timerfd.c", + "musl/src/linux/unshare.c", + "musl/src/linux/utimes.c", + "musl/src/linux/vhangup.c", + "musl/src/linux/vmsplice.c", + "musl/src/linux/wait3.c", + "musl/src/linux/wait4.c", + "musl/src/linux/x32/sysinfo.c", + "musl/src/linux/xattr.c", + "musl/src/locale/__lctrans.c", + "musl/src/locale/__mo_lookup.c", + "musl/src/locale/bind_textdomain_codeset.c", + "musl/src/locale/c_locale.c", + "musl/src/locale/catclose.c", + "musl/src/locale/catgets.c", + "musl/src/locale/catopen.c", + "musl/src/locale/dcngettext.c", + "musl/src/locale/duplocale.c", + "musl/src/locale/freelocale.c", + "musl/src/locale/iconv.c", + "musl/src/locale/iconv_close.c", + "musl/src/locale/langinfo.c", + "musl/src/locale/locale_map.c", + "musl/src/locale/localeconv.c", + "musl/src/locale/newlocale.c", + "musl/src/locale/pleval.c", + "musl/src/locale/setlocale.c", + "musl/src/locale/strcoll.c", + "musl/src/locale/strfmon.c", + "musl/src/locale/strxfrm.c", + "musl/src/locale/textdomain.c", + "musl/src/locale/uselocale.c", + "musl/src/locale/wcscoll.c", + "musl/src/locale/wcsxfrm.c", + "musl/src/malloc/aligned_alloc.c", + "musl/src/malloc/expand_heap.c", + "musl/src/malloc/lite_malloc.c", + "musl/src/malloc/malloc.c", + "musl/src/malloc/malloc_usable_size.c", + "musl/src/malloc/memalign.c", + "musl/src/malloc/posix_memalign.c", + "musl/src/math/__cos.c", + "musl/src/math/__cosdf.c", + "musl/src/math/__cosl.c", + "musl/src/math/__expo2.c", + "musl/src/math/__expo2f.c", + "musl/src/math/__fpclassify.c", + "musl/src/math/__fpclassifyf.c", + "musl/src/math/__fpclassifyl.c", + "musl/src/math/__invtrigl.c", + "musl/src/math/__math_divzero.c", + "musl/src/math/__math_divzerof.c", + "musl/src/math/__math_invalid.c", + "musl/src/math/__math_invalidf.c", + "musl/src/math/__math_oflow.c", + "musl/src/math/__math_oflowf.c", + "musl/src/math/__math_uflow.c", + "musl/src/math/__math_uflowf.c", + "musl/src/math/__math_xflow.c", + "musl/src/math/__math_xflowf.c", + "musl/src/math/__polevll.c", + "musl/src/math/__rem_pio2.c", + "musl/src/math/__rem_pio2_large.c", + "musl/src/math/__rem_pio2f.c", + "musl/src/math/__rem_pio2l.c", + "musl/src/math/__signbit.c", + "musl/src/math/__signbitf.c", + "musl/src/math/__signbitl.c", + "musl/src/math/__sin.c", + "musl/src/math/__sindf.c", + "musl/src/math/__sinl.c", + "musl/src/math/__tan.c", + "musl/src/math/__tandf.c", + "musl/src/math/__tanl.c", + "musl/src/math/aarch64/ceil.c", + "musl/src/math/aarch64/ceilf.c", + "musl/src/math/aarch64/fabs.c", + "musl/src/math/aarch64/fabsf.c", + "musl/src/math/aarch64/floor.c", + "musl/src/math/aarch64/floorf.c", + "musl/src/math/aarch64/fma.c", + "musl/src/math/aarch64/fmaf.c", + "musl/src/math/aarch64/fmax.c", + "musl/src/math/aarch64/fmaxf.c", + "musl/src/math/aarch64/fmin.c", + "musl/src/math/aarch64/fminf.c", + "musl/src/math/aarch64/llrint.c", + "musl/src/math/aarch64/llrintf.c", + "musl/src/math/aarch64/llround.c", + "musl/src/math/aarch64/llroundf.c", + "musl/src/math/aarch64/lrint.c", + "musl/src/math/aarch64/lrintf.c", + "musl/src/math/aarch64/lround.c", + "musl/src/math/aarch64/lroundf.c", + "musl/src/math/aarch64/nearbyint.c", + "musl/src/math/aarch64/nearbyintf.c", + "musl/src/math/aarch64/rint.c", + "musl/src/math/aarch64/rintf.c", + "musl/src/math/aarch64/round.c", + "musl/src/math/aarch64/roundf.c", + "musl/src/math/aarch64/sqrt.c", + "musl/src/math/aarch64/sqrtf.c", + "musl/src/math/aarch64/trunc.c", + "musl/src/math/aarch64/truncf.c", + "musl/src/math/acos.c", + "musl/src/math/acosf.c", + "musl/src/math/acosh.c", + "musl/src/math/acoshf.c", + "musl/src/math/acoshl.c", + "musl/src/math/acosl.c", + "musl/src/math/arm/fabs.c", + "musl/src/math/arm/fabsf.c", + "musl/src/math/arm/fma.c", + "musl/src/math/arm/fmaf.c", + "musl/src/math/arm/sqrt.c", + "musl/src/math/arm/sqrtf.c", + "musl/src/math/asin.c", + "musl/src/math/asinf.c", + "musl/src/math/asinh.c", + "musl/src/math/asinhf.c", + "musl/src/math/asinhl.c", + "musl/src/math/asinl.c", + "musl/src/math/atan.c", + "musl/src/math/atan2.c", + "musl/src/math/atan2f.c", + "musl/src/math/atan2l.c", + "musl/src/math/atanf.c", + "musl/src/math/atanh.c", + "musl/src/math/atanhf.c", + "musl/src/math/atanhl.c", + "musl/src/math/atanl.c", + "musl/src/math/cbrt.c", + "musl/src/math/cbrtf.c", + "musl/src/math/cbrtl.c", + "musl/src/math/ceil.c", + "musl/src/math/ceilf.c", + "musl/src/math/ceill.c", + "musl/src/math/copysign.c", + "musl/src/math/copysignf.c", + "musl/src/math/copysignl.c", + "musl/src/math/cos.c", + "musl/src/math/cosf.c", + "musl/src/math/cosh.c", + "musl/src/math/coshf.c", + "musl/src/math/coshl.c", + "musl/src/math/cosl.c", + "musl/src/math/erf.c", + "musl/src/math/erff.c", + "musl/src/math/erfl.c", + "musl/src/math/exp.c", + "musl/src/math/exp10.c", + "musl/src/math/exp10f.c", + "musl/src/math/exp10l.c", + "musl/src/math/exp2.c", + "musl/src/math/exp2f.c", + "musl/src/math/exp2f_data.c", + "musl/src/math/exp2l.c", + "musl/src/math/exp_data.c", + "musl/src/math/expf.c", + "musl/src/math/expl.c", + "musl/src/math/expm1.c", + "musl/src/math/expm1f.c", + "musl/src/math/expm1l.c", + "musl/src/math/fabs.c", + "musl/src/math/fabsf.c", + "musl/src/math/fabsl.c", + "musl/src/math/fdim.c", + "musl/src/math/fdimf.c", + "musl/src/math/fdiml.c", + "musl/src/math/finite.c", + "musl/src/math/finitef.c", + "musl/src/math/floor.c", + "musl/src/math/floorf.c", + "musl/src/math/floorl.c", + "musl/src/math/fma.c", + "musl/src/math/fmaf.c", + "musl/src/math/fmal.c", + "musl/src/math/fmax.c", + "musl/src/math/fmaxf.c", + "musl/src/math/fmaxl.c", + "musl/src/math/fmin.c", + "musl/src/math/fminf.c", + "musl/src/math/fminl.c", + "musl/src/math/fmod.c", + "musl/src/math/fmodf.c", + "musl/src/math/fmodl.c", + "musl/src/math/frexp.c", + "musl/src/math/frexpf.c", + "musl/src/math/frexpl.c", + "musl/src/math/hypot.c", + "musl/src/math/hypotf.c", + "musl/src/math/hypotl.c", + "musl/src/math/i386/__invtrigl.s", + "musl/src/math/i386/acos.s", + "musl/src/math/i386/acosf.s", + "musl/src/math/i386/acosl.s", + "musl/src/math/i386/asin.s", + "musl/src/math/i386/asinf.s", + "musl/src/math/i386/asinl.s", + "musl/src/math/i386/atan.s", + "musl/src/math/i386/atan2.s", + "musl/src/math/i386/atan2f.s", + "musl/src/math/i386/atan2l.s", + "musl/src/math/i386/atanf.s", + "musl/src/math/i386/atanl.s", + "musl/src/math/i386/ceil.s", + "musl/src/math/i386/ceilf.s", + "musl/src/math/i386/ceill.s", + "musl/src/math/i386/exp2l.s", + "musl/src/math/i386/exp_ld.s", + "musl/src/math/i386/expl.s", + "musl/src/math/i386/expm1l.s", + "musl/src/math/i386/fabs.s", + "musl/src/math/i386/fabsf.s", + "musl/src/math/i386/fabsl.s", + "musl/src/math/i386/floor.s", + "musl/src/math/i386/floorf.s", + "musl/src/math/i386/floorl.s", + "musl/src/math/i386/fmod.s", + "musl/src/math/i386/fmodf.s", + "musl/src/math/i386/fmodl.s", + "musl/src/math/i386/hypot.s", + "musl/src/math/i386/hypotf.s", + "musl/src/math/i386/ldexp.s", + "musl/src/math/i386/ldexpf.s", + "musl/src/math/i386/ldexpl.s", + "musl/src/math/i386/llrint.s", + "musl/src/math/i386/llrintf.s", + "musl/src/math/i386/llrintl.s", + "musl/src/math/i386/log.s", + "musl/src/math/i386/log10.s", + "musl/src/math/i386/log10f.s", + "musl/src/math/i386/log10l.s", + "musl/src/math/i386/log1p.s", + "musl/src/math/i386/log1pf.s", + "musl/src/math/i386/log1pl.s", + "musl/src/math/i386/log2.s", + "musl/src/math/i386/log2f.s", + "musl/src/math/i386/log2l.s", + "musl/src/math/i386/logf.s", + "musl/src/math/i386/logl.s", + "musl/src/math/i386/lrint.s", + "musl/src/math/i386/lrintf.s", + "musl/src/math/i386/lrintl.s", + "musl/src/math/i386/remainder.s", + "musl/src/math/i386/remainderf.s", + "musl/src/math/i386/remainderl.s", + "musl/src/math/i386/remquo.s", + "musl/src/math/i386/remquof.s", + "musl/src/math/i386/remquol.s", + "musl/src/math/i386/rint.s", + "musl/src/math/i386/rintf.s", + "musl/src/math/i386/rintl.s", + "musl/src/math/i386/scalbln.s", + "musl/src/math/i386/scalblnf.s", + "musl/src/math/i386/scalblnl.s", + "musl/src/math/i386/scalbn.s", + "musl/src/math/i386/scalbnf.s", + "musl/src/math/i386/scalbnl.s", + "musl/src/math/i386/sqrt.s", + "musl/src/math/i386/sqrtf.s", + "musl/src/math/i386/sqrtl.s", + "musl/src/math/i386/trunc.s", + "musl/src/math/i386/truncf.s", + "musl/src/math/i386/truncl.s", + "musl/src/math/ilogb.c", + "musl/src/math/ilogbf.c", + "musl/src/math/ilogbl.c", + "musl/src/math/j0.c", + "musl/src/math/j0f.c", + "musl/src/math/j1.c", + "musl/src/math/j1f.c", + "musl/src/math/jn.c", + "musl/src/math/jnf.c", + "musl/src/math/ldexp.c", + "musl/src/math/ldexpf.c", + "musl/src/math/ldexpl.c", + "musl/src/math/lgamma.c", + "musl/src/math/lgamma_r.c", + "musl/src/math/lgammaf.c", + "musl/src/math/lgammaf_r.c", + "musl/src/math/lgammal.c", + "musl/src/math/llrint.c", + "musl/src/math/llrintf.c", + "musl/src/math/llrintl.c", + "musl/src/math/llround.c", + "musl/src/math/llroundf.c", + "musl/src/math/llroundl.c", + "musl/src/math/log.c", + "musl/src/math/log10.c", + "musl/src/math/log10f.c", + "musl/src/math/log10l.c", + "musl/src/math/log1p.c", + "musl/src/math/log1pf.c", + "musl/src/math/log1pl.c", + "musl/src/math/log2.c", + "musl/src/math/log2_data.c", + "musl/src/math/log2f.c", + "musl/src/math/log2f_data.c", + "musl/src/math/log2l.c", + "musl/src/math/log_data.c", + "musl/src/math/logb.c", + "musl/src/math/logbf.c", + "musl/src/math/logbl.c", + "musl/src/math/logf.c", + "musl/src/math/logf_data.c", + "musl/src/math/logl.c", + "musl/src/math/lrint.c", + "musl/src/math/lrintf.c", + "musl/src/math/lrintl.c", + "musl/src/math/lround.c", + "musl/src/math/lroundf.c", + "musl/src/math/lroundl.c", + "musl/src/math/mips/fabs.c", + "musl/src/math/mips/fabsf.c", + "musl/src/math/mips/sqrt.c", + "musl/src/math/mips/sqrtf.c", + "musl/src/math/modf.c", + "musl/src/math/modff.c", + "musl/src/math/modfl.c", + "musl/src/math/nan.c", + "musl/src/math/nanf.c", + "musl/src/math/nanl.c", + "musl/src/math/nearbyint.c", + "musl/src/math/nearbyintf.c", + "musl/src/math/nearbyintl.c", + "musl/src/math/nextafter.c", + "musl/src/math/nextafterf.c", + "musl/src/math/nextafterl.c", + "musl/src/math/nexttoward.c", + "musl/src/math/nexttowardf.c", + "musl/src/math/nexttowardl.c", + "musl/src/math/pow.c", + "musl/src/math/pow_data.c", + "musl/src/math/powerpc/fabs.c", + "musl/src/math/powerpc/fabsf.c", + "musl/src/math/powerpc/fma.c", + "musl/src/math/powerpc/fmaf.c", + "musl/src/math/powerpc/sqrt.c", + "musl/src/math/powerpc/sqrtf.c", + "musl/src/math/powerpc64/ceil.c", + "musl/src/math/powerpc64/ceilf.c", + "musl/src/math/powerpc64/fabs.c", + "musl/src/math/powerpc64/fabsf.c", + "musl/src/math/powerpc64/floor.c", + "musl/src/math/powerpc64/floorf.c", + "musl/src/math/powerpc64/fma.c", + "musl/src/math/powerpc64/fmaf.c", + "musl/src/math/powerpc64/fmax.c", + "musl/src/math/powerpc64/fmaxf.c", + "musl/src/math/powerpc64/fmin.c", + "musl/src/math/powerpc64/fminf.c", + "musl/src/math/powerpc64/lrint.c", + "musl/src/math/powerpc64/lrintf.c", + "musl/src/math/powerpc64/lround.c", + "musl/src/math/powerpc64/lroundf.c", + "musl/src/math/powerpc64/round.c", + "musl/src/math/powerpc64/roundf.c", + "musl/src/math/powerpc64/sqrt.c", + "musl/src/math/powerpc64/sqrtf.c", + "musl/src/math/powerpc64/trunc.c", + "musl/src/math/powerpc64/truncf.c", + "musl/src/math/powf.c", + "musl/src/math/powf_data.c", + "musl/src/math/powl.c", + "musl/src/math/remainder.c", + "musl/src/math/remainderf.c", + "musl/src/math/remainderl.c", + "musl/src/math/remquo.c", + "musl/src/math/remquof.c", + "musl/src/math/remquol.c", + "musl/src/math/rint.c", + "musl/src/math/rintf.c", + "musl/src/math/rintl.c", + "musl/src/math/riscv64/copysign.c", + "musl/src/math/riscv64/copysignf.c", + "musl/src/math/riscv64/fabs.c", + "musl/src/math/riscv64/fabsf.c", + "musl/src/math/riscv64/fma.c", + "musl/src/math/riscv64/fmaf.c", + "musl/src/math/riscv64/fmax.c", + "musl/src/math/riscv64/fmaxf.c", + "musl/src/math/riscv64/fmin.c", + "musl/src/math/riscv64/fminf.c", + "musl/src/math/riscv64/sqrt.c", + "musl/src/math/riscv64/sqrtf.c", + "musl/src/math/round.c", + "musl/src/math/roundf.c", + "musl/src/math/roundl.c", + "musl/src/math/s390x/ceil.c", + "musl/src/math/s390x/ceilf.c", + "musl/src/math/s390x/ceill.c", + "musl/src/math/s390x/fabs.c", + "musl/src/math/s390x/fabsf.c", + "musl/src/math/s390x/fabsl.c", + "musl/src/math/s390x/floor.c", + "musl/src/math/s390x/floorf.c", + "musl/src/math/s390x/floorl.c", + "musl/src/math/s390x/fma.c", + "musl/src/math/s390x/fmaf.c", + "musl/src/math/s390x/nearbyint.c", + "musl/src/math/s390x/nearbyintf.c", + "musl/src/math/s390x/nearbyintl.c", + "musl/src/math/s390x/rint.c", + "musl/src/math/s390x/rintf.c", + "musl/src/math/s390x/rintl.c", + "musl/src/math/s390x/round.c", + "musl/src/math/s390x/roundf.c", + "musl/src/math/s390x/roundl.c", + "musl/src/math/s390x/sqrt.c", + "musl/src/math/s390x/sqrtf.c", + "musl/src/math/s390x/sqrtl.c", + "musl/src/math/s390x/trunc.c", + "musl/src/math/s390x/truncf.c", + "musl/src/math/s390x/truncl.c", + "musl/src/math/scalb.c", + "musl/src/math/scalbf.c", + "musl/src/math/scalbln.c", + "musl/src/math/scalblnf.c", + "musl/src/math/scalblnl.c", + "musl/src/math/scalbn.c", + "musl/src/math/scalbnf.c", + "musl/src/math/scalbnl.c", + "musl/src/math/signgam.c", + "musl/src/math/significand.c", + "musl/src/math/significandf.c", + "musl/src/math/sin.c", + "musl/src/math/sincos.c", + "musl/src/math/sincosf.c", + "musl/src/math/sincosl.c", + "musl/src/math/sinf.c", + "musl/src/math/sinh.c", + "musl/src/math/sinhf.c", + "musl/src/math/sinhl.c", + "musl/src/math/sinl.c", + "musl/src/math/sqrt.c", + "musl/src/math/sqrtf.c", + "musl/src/math/sqrtl.c", + "musl/src/math/tan.c", + "musl/src/math/tanf.c", + "musl/src/math/tanh.c", + "musl/src/math/tanhf.c", + "musl/src/math/tanhl.c", + "musl/src/math/tanl.c", + "musl/src/math/tgamma.c", + "musl/src/math/tgammaf.c", + "musl/src/math/tgammal.c", + "musl/src/math/trunc.c", + "musl/src/math/truncf.c", + "musl/src/math/truncl.c", + "musl/src/math/x32/__invtrigl.s", + "musl/src/math/x32/acosl.s", + "musl/src/math/x32/asinl.s", + "musl/src/math/x32/atan2l.s", + "musl/src/math/x32/atanl.s", + "musl/src/math/x32/ceill.s", + "musl/src/math/x32/exp2l.s", + "musl/src/math/x32/expl.s", + "musl/src/math/x32/expm1l.s", + "musl/src/math/x32/fabs.s", + "musl/src/math/x32/fabsf.s", + "musl/src/math/x32/fabsl.s", + "musl/src/math/x32/floorl.s", + "musl/src/math/x32/fma.c", + "musl/src/math/x32/fmaf.c", + "musl/src/math/x32/fmodl.s", + "musl/src/math/x32/llrint.s", + "musl/src/math/x32/llrintf.s", + "musl/src/math/x32/llrintl.s", + "musl/src/math/x32/log10l.s", + "musl/src/math/x32/log1pl.s", + "musl/src/math/x32/log2l.s", + "musl/src/math/x32/logl.s", + "musl/src/math/x32/lrint.s", + "musl/src/math/x32/lrintf.s", + "musl/src/math/x32/lrintl.s", + "musl/src/math/x32/remainderl.s", + "musl/src/math/x32/rintl.s", + "musl/src/math/x32/sqrt.s", + "musl/src/math/x32/sqrtf.s", + "musl/src/math/x32/sqrtl.s", + "musl/src/math/x32/truncl.s", + "musl/src/math/x86_64/__invtrigl.s", + "musl/src/math/x86_64/acosl.s", + "musl/src/math/x86_64/asinl.s", + "musl/src/math/x86_64/atan2l.s", + "musl/src/math/x86_64/atanl.s", + "musl/src/math/x86_64/ceill.s", + "musl/src/math/x86_64/exp2l.s", + "musl/src/math/x86_64/expl.s", + "musl/src/math/x86_64/expm1l.s", + "musl/src/math/x86_64/fabs.s", + "musl/src/math/x86_64/fabsf.s", + "musl/src/math/x86_64/fabsl.s", + "musl/src/math/x86_64/floorl.s", + "musl/src/math/x86_64/fma.c", + "musl/src/math/x86_64/fmaf.c", + "musl/src/math/x86_64/fmodl.s", + "musl/src/math/x86_64/llrint.s", + "musl/src/math/x86_64/llrintf.s", + "musl/src/math/x86_64/llrintl.s", + "musl/src/math/x86_64/log10l.s", + "musl/src/math/x86_64/log1pl.s", + "musl/src/math/x86_64/log2l.s", + "musl/src/math/x86_64/logl.s", + "musl/src/math/x86_64/lrint.s", + "musl/src/math/x86_64/lrintf.s", + "musl/src/math/x86_64/lrintl.s", + "musl/src/math/x86_64/remainderl.s", + "musl/src/math/x86_64/rintl.s", + "musl/src/math/x86_64/sqrt.s", + "musl/src/math/x86_64/sqrtf.s", + "musl/src/math/x86_64/sqrtl.s", + "musl/src/math/x86_64/truncl.s", + "musl/src/misc/a64l.c", + "musl/src/misc/basename.c", + "musl/src/misc/dirname.c", + "musl/src/misc/ffs.c", + "musl/src/misc/ffsl.c", + "musl/src/misc/ffsll.c", + "musl/src/misc/fmtmsg.c", + "musl/src/misc/forkpty.c", + "musl/src/misc/get_current_dir_name.c", + "musl/src/misc/getauxval.c", + "musl/src/misc/getdomainname.c", + "musl/src/misc/getentropy.c", + "musl/src/misc/gethostid.c", + "musl/src/misc/getopt.c", + "musl/src/misc/getopt_long.c", + "musl/src/misc/getpriority.c", + "musl/src/misc/getresgid.c", + "musl/src/misc/getresuid.c", + "musl/src/misc/getrlimit.c", + "musl/src/misc/getrusage.c", + "musl/src/misc/getsubopt.c", + "musl/src/misc/initgroups.c", + "musl/src/misc/ioctl.c", + "musl/src/misc/issetugid.c", + "musl/src/misc/lockf.c", + "musl/src/misc/login_tty.c", + "musl/src/misc/mntent.c", + "musl/src/misc/nftw.c", + "musl/src/misc/openpty.c", + "musl/src/misc/ptsname.c", + "musl/src/misc/pty.c", + "musl/src/misc/realpath.c", + "musl/src/misc/setdomainname.c", + "musl/src/misc/setpriority.c", + "musl/src/misc/setrlimit.c", + "musl/src/misc/syscall.c", + "musl/src/misc/syslog.c", + "musl/src/misc/uname.c", + "musl/src/misc/wordexp.c", + "musl/src/mman/madvise.c", + "musl/src/mman/mincore.c", + "musl/src/mman/mlock.c", + "musl/src/mman/mlockall.c", + "musl/src/mman/mmap.c", + "musl/src/mman/mprotect.c", + "musl/src/mman/mremap.c", + "musl/src/mman/msync.c", + "musl/src/mman/munlock.c", + "musl/src/mman/munlockall.c", + "musl/src/mman/munmap.c", + "musl/src/mman/posix_madvise.c", + "musl/src/mman/shm_open.c", + "musl/src/mq/mq_close.c", + "musl/src/mq/mq_getattr.c", + "musl/src/mq/mq_notify.c", + "musl/src/mq/mq_open.c", + "musl/src/mq/mq_receive.c", + "musl/src/mq/mq_send.c", + "musl/src/mq/mq_setattr.c", + "musl/src/mq/mq_timedreceive.c", + "musl/src/mq/mq_timedsend.c", + "musl/src/mq/mq_unlink.c", + "musl/src/multibyte/btowc.c", + "musl/src/multibyte/c16rtomb.c", + "musl/src/multibyte/c32rtomb.c", + "musl/src/multibyte/internal.c", + "musl/src/multibyte/mblen.c", + "musl/src/multibyte/mbrlen.c", + "musl/src/multibyte/mbrtoc16.c", + "musl/src/multibyte/mbrtoc32.c", + "musl/src/multibyte/mbrtowc.c", + "musl/src/multibyte/mbsinit.c", + "musl/src/multibyte/mbsnrtowcs.c", + "musl/src/multibyte/mbsrtowcs.c", + "musl/src/multibyte/mbstowcs.c", + "musl/src/multibyte/mbtowc.c", + "musl/src/multibyte/wcrtomb.c", + "musl/src/multibyte/wcsnrtombs.c", + "musl/src/multibyte/wcsrtombs.c", + "musl/src/multibyte/wcstombs.c", + "musl/src/multibyte/wctob.c", + "musl/src/multibyte/wctomb.c", + "musl/src/network/accept.c", + "musl/src/network/accept4.c", + "musl/src/network/bind.c", + "musl/src/network/connect.c", + "musl/src/network/dn_comp.c", + "musl/src/network/dn_expand.c", + "musl/src/network/dn_skipname.c", + "musl/src/network/dns_parse.c", + "musl/src/network/ent.c", + "musl/src/network/ether.c", + "musl/src/network/freeaddrinfo.c", + "musl/src/network/gai_strerror.c", + "musl/src/network/getaddrinfo.c", + "musl/src/network/gethostbyaddr.c", + "musl/src/network/gethostbyaddr_r.c", + "musl/src/network/gethostbyname.c", + "musl/src/network/gethostbyname2.c", + "musl/src/network/gethostbyname2_r.c", + "musl/src/network/gethostbyname_r.c", + "musl/src/network/getifaddrs.c", + "musl/src/network/getnameinfo.c", + "musl/src/network/getpeername.c", + "musl/src/network/getservbyname.c", + "musl/src/network/getservbyname_r.c", + "musl/src/network/getservbyport.c", + "musl/src/network/getservbyport_r.c", + "musl/src/network/getsockname.c", + "musl/src/network/getsockopt.c", + "musl/src/network/h_errno.c", + "musl/src/network/herror.c", + "musl/src/network/hstrerror.c", + "musl/src/network/htonl.c", + "musl/src/network/htons.c", + "musl/src/network/if_freenameindex.c", + "musl/src/network/if_indextoname.c", + "musl/src/network/if_nameindex.c", + "musl/src/network/if_nametoindex.c", + "musl/src/network/in6addr_any.c", + "musl/src/network/in6addr_loopback.c", + "musl/src/network/inet_addr.c", + "musl/src/network/inet_aton.c", + "musl/src/network/inet_legacy.c", + "musl/src/network/inet_ntoa.c", + "musl/src/network/inet_ntop.c", + "musl/src/network/inet_pton.c", + "musl/src/network/listen.c", + "musl/src/network/lookup_ipliteral.c", + "musl/src/network/lookup_name.c", + "musl/src/network/lookup_serv.c", + "musl/src/network/netlink.c", + "musl/src/network/netname.c", + "musl/src/network/ns_parse.c", + "musl/src/network/ntohl.c", + "musl/src/network/ntohs.c", + "musl/src/network/proto.c", + "musl/src/network/recv.c", + "musl/src/network/recvfrom.c", + "musl/src/network/recvmmsg.c", + "musl/src/network/recvmsg.c", + "musl/src/network/res_init.c", + "musl/src/network/res_mkquery.c", + "musl/src/network/res_msend.c", + "musl/src/network/res_query.c", + "musl/src/network/res_querydomain.c", + "musl/src/network/res_send.c", + "musl/src/network/res_state.c", + "musl/src/network/resolvconf.c", + "musl/src/network/send.c", + "musl/src/network/sendmmsg.c", + "musl/src/network/sendmsg.c", + "musl/src/network/sendto.c", + "musl/src/network/serv.c", + "musl/src/network/setsockopt.c", + "musl/src/network/shutdown.c", + "musl/src/network/sockatmark.c", + "musl/src/network/socket.c", + "musl/src/network/socketpair.c", + "musl/src/passwd/fgetgrent.c", + "musl/src/passwd/fgetpwent.c", + "musl/src/passwd/fgetspent.c", + "musl/src/passwd/getgr_a.c", + "musl/src/passwd/getgr_r.c", + "musl/src/passwd/getgrent.c", + "musl/src/passwd/getgrent_a.c", + "musl/src/passwd/getgrouplist.c", + "musl/src/passwd/getpw_a.c", + "musl/src/passwd/getpw_r.c", + "musl/src/passwd/getpwent.c", + "musl/src/passwd/getpwent_a.c", + "musl/src/passwd/getspent.c", + "musl/src/passwd/getspnam.c", + "musl/src/passwd/getspnam_r.c", + "musl/src/passwd/lckpwdf.c", + "musl/src/passwd/nscd_query.c", + "musl/src/passwd/putgrent.c", + "musl/src/passwd/putpwent.c", + "musl/src/passwd/putspent.c", + "musl/src/prng/__rand48_step.c", + "musl/src/prng/__seed48.c", + "musl/src/prng/drand48.c", + "musl/src/prng/lcong48.c", + "musl/src/prng/lrand48.c", + "musl/src/prng/mrand48.c", + "musl/src/prng/rand.c", + "musl/src/prng/rand_r.c", + "musl/src/prng/random.c", + "musl/src/prng/seed48.c", + "musl/src/prng/srand48.c", + "musl/src/process/arm/vfork.s", + "musl/src/process/execl.c", + "musl/src/process/execle.c", + "musl/src/process/execlp.c", + "musl/src/process/execv.c", + "musl/src/process/execve.c", + "musl/src/process/execvp.c", + "musl/src/process/fexecve.c", + "musl/src/process/fork.c", + "musl/src/process/i386/vfork.s", + "musl/src/process/posix_spawn.c", + "musl/src/process/posix_spawn_file_actions_addchdir.c", + "musl/src/process/posix_spawn_file_actions_addclose.c", + "musl/src/process/posix_spawn_file_actions_adddup2.c", + "musl/src/process/posix_spawn_file_actions_addfchdir.c", + "musl/src/process/posix_spawn_file_actions_addopen.c", + "musl/src/process/posix_spawn_file_actions_destroy.c", + "musl/src/process/posix_spawn_file_actions_init.c", + "musl/src/process/posix_spawnattr_destroy.c", + "musl/src/process/posix_spawnattr_getflags.c", + "musl/src/process/posix_spawnattr_getpgroup.c", + "musl/src/process/posix_spawnattr_getsigdefault.c", + "musl/src/process/posix_spawnattr_getsigmask.c", + "musl/src/process/posix_spawnattr_init.c", + "musl/src/process/posix_spawnattr_sched.c", + "musl/src/process/posix_spawnattr_setflags.c", + "musl/src/process/posix_spawnattr_setpgroup.c", + "musl/src/process/posix_spawnattr_setsigdefault.c", + "musl/src/process/posix_spawnattr_setsigmask.c", + "musl/src/process/posix_spawnp.c", + "musl/src/process/s390x/vfork.s", + "musl/src/process/sh/vfork.s", + "musl/src/process/system.c", + "musl/src/process/vfork.c", + "musl/src/process/wait.c", + "musl/src/process/waitid.c", + "musl/src/process/waitpid.c", + "musl/src/process/x32/vfork.s", + "musl/src/process/x86_64/vfork.s", + "musl/src/regex/fnmatch.c", + "musl/src/regex/glob.c", + "musl/src/regex/regcomp.c", + "musl/src/regex/regerror.c", + "musl/src/regex/regexec.c", + "musl/src/regex/tre-mem.c", + "musl/src/sched/affinity.c", + "musl/src/sched/sched_cpucount.c", + "musl/src/sched/sched_get_priority_max.c", + "musl/src/sched/sched_getcpu.c", + "musl/src/sched/sched_getparam.c", + "musl/src/sched/sched_getscheduler.c", + "musl/src/sched/sched_rr_get_interval.c", + "musl/src/sched/sched_setparam.c", + "musl/src/sched/sched_setscheduler.c", + "musl/src/sched/sched_yield.c", + "musl/src/search/hsearch.c", + "musl/src/search/insque.c", + "musl/src/search/lsearch.c", + "musl/src/search/tdelete.c", + "musl/src/search/tdestroy.c", + "musl/src/search/tfind.c", + "musl/src/search/tsearch.c", + "musl/src/search/twalk.c", + "musl/src/select/poll.c", + "musl/src/select/pselect.c", + "musl/src/select/select.c", + "musl/src/setjmp/aarch64/longjmp.s", + "musl/src/setjmp/aarch64/setjmp.s", + "musl/src/setjmp/arm/longjmp.S", + "musl/src/setjmp/arm/setjmp.S", + "musl/src/setjmp/i386/longjmp.s", + "musl/src/setjmp/i386/setjmp.s", + "musl/src/setjmp/longjmp.c", + "musl/src/setjmp/m68k/longjmp.s", + "musl/src/setjmp/m68k/setjmp.s", + "musl/src/setjmp/microblaze/longjmp.s", + "musl/src/setjmp/microblaze/setjmp.s", + "musl/src/setjmp/mips/longjmp.S", + "musl/src/setjmp/mips/setjmp.S", + "musl/src/setjmp/mips64/longjmp.S", + "musl/src/setjmp/mips64/setjmp.S", + "musl/src/setjmp/mipsn32/longjmp.S", + "musl/src/setjmp/mipsn32/setjmp.S", + "musl/src/setjmp/or1k/longjmp.s", + "musl/src/setjmp/or1k/setjmp.s", + "musl/src/setjmp/powerpc/longjmp.S", + "musl/src/setjmp/powerpc/setjmp.S", + "musl/src/setjmp/powerpc64/longjmp.s", + "musl/src/setjmp/powerpc64/setjmp.s", + "musl/src/setjmp/riscv64/longjmp.S", + "musl/src/setjmp/riscv64/setjmp.S", + "musl/src/setjmp/s390x/longjmp.s", + "musl/src/setjmp/s390x/setjmp.s", + "musl/src/setjmp/setjmp.c", + "musl/src/setjmp/sh/longjmp.S", + "musl/src/setjmp/sh/setjmp.S", + "musl/src/setjmp/x32/longjmp.s", + "musl/src/setjmp/x32/setjmp.s", + "musl/src/setjmp/x86_64/longjmp.s", + "musl/src/setjmp/x86_64/setjmp.s", + "musl/src/signal/aarch64/restore.s", + "musl/src/signal/aarch64/sigsetjmp.s", + "musl/src/signal/arm/restore.s", + "musl/src/signal/arm/sigsetjmp.s", + "musl/src/signal/block.c", + "musl/src/signal/getitimer.c", + "musl/src/signal/i386/restore.s", + "musl/src/signal/i386/sigsetjmp.s", + "musl/src/signal/kill.c", + "musl/src/signal/killpg.c", + "musl/src/signal/m68k/sigsetjmp.s", + "musl/src/signal/microblaze/restore.s", + "musl/src/signal/microblaze/sigsetjmp.s", + "musl/src/signal/mips/restore.s", + "musl/src/signal/mips/sigsetjmp.s", + "musl/src/signal/mips64/restore.s", + "musl/src/signal/mips64/sigsetjmp.s", + "musl/src/signal/mipsn32/restore.s", + "musl/src/signal/mipsn32/sigsetjmp.s", + "musl/src/signal/or1k/sigsetjmp.s", + "musl/src/signal/powerpc/restore.s", + "musl/src/signal/powerpc/sigsetjmp.s", + "musl/src/signal/powerpc64/restore.s", + "musl/src/signal/powerpc64/sigsetjmp.s", + "musl/src/signal/psiginfo.c", + "musl/src/signal/psignal.c", + "musl/src/signal/raise.c", + "musl/src/signal/restore.c", + "musl/src/signal/riscv64/restore.s", + "musl/src/signal/riscv64/sigsetjmp.s", + "musl/src/signal/s390x/restore.s", + "musl/src/signal/s390x/sigsetjmp.s", + "musl/src/signal/setitimer.c", + "musl/src/signal/sh/restore.s", + "musl/src/signal/sh/sigsetjmp.s", + "musl/src/signal/sigaction.c", + "musl/src/signal/sigaddset.c", + "musl/src/signal/sigaltstack.c", + "musl/src/signal/sigandset.c", + "musl/src/signal/sigdelset.c", + "musl/src/signal/sigemptyset.c", + "musl/src/signal/sigfillset.c", + "musl/src/signal/sighold.c", + "musl/src/signal/sigignore.c", + "musl/src/signal/siginterrupt.c", + "musl/src/signal/sigisemptyset.c", + "musl/src/signal/sigismember.c", + "musl/src/signal/siglongjmp.c", + "musl/src/signal/signal.c", + "musl/src/signal/sigorset.c", + "musl/src/signal/sigpause.c", + "musl/src/signal/sigpending.c", + "musl/src/signal/sigprocmask.c", + "musl/src/signal/sigqueue.c", + "musl/src/signal/sigrelse.c", + "musl/src/signal/sigrtmax.c", + "musl/src/signal/sigrtmin.c", + "musl/src/signal/sigset.c", + "musl/src/signal/sigsetjmp.c", + "musl/src/signal/sigsetjmp_tail.c", + "musl/src/signal/sigsuspend.c", + "musl/src/signal/sigtimedwait.c", + "musl/src/signal/sigwait.c", + "musl/src/signal/sigwaitinfo.c", + "musl/src/signal/x32/getitimer.c", + "musl/src/signal/x32/restore.s", + "musl/src/signal/x32/setitimer.c", + "musl/src/signal/x32/sigsetjmp.s", + "musl/src/signal/x86_64/restore.s", + "musl/src/signal/x86_64/sigsetjmp.s", + "musl/src/stat/__xstat.c", + "musl/src/stat/chmod.c", + "musl/src/stat/fchmod.c", + "musl/src/stat/fchmodat.c", + "musl/src/stat/fstat.c", + "musl/src/stat/fstatat.c", + "musl/src/stat/futimens.c", + "musl/src/stat/futimesat.c", + "musl/src/stat/lchmod.c", + "musl/src/stat/lstat.c", + "musl/src/stat/mkdir.c", + "musl/src/stat/mkdirat.c", + "musl/src/stat/mkfifo.c", + "musl/src/stat/mkfifoat.c", + "musl/src/stat/mknod.c", + "musl/src/stat/mknodat.c", + "musl/src/stat/stat.c", + "musl/src/stat/statvfs.c", + "musl/src/stat/umask.c", + "musl/src/stat/utimensat.c", + "musl/src/stdio/__fclose_ca.c", + "musl/src/stdio/__fdopen.c", + "musl/src/stdio/__fmodeflags.c", + "musl/src/stdio/__fopen_rb_ca.c", + "musl/src/stdio/__lockfile.c", + "musl/src/stdio/__overflow.c", + "musl/src/stdio/__stdio_close.c", + "musl/src/stdio/__stdio_exit.c", + "musl/src/stdio/__stdio_read.c", + "musl/src/stdio/__stdio_seek.c", + "musl/src/stdio/__stdio_write.c", + "musl/src/stdio/__stdout_write.c", + "musl/src/stdio/__string_read.c", + "musl/src/stdio/__toread.c", + "musl/src/stdio/__towrite.c", + "musl/src/stdio/__uflow.c", + "musl/src/stdio/asprintf.c", + "musl/src/stdio/clearerr.c", + "musl/src/stdio/dprintf.c", + "musl/src/stdio/ext.c", + "musl/src/stdio/ext2.c", + "musl/src/stdio/fclose.c", + "musl/src/stdio/feof.c", + "musl/src/stdio/ferror.c", + "musl/src/stdio/fflush.c", + "musl/src/stdio/fgetc.c", + "musl/src/stdio/fgetln.c", + "musl/src/stdio/fgetpos.c", + "musl/src/stdio/fgets.c", + "musl/src/stdio/fgetwc.c", + "musl/src/stdio/fgetws.c", + "musl/src/stdio/fileno.c", + "musl/src/stdio/flockfile.c", + "musl/src/stdio/fmemopen.c", + "musl/src/stdio/fopen.c", + "musl/src/stdio/fopencookie.c", + "musl/src/stdio/fprintf.c", + "musl/src/stdio/fputc.c", + "musl/src/stdio/fputs.c", + "musl/src/stdio/fputwc.c", + "musl/src/stdio/fputws.c", + "musl/src/stdio/fread.c", + "musl/src/stdio/freopen.c", + "musl/src/stdio/fscanf.c", + "musl/src/stdio/fseek.c", + "musl/src/stdio/fsetpos.c", + "musl/src/stdio/ftell.c", + "musl/src/stdio/ftrylockfile.c", + "musl/src/stdio/funlockfile.c", + "musl/src/stdio/fwide.c", + "musl/src/stdio/fwprintf.c", + "musl/src/stdio/fwrite.c", + "musl/src/stdio/fwscanf.c", + "musl/src/stdio/getc.c", + "musl/src/stdio/getc_unlocked.c", + "musl/src/stdio/getchar.c", + "musl/src/stdio/getchar_unlocked.c", + "musl/src/stdio/getdelim.c", + "musl/src/stdio/getline.c", + "musl/src/stdio/gets.c", + "musl/src/stdio/getw.c", + "musl/src/stdio/getwc.c", + "musl/src/stdio/getwchar.c", + "musl/src/stdio/ofl.c", + "musl/src/stdio/ofl_add.c", + "musl/src/stdio/open_memstream.c", + "musl/src/stdio/open_wmemstream.c", + "musl/src/stdio/pclose.c", + "musl/src/stdio/perror.c", + "musl/src/stdio/popen.c", + "musl/src/stdio/printf.c", + "musl/src/stdio/putc.c", + "musl/src/stdio/putc_unlocked.c", + "musl/src/stdio/putchar.c", + "musl/src/stdio/putchar_unlocked.c", + "musl/src/stdio/puts.c", + "musl/src/stdio/putw.c", + "musl/src/stdio/putwc.c", + "musl/src/stdio/putwchar.c", + "musl/src/stdio/remove.c", + "musl/src/stdio/rename.c", + "musl/src/stdio/rewind.c", + "musl/src/stdio/scanf.c", + "musl/src/stdio/setbuf.c", + "musl/src/stdio/setbuffer.c", + "musl/src/stdio/setlinebuf.c", + "musl/src/stdio/setvbuf.c", + "musl/src/stdio/snprintf.c", + "musl/src/stdio/sprintf.c", + "musl/src/stdio/sscanf.c", + "musl/src/stdio/stderr.c", + "musl/src/stdio/stdin.c", + "musl/src/stdio/stdout.c", + "musl/src/stdio/swprintf.c", + "musl/src/stdio/swscanf.c", + "musl/src/stdio/tempnam.c", + "musl/src/stdio/tmpfile.c", + "musl/src/stdio/tmpnam.c", + "musl/src/stdio/ungetc.c", + "musl/src/stdio/ungetwc.c", + "musl/src/stdio/vasprintf.c", + "musl/src/stdio/vdprintf.c", + "musl/src/stdio/vfprintf.c", + "musl/src/stdio/vfscanf.c", + "musl/src/stdio/vfwprintf.c", + "musl/src/stdio/vfwscanf.c", + "musl/src/stdio/vprintf.c", + "musl/src/stdio/vscanf.c", + "musl/src/stdio/vsnprintf.c", + "musl/src/stdio/vsprintf.c", + "musl/src/stdio/vsscanf.c", + "musl/src/stdio/vswprintf.c", + "musl/src/stdio/vswscanf.c", + "musl/src/stdio/vwprintf.c", + "musl/src/stdio/vwscanf.c", + "musl/src/stdio/wprintf.c", + "musl/src/stdio/wscanf.c", + "musl/src/stdlib/abs.c", + "musl/src/stdlib/atof.c", + "musl/src/stdlib/atoi.c", + "musl/src/stdlib/atol.c", + "musl/src/stdlib/atoll.c", + "musl/src/stdlib/bsearch.c", + "musl/src/stdlib/div.c", + "musl/src/stdlib/ecvt.c", + "musl/src/stdlib/fcvt.c", + "musl/src/stdlib/gcvt.c", + "musl/src/stdlib/imaxabs.c", + "musl/src/stdlib/imaxdiv.c", + "musl/src/stdlib/labs.c", + "musl/src/stdlib/ldiv.c", + "musl/src/stdlib/llabs.c", + "musl/src/stdlib/lldiv.c", + "musl/src/stdlib/qsort.c", + "musl/src/stdlib/strtod.c", + "musl/src/stdlib/strtol.c", + "musl/src/stdlib/wcstod.c", + "musl/src/stdlib/wcstol.c", + "musl/src/string/arm/__aeabi_memcpy.s", + "musl/src/string/arm/__aeabi_memset.s", + "musl/src/string/arm/memcpy.c", + "musl/src/string/arm/memcpy_le.S", + "musl/src/string/bcmp.c", + "musl/src/string/bcopy.c", + "musl/src/string/bzero.c", + "musl/src/string/explicit_bzero.c", + "musl/src/string/i386/memcpy.s", + "musl/src/string/i386/memmove.s", + "musl/src/string/i386/memset.s", + "musl/src/string/index.c", + "musl/src/string/memccpy.c", + "musl/src/string/memchr.c", + "musl/src/string/memcmp.c", + "musl/src/string/memcpy.c", + "musl/src/string/memmem.c", + "musl/src/string/memmove.c", + "musl/src/string/mempcpy.c", + "musl/src/string/memrchr.c", + "musl/src/string/memset.c", + "musl/src/string/rindex.c", + "musl/src/string/stpcpy.c", + "musl/src/string/stpncpy.c", + "musl/src/string/strcasecmp.c", + "musl/src/string/strcasestr.c", + "musl/src/string/strcat.c", + "musl/src/string/strchr.c", + "musl/src/string/strchrnul.c", + "musl/src/string/strcmp.c", + "musl/src/string/strcpy.c", + "musl/src/string/strcspn.c", + "musl/src/string/strdup.c", + "musl/src/string/strerror_r.c", + "musl/src/string/strlcat.c", + "musl/src/string/strlcpy.c", + "musl/src/string/strlen.c", + "musl/src/string/strncasecmp.c", + "musl/src/string/strncat.c", + "musl/src/string/strncmp.c", + "musl/src/string/strncpy.c", + "musl/src/string/strndup.c", + "musl/src/string/strnlen.c", + "musl/src/string/strpbrk.c", + "musl/src/string/strrchr.c", + "musl/src/string/strsep.c", + "musl/src/string/strsignal.c", + "musl/src/string/strspn.c", + "musl/src/string/strstr.c", + "musl/src/string/strtok.c", + "musl/src/string/strtok_r.c", + "musl/src/string/strverscmp.c", + "musl/src/string/swab.c", + "musl/src/string/wcpcpy.c", + "musl/src/string/wcpncpy.c", + "musl/src/string/wcscasecmp.c", + "musl/src/string/wcscasecmp_l.c", + "musl/src/string/wcscat.c", + "musl/src/string/wcschr.c", + "musl/src/string/wcscmp.c", + "musl/src/string/wcscpy.c", + "musl/src/string/wcscspn.c", + "musl/src/string/wcsdup.c", + "musl/src/string/wcslen.c", + "musl/src/string/wcsncasecmp.c", + "musl/src/string/wcsncasecmp_l.c", + "musl/src/string/wcsncat.c", + "musl/src/string/wcsncmp.c", + "musl/src/string/wcsncpy.c", + "musl/src/string/wcsnlen.c", + "musl/src/string/wcspbrk.c", + "musl/src/string/wcsrchr.c", + "musl/src/string/wcsspn.c", + "musl/src/string/wcsstr.c", + "musl/src/string/wcstok.c", + "musl/src/string/wcswcs.c", + "musl/src/string/wmemchr.c", + "musl/src/string/wmemcmp.c", + "musl/src/string/wmemcpy.c", + "musl/src/string/wmemmove.c", + "musl/src/string/wmemset.c", + "musl/src/string/x86_64/memcpy.s", + "musl/src/string/x86_64/memmove.s", + "musl/src/string/x86_64/memset.s", + "musl/src/temp/__randname.c", + "musl/src/temp/mkdtemp.c", + "musl/src/temp/mkostemp.c", + "musl/src/temp/mkostemps.c", + "musl/src/temp/mkstemp.c", + "musl/src/temp/mkstemps.c", + "musl/src/temp/mktemp.c", + "musl/src/termios/cfgetospeed.c", + "musl/src/termios/cfmakeraw.c", + "musl/src/termios/cfsetospeed.c", + "musl/src/termios/tcdrain.c", + "musl/src/termios/tcflow.c", + "musl/src/termios/tcflush.c", + "musl/src/termios/tcgetattr.c", + "musl/src/termios/tcgetsid.c", + "musl/src/termios/tcsendbreak.c", + "musl/src/termios/tcsetattr.c", + "musl/src/thread/__lock.c", + "musl/src/thread/__set_thread_area.c", + "musl/src/thread/__syscall_cp.c", + "musl/src/thread/__timedwait.c", + "musl/src/thread/__tls_get_addr.c", + "musl/src/thread/__unmapself.c", + "musl/src/thread/__wait.c", + "musl/src/thread/aarch64/__set_thread_area.s", + "musl/src/thread/aarch64/__unmapself.s", + "musl/src/thread/aarch64/clone.s", + "musl/src/thread/aarch64/syscall_cp.s", + "musl/src/thread/arm/__aeabi_read_tp.s", + "musl/src/thread/arm/__set_thread_area.c", + "musl/src/thread/arm/__unmapself.s", + "musl/src/thread/arm/atomics.s", + "musl/src/thread/arm/clone.s", + "musl/src/thread/arm/syscall_cp.s", + "musl/src/thread/call_once.c", + "musl/src/thread/clone.c", + "musl/src/thread/cnd_broadcast.c", + "musl/src/thread/cnd_destroy.c", + "musl/src/thread/cnd_init.c", + "musl/src/thread/cnd_signal.c", + "musl/src/thread/cnd_timedwait.c", + "musl/src/thread/cnd_wait.c", + "musl/src/thread/default_attr.c", + "musl/src/thread/i386/__set_thread_area.s", + "musl/src/thread/i386/__unmapself.s", + "musl/src/thread/i386/clone.s", + "musl/src/thread/i386/syscall_cp.s", + "musl/src/thread/i386/tls.s", + "musl/src/thread/lock_ptc.c", + "musl/src/thread/m68k/__m68k_read_tp.s", + "musl/src/thread/m68k/clone.s", + "musl/src/thread/m68k/syscall_cp.s", + "musl/src/thread/microblaze/__set_thread_area.s", + "musl/src/thread/microblaze/__unmapself.s", + "musl/src/thread/microblaze/clone.s", + "musl/src/thread/microblaze/syscall_cp.s", + "musl/src/thread/mips/__unmapself.s", + "musl/src/thread/mips/clone.s", + "musl/src/thread/mips/syscall_cp.s", + "musl/src/thread/mips64/__unmapself.s", + "musl/src/thread/mips64/clone.s", + "musl/src/thread/mips64/syscall_cp.s", + "musl/src/thread/mipsn32/__unmapself.s", + "musl/src/thread/mipsn32/clone.s", + "musl/src/thread/mipsn32/syscall_cp.s", + "musl/src/thread/mtx_destroy.c", + "musl/src/thread/mtx_init.c", + "musl/src/thread/mtx_lock.c", + "musl/src/thread/mtx_timedlock.c", + "musl/src/thread/mtx_trylock.c", + "musl/src/thread/mtx_unlock.c", + "musl/src/thread/or1k/__set_thread_area.s", + "musl/src/thread/or1k/__unmapself.s", + "musl/src/thread/or1k/clone.s", + "musl/src/thread/or1k/syscall_cp.s", + "musl/src/thread/powerpc/__set_thread_area.s", + "musl/src/thread/powerpc/__unmapself.s", + "musl/src/thread/powerpc/clone.s", + "musl/src/thread/powerpc/syscall_cp.s", + "musl/src/thread/powerpc64/__set_thread_area.s", + "musl/src/thread/powerpc64/__unmapself.s", + "musl/src/thread/powerpc64/clone.s", + "musl/src/thread/powerpc64/syscall_cp.s", + "musl/src/thread/pthread_atfork.c", + "musl/src/thread/pthread_attr_destroy.c", + "musl/src/thread/pthread_attr_get.c", + "musl/src/thread/pthread_attr_init.c", + "musl/src/thread/pthread_attr_setdetachstate.c", + "musl/src/thread/pthread_attr_setguardsize.c", + "musl/src/thread/pthread_attr_setinheritsched.c", + "musl/src/thread/pthread_attr_setschedparam.c", + "musl/src/thread/pthread_attr_setschedpolicy.c", + "musl/src/thread/pthread_attr_setscope.c", + "musl/src/thread/pthread_attr_setstack.c", + "musl/src/thread/pthread_attr_setstacksize.c", + "musl/src/thread/pthread_barrier_destroy.c", + "musl/src/thread/pthread_barrier_init.c", + "musl/src/thread/pthread_barrier_wait.c", + "musl/src/thread/pthread_barrierattr_destroy.c", + "musl/src/thread/pthread_barrierattr_init.c", + "musl/src/thread/pthread_barrierattr_setpshared.c", + "musl/src/thread/pthread_cancel.c", + "musl/src/thread/pthread_cleanup_push.c", + "musl/src/thread/pthread_cond_broadcast.c", + "musl/src/thread/pthread_cond_destroy.c", + "musl/src/thread/pthread_cond_init.c", + "musl/src/thread/pthread_cond_signal.c", + "musl/src/thread/pthread_cond_timedwait.c", + "musl/src/thread/pthread_cond_wait.c", + "musl/src/thread/pthread_condattr_destroy.c", + "musl/src/thread/pthread_condattr_init.c", + "musl/src/thread/pthread_condattr_setclock.c", + "musl/src/thread/pthread_condattr_setpshared.c", + "musl/src/thread/pthread_create.c", + "musl/src/thread/pthread_detach.c", + "musl/src/thread/pthread_equal.c", + "musl/src/thread/pthread_getattr_np.c", + "musl/src/thread/pthread_getconcurrency.c", + "musl/src/thread/pthread_getcpuclockid.c", + "musl/src/thread/pthread_getschedparam.c", + "musl/src/thread/pthread_getspecific.c", + "musl/src/thread/pthread_join.c", + "musl/src/thread/pthread_key_create.c", + "musl/src/thread/pthread_kill.c", + "musl/src/thread/pthread_mutex_consistent.c", + "musl/src/thread/pthread_mutex_destroy.c", + "musl/src/thread/pthread_mutex_getprioceiling.c", + "musl/src/thread/pthread_mutex_init.c", + "musl/src/thread/pthread_mutex_lock.c", + "musl/src/thread/pthread_mutex_setprioceiling.c", + "musl/src/thread/pthread_mutex_timedlock.c", + "musl/src/thread/pthread_mutex_trylock.c", + "musl/src/thread/pthread_mutex_unlock.c", + "musl/src/thread/pthread_mutexattr_destroy.c", + "musl/src/thread/pthread_mutexattr_init.c", + "musl/src/thread/pthread_mutexattr_setprotocol.c", + "musl/src/thread/pthread_mutexattr_setpshared.c", + "musl/src/thread/pthread_mutexattr_setrobust.c", + "musl/src/thread/pthread_mutexattr_settype.c", + "musl/src/thread/pthread_once.c", + "musl/src/thread/pthread_rwlock_destroy.c", + "musl/src/thread/pthread_rwlock_init.c", + "musl/src/thread/pthread_rwlock_rdlock.c", + "musl/src/thread/pthread_rwlock_timedrdlock.c", + "musl/src/thread/pthread_rwlock_timedwrlock.c", + "musl/src/thread/pthread_rwlock_tryrdlock.c", + "musl/src/thread/pthread_rwlock_trywrlock.c", + "musl/src/thread/pthread_rwlock_unlock.c", + "musl/src/thread/pthread_rwlock_wrlock.c", + "musl/src/thread/pthread_rwlockattr_destroy.c", + "musl/src/thread/pthread_rwlockattr_init.c", + "musl/src/thread/pthread_rwlockattr_setpshared.c", + "musl/src/thread/pthread_self.c", + "musl/src/thread/pthread_setattr_default_np.c", + "musl/src/thread/pthread_setcancelstate.c", + "musl/src/thread/pthread_setcanceltype.c", + "musl/src/thread/pthread_setconcurrency.c", + "musl/src/thread/pthread_setname_np.c", + "musl/src/thread/pthread_setschedparam.c", + "musl/src/thread/pthread_setschedprio.c", + "musl/src/thread/pthread_setspecific.c", + "musl/src/thread/pthread_sigmask.c", + "musl/src/thread/pthread_spin_destroy.c", + "musl/src/thread/pthread_spin_init.c", + "musl/src/thread/pthread_spin_lock.c", + "musl/src/thread/pthread_spin_trylock.c", + "musl/src/thread/pthread_spin_unlock.c", + "musl/src/thread/pthread_testcancel.c", + "musl/src/thread/riscv64/__set_thread_area.s", + "musl/src/thread/riscv64/__unmapself.s", + "musl/src/thread/riscv64/clone.s", + "musl/src/thread/riscv64/syscall_cp.s", + "musl/src/thread/s390x/__set_thread_area.s", + "musl/src/thread/s390x/__tls_get_offset.s", + "musl/src/thread/s390x/__unmapself.s", + "musl/src/thread/s390x/clone.s", + "musl/src/thread/s390x/syscall_cp.s", + "musl/src/thread/sem_destroy.c", + "musl/src/thread/sem_getvalue.c", + "musl/src/thread/sem_init.c", + "musl/src/thread/sem_open.c", + "musl/src/thread/sem_post.c", + "musl/src/thread/sem_timedwait.c", + "musl/src/thread/sem_trywait.c", + "musl/src/thread/sem_unlink.c", + "musl/src/thread/sem_wait.c", + "musl/src/thread/sh/__set_thread_area.c", + "musl/src/thread/sh/__unmapself.c", + "musl/src/thread/sh/__unmapself_mmu.s", + "musl/src/thread/sh/atomics.s", + "musl/src/thread/sh/clone.s", + "musl/src/thread/sh/syscall_cp.s", + "musl/src/thread/synccall.c", + "musl/src/thread/syscall_cp.c", + "musl/src/thread/thrd_create.c", + "musl/src/thread/thrd_exit.c", + "musl/src/thread/thrd_join.c", + "musl/src/thread/thrd_sleep.c", + "musl/src/thread/thrd_yield.c", + "musl/src/thread/tls.c", + "musl/src/thread/tss_create.c", + "musl/src/thread/tss_delete.c", + "musl/src/thread/tss_set.c", + "musl/src/thread/vmlock.c", + "musl/src/thread/x32/__set_thread_area.s", + "musl/src/thread/x32/__unmapself.s", + "musl/src/thread/x32/clone.s", + "musl/src/thread/x32/syscall_cp.s", + "musl/src/thread/x86_64/__set_thread_area.s", + "musl/src/thread/x86_64/__unmapself.s", + "musl/src/thread/x86_64/clone.s", + "musl/src/thread/x86_64/syscall_cp.s", + "musl/src/time/__map_file.c", + "musl/src/time/__month_to_secs.c", + "musl/src/time/__secs_to_tm.c", + "musl/src/time/__tm_to_secs.c", + "musl/src/time/__tz.c", + "musl/src/time/__year_to_secs.c", + "musl/src/time/asctime.c", + "musl/src/time/asctime_r.c", + "musl/src/time/clock.c", + "musl/src/time/clock_getcpuclockid.c", + "musl/src/time/clock_getres.c", + "musl/src/time/clock_gettime.c", + "musl/src/time/clock_nanosleep.c", + "musl/src/time/clock_settime.c", + "musl/src/time/ctime.c", + "musl/src/time/ctime_r.c", + "musl/src/time/difftime.c", + "musl/src/time/ftime.c", + "musl/src/time/getdate.c", + "musl/src/time/gettimeofday.c", + "musl/src/time/gmtime.c", + "musl/src/time/gmtime_r.c", + "musl/src/time/localtime.c", + "musl/src/time/localtime_r.c", + "musl/src/time/mktime.c", + "musl/src/time/nanosleep.c", + "musl/src/time/strftime.c", + "musl/src/time/strptime.c", + "musl/src/time/time.c", + "musl/src/time/timegm.c", + "musl/src/time/timer_create.c", + "musl/src/time/timer_delete.c", + "musl/src/time/timer_getoverrun.c", + "musl/src/time/timer_gettime.c", + "musl/src/time/timer_settime.c", + "musl/src/time/times.c", + "musl/src/time/timespec_get.c", + "musl/src/time/utime.c", + "musl/src/time/wcsftime.c", + "musl/src/unistd/_exit.c", + "musl/src/unistd/access.c", + "musl/src/unistd/acct.c", + "musl/src/unistd/alarm.c", + "musl/src/unistd/chdir.c", + "musl/src/unistd/chown.c", + "musl/src/unistd/close.c", + "musl/src/unistd/ctermid.c", + "musl/src/unistd/dup.c", + "musl/src/unistd/dup2.c", + "musl/src/unistd/dup3.c", + "musl/src/unistd/faccessat.c", + "musl/src/unistd/fchdir.c", + "musl/src/unistd/fchown.c", + "musl/src/unistd/fchownat.c", + "musl/src/unistd/fdatasync.c", + "musl/src/unistd/fsync.c", + "musl/src/unistd/ftruncate.c", + "musl/src/unistd/getcwd.c", + "musl/src/unistd/getegid.c", + "musl/src/unistd/geteuid.c", + "musl/src/unistd/getgid.c", + "musl/src/unistd/getgroups.c", + "musl/src/unistd/gethostname.c", + "musl/src/unistd/getlogin.c", + "musl/src/unistd/getlogin_r.c", + "musl/src/unistd/getpgid.c", + "musl/src/unistd/getpgrp.c", + "musl/src/unistd/getpid.c", + "musl/src/unistd/getppid.c", + "musl/src/unistd/getsid.c", + "musl/src/unistd/getuid.c", + "musl/src/unistd/isatty.c", + "musl/src/unistd/lchown.c", + "musl/src/unistd/link.c", + "musl/src/unistd/linkat.c", + "musl/src/unistd/lseek.c", + "musl/src/unistd/mips/pipe.s", + "musl/src/unistd/mips64/pipe.s", + "musl/src/unistd/mipsn32/lseek.c", + "musl/src/unistd/mipsn32/pipe.s", + "musl/src/unistd/nice.c", + "musl/src/unistd/pause.c", + "musl/src/unistd/pipe.c", + "musl/src/unistd/pipe2.c", + "musl/src/unistd/posix_close.c", + "musl/src/unistd/pread.c", + "musl/src/unistd/preadv.c", + "musl/src/unistd/pwrite.c", + "musl/src/unistd/pwritev.c", + "musl/src/unistd/read.c", + "musl/src/unistd/readlink.c", + "musl/src/unistd/readlinkat.c", + "musl/src/unistd/readv.c", + "musl/src/unistd/renameat.c", + "musl/src/unistd/rmdir.c", + "musl/src/unistd/setegid.c", + "musl/src/unistd/seteuid.c", + "musl/src/unistd/setgid.c", + "musl/src/unistd/setpgid.c", + "musl/src/unistd/setpgrp.c", + "musl/src/unistd/setregid.c", + "musl/src/unistd/setresgid.c", + "musl/src/unistd/setresuid.c", + "musl/src/unistd/setreuid.c", + "musl/src/unistd/setsid.c", + "musl/src/unistd/setuid.c", + "musl/src/unistd/setxid.c", + "musl/src/unistd/sh/pipe.s", + "musl/src/unistd/sleep.c", + "musl/src/unistd/symlink.c", + "musl/src/unistd/symlinkat.c", + "musl/src/unistd/sync.c", + "musl/src/unistd/tcgetpgrp.c", + "musl/src/unistd/tcsetpgrp.c", + "musl/src/unistd/truncate.c", + "musl/src/unistd/ttyname.c", + "musl/src/unistd/ttyname_r.c", + "musl/src/unistd/ualarm.c", + "musl/src/unistd/unlink.c", + "musl/src/unistd/unlinkat.c", + "musl/src/unistd/usleep.c", + "musl/src/unistd/write.c", + "musl/src/unistd/writev.c", + "musl/src/unistd/x32/lseek.c", +}; +pub const compat_time32_files = [_][]const u8{ + "musl/compat/time32/__xstat.c", + "musl/compat/time32/adjtime32.c", + "musl/compat/time32/adjtimex_time32.c", + "musl/compat/time32/aio_suspend_time32.c", + "musl/compat/time32/clock_adjtime32.c", + "musl/compat/time32/clock_getres_time32.c", + "musl/compat/time32/clock_gettime32.c", + "musl/compat/time32/clock_nanosleep_time32.c", + "musl/compat/time32/clock_settime32.c", + "musl/compat/time32/cnd_timedwait_time32.c", + "musl/compat/time32/ctime32.c", + "musl/compat/time32/ctime32_r.c", + "musl/compat/time32/difftime32.c", + "musl/compat/time32/fstat_time32.c", + "musl/compat/time32/fstatat_time32.c", + "musl/compat/time32/ftime32.c", + "musl/compat/time32/futimens_time32.c", + "musl/compat/time32/futimes_time32.c", + "musl/compat/time32/futimesat_time32.c", + "musl/compat/time32/getitimer_time32.c", + "musl/compat/time32/getrusage_time32.c", + "musl/compat/time32/gettimeofday_time32.c", + "musl/compat/time32/gmtime32.c", + "musl/compat/time32/gmtime32_r.c", + "musl/compat/time32/localtime32.c", + "musl/compat/time32/localtime32_r.c", + "musl/compat/time32/lstat_time32.c", + "musl/compat/time32/lutimes_time32.c", + "musl/compat/time32/mktime32.c", + "musl/compat/time32/mq_timedreceive_time32.c", + "musl/compat/time32/mq_timedsend_time32.c", + "musl/compat/time32/mtx_timedlock_time32.c", + "musl/compat/time32/nanosleep_time32.c", + "musl/compat/time32/ppoll_time32.c", + "musl/compat/time32/pselect_time32.c", + "musl/compat/time32/pthread_cond_timedwait_time32.c", + "musl/compat/time32/pthread_mutex_timedlock_time32.c", + "musl/compat/time32/pthread_rwlock_timedrdlock_time32.c", + "musl/compat/time32/pthread_rwlock_timedwrlock_time32.c", + "musl/compat/time32/pthread_timedjoin_np_time32.c", + "musl/compat/time32/recvmmsg_time32.c", + "musl/compat/time32/sched_rr_get_interval_time32.c", + "musl/compat/time32/select_time32.c", + "musl/compat/time32/sem_timedwait_time32.c", + "musl/compat/time32/semtimedop_time32.c", + "musl/compat/time32/setitimer_time32.c", + "musl/compat/time32/settimeofday_time32.c", + "musl/compat/time32/sigtimedwait_time32.c", + "musl/compat/time32/stat_time32.c", + "musl/compat/time32/stime32.c", + "musl/compat/time32/thrd_sleep_time32.c", + "musl/compat/time32/time32.c", + "musl/compat/time32/time32gm.c", + "musl/compat/time32/timer_gettime32.c", + "musl/compat/time32/timer_settime32.c", + "musl/compat/time32/timerfd_gettime32.c", + "musl/compat/time32/timerfd_settime32.c", + "musl/compat/time32/timespec_get_time32.c", + "musl/compat/time32/utime_time32.c", + "musl/compat/time32/utimensat_time32.c", + "musl/compat/time32/utimes_time32.c", + "musl/compat/time32/wait3_time32.c", + "musl/compat/time32/wait4_time32.c", +}; diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig new file mode 100644 index 0000000000..c2ce99db22 --- /dev/null +++ b/src-self-hosted/stage1.zig @@ -0,0 +1,495 @@ +//! This is the main entry point for the Zig/C++ hybrid compiler (stage1). +//! It has the functions exported from Zig, called in C++, and bindings for +//! the functions exported from C++, called from Zig. + +const std = @import("std"); +const assert = std.debug.assert; +const mem = std.mem; +const build_options = @import("build_options"); +const stage2 = @import("main.zig"); +const fatal = stage2.fatal; +const CrossTarget = std.zig.CrossTarget; +const Target = std.Target; + +comptime { + assert(std.builtin.link_libc); + assert(build_options.is_stage1); + _ = @import("compiler_rt"); +} + +pub const log = stage2.log; +pub const log_level = stage2.log_level; + +pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int { + std.debug.maybeEnableSegfaultHandler(); + + const gpa = std.heap.c_allocator; + var arena_instance = std.heap.ArenaAllocator.init(gpa); + defer arena_instance.deinit(); + const arena = &arena_instance.allocator; + + const args = arena.alloc([]const u8, @intCast(usize, argc)) catch fatal("out of memory", .{}); + for (args) |*arg, i| { + arg.* = mem.spanZ(argv[i]); + } + stage2.mainArgs(gpa, arena, args) catch |err| fatal("{}", .{err}); + return 0; +} + +// ABI warning +export fn stage2_panic(ptr: [*]const u8, len: usize) void { + @panic(ptr[0..len]); +} + +// ABI warning +const Error = extern enum { + None, + OutOfMemory, + InvalidFormat, + SemanticAnalyzeFail, + AccessDenied, + Interrupted, + SystemResources, + FileNotFound, + FileSystem, + FileTooBig, + DivByZero, + Overflow, + PathAlreadyExists, + Unexpected, + ExactDivRemainder, + NegativeDenominator, + ShiftedOutOneBits, + CCompileErrors, + EndOfFile, + IsDir, + NotDir, + UnsupportedOperatingSystem, + SharingViolation, + PipeBusy, + PrimitiveTypeNotFound, + CacheUnavailable, + PathTooLong, + CCompilerCannotFindFile, + NoCCompilerInstalled, + ReadingDepFile, + InvalidDepFile, + MissingArchitecture, + MissingOperatingSystem, + UnknownArchitecture, + UnknownOperatingSystem, + UnknownABI, + InvalidFilename, + DiskQuota, + DiskSpace, + UnexpectedWriteFailure, + UnexpectedSeekFailure, + UnexpectedFileTruncationFailure, + Unimplemented, + OperationAborted, + BrokenPipe, + NoSpaceLeft, + NotLazy, + IsAsync, + ImportOutsidePkgPath, + UnknownCpuModel, + UnknownCpuFeature, + InvalidCpuFeatures, + InvalidLlvmCpuFeaturesFormat, + UnknownApplicationBinaryInterface, + ASTUnitFailure, + BadPathName, + SymLinkLoop, + ProcessFdQuotaExceeded, + SystemFdQuotaExceeded, + NoDevice, + DeviceBusy, + UnableToSpawnCCompiler, + CCompilerExitCode, + CCompilerCrashed, + CCompilerCannotFindHeaders, + LibCRuntimeNotFound, + LibCStdLibHeaderNotFound, + LibCKernel32LibNotFound, + UnsupportedArchitecture, + WindowsSdkNotFound, + UnknownDynamicLinkerPath, + TargetHasNoDynamicLinker, + InvalidAbiVersion, + InvalidOperatingSystemVersion, + UnknownClangOption, + NestedResponseFile, + ZigIsTheCCompiler, + FileBusy, + Locked, +}; + +// ABI warning +export fn stage2_attach_segfault_handler() void { + if (std.debug.runtime_safety and std.debug.have_segfault_handling_support) { + std.debug.attachSegfaultHandler(); + } +} + +// ABI warning +export fn stage2_progress_create() *std.Progress { + const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory"); + ptr.* = std.Progress{}; + return ptr; +} + +// ABI warning +export fn stage2_progress_destroy(progress: *std.Progress) void { + std.heap.c_allocator.destroy(progress); +} + +// ABI warning +export fn stage2_progress_start_root( + progress: *std.Progress, + name_ptr: [*]const u8, + name_len: usize, + estimated_total_items: usize, +) *std.Progress.Node { + return progress.start( + name_ptr[0..name_len], + if (estimated_total_items == 0) null else estimated_total_items, + ) catch @panic("timer unsupported"); +} + +// ABI warning +export fn stage2_progress_disable_tty(progress: *std.Progress) void { + progress.terminal = null; +} + +// ABI warning +export fn stage2_progress_start( + node: *std.Progress.Node, + name_ptr: [*]const u8, + name_len: usize, + estimated_total_items: usize, +) *std.Progress.Node { + const child_node = std.heap.c_allocator.create(std.Progress.Node) catch @panic("out of memory"); + child_node.* = node.start( + name_ptr[0..name_len], + if (estimated_total_items == 0) null else estimated_total_items, + ); + child_node.activate(); + return child_node; +} + +// ABI warning +export fn stage2_progress_end(node: *std.Progress.Node) void { + node.end(); + if (&node.context.root != node) { + std.heap.c_allocator.destroy(node); + } +} + +// ABI warning +export fn stage2_progress_complete_one(node: *std.Progress.Node) void { + node.completeOne(); +} + +// ABI warning +export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usize, total_count: usize) void { + node.completed_items = done_count; + node.estimated_total_items = total_count; + node.activate(); + node.context.maybeRefresh(); +} + +// ABI warning +const Stage2Target = extern struct { + arch: c_int, + vendor: c_int, + + abi: c_int, + os: c_int, + + is_native_os: bool, + is_native_cpu: bool, + + llvm_cpu_name: ?[*:0]const u8, + llvm_cpu_features: ?[*:0]const u8, + cpu_builtin_str: ?[*:0]const u8, + os_builtin_str: ?[*:0]const u8, + + dynamic_linker: ?[*:0]const u8, + + llvm_cpu_features_asm_ptr: [*]const [*:0]const u8, + llvm_cpu_features_asm_len: usize, + + fn fromTarget(self: *Stage2Target, cross_target: CrossTarget) !void { + const allocator = std.heap.c_allocator; + + var dynamic_linker: ?[*:0]u8 = null; + const target = try crossTargetToTarget(cross_target, &dynamic_linker); + + const generic_arch_name = target.cpu.arch.genericName(); + var cpu_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, + \\Cpu{{ + \\ .arch = .{}, + \\ .model = &Target.{}.cpu.{}, + \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ + \\ + , .{ + @tagName(target.cpu.arch), + generic_arch_name, + target.cpu.model.name, + generic_arch_name, + generic_arch_name, + }); + defer cpu_builtin_str_buffer.deinit(); + + var llvm_features_buffer = try std.ArrayListSentineled(u8, 0).initSize(allocator, 0); + defer llvm_features_buffer.deinit(); + + // Unfortunately we have to do the work twice, because Clang does not support + // the same command line parameters for CPU features when assembling code as it does + // when compiling C code. + var asm_features_list = std.ArrayList([*:0]const u8).init(allocator); + defer asm_features_list.deinit(); + + for (target.cpu.arch.allFeaturesList()) |feature, index_usize| { + const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); + const is_enabled = target.cpu.features.isEnabled(index); + + if (feature.llvm_name) |llvm_name| { + const plus_or_minus = "-+"[@boolToInt(is_enabled)]; + try llvm_features_buffer.append(plus_or_minus); + try llvm_features_buffer.appendSlice(llvm_name); + try llvm_features_buffer.appendSlice(","); + } + + if (is_enabled) { + // TODO some kind of "zig identifier escape" function rather than + // unconditionally using @"" syntax + try cpu_builtin_str_buffer.appendSlice(" .@\""); + try cpu_builtin_str_buffer.appendSlice(feature.name); + try cpu_builtin_str_buffer.appendSlice("\",\n"); + } + } + + switch (target.cpu.arch) { + .riscv32, .riscv64 => { + if (Target.riscv.featureSetHas(target.cpu.features, .relax)) { + try asm_features_list.append("-mrelax"); + } else { + try asm_features_list.append("-mno-relax"); + } + }, + else => { + // TODO + // Argh, why doesn't the assembler accept the list of CPU features?! + // I don't see a way to do this other than hard coding everything. + }, + } + + try cpu_builtin_str_buffer.appendSlice( + \\ }), + \\}; + \\ + ); + + assert(mem.endsWith(u8, llvm_features_buffer.span(), ",")); + llvm_features_buffer.shrink(llvm_features_buffer.len() - 1); + + var os_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, + \\Os{{ + \\ .tag = .{}, + \\ .version_range = .{{ + , .{@tagName(target.os.tag)}); + defer os_builtin_str_buffer.deinit(); + + // We'll re-use the OS version range builtin string for the cache hash. + const os_builtin_str_ver_start_index = os_builtin_str_buffer.len(); + + @setEvalBranchQuota(2000); + switch (target.os.tag) { + .freestanding, + .ananas, + .cloudabi, + .dragonfly, + .fuchsia, + .ios, + .kfreebsd, + .lv2, + .solaris, + .haiku, + .minix, + .rtems, + .nacl, + .cnk, + .aix, + .cuda, + .nvcl, + .amdhsa, + .ps4, + .elfiamcu, + .tvos, + .watchos, + .mesa3d, + .contiki, + .amdpal, + .hermit, + .hurd, + .wasi, + .emscripten, + .uefi, + .other, + => try os_builtin_str_buffer.appendSlice(" .none = {} }\n"), + + .freebsd, + .macosx, + .netbsd, + .openbsd, + => try os_builtin_str_buffer.outStream().print( + \\ .semver = .{{ + \\ .min = .{{ + \\ .major = {}, + \\ .minor = {}, + \\ .patch = {}, + \\ }}, + \\ .max = .{{ + \\ .major = {}, + \\ .minor = {}, + \\ .patch = {}, + \\ }}, + \\ }}}}, + \\ + , .{ + target.os.version_range.semver.min.major, + target.os.version_range.semver.min.minor, + target.os.version_range.semver.min.patch, + + target.os.version_range.semver.max.major, + target.os.version_range.semver.max.minor, + target.os.version_range.semver.max.patch, + }), + + .linux => try os_builtin_str_buffer.outStream().print( + \\ .linux = .{{ + \\ .range = .{{ + \\ .min = .{{ + \\ .major = {}, + \\ .minor = {}, + \\ .patch = {}, + \\ }}, + \\ .max = .{{ + \\ .major = {}, + \\ .minor = {}, + \\ .patch = {}, + \\ }}, + \\ }}, + \\ .glibc = .{{ + \\ .major = {}, + \\ .minor = {}, + \\ .patch = {}, + \\ }}, + \\ }}}}, + \\ + , .{ + target.os.version_range.linux.range.min.major, + target.os.version_range.linux.range.min.minor, + target.os.version_range.linux.range.min.patch, + + target.os.version_range.linux.range.max.major, + target.os.version_range.linux.range.max.minor, + target.os.version_range.linux.range.max.patch, + + target.os.version_range.linux.glibc.major, + target.os.version_range.linux.glibc.minor, + target.os.version_range.linux.glibc.patch, + }), + + .windows => try os_builtin_str_buffer.outStream().print( + \\ .windows = .{{ + \\ .min = {s}, + \\ .max = {s}, + \\ }}}}, + \\ + , .{ + target.os.version_range.windows.min, + target.os.version_range.windows.max, + }), + } + try os_builtin_str_buffer.appendSlice("};\n"); + + const glibc_or_darwin_version = blk: { + if (target.isGnuLibC()) { + const stage1_glibc = try std.heap.c_allocator.create(Stage2SemVer); + const stage2_glibc = target.os.version_range.linux.glibc; + stage1_glibc.* = .{ + .major = stage2_glibc.major, + .minor = stage2_glibc.minor, + .patch = stage2_glibc.patch, + }; + break :blk stage1_glibc; + } else if (target.isDarwin()) { + const stage1_semver = try std.heap.c_allocator.create(Stage2SemVer); + const stage2_semver = target.os.version_range.semver.min; + stage1_semver.* = .{ + .major = stage2_semver.major, + .minor = stage2_semver.minor, + .patch = stage2_semver.patch, + }; + break :blk stage1_semver; + } else { + break :blk null; + } + }; + + const std_dl = target.standardDynamicLinkerPath(); + const std_dl_z = if (std_dl.get()) |dl| + (try mem.dupeZ(std.heap.c_allocator, u8, dl)).ptr + else + null; + + const asm_features = asm_features_list.toOwnedSlice(); + self.* = .{ + .arch = @enumToInt(target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch + .vendor = 0, + .os = @enumToInt(target.os.tag), + .abi = @enumToInt(target.abi), + .llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null, + .llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr, + .llvm_cpu_features_asm_ptr = asm_features.ptr, + .llvm_cpu_features_asm_len = asm_features.len, + .cpu_builtin_str = cpu_builtin_str_buffer.toOwnedSlice().ptr, + .os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr, + .is_native_os = cross_target.isNativeOs(), + .is_native_cpu = cross_target.isNativeCpu(), + .glibc_or_darwin_version = glibc_or_darwin_version, + .dynamic_linker = dynamic_linker, + .standard_dynamic_linker_path = std_dl_z, + }; + } +}; + +fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) !Target { + var info = try std.zig.system.NativeTargetInfo.detect(std.heap.c_allocator, cross_target); + if (info.cpu_detection_unimplemented) { + // TODO We want to just use detected_info.target but implementing + // CPU model & feature detection is todo so here we rely on LLVM. + const llvm = @import("llvm.zig"); + const llvm_cpu_name = llvm.GetHostCPUName(); + const llvm_cpu_features = llvm.GetNativeFeatures(); + const arch = Target.current.cpu.arch; + info.target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features); + cross_target.updateCpuFeatures(&info.target.cpu.features); + info.target.cpu.arch = cross_target.getCpuArch(); + } + if (info.dynamic_linker.get()) |dl| { + dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl); + } else { + dynamic_linker_ptr.* = null; + } + return info.target; +} + +// ABI warning +const Stage2SemVer = extern struct { + major: u32, + minor: u32, + patch: u32, +}; diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig deleted file mode 100644 index bfa37b603e..0000000000 --- a/src-self-hosted/stage2.zig +++ /dev/null @@ -1,1054 +0,0 @@ -// This is Zig code that is used by both stage1 and stage2. -// The prototypes in src/userland.h must match these definitions. - -const std = @import("std"); -const io = std.io; -const mem = std.mem; -const fs = std.fs; -const process = std.process; -const Allocator = mem.Allocator; -const ArrayList = std.ArrayList; -const ArrayListSentineled = std.ArrayListSentineled; -const Target = std.Target; -const CrossTarget = std.zig.CrossTarget; -const self_hosted_main = @import("main.zig"); -const DepTokenizer = @import("DepTokenizer.zig"); -const assert = std.debug.assert; -const LibCInstallation = @import("libc_installation.zig").LibCInstallation; - -var stderr_file: fs.File = undefined; -var stderr: fs.File.OutStream = undefined; -var stdout: fs.File.OutStream = undefined; - -comptime { - _ = @import("DepTokenizer.zig"); -} - -// ABI warning -export fn stage2_zen(ptr: *[*]const u8, len: *usize) void { - const info_zen = @import("main.zig").info_zen; - ptr.* = info_zen; - len.* = info_zen.len; -} - -// ABI warning -export fn stage2_panic(ptr: [*]const u8, len: usize) void { - @panic(ptr[0..len]); -} - -// ABI warning -const Error = extern enum { - None, - OutOfMemory, - InvalidFormat, - SemanticAnalyzeFail, - AccessDenied, - Interrupted, - SystemResources, - FileNotFound, - FileSystem, - FileTooBig, - DivByZero, - Overflow, - PathAlreadyExists, - Unexpected, - ExactDivRemainder, - NegativeDenominator, - ShiftedOutOneBits, - CCompileErrors, - EndOfFile, - IsDir, - NotDir, - UnsupportedOperatingSystem, - SharingViolation, - PipeBusy, - PrimitiveTypeNotFound, - CacheUnavailable, - PathTooLong, - CCompilerCannotFindFile, - NoCCompilerInstalled, - ReadingDepFile, - InvalidDepFile, - MissingArchitecture, - MissingOperatingSystem, - UnknownArchitecture, - UnknownOperatingSystem, - UnknownABI, - InvalidFilename, - DiskQuota, - DiskSpace, - UnexpectedWriteFailure, - UnexpectedSeekFailure, - UnexpectedFileTruncationFailure, - Unimplemented, - OperationAborted, - BrokenPipe, - NoSpaceLeft, - NotLazy, - IsAsync, - ImportOutsidePkgPath, - UnknownCpuModel, - UnknownCpuFeature, - InvalidCpuFeatures, - InvalidLlvmCpuFeaturesFormat, - UnknownApplicationBinaryInterface, - ASTUnitFailure, - BadPathName, - SymLinkLoop, - ProcessFdQuotaExceeded, - SystemFdQuotaExceeded, - NoDevice, - DeviceBusy, - UnableToSpawnCCompiler, - CCompilerExitCode, - CCompilerCrashed, - CCompilerCannotFindHeaders, - LibCRuntimeNotFound, - LibCStdLibHeaderNotFound, - LibCKernel32LibNotFound, - UnsupportedArchitecture, - WindowsSdkNotFound, - UnknownDynamicLinkerPath, - TargetHasNoDynamicLinker, - InvalidAbiVersion, - InvalidOperatingSystemVersion, - UnknownClangOption, - NestedResponseFile, - ZigIsTheCCompiler, - FileBusy, - Locked, -}; - -const FILE = std.c.FILE; -const ast = std.zig.ast; -const translate_c = @import("translate_c.zig"); - -/// Args should have a null terminating last arg. -export fn stage2_translate_c( - out_ast: **ast.Tree, - out_errors_ptr: *[*]translate_c.ClangErrMsg, - out_errors_len: *usize, - args_begin: [*]?[*]const u8, - args_end: [*]?[*]const u8, - resources_path: [*:0]const u8, -) Error { - var errors: []translate_c.ClangErrMsg = &[0]translate_c.ClangErrMsg{}; - out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) { - error.SemanticAnalyzeFail => { - out_errors_ptr.* = errors.ptr; - out_errors_len.* = errors.len; - return .CCompileErrors; - }, - error.ASTUnitFailure => return .ASTUnitFailure, - error.OutOfMemory => return .OutOfMemory, - }; - return .None; -} - -export fn stage2_free_clang_errors(errors_ptr: [*]translate_c.ClangErrMsg, errors_len: usize) void { - translate_c.freeErrors(errors_ptr[0..errors_len]); -} - -export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error { - const c_out_stream = std.io.cOutStream(output_file); - _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) { - error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode - error.NotOpenForWriting => unreachable, - error.SystemResources => return .SystemResources, - error.OperationAborted => return .OperationAborted, - error.BrokenPipe => return .BrokenPipe, - error.DiskQuota => return .DiskQuota, - error.FileTooBig => return .FileTooBig, - error.NoSpaceLeft => return .NoSpaceLeft, - error.AccessDenied => return .AccessDenied, - error.OutOfMemory => return .OutOfMemory, - error.Unexpected => return .Unexpected, - error.InputOutput => return .FileSystem, - }; - return .None; -} - -export fn stage2_fmt(argc: c_int, argv: [*]const [*:0]const u8) c_int { - if (std.debug.runtime_safety) { - fmtMain(argc, argv) catch unreachable; - } else { - fmtMain(argc, argv) catch |e| { - std.debug.warn("{}\n", .{@errorName(e)}); - return -1; - }; - } - return 0; -} - -fn argvToArrayList(allocator: *Allocator, argc: c_int, argv: [*]const [*:0]const u8) !ArrayList([]const u8) { - var args_list = std.ArrayList([]const u8).init(allocator); - const argc_usize = @intCast(usize, argc); - var arg_i: usize = 0; - while (arg_i < argc_usize) : (arg_i += 1) { - try args_list.append(mem.spanZ(argv[arg_i])); - } - - return args_list; -} - -fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void { - const allocator = std.heap.c_allocator; - - var args_list = try argvToArrayList(allocator, argc, argv); - defer args_list.deinit(); - - const args = args_list.span()[2..]; - return self_hosted_main.cmdFmt(allocator, args); -} - -export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer { - const t = std.heap.c_allocator.create(DepTokenizer) catch @panic("failed to create .d tokenizer"); - t.* = DepTokenizer.init(std.heap.c_allocator, input[0..len]); - return stage2_DepTokenizer{ - .handle = t, - }; -} - -export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void { - self.handle.deinit(); -} - -export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult { - const otoken = self.handle.next() catch { - const textz = std.ArrayListSentineled(u8, 0).init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text"); - return stage2_DepNextResult{ - .type_id = .error_, - .textz = textz.span().ptr, - }; - }; - const token = otoken orelse { - return stage2_DepNextResult{ - .type_id = .null_, - .textz = undefined, - }; - }; - const textz = std.ArrayListSentineled(u8, 0).init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text"); - return stage2_DepNextResult{ - .type_id = switch (token.id) { - .target => .target, - .prereq => .prereq, - }, - .textz = textz.span().ptr, - }; -} - -const stage2_DepTokenizer = extern struct { - handle: *DepTokenizer, -}; - -const stage2_DepNextResult = extern struct { - type_id: TypeId, - - // when type_id == error --> error text - // when type_id == null --> undefined - // when type_id == target --> target pathname - // when type_id == prereq --> prereq pathname - textz: [*]const u8, - - const TypeId = extern enum { - error_, - null_, - target, - prereq, - }; -}; - -// ABI warning -export fn stage2_attach_segfault_handler() void { - if (std.debug.runtime_safety and std.debug.have_segfault_handling_support) { - std.debug.attachSegfaultHandler(); - } -} - -// ABI warning -export fn stage2_progress_create() *std.Progress { - const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory"); - ptr.* = std.Progress{}; - return ptr; -} - -// ABI warning -export fn stage2_progress_destroy(progress: *std.Progress) void { - std.heap.c_allocator.destroy(progress); -} - -// ABI warning -export fn stage2_progress_start_root( - progress: *std.Progress, - name_ptr: [*]const u8, - name_len: usize, - estimated_total_items: usize, -) *std.Progress.Node { - return progress.start( - name_ptr[0..name_len], - if (estimated_total_items == 0) null else estimated_total_items, - ) catch @panic("timer unsupported"); -} - -// ABI warning -export fn stage2_progress_disable_tty(progress: *std.Progress) void { - progress.terminal = null; -} - -// ABI warning -export fn stage2_progress_start( - node: *std.Progress.Node, - name_ptr: [*]const u8, - name_len: usize, - estimated_total_items: usize, -) *std.Progress.Node { - const child_node = std.heap.c_allocator.create(std.Progress.Node) catch @panic("out of memory"); - child_node.* = node.start( - name_ptr[0..name_len], - if (estimated_total_items == 0) null else estimated_total_items, - ); - child_node.activate(); - return child_node; -} - -// ABI warning -export fn stage2_progress_end(node: *std.Progress.Node) void { - node.end(); - if (&node.context.root != node) { - std.heap.c_allocator.destroy(node); - } -} - -// ABI warning -export fn stage2_progress_complete_one(node: *std.Progress.Node) void { - node.completeOne(); -} - -// ABI warning -export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usize, total_count: usize) void { - node.completed_items = done_count; - node.estimated_total_items = total_count; - node.activate(); - node.context.maybeRefresh(); -} - -fn detectNativeCpuWithLLVM( - arch: Target.Cpu.Arch, - llvm_cpu_name_z: ?[*:0]const u8, - llvm_cpu_features_opt: ?[*:0]const u8, -) !Target.Cpu { - var result = Target.Cpu.baseline(arch); - - if (llvm_cpu_name_z) |cpu_name_z| { - const llvm_cpu_name = mem.spanZ(cpu_name_z); - - for (arch.allCpuModels()) |model| { - const this_llvm_name = model.llvm_name orelse continue; - if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) { - // Here we use the non-dependencies-populated set, - // so that subtracting features later in this function - // affect the prepopulated set. - result = Target.Cpu{ - .arch = arch, - .model = model, - .features = model.features, - }; - break; - } - } - } - - const all_features = arch.allFeaturesList(); - - if (llvm_cpu_features_opt) |llvm_cpu_features| { - var it = mem.tokenize(mem.spanZ(llvm_cpu_features), ","); - while (it.next()) |decorated_llvm_feat| { - var op: enum { - add, - sub, - } = undefined; - var llvm_feat: []const u8 = undefined; - if (mem.startsWith(u8, decorated_llvm_feat, "+")) { - op = .add; - llvm_feat = decorated_llvm_feat[1..]; - } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) { - op = .sub; - llvm_feat = decorated_llvm_feat[1..]; - } else { - return error.InvalidLlvmCpuFeaturesFormat; - } - for (all_features) |feature, index_usize| { - const this_llvm_name = feature.llvm_name orelse continue; - if (mem.eql(u8, llvm_feat, this_llvm_name)) { - const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); - switch (op) { - .add => result.features.addFeature(index), - .sub => result.features.removeFeature(index), - } - break; - } - } - } - } - - result.features.populateDependencies(all_features); - return result; -} - -export fn stage2_env(argc: c_int, argv: [*]const [*:0]const u8) c_int { - const allocator = std.heap.c_allocator; - - var args_list = argvToArrayList(allocator, argc, argv) catch |err| { - std.debug.print("unable to parse arguments: {}\n", .{@errorName(err)}); - return -1; - }; - defer args_list.deinit(); - - const args = args_list.span()[2..]; - - @import("print_env.zig").cmdEnv(allocator, args, std.io.getStdOut().outStream()) catch |err| { - std.debug.print("unable to print info: {}\n", .{@errorName(err)}); - return -1; - }; - - return 0; -} - -export fn stage2_cc(argc: c_int, argv: [*]const [*:0]const u8, is_cpp: bool) c_int { - const allocator = std.heap.c_allocator; - - var args_list = argvToArrayList(allocator, argc, argv) catch |err| { - std.debug.print("unable to parse arguments: {}\n", .{@errorName(err)}); - return -1; - }; - defer args_list.deinit(); - - self_hosted_main.buildOutputType(allocator, allocator, args_list.items, if (is_cpp) .cpp else .cc) catch |err| { - std.debug.print("zig cc failure: {}\n", .{@errorName(err)}); - return -1; - }; - - return 0; -} - -// ABI warning -export fn stage2_cmd_targets( - zig_triple: ?[*:0]const u8, - mcpu: ?[*:0]const u8, - dynamic_linker: ?[*:0]const u8, -) c_int { - cmdTargets(zig_triple, mcpu, dynamic_linker) catch |err| { - std.debug.warn("unable to list targets: {}\n", .{@errorName(err)}); - return -1; - }; - return 0; -} - -fn cmdTargets( - zig_triple_oz: ?[*:0]const u8, - mcpu_oz: ?[*:0]const u8, - dynamic_linker_oz: ?[*:0]const u8, -) !void { - const cross_target = try stage2CrossTarget(zig_triple_oz, mcpu_oz, dynamic_linker_oz); - var dynamic_linker: ?[*:0]u8 = null; - const target = try crossTargetToTarget(cross_target, &dynamic_linker); - return @import("print_targets.zig").cmdTargets( - std.heap.c_allocator, - &[0][]u8{}, - std.io.getStdOut().outStream(), - target, - ); -} - -// ABI warning -export fn stage2_target_parse( - target: *Stage2Target, - zig_triple: ?[*:0]const u8, - mcpu: ?[*:0]const u8, - dynamic_linker: ?[*:0]const u8, -) Error { - stage2TargetParse(target, zig_triple, mcpu, dynamic_linker) catch |err| switch (err) { - error.OutOfMemory => return .OutOfMemory, - error.UnknownArchitecture => return .UnknownArchitecture, - error.UnknownOperatingSystem => return .UnknownOperatingSystem, - error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface, - error.MissingOperatingSystem => return .MissingOperatingSystem, - error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat, - error.UnexpectedExtraField => return .SemanticAnalyzeFail, - error.InvalidAbiVersion => return .InvalidAbiVersion, - error.InvalidOperatingSystemVersion => return .InvalidOperatingSystemVersion, - error.FileSystem => return .FileSystem, - error.SymLinkLoop => return .SymLinkLoop, - error.SystemResources => return .SystemResources, - error.ProcessFdQuotaExceeded => return .ProcessFdQuotaExceeded, - error.SystemFdQuotaExceeded => return .SystemFdQuotaExceeded, - error.DeviceBusy => return .DeviceBusy, - }; - return .None; -} - -fn stage2CrossTarget( - zig_triple_oz: ?[*:0]const u8, - mcpu_oz: ?[*:0]const u8, - dynamic_linker_oz: ?[*:0]const u8, -) !CrossTarget { - const mcpu = mem.spanZ(mcpu_oz); - const dynamic_linker = mem.spanZ(dynamic_linker_oz); - var diags: CrossTarget.ParseOptions.Diagnostics = .{}; - const target: CrossTarget = CrossTarget.parse(.{ - .arch_os_abi = mem.spanZ(zig_triple_oz) orelse "native", - .cpu_features = mcpu, - .dynamic_linker = dynamic_linker, - .diagnostics = &diags, - }) catch |err| switch (err) { - error.UnknownCpuModel => { - std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{ - diags.cpu_name.?, - @tagName(diags.arch.?), - }); - for (diags.arch.?.allCpuModels()) |cpu| { - std.debug.warn(" {}\n", .{cpu.name}); - } - process.exit(1); - }, - error.UnknownCpuFeature => { - std.debug.warn( - \\Unknown CPU feature: '{}' - \\Available CPU features for architecture '{}': - \\ - , .{ - diags.unknown_feature_name, - @tagName(diags.arch.?), - }); - for (diags.arch.?.allFeaturesList()) |feature| { - std.debug.warn(" {}: {}\n", .{ feature.name, feature.description }); - } - process.exit(1); - }, - else => |e| return e, - }; - - return target; -} - -fn stage2TargetParse( - stage1_target: *Stage2Target, - zig_triple_oz: ?[*:0]const u8, - mcpu_oz: ?[*:0]const u8, - dynamic_linker_oz: ?[*:0]const u8, -) !void { - const target = try stage2CrossTarget(zig_triple_oz, mcpu_oz, dynamic_linker_oz); - try stage1_target.fromTarget(target); -} - -// ABI warning -const Stage2LibCInstallation = extern struct { - include_dir: [*]const u8, - include_dir_len: usize, - sys_include_dir: [*]const u8, - sys_include_dir_len: usize, - crt_dir: [*]const u8, - crt_dir_len: usize, - msvc_lib_dir: [*]const u8, - msvc_lib_dir_len: usize, - kernel32_lib_dir: [*]const u8, - kernel32_lib_dir_len: usize, - - fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void { - if (libc.include_dir) |s| { - self.include_dir = s.ptr; - self.include_dir_len = s.len; - } else { - self.include_dir = ""; - self.include_dir_len = 0; - } - if (libc.sys_include_dir) |s| { - self.sys_include_dir = s.ptr; - self.sys_include_dir_len = s.len; - } else { - self.sys_include_dir = ""; - self.sys_include_dir_len = 0; - } - if (libc.crt_dir) |s| { - self.crt_dir = s.ptr; - self.crt_dir_len = s.len; - } else { - self.crt_dir = ""; - self.crt_dir_len = 0; - } - if (libc.msvc_lib_dir) |s| { - self.msvc_lib_dir = s.ptr; - self.msvc_lib_dir_len = s.len; - } else { - self.msvc_lib_dir = ""; - self.msvc_lib_dir_len = 0; - } - if (libc.kernel32_lib_dir) |s| { - self.kernel32_lib_dir = s.ptr; - self.kernel32_lib_dir_len = s.len; - } else { - self.kernel32_lib_dir = ""; - self.kernel32_lib_dir_len = 0; - } - } - - fn toStage2(self: Stage2LibCInstallation) LibCInstallation { - var libc: LibCInstallation = .{}; - if (self.include_dir_len != 0) { - libc.include_dir = self.include_dir[0..self.include_dir_len]; - } - if (self.sys_include_dir_len != 0) { - libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len]; - } - if (self.crt_dir_len != 0) { - libc.crt_dir = self.crt_dir[0..self.crt_dir_len]; - } - if (self.msvc_lib_dir_len != 0) { - libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len]; - } - if (self.kernel32_lib_dir_len != 0) { - libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len]; - } - return libc; - } -}; - -// ABI warning -export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [*:0]const u8) Error { - const libc_file = mem.spanZ(libc_file_z); - var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file) catch |err| switch (err) { - error.ParseError => return .SemanticAnalyzeFail, - error.FileTooBig => return .FileTooBig, - error.InputOutput => return .FileSystem, - error.NoSpaceLeft => return .NoSpaceLeft, - error.AccessDenied => return .AccessDenied, - error.BrokenPipe => return .BrokenPipe, - error.SystemResources => return .SystemResources, - error.OperationAborted => return .OperationAborted, - error.WouldBlock => unreachable, - error.NotOpenForReading => unreachable, - error.Unexpected => return .Unexpected, - error.IsDir => return .IsDir, - error.ConnectionResetByPeer => unreachable, - error.ConnectionTimedOut => unreachable, - error.OutOfMemory => return .OutOfMemory, - error.Unseekable => unreachable, - error.SharingViolation => return .SharingViolation, - error.PathAlreadyExists => unreachable, - error.FileNotFound => return .FileNotFound, - error.PipeBusy => return .PipeBusy, - error.NameTooLong => return .PathTooLong, - error.InvalidUtf8 => return .BadPathName, - error.BadPathName => return .BadPathName, - error.SymLinkLoop => return .SymLinkLoop, - error.ProcessFdQuotaExceeded => return .ProcessFdQuotaExceeded, - error.SystemFdQuotaExceeded => return .SystemFdQuotaExceeded, - error.NoDevice => return .NoDevice, - error.NotDir => return .NotDir, - error.DeviceBusy => return .DeviceBusy, - error.FileLocksNotSupported => unreachable, - }; - stage1_libc.initFromStage2(libc); - return .None; -} - -// ABI warning -export fn stage2_libc_find_native(stage1_libc: *Stage2LibCInstallation) Error { - var libc = LibCInstallation.findNative(.{ - .allocator = std.heap.c_allocator, - .verbose = true, - }) catch |err| switch (err) { - error.OutOfMemory => return .OutOfMemory, - error.FileSystem => return .FileSystem, - error.UnableToSpawnCCompiler => return .UnableToSpawnCCompiler, - error.CCompilerExitCode => return .CCompilerExitCode, - error.CCompilerCrashed => return .CCompilerCrashed, - error.CCompilerCannotFindHeaders => return .CCompilerCannotFindHeaders, - error.LibCRuntimeNotFound => return .LibCRuntimeNotFound, - error.LibCStdLibHeaderNotFound => return .LibCStdLibHeaderNotFound, - error.LibCKernel32LibNotFound => return .LibCKernel32LibNotFound, - error.UnsupportedArchitecture => return .UnsupportedArchitecture, - error.WindowsSdkNotFound => return .WindowsSdkNotFound, - error.ZigIsTheCCompiler => return .ZigIsTheCCompiler, - }; - stage1_libc.initFromStage2(libc); - return .None; -} - -// ABI warning -export fn stage2_libc_render(stage1_libc: *Stage2LibCInstallation, output_file: *FILE) Error { - var libc = stage1_libc.toStage2(); - const c_out_stream = std.io.cOutStream(output_file); - libc.render(c_out_stream) catch |err| switch (err) { - error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode - error.NotOpenForWriting => unreachable, - error.SystemResources => return .SystemResources, - error.OperationAborted => return .OperationAborted, - error.BrokenPipe => return .BrokenPipe, - error.DiskQuota => return .DiskQuota, - error.FileTooBig => return .FileTooBig, - error.NoSpaceLeft => return .NoSpaceLeft, - error.AccessDenied => return .AccessDenied, - error.Unexpected => return .Unexpected, - error.InputOutput => return .FileSystem, - }; - return .None; -} - -// ABI warning -const Stage2Target = extern struct { - arch: c_int, - vendor: c_int, - - abi: c_int, - os: c_int, - - is_native_os: bool, - is_native_cpu: bool, - - glibc_or_darwin_version: ?*Stage2SemVer, - - llvm_cpu_name: ?[*:0]const u8, - llvm_cpu_features: ?[*:0]const u8, - cpu_builtin_str: ?[*:0]const u8, - cache_hash: ?[*:0]const u8, - cache_hash_len: usize, - os_builtin_str: ?[*:0]const u8, - - dynamic_linker: ?[*:0]const u8, - standard_dynamic_linker_path: ?[*:0]const u8, - - llvm_cpu_features_asm_ptr: [*]const [*:0]const u8, - llvm_cpu_features_asm_len: usize, - - fn fromTarget(self: *Stage2Target, cross_target: CrossTarget) !void { - const allocator = std.heap.c_allocator; - - var dynamic_linker: ?[*:0]u8 = null; - const target = try crossTargetToTarget(cross_target, &dynamic_linker); - - var cache_hash = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, "{}\n{}\n", .{ - target.cpu.model.name, - target.cpu.features.asBytes(), - }); - defer cache_hash.deinit(); - - const generic_arch_name = target.cpu.arch.genericName(); - var cpu_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, - \\Cpu{{ - \\ .arch = .{}, - \\ .model = &Target.{}.cpu.{}, - \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ - \\ - , .{ - @tagName(target.cpu.arch), - generic_arch_name, - target.cpu.model.name, - generic_arch_name, - generic_arch_name, - }); - defer cpu_builtin_str_buffer.deinit(); - - var llvm_features_buffer = try std.ArrayListSentineled(u8, 0).initSize(allocator, 0); - defer llvm_features_buffer.deinit(); - - // Unfortunately we have to do the work twice, because Clang does not support - // the same command line parameters for CPU features when assembling code as it does - // when compiling C code. - var asm_features_list = std.ArrayList([*:0]const u8).init(allocator); - defer asm_features_list.deinit(); - - for (target.cpu.arch.allFeaturesList()) |feature, index_usize| { - const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); - const is_enabled = target.cpu.features.isEnabled(index); - - if (feature.llvm_name) |llvm_name| { - const plus_or_minus = "-+"[@boolToInt(is_enabled)]; - try llvm_features_buffer.append(plus_or_minus); - try llvm_features_buffer.appendSlice(llvm_name); - try llvm_features_buffer.appendSlice(","); - } - - if (is_enabled) { - // TODO some kind of "zig identifier escape" function rather than - // unconditionally using @"" syntax - try cpu_builtin_str_buffer.appendSlice(" .@\""); - try cpu_builtin_str_buffer.appendSlice(feature.name); - try cpu_builtin_str_buffer.appendSlice("\",\n"); - } - } - - switch (target.cpu.arch) { - .riscv32, .riscv64 => { - if (std.Target.riscv.featureSetHas(target.cpu.features, .relax)) { - try asm_features_list.append("-mrelax"); - } else { - try asm_features_list.append("-mno-relax"); - } - }, - else => { - // TODO - // Argh, why doesn't the assembler accept the list of CPU features?! - // I don't see a way to do this other than hard coding everything. - }, - } - - try cpu_builtin_str_buffer.appendSlice( - \\ }), - \\}; - \\ - ); - - assert(mem.endsWith(u8, llvm_features_buffer.span(), ",")); - llvm_features_buffer.shrink(llvm_features_buffer.len() - 1); - - var os_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, - \\Os{{ - \\ .tag = .{}, - \\ .version_range = .{{ - , .{@tagName(target.os.tag)}); - defer os_builtin_str_buffer.deinit(); - - // We'll re-use the OS version range builtin string for the cache hash. - const os_builtin_str_ver_start_index = os_builtin_str_buffer.len(); - - @setEvalBranchQuota(2000); - switch (target.os.tag) { - .freestanding, - .ananas, - .cloudabi, - .dragonfly, - .fuchsia, - .ios, - .kfreebsd, - .lv2, - .solaris, - .haiku, - .minix, - .rtems, - .nacl, - .cnk, - .aix, - .cuda, - .nvcl, - .amdhsa, - .ps4, - .elfiamcu, - .tvos, - .watchos, - .mesa3d, - .contiki, - .amdpal, - .hermit, - .hurd, - .wasi, - .emscripten, - .uefi, - .other, - => try os_builtin_str_buffer.appendSlice(" .none = {} }\n"), - - .freebsd, - .macosx, - .netbsd, - .openbsd, - => try os_builtin_str_buffer.outStream().print( - \\ .semver = .{{ - \\ .min = .{{ - \\ .major = {}, - \\ .minor = {}, - \\ .patch = {}, - \\ }}, - \\ .max = .{{ - \\ .major = {}, - \\ .minor = {}, - \\ .patch = {}, - \\ }}, - \\ }}}}, - \\ - , .{ - target.os.version_range.semver.min.major, - target.os.version_range.semver.min.minor, - target.os.version_range.semver.min.patch, - - target.os.version_range.semver.max.major, - target.os.version_range.semver.max.minor, - target.os.version_range.semver.max.patch, - }), - - .linux => try os_builtin_str_buffer.outStream().print( - \\ .linux = .{{ - \\ .range = .{{ - \\ .min = .{{ - \\ .major = {}, - \\ .minor = {}, - \\ .patch = {}, - \\ }}, - \\ .max = .{{ - \\ .major = {}, - \\ .minor = {}, - \\ .patch = {}, - \\ }}, - \\ }}, - \\ .glibc = .{{ - \\ .major = {}, - \\ .minor = {}, - \\ .patch = {}, - \\ }}, - \\ }}}}, - \\ - , .{ - target.os.version_range.linux.range.min.major, - target.os.version_range.linux.range.min.minor, - target.os.version_range.linux.range.min.patch, - - target.os.version_range.linux.range.max.major, - target.os.version_range.linux.range.max.minor, - target.os.version_range.linux.range.max.patch, - - target.os.version_range.linux.glibc.major, - target.os.version_range.linux.glibc.minor, - target.os.version_range.linux.glibc.patch, - }), - - .windows => try os_builtin_str_buffer.outStream().print( - \\ .windows = .{{ - \\ .min = {s}, - \\ .max = {s}, - \\ }}}}, - \\ - , .{ - target.os.version_range.windows.min, - target.os.version_range.windows.max, - }), - } - try os_builtin_str_buffer.appendSlice("};\n"); - - try cache_hash.appendSlice( - os_builtin_str_buffer.span()[os_builtin_str_ver_start_index..os_builtin_str_buffer.len()], - ); - - const glibc_or_darwin_version = blk: { - if (target.isGnuLibC()) { - const stage1_glibc = try std.heap.c_allocator.create(Stage2SemVer); - const stage2_glibc = target.os.version_range.linux.glibc; - stage1_glibc.* = .{ - .major = stage2_glibc.major, - .minor = stage2_glibc.minor, - .patch = stage2_glibc.patch, - }; - break :blk stage1_glibc; - } else if (target.isDarwin()) { - const stage1_semver = try std.heap.c_allocator.create(Stage2SemVer); - const stage2_semver = target.os.version_range.semver.min; - stage1_semver.* = .{ - .major = stage2_semver.major, - .minor = stage2_semver.minor, - .patch = stage2_semver.patch, - }; - break :blk stage1_semver; - } else { - break :blk null; - } - }; - - const std_dl = target.standardDynamicLinkerPath(); - const std_dl_z = if (std_dl.get()) |dl| - (try mem.dupeZ(std.heap.c_allocator, u8, dl)).ptr - else - null; - - const cache_hash_slice = cache_hash.toOwnedSlice(); - const asm_features = asm_features_list.toOwnedSlice(); - self.* = .{ - .arch = @enumToInt(target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch - .vendor = 0, - .os = @enumToInt(target.os.tag), - .abi = @enumToInt(target.abi), - .llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null, - .llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr, - .llvm_cpu_features_asm_ptr = asm_features.ptr, - .llvm_cpu_features_asm_len = asm_features.len, - .cpu_builtin_str = cpu_builtin_str_buffer.toOwnedSlice().ptr, - .os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr, - .cache_hash = cache_hash_slice.ptr, - .cache_hash_len = cache_hash_slice.len, - .is_native_os = cross_target.isNativeOs(), - .is_native_cpu = cross_target.isNativeCpu(), - .glibc_or_darwin_version = glibc_or_darwin_version, - .dynamic_linker = dynamic_linker, - .standard_dynamic_linker_path = std_dl_z, - }; - } -}; - -fn enumInt(comptime Enum: type, int: c_int) Enum { - return @intToEnum(Enum, @intCast(@TagType(Enum), int)); -} - -fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) !Target { - var info = try std.zig.system.NativeTargetInfo.detect(std.heap.c_allocator, cross_target); - if (info.cpu_detection_unimplemented) { - // TODO We want to just use detected_info.target but implementing - // CPU model & feature detection is todo so here we rely on LLVM. - const llvm = @import("llvm.zig"); - const llvm_cpu_name = llvm.GetHostCPUName(); - const llvm_cpu_features = llvm.GetNativeFeatures(); - const arch = std.Target.current.cpu.arch; - info.target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features); - cross_target.updateCpuFeatures(&info.target.cpu.features); - info.target.cpu.arch = cross_target.getCpuArch(); - } - if (info.dynamic_linker.get()) |dl| { - dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl); - } else { - dynamic_linker_ptr.* = null; - } - return info.target; -} - -// ABI warning -const Stage2SemVer = extern struct { - major: u32, - minor: u32, - patch: u32, -}; - -// ABI warning -const Stage2NativePaths = extern struct { - include_dirs_ptr: [*][*:0]u8, - include_dirs_len: usize, - lib_dirs_ptr: [*][*:0]u8, - lib_dirs_len: usize, - rpaths_ptr: [*][*:0]u8, - rpaths_len: usize, - warnings_ptr: [*][*:0]u8, - warnings_len: usize, -}; -// ABI warning -export fn stage2_detect_native_paths(stage1_paths: *Stage2NativePaths) Error { - stage2DetectNativePaths(stage1_paths) catch |err| switch (err) { - error.OutOfMemory => return .OutOfMemory, - }; - return .None; -} - -fn stage2DetectNativePaths(stage1_paths: *Stage2NativePaths) !void { - var paths = try std.zig.system.NativePaths.detect(std.heap.c_allocator); - errdefer paths.deinit(); - - try convertSlice(paths.include_dirs.span(), &stage1_paths.include_dirs_ptr, &stage1_paths.include_dirs_len); - try convertSlice(paths.lib_dirs.span(), &stage1_paths.lib_dirs_ptr, &stage1_paths.lib_dirs_len); - try convertSlice(paths.rpaths.span(), &stage1_paths.rpaths_ptr, &stage1_paths.rpaths_len); - try convertSlice(paths.warnings.span(), &stage1_paths.warnings_ptr, &stage1_paths.warnings_len); -} - -fn convertSlice(slice: [][:0]u8, ptr: *[*][*:0]u8, len: *usize) !void { - len.* = slice.len; - const new_slice = try std.heap.c_allocator.alloc([*:0]u8, slice.len); - for (slice) |item, i| { - new_slice[i] = item.ptr; - } - ptr.* = new_slice.ptr; -} - -export const stage2_is_zig0 = false; diff --git a/src/all_types.hpp b/src/all_types.hpp index 1fa04f2b79..7b8ad57483 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -10,7 +10,6 @@ #include "list.hpp" #include "buffer.hpp" -#include "cache_hash.hpp" #include "zig_llvm.h" #include "hash_map.hpp" #include "errmsg.hpp" @@ -1639,8 +1638,6 @@ struct ZigType { size_t abi_size; // Number of bits of information in this type. Known after ResolveStatusSizeKnown. size_t size_in_bits; - - bool gen_h_loop_flag; }; enum FnAnalState { @@ -1976,67 +1973,16 @@ struct TimeEvent { const char *name; }; -enum BuildMode { - BuildModeDebug, - BuildModeFastRelease, - BuildModeSafeRelease, - BuildModeSmallRelease, -}; - -enum CodeModel { - CodeModelDefault, - CodeModelTiny, - CodeModelSmall, - CodeModelKernel, - CodeModelMedium, - CodeModelLarge, -}; - -struct LinkLib { - Buf *name; - Buf *path; - ZigList symbols; // the list of symbols that we depend on from this lib - bool provided_explicitly; -}; - -enum ValgrindSupport { - ValgrindSupportAuto, - ValgrindSupportDisabled, - ValgrindSupportEnabled, -}; - -enum WantPIC { - WantPICAuto, - WantPICDisabled, - WantPICEnabled, -}; - -enum WantStackCheck { - WantStackCheckAuto, - WantStackCheckDisabled, - WantStackCheckEnabled, -}; - -enum WantCSanitize { - WantCSanitizeAuto, - WantCSanitizeDisabled, - WantCSanitizeEnabled, -}; - -enum OptionalBool { - OptionalBoolNull, - OptionalBoolFalse, - OptionalBoolTrue, -}; - struct CFile { ZigList args; const char *source_path; const char *preprocessor_only_basename; }; -// When adding fields, check if they should be added to the hash computation in build_with_cache struct CodeGen { + // Other code depends on this being first. + ZigStage1 stage1; + // arena allocator destroyed just prior to codegen emit heap::ArenaAllocator *pass1_arena; @@ -2048,8 +1994,6 @@ struct CodeGen { ZigLLVMDIBuilder *dbuilder; ZigLLVMDICompileUnit *compile_unit; ZigLLVMDIFile *compile_unit_file; - LinkLib *libc_link_lib; - LinkLib *libcpp_link_lib; LLVMTargetDataRef target_data_ref; LLVMTargetMachineRef target_machine; ZigLLVMDIFile *dummy_di_file; @@ -2104,7 +2048,6 @@ struct CodeGen { ZigList inline_fns; ZigList test_fns; ZigList errors_by_index; - ZigList caches_to_release; size_t largest_err_name_len; ZigList type_resolve_stack; @@ -2173,7 +2116,6 @@ struct CodeGen { Buf llvm_triple_str; Buf global_asm; Buf o_file_output_path; - Buf bin_file_output_path; Buf asm_file_output_path; Buf llvm_ir_file_output_path; Buf *cache_dir; @@ -2184,7 +2126,7 @@ struct CodeGen { const char **libc_include_dir_list; size_t libc_include_dir_len; - Buf *zig_c_headers_dir; // Cannot be overridden; derived from zig_lib_dir. + Buf *builtin_zig_path; Buf *zig_std_special_dir; // Cannot be overridden; derived from zig_lib_dir. IrInstSrc *invalid_inst_src; @@ -2206,18 +2148,9 @@ struct CodeGen { Stage2ProgressNode *main_progress_node; Stage2ProgressNode *sub_progress_node; - WantPIC want_pic; - WantStackCheck want_stack_check; - WantCSanitize want_sanitize_c; - CacheHash cache_hash; ErrColor err_color; uint32_t next_unresolved_index; unsigned pointer_size_bytes; - uint32_t target_os_index; - uint32_t target_arch_index; - uint32_t target_sub_arch_index; - uint32_t target_abi_index; - uint32_t target_oformat_index; bool is_big_endian; bool have_c_main; bool have_winmain; @@ -2226,9 +2159,6 @@ struct CodeGen { bool have_wwinmain_crt_startup; bool have_dllmain_crt_startup; bool have_err_ret_tracing; - bool link_eh_frame_hdr; - bool c_want_stdint; - bool c_want_stdbool; bool verbose_tokenize; bool verbose_ast; bool verbose_link; @@ -2239,61 +2169,24 @@ struct CodeGen { bool verbose_llvm_cpu_features; bool error_during_imports; bool generate_error_name_table; - bool enable_cache; // mutually exclusive with output_dir bool enable_time_report; bool enable_stack_report; - bool system_linker_hack; bool reported_bad_link_libc_error; - bool is_dynamic; // shared library rather than static library. dynamic musl rather than static musl. bool need_frame_size_prefix_data; - bool disable_c_depfile; - - //////////////////////////// Participates in Input Parameter Cache Hash - /////// Note: there is a separate cache hash for builtin.zig, when adding fields, - /////// consider if they need to go into both. - ZigList link_libs_list; - // add -framework [name] args to linker - ZigList darwin_frameworks; - // add -rpath [name] args to linker - ZigList rpath_list; - ZigList forbidden_libs; - ZigList link_objects; - ZigList assembly_files; - ZigList c_source_files; - ZigList lib_dirs; - ZigList framework_dirs; - - Stage2LibCInstallation *libc; - - bool is_versioned; - size_t version_major; - size_t version_minor; - size_t version_patch; - const char *linker_script; - size_t stack_size_override; + bool link_libc; + bool link_libcpp; BuildMode build_mode; - OutType out_type; const ZigTarget *zig_target; TargetSubsystem subsystem; // careful using this directly; see detect_subsystem - ValgrindSupport valgrind_support; CodeModel code_model; - OptionalBool linker_gc_sections; - OptionalBool linker_allow_shlib_undefined; - OptionalBool linker_bind_global_refs_locally; bool strip_debug_symbols; bool is_test_build; bool is_single_threaded; - bool want_single_threaded; - bool linker_rdynamic; - bool each_lib_rpath; - bool is_dummy_so; - bool disable_gen_h; - bool bundle_compiler_rt; bool have_pic; - bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic + bool link_mode_dynamic; + bool dll_export_fns; bool have_stack_probing; - bool have_sanitize_c; bool function_sections; bool enable_dump_analysis; bool enable_doc_generation; @@ -2301,23 +2194,13 @@ struct CodeGen { bool emit_asm; bool emit_llvm_ir; bool test_is_evented; - bool linker_z_nodelete; - bool linker_z_defs; + bool valgrind_enabled; Buf *root_out_name; Buf *test_filter; Buf *test_name_prefix; Buf *zig_lib_dir; Buf *zig_std_dir; - Buf *version_script_path; - Buf *override_soname; - Buf *linker_optimization; - - const char **llvm_argv; - size_t llvm_argv_len; - - const char **clang_argv; - size_t clang_argv_len; }; struct ZigVar { diff --git a/src/analyze.cpp b/src/analyze.cpp index b97423da73..ea19d81995 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3496,7 +3496,7 @@ void add_var_export(CodeGen *g, ZigVar *var, const char *symbol_name, GlobalLink } void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, CallingConvention cc) { - if (cc == CallingConventionC && strcmp(symbol_name, "main") == 0 && g->libc_link_lib != nullptr) { + if (cc == CallingConventionC && strcmp(symbol_name, "main") == 0 && g->link_libc) { g->have_c_main = true; } else if (cc == CallingConventionStdcall && g->zig_target->os == OsWindows) { if (strcmp(symbol_name, "WinMain") == 0) { @@ -7863,40 +7863,6 @@ const char *type_id_name(ZigTypeId id) { zig_unreachable(); } -LinkLib *create_link_lib(Buf *name) { - LinkLib *link_lib = heap::c_allocator.create(); - link_lib->name = name; - return link_lib; -} - -LinkLib *add_link_lib(CodeGen *g, Buf *name) { - bool is_libc = buf_eql_str(name, "c"); - bool is_libcpp = buf_eql_str(name, "c++") || buf_eql_str(name, "c++abi"); - - if (is_libc && g->libc_link_lib != nullptr) - return g->libc_link_lib; - - if (is_libcpp && g->libcpp_link_lib != nullptr) - return g->libcpp_link_lib; - - for (size_t i = 0; i < g->link_libs_list.length; i += 1) { - LinkLib *existing_lib = g->link_libs_list.at(i); - if (buf_eql_buf(existing_lib->name, name)) { - return existing_lib; - } - } - - LinkLib *link_lib = create_link_lib(name); - g->link_libs_list.append(link_lib); - - if (is_libc) - g->libc_link_lib = link_lib; - if (is_libcpp) - g->libcpp_link_lib = link_lib; - - return link_lib; -} - ZigType *get_align_amt_type(CodeGen *g) { if (g->align_amt_type == nullptr) { // according to LLVM the maximum alignment is 1 << 29. @@ -8017,12 +7983,13 @@ not_integer: return ErrorNone; } -Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents) { - if (g->enable_cache) { - return cache_add_file_fetch(&g->cache_hash, resolved_path, contents); - } else { - return os_fetch_file_path(resolved_path, contents); - } +Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents_buf) { + size_t len; + const char *contents = stage2_fetch_file(&g->stage1, buf_ptr(resolved_path), buf_len(resolved_path), &len); + if (contents == nullptr) + return ErrorNoMem; + buf_init_from_mem(contents_buf, contents, len); + return ErrorNone; } static X64CABIClass type_windows_abi_x86_64_class(CodeGen *g, ZigType *ty, size_t ty_size) { diff --git a/src/analyze.hpp b/src/analyze.hpp index 0df1a4ba91..07601e6dea 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -200,8 +200,6 @@ ZigTypeId type_id_at_index(size_t index); size_t type_id_len(); size_t type_id_index(ZigType *entry); ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id); -LinkLib *create_link_lib(Buf *name); -LinkLib *add_link_lib(CodeGen *codegen, Buf *lib); bool optional_value_is_null(ZigValue *val); uint32_t get_abi_alignment(CodeGen *g, ZigType *type_entry); @@ -256,7 +254,6 @@ Error ensure_const_val_repr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_no void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn); Buf *type_bare_name(ZigType *t); Buf *type_h_name(ZigType *t); -Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose); LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type); ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type); diff --git a/src/blake2.h b/src/blake2.h deleted file mode 100644 index 6420c5367a..0000000000 --- a/src/blake2.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. -*/ -#ifndef BLAKE2_H -#define BLAKE2_H - -#include -#include - -#if defined(_MSC_VER) -#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) -#else -#define BLAKE2_PACKED(x) x __attribute__((packed)) -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - - enum blake2s_constant - { - BLAKE2S_BLOCKBYTES = 64, - BLAKE2S_OUTBYTES = 32, - BLAKE2S_KEYBYTES = 32, - BLAKE2S_SALTBYTES = 8, - BLAKE2S_PERSONALBYTES = 8 - }; - - enum blake2b_constant - { - BLAKE2B_BLOCKBYTES = 128, - BLAKE2B_OUTBYTES = 64, - BLAKE2B_KEYBYTES = 64, - BLAKE2B_SALTBYTES = 16, - BLAKE2B_PERSONALBYTES = 16 - }; - - typedef struct blake2s_state__ - { - uint32_t h[8]; - uint32_t t[2]; - uint32_t f[2]; - uint8_t buf[BLAKE2S_BLOCKBYTES]; - size_t buflen; - size_t outlen; - uint8_t last_node; - } blake2s_state; - - typedef struct blake2b_state__ - { - uint64_t h[8]; - uint64_t t[2]; - uint64_t f[2]; - uint8_t buf[BLAKE2B_BLOCKBYTES]; - size_t buflen; - size_t outlen; - uint8_t last_node; - } blake2b_state; - - typedef struct blake2sp_state__ - { - blake2s_state S[8][1]; - blake2s_state R[1]; - uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; - size_t buflen; - size_t outlen; - } blake2sp_state; - - typedef struct blake2bp_state__ - { - blake2b_state S[4][1]; - blake2b_state R[1]; - uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; - size_t buflen; - size_t outlen; - } blake2bp_state; - - - BLAKE2_PACKED(struct blake2s_param__ - { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint32_t node_offset; /* 12 */ - uint16_t xof_length; /* 14 */ - uint8_t node_depth; /* 15 */ - uint8_t inner_length; /* 16 */ - /* uint8_t reserved[0]; */ - uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ - uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ - }); - - typedef struct blake2s_param__ blake2s_param; - - BLAKE2_PACKED(struct blake2b_param__ - { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint32_t node_offset; /* 12 */ - uint32_t xof_length; /* 16 */ - uint8_t node_depth; /* 17 */ - uint8_t inner_length; /* 18 */ - uint8_t reserved[14]; /* 32 */ - uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ - uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ - }); - - typedef struct blake2b_param__ blake2b_param; - - typedef struct blake2xs_state__ - { - blake2s_state S[1]; - blake2s_param P[1]; - } blake2xs_state; - - typedef struct blake2xb_state__ - { - blake2b_state S[1]; - blake2b_param P[1]; - } blake2xb_state; - - /* Padded structs result in a compile-time error */ - enum { - BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES), - BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES) - }; - - /* Streaming API */ - int blake2s_init( blake2s_state *S, size_t outlen ); - int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); - int blake2s_update( blake2s_state *S, const void *in, size_t inlen ); - int blake2s_final( blake2s_state *S, void *out, size_t outlen ); - - int blake2b_init( blake2b_state *S, size_t outlen ); - int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); - int blake2b_update( blake2b_state *S, const void *in, size_t inlen ); - int blake2b_final( blake2b_state *S, void *out, size_t outlen ); - - int blake2sp_init( blake2sp_state *S, size_t outlen ); - int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen ); - int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ); - - int blake2bp_init( blake2bp_state *S, size_t outlen ); - int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen ); - int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ); - - /* Variable output length API */ - int blake2xs_init( blake2xs_state *S, const size_t outlen ); - int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen ); - int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen ); - int blake2xs_final(blake2xs_state *S, void *out, size_t outlen); - - int blake2xb_init( blake2xb_state *S, const size_t outlen ); - int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen ); - int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen ); - int blake2xb_final(blake2xb_state *S, void *out, size_t outlen); - - /* Simple API */ - int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - - int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - - int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - - /* This is simply an alias for blake2b */ - int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - -#if defined(__cplusplus) -} -#endif - -#endif - diff --git a/src/blake2b.c b/src/blake2b.c deleted file mode 100644 index 600f951b9b..0000000000 --- a/src/blake2b.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. -*/ - -#include -#include -#include - -#include "blake2.h" -/* - BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. -*/ -#ifndef BLAKE2_IMPL_H -#define BLAKE2_IMPL_H - -#include -#include - -#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) - #if defined(_MSC_VER) - #define BLAKE2_INLINE __inline - #elif defined(__GNUC__) - #define BLAKE2_INLINE __inline__ - #else - #define BLAKE2_INLINE - #endif -#else - #define BLAKE2_INLINE inline -#endif - -static BLAKE2_INLINE uint32_t load32( const void *src ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - uint32_t w; - memcpy(&w, src, sizeof w); - return w; -#else - const uint8_t *p = ( const uint8_t * )src; - return (( uint32_t )( p[0] ) << 0) | - (( uint32_t )( p[1] ) << 8) | - (( uint32_t )( p[2] ) << 16) | - (( uint32_t )( p[3] ) << 24) ; -#endif -} - -static BLAKE2_INLINE uint64_t load64( const void *src ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - uint64_t w; - memcpy(&w, src, sizeof w); - return w; -#else - const uint8_t *p = ( const uint8_t * )src; - return (( uint64_t )( p[0] ) << 0) | - (( uint64_t )( p[1] ) << 8) | - (( uint64_t )( p[2] ) << 16) | - (( uint64_t )( p[3] ) << 24) | - (( uint64_t )( p[4] ) << 32) | - (( uint64_t )( p[5] ) << 40) | - (( uint64_t )( p[6] ) << 48) | - (( uint64_t )( p[7] ) << 56) ; -#endif -} - -static BLAKE2_INLINE uint16_t load16( const void *src ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - uint16_t w; - memcpy(&w, src, sizeof w); - return w; -#else - const uint8_t *p = ( const uint8_t * )src; - return ( uint16_t )((( uint32_t )( p[0] ) << 0) | - (( uint32_t )( p[1] ) << 8)); -#endif -} - -static BLAKE2_INLINE void store16( void *dst, uint16_t w ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - memcpy(dst, &w, sizeof w); -#else - uint8_t *p = ( uint8_t * )dst; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; -#endif -} - -static BLAKE2_INLINE void store32( void *dst, uint32_t w ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - memcpy(dst, &w, sizeof w); -#else - uint8_t *p = ( uint8_t * )dst; - p[0] = (uint8_t)(w >> 0); - p[1] = (uint8_t)(w >> 8); - p[2] = (uint8_t)(w >> 16); - p[3] = (uint8_t)(w >> 24); -#endif -} - -static BLAKE2_INLINE void store64( void *dst, uint64_t w ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - memcpy(dst, &w, sizeof w); -#else - uint8_t *p = ( uint8_t * )dst; - p[0] = (uint8_t)(w >> 0); - p[1] = (uint8_t)(w >> 8); - p[2] = (uint8_t)(w >> 16); - p[3] = (uint8_t)(w >> 24); - p[4] = (uint8_t)(w >> 32); - p[5] = (uint8_t)(w >> 40); - p[6] = (uint8_t)(w >> 48); - p[7] = (uint8_t)(w >> 56); -#endif -} - -static BLAKE2_INLINE uint64_t load48( const void *src ) -{ - const uint8_t *p = ( const uint8_t * )src; - return (( uint64_t )( p[0] ) << 0) | - (( uint64_t )( p[1] ) << 8) | - (( uint64_t )( p[2] ) << 16) | - (( uint64_t )( p[3] ) << 24) | - (( uint64_t )( p[4] ) << 32) | - (( uint64_t )( p[5] ) << 40) ; -} - -static BLAKE2_INLINE void store48( void *dst, uint64_t w ) -{ - uint8_t *p = ( uint8_t * )dst; - p[0] = (uint8_t)(w >> 0); - p[1] = (uint8_t)(w >> 8); - p[2] = (uint8_t)(w >> 16); - p[3] = (uint8_t)(w >> 24); - p[4] = (uint8_t)(w >> 32); - p[5] = (uint8_t)(w >> 40); -} - -static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) -{ - return ( w >> c ) | ( w << ( 32 - c ) ); -} - -static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c ) -{ - return ( w >> c ) | ( w << ( 64 - c ) ); -} - -/* prevents compiler optimizing out memset() */ -static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) -{ - static void *(*const volatile memset_v)(void *, int, size_t) = &memset; - memset_v(v, 0, n); -} - -#endif - -static const uint64_t blake2b_IV[8] = -{ - 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL -}; - -static const uint8_t blake2b_sigma[12][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } -}; - - -static void blake2b_set_lastnode( blake2b_state *S ) -{ - S->f[1] = (uint64_t)-1; -} - -/* Some helper functions, not necessarily useful */ -static int blake2b_is_lastblock( const blake2b_state *S ) -{ - return S->f[0] != 0; -} - -static void blake2b_set_lastblock( blake2b_state *S ) -{ - if( S->last_node ) blake2b_set_lastnode( S ); - - S->f[0] = (uint64_t)-1; -} - -static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) -{ - S->t[0] += inc; - S->t[1] += ( S->t[0] < inc ); -} - -static void blake2b_init0( blake2b_state *S ) -{ - size_t i; - memset( S, 0, sizeof( blake2b_state ) ); - - for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; -} - -/* init xors IV with input parameter block */ -int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) -{ - const uint8_t *p = ( const uint8_t * )( P ); - size_t i; - - blake2b_init0( S ); - - /* IV XOR ParamBlock */ - for( i = 0; i < 8; ++i ) - S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); - - S->outlen = P->digest_length; - return 0; -} - - - -int blake2b_init( blake2b_state *S, size_t outlen ) -{ - blake2b_param P[1]; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store32( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - memset( P->reserved, 0, sizeof( P->reserved ) ); - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - return blake2b_init_param( S, P ); -} - - -int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2b_param P[1]; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - - if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = (uint8_t)keylen; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store32( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - memset( P->reserved, 0, sizeof( P->reserved ) ); - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - - if( blake2b_init_param( S, P ) < 0 ) return -1; - - { - uint8_t block[BLAKE2B_BLOCKBYTES]; - memset( block, 0, BLAKE2B_BLOCKBYTES ); - memcpy( block, key, keylen ); - blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); - secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - -#define G(r,i,a,b,c,d) \ - do { \ - a = a + b + m[blake2b_sigma[r][2*i+0]]; \ - d = rotr64(d ^ a, 32); \ - c = c + d; \ - b = rotr64(b ^ c, 24); \ - a = a + b + m[blake2b_sigma[r][2*i+1]]; \ - d = rotr64(d ^ a, 16); \ - c = c + d; \ - b = rotr64(b ^ c, 63); \ - } while(0) - -#define ROUND(r) \ - do { \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - } while(0) - -static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) -{ - uint64_t m[16]; - uint64_t v[16]; - size_t i; - - for( i = 0; i < 16; ++i ) { - m[i] = load64( block + i * sizeof( m[i] ) ); - } - - for( i = 0; i < 8; ++i ) { - v[i] = S->h[i]; - } - - v[ 8] = blake2b_IV[0]; - v[ 9] = blake2b_IV[1]; - v[10] = blake2b_IV[2]; - v[11] = blake2b_IV[3]; - v[12] = blake2b_IV[4] ^ S->t[0]; - v[13] = blake2b_IV[5] ^ S->t[1]; - v[14] = blake2b_IV[6] ^ S->f[0]; - v[15] = blake2b_IV[7] ^ S->f[1]; - - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - ROUND( 10 ); - ROUND( 11 ); - - for( i = 0; i < 8; ++i ) { - S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; - } -} - -#undef G -#undef ROUND - -int blake2b_update( blake2b_state *S, const void *pin, size_t inlen ) -{ - const unsigned char * in = (const unsigned char *)pin; - if( inlen > 0 ) - { - size_t left = S->buflen; - size_t fill = BLAKE2B_BLOCKBYTES - left; - if( inlen > fill ) - { - S->buflen = 0; - memcpy( S->buf + left, in, fill ); /* Fill buffer */ - blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); - blake2b_compress( S, S->buf ); /* Compress */ - in += fill; inlen -= fill; - while(inlen > BLAKE2B_BLOCKBYTES) { - blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); - blake2b_compress( S, in ); - in += BLAKE2B_BLOCKBYTES; - inlen -= BLAKE2B_BLOCKBYTES; - } - } - memcpy( S->buf + S->buflen, in, inlen ); - S->buflen += inlen; - } - return 0; -} - -int blake2b_final( blake2b_state *S, void *out, size_t outlen ) -{ - uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; - size_t i; - - if( out == NULL || outlen < S->outlen ) - return -1; - - if( blake2b_is_lastblock( S ) ) - return -1; - - blake2b_increment_counter( S, S->buflen ); - blake2b_set_lastblock( S ); - memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ - blake2b_compress( S, S->buf ); - - for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ - store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); - - memcpy( out, buffer, S->outlen ); - secure_zero_memory(buffer, sizeof(buffer)); - return 0; -} - -/* inlen, at least, should be uint64_t. Others can be size_t. */ -int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) -{ - blake2b_state S[1]; - - /* Verify parameters */ - if ( NULL == in && inlen > 0 ) return -1; - - if ( NULL == out ) return -1; - - if( NULL == key && keylen > 0 ) return -1; - - if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; - - if( keylen > BLAKE2B_KEYBYTES ) return -1; - - if( keylen > 0 ) - { - if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; - } - else - { - if( blake2b_init( S, outlen ) < 0 ) return -1; - } - - blake2b_update( S, ( const uint8_t * )in, inlen ); - blake2b_final( S, out, outlen ); - return 0; -} - -int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { - return blake2b(out, outlen, in, inlen, key, keylen); -} - -#if defined(SUPERCOP) -int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) -{ - return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 ); -} -#endif - -#if defined(BLAKE2B_SELFTEST) -#include -#include "blake2-kat.h" -int main( void ) -{ - uint8_t key[BLAKE2B_KEYBYTES]; - uint8_t buf[BLAKE2_KAT_LENGTH]; - size_t i, step; - - for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - /* Test simple API */ - for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2B_OUTBYTES]; - blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); - - if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) - { - goto fail; - } - } - - /* Test streaming API */ - for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) { - for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { - uint8_t hash[BLAKE2B_OUTBYTES]; - blake2b_state S; - uint8_t * p = buf; - size_t mlen = i; - int err = 0; - - if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) { - goto fail; - } - - while (mlen >= step) { - if ( (err = blake2b_update(&S, p, step)) < 0 ) { - goto fail; - } - mlen -= step; - p += step; - } - if ( (err = blake2b_update(&S, p, mlen)) < 0) { - goto fail; - } - if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) { - goto fail; - } - - if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) { - goto fail; - } - } - } - - puts( "ok" ); - return 0; -fail: - puts("error"); - return -1; -} -#endif - diff --git a/src/cache_hash.cpp b/src/cache_hash.cpp deleted file mode 100644 index c12d8f29ef..0000000000 --- a/src/cache_hash.cpp +++ /dev/null @@ -1,595 +0,0 @@ -/* - * Copyright (c) 2018 Andrew Kelley - * - * This file is part of zig, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#include "stage2.h" -#include "cache_hash.hpp" -#include "all_types.hpp" -#include "buffer.hpp" -#include "os.hpp" - -#include - -void cache_init(CacheHash *ch, Buf *manifest_dir) { - int rc = blake2b_init(&ch->blake, 48); - assert(rc == 0); - ch->files = {}; - ch->manifest_dir = manifest_dir; - ch->manifest_file_path = nullptr; - ch->manifest_dirty = false; - ch->force_check_manifest = false; - ch->b64_digest = BUF_INIT; -} - -void cache_mem(CacheHash *ch, const char *ptr, size_t len) { - assert(ch->manifest_file_path == nullptr); - assert(ptr != nullptr); - blake2b_update(&ch->blake, ptr, len); -} - -void cache_slice(CacheHash *ch, Slice slice) { - // mix the length into the hash so that two juxtaposed cached slices can't collide - cache_usize(ch, slice.len); - cache_mem(ch, slice.ptr, slice.len); -} - -void cache_str(CacheHash *ch, const char *ptr) { - // + 1 to include the null byte - cache_mem(ch, ptr, strlen(ptr) + 1); -} - -void cache_int(CacheHash *ch, int x) { - assert(ch->manifest_file_path == nullptr); - // + 1 to include the null byte - uint8_t buf[sizeof(int) + 1]; - memcpy(buf, &x, sizeof(int)); - buf[sizeof(int)] = 0; - blake2b_update(&ch->blake, buf, sizeof(int) + 1); -} - -void cache_usize(CacheHash *ch, size_t x) { - assert(ch->manifest_file_path == nullptr); - // + 1 to include the null byte - uint8_t buf[sizeof(size_t) + 1]; - memcpy(buf, &x, sizeof(size_t)); - buf[sizeof(size_t)] = 0; - blake2b_update(&ch->blake, buf, sizeof(size_t) + 1); -} - -void cache_bool(CacheHash *ch, bool x) { - assert(ch->manifest_file_path == nullptr); - blake2b_update(&ch->blake, &x, 1); -} - -void cache_buf(CacheHash *ch, Buf *buf) { - assert(ch->manifest_file_path == nullptr); - assert(buf != nullptr); - // + 1 to include the null byte - blake2b_update(&ch->blake, buf_ptr(buf), buf_len(buf) + 1); -} - -void cache_buf_opt(CacheHash *ch, Buf *buf) { - assert(ch->manifest_file_path == nullptr); - if (buf == nullptr) { - cache_str(ch, ""); - cache_str(ch, ""); - } else { - cache_buf(ch, buf); - } -} - -void cache_list_of_link_lib(CacheHash *ch, LinkLib **ptr, size_t len) { - assert(ch->manifest_file_path == nullptr); - for (size_t i = 0; i < len; i += 1) { - LinkLib *lib = ptr[i]; - if (lib->provided_explicitly) { - cache_buf(ch, lib->name); - } - } - cache_str(ch, ""); -} - -void cache_list_of_buf(CacheHash *ch, Buf **ptr, size_t len) { - assert(ch->manifest_file_path == nullptr); - for (size_t i = 0; i < len; i += 1) { - Buf *buf = ptr[i]; - cache_buf(ch, buf); - } - cache_str(ch, ""); -} - -void cache_list_of_file(CacheHash *ch, Buf **ptr, size_t len) { - assert(ch->manifest_file_path == nullptr); - - for (size_t i = 0; i < len; i += 1) { - Buf *buf = ptr[i]; - cache_file(ch, buf); - } - cache_str(ch, ""); -} - -void cache_list_of_str(CacheHash *ch, const char **ptr, size_t len) { - assert(ch->manifest_file_path == nullptr); - - for (size_t i = 0; i < len; i += 1) { - const char *s = ptr[i]; - cache_str(ch, s); - } - cache_str(ch, ""); -} - -void cache_file(CacheHash *ch, Buf *file_path) { - assert(ch->manifest_file_path == nullptr); - assert(file_path != nullptr); - Buf *resolved_path = buf_alloc(); - *resolved_path = os_path_resolve(&file_path, 1); - CacheHashFile *chf = ch->files.add_one(); - chf->path = resolved_path; - cache_buf(ch, resolved_path); -} - -void cache_file_opt(CacheHash *ch, Buf *file_path) { - assert(ch->manifest_file_path == nullptr); - if (file_path == nullptr) { - cache_str(ch, ""); - cache_str(ch, ""); - } else { - cache_file(ch, file_path); - } -} - -// Ported from std/base64.zig -static uint8_t base64_fs_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; -static void base64_encode(Slice dest, Slice source) { - size_t dest_len = ((source.len + 2) / 3) * 4; - assert(dest.len == dest_len); - - size_t i = 0; - size_t out_index = 0; - for (; i + 2 < source.len; i += 3) { - dest.ptr[out_index] = base64_fs_alphabet[(source.ptr[i] >> 2) & 0x3f]; - out_index += 1; - - dest.ptr[out_index] = base64_fs_alphabet[((source.ptr[i] & 0x3) << 4) | ((source.ptr[i + 1] & 0xf0) >> 4)]; - out_index += 1; - - dest.ptr[out_index] = base64_fs_alphabet[((source.ptr[i + 1] & 0xf) << 2) | ((source.ptr[i + 2] & 0xc0) >> 6)]; - out_index += 1; - - dest.ptr[out_index] = base64_fs_alphabet[source.ptr[i + 2] & 0x3f]; - out_index += 1; - } - - // Assert that we never need pad characters. - assert(i == source.len); -} - -// Ported from std/base64.zig -static Error base64_decode(Slice dest, Slice source) { - if (source.len % 4 != 0) - return ErrorInvalidFormat; - if (dest.len != (source.len / 4) * 3) - return ErrorInvalidFormat; - - // In Zig this is comptime computed. In C++ it's not worth it to do that. - uint8_t char_to_index[256]; - bool char_in_alphabet[256] = {0}; - for (size_t i = 0; i < 64; i += 1) { - uint8_t c = base64_fs_alphabet[i]; - assert(!char_in_alphabet[c]); - char_in_alphabet[c] = true; - char_to_index[c] = i; - } - - size_t src_cursor = 0; - size_t dest_cursor = 0; - - for (;src_cursor < source.len; src_cursor += 4) { - if (!char_in_alphabet[source.ptr[src_cursor + 0]]) return ErrorInvalidFormat; - if (!char_in_alphabet[source.ptr[src_cursor + 1]]) return ErrorInvalidFormat; - if (!char_in_alphabet[source.ptr[src_cursor + 2]]) return ErrorInvalidFormat; - if (!char_in_alphabet[source.ptr[src_cursor + 3]]) return ErrorInvalidFormat; - dest.ptr[dest_cursor + 0] = (char_to_index[source.ptr[src_cursor + 0]] << 2) | (char_to_index[source.ptr[src_cursor + 1]] >> 4); - dest.ptr[dest_cursor + 1] = (char_to_index[source.ptr[src_cursor + 1]] << 4) | (char_to_index[source.ptr[src_cursor + 2]] >> 2); - dest.ptr[dest_cursor + 2] = (char_to_index[source.ptr[src_cursor + 2]] << 6) | (char_to_index[source.ptr[src_cursor + 3]]); - dest_cursor += 3; - } - - assert(src_cursor == source.len); - assert(dest_cursor == dest.len); - return ErrorNone; -} - -static Error hash_file(uint8_t *digest, OsFile handle, Buf *contents) { - Error err; - - if (contents) { - buf_resize(contents, 0); - } - - blake2b_state blake; - int rc = blake2b_init(&blake, 48); - assert(rc == 0); - - for (;;) { - uint8_t buf[4096]; - size_t amt = 4096; - if ((err = os_file_read(handle, buf, &amt))) - return err; - if (amt == 0) { - rc = blake2b_final(&blake, digest, 48); - assert(rc == 0); - return ErrorNone; - } - blake2b_update(&blake, buf, amt); - if (contents) { - buf_append_mem(contents, (char*)buf, amt); - } - } -} - -// If the wall clock time, rounded to the same precision as the -// mtime, is equal to the mtime, then we cannot rely on this mtime -// yet. We will instead save an mtime value that indicates the hash -// must be unconditionally computed. -static bool is_problematic_timestamp(const OsTimeStamp *fs_clock) { - OsTimeStamp wall_clock = os_timestamp_calendar(); - // First make all the least significant zero bits in the fs_clock, also zero bits in the wall clock. - if (fs_clock->nsec == 0) { - wall_clock.nsec = 0; - if (fs_clock->sec == 0) { - wall_clock.sec = 0; - } else { - wall_clock.sec &= (-1ull) << ctzll(fs_clock->sec); - } - } else { - wall_clock.nsec &= (-1ull) << ctzll(fs_clock->nsec); - } - return wall_clock.nsec == fs_clock->nsec && wall_clock.sec == fs_clock->sec; -} - -static Error populate_file_hash(CacheHash *ch, CacheHashFile *chf, Buf *contents) { - Error err; - - assert(chf->path != nullptr); - - OsFile this_file; - if ((err = os_file_open_r(chf->path, &this_file, &chf->attr))) - return err; - - if (is_problematic_timestamp(&chf->attr.mtime)) { - chf->attr.mtime.sec = 0; - chf->attr.mtime.nsec = 0; - chf->attr.inode = 0; - } - - if ((err = hash_file(chf->bin_digest, this_file, contents))) { - os_file_close(&this_file); - return err; - } - os_file_close(&this_file); - - blake2b_update(&ch->blake, chf->bin_digest, 48); - - return ErrorNone; -} - -Error cache_hit(CacheHash *ch, Buf *out_digest) { - Error err; - - uint8_t bin_digest[48]; - int rc = blake2b_final(&ch->blake, bin_digest, 48); - assert(rc == 0); - - buf_resize(&ch->b64_digest, 64); - base64_encode(buf_to_slice(&ch->b64_digest), {bin_digest, 48}); - - if (ch->files.length == 0 && !ch->force_check_manifest) { - buf_resize(out_digest, 64); - base64_encode(buf_to_slice(out_digest), {bin_digest, 48}); - return ErrorNone; - } - - rc = blake2b_init(&ch->blake, 48); - assert(rc == 0); - blake2b_update(&ch->blake, bin_digest, 48); - - ch->manifest_file_path = buf_alloc(); - os_path_join(ch->manifest_dir, &ch->b64_digest, ch->manifest_file_path); - - buf_append_str(ch->manifest_file_path, ".txt"); - - if ((err = os_make_path(ch->manifest_dir))) - return err; - - if ((err = os_file_open_lock_rw(ch->manifest_file_path, &ch->manifest_file))) - return err; - - Buf line_buf = BUF_INIT; - buf_resize(&line_buf, 512); - if ((err = os_file_read_all(ch->manifest_file, &line_buf))) { - os_file_close(&ch->manifest_file); - return err; - } - - size_t input_file_count = ch->files.length; - bool any_file_changed = false; - Error return_code = ErrorNone; - size_t file_i = 0; - SplitIterator line_it = memSplit(buf_to_slice(&line_buf), str("\n")); - for (;; file_i += 1) { - Optional> opt_line = SplitIterator_next(&line_it); - - CacheHashFile *chf; - if (file_i < input_file_count) { - chf = &ch->files.at(file_i); - } else if (any_file_changed) { - // cache miss. - // keep the manifest file open with the rw lock - // reset the hash - rc = blake2b_init(&ch->blake, 48); - assert(rc == 0); - blake2b_update(&ch->blake, bin_digest, 48); - ch->files.resize(input_file_count); - // bring the hash up to the input file hashes - for (file_i = 0; file_i < input_file_count; file_i += 1) { - blake2b_update(&ch->blake, ch->files.at(file_i).bin_digest, 48); - } - // caller can notice that out_digest is unmodified. - return return_code; - } else if (!opt_line.is_some) { - break; - } else { - chf = ch->files.add_one(); - chf->path = nullptr; - } - - if (!opt_line.is_some) - break; - - SplitIterator it = memSplit(opt_line.value, str(" ")); - - Optional> opt_inode = SplitIterator_next(&it); - if (!opt_inode.is_some) { - return_code = ErrorInvalidFormat; - break; - } - chf->attr.inode = strtoull((const char *)opt_inode.value.ptr, nullptr, 10); - - Optional> opt_mtime_sec = SplitIterator_next(&it); - if (!opt_mtime_sec.is_some) { - return_code = ErrorInvalidFormat; - break; - } - chf->attr.mtime.sec = strtoull((const char *)opt_mtime_sec.value.ptr, nullptr, 10); - - Optional> opt_mtime_nsec = SplitIterator_next(&it); - if (!opt_mtime_nsec.is_some) { - return_code = ErrorInvalidFormat; - break; - } - chf->attr.mtime.nsec = strtoull((const char *)opt_mtime_nsec.value.ptr, nullptr, 10); - - Optional> opt_digest = SplitIterator_next(&it); - if (!opt_digest.is_some) { - return_code = ErrorInvalidFormat; - break; - } - if ((err = base64_decode({chf->bin_digest, 48}, opt_digest.value))) { - return_code = ErrorInvalidFormat; - break; - } - - Slice file_path = SplitIterator_rest(&it); - if (file_path.len == 0) { - return_code = ErrorInvalidFormat; - break; - } - Buf *this_path = buf_create_from_slice(file_path); - if (chf->path != nullptr && !buf_eql_buf(this_path, chf->path)) { - return_code = ErrorInvalidFormat; - break; - } - chf->path = this_path; - - // if the mtime matches we can trust the digest - OsFile this_file; - OsFileAttr actual_attr; - if ((err = os_file_open_r(chf->path, &this_file, &actual_attr))) { - fprintf(stderr, "Unable to open %s\n: %s", buf_ptr(chf->path), err_str(err)); - os_file_close(&ch->manifest_file); - return ErrorCacheUnavailable; - } - if (chf->attr.mtime.sec == actual_attr.mtime.sec && - chf->attr.mtime.nsec == actual_attr.mtime.nsec && - chf->attr.inode == actual_attr.inode) - { - os_file_close(&this_file); - } else { - // we have to recompute the digest. - // later we'll rewrite the manifest with the new mtime/digest values - ch->manifest_dirty = true; - chf->attr = actual_attr; - - if (is_problematic_timestamp(&actual_attr.mtime)) { - chf->attr.mtime.sec = 0; - chf->attr.mtime.nsec = 0; - chf->attr.inode = 0; - } - - uint8_t actual_digest[48]; - if ((err = hash_file(actual_digest, this_file, nullptr))) { - os_file_close(&this_file); - os_file_close(&ch->manifest_file); - return err; - } - os_file_close(&this_file); - if (memcmp(chf->bin_digest, actual_digest, 48) != 0) { - memcpy(chf->bin_digest, actual_digest, 48); - // keep going until we have the input file digests - any_file_changed = true; - } - } - if (!any_file_changed) { - blake2b_update(&ch->blake, chf->bin_digest, 48); - } - } - if (file_i < input_file_count || file_i == 0 || return_code != ErrorNone) { - // manifest file is empty or missing entries, so this is a cache miss - ch->manifest_dirty = true; - for (; file_i < input_file_count; file_i += 1) { - CacheHashFile *chf = &ch->files.at(file_i); - if ((err = populate_file_hash(ch, chf, nullptr))) { - fprintf(stderr, "Unable to hash %s: %s\n", buf_ptr(chf->path), err_str(err)); - os_file_close(&ch->manifest_file); - return ErrorCacheUnavailable; - } - } - if (return_code != ErrorNone && return_code != ErrorInvalidFormat) { - os_file_close(&ch->manifest_file); - } - return return_code; - } - // Cache Hit - return cache_final(ch, out_digest); -} - -Error cache_add_file_fetch(CacheHash *ch, Buf *resolved_path, Buf *contents) { - Error err; - - assert(ch->manifest_file_path != nullptr); - CacheHashFile *chf = ch->files.add_one(); - chf->path = resolved_path; - if ((err = populate_file_hash(ch, chf, contents))) { - os_file_close(&ch->manifest_file); - return err; - } - - return ErrorNone; -} - -Error cache_add_file(CacheHash *ch, Buf *path) { - Buf *resolved_path = buf_alloc(); - *resolved_path = os_path_resolve(&path, 1); - return cache_add_file_fetch(ch, resolved_path, nullptr); -} - -Error cache_add_dep_file(CacheHash *ch, Buf *dep_file_path, bool verbose) { - Error err; - Buf *contents = buf_alloc(); - if ((err = os_fetch_file_path(dep_file_path, contents))) { - if (err == ErrorFileNotFound) - return err; - if (verbose) { - fprintf(stderr, "%s: unable to read .d file: %s\n", err_str(err), buf_ptr(dep_file_path)); - } - return ErrorReadingDepFile; - } - auto it = stage2_DepTokenizer_init(buf_ptr(contents), buf_len(contents)); - // skip first token: target - { - auto result = stage2_DepTokenizer_next(&it); - switch (result.type_id) { - case stage2_DepNextResult::error: - if (verbose) { - fprintf(stderr, "%s: failed processing .d file: %s\n", result.textz, buf_ptr(dep_file_path)); - } - err = ErrorInvalidDepFile; - goto finish; - case stage2_DepNextResult::null: - err = ErrorNone; - goto finish; - case stage2_DepNextResult::target: - case stage2_DepNextResult::prereq: - err = ErrorNone; - break; - } - } - // Process 0+ preqreqs. - // clang is invoked in single-source mode so we never get more targets. - for (;;) { - auto result = stage2_DepTokenizer_next(&it); - switch (result.type_id) { - case stage2_DepNextResult::error: - if (verbose) { - fprintf(stderr, "%s: failed processing .d file: %s\n", result.textz, buf_ptr(dep_file_path)); - } - err = ErrorInvalidDepFile; - goto finish; - case stage2_DepNextResult::null: - case stage2_DepNextResult::target: - err = ErrorNone; - goto finish; - case stage2_DepNextResult::prereq: - break; - } - auto textbuf = buf_alloc(); - buf_init_from_str(textbuf, result.textz); - if ((err = cache_add_file(ch, textbuf))) { - if (verbose) { - fprintf(stderr, "unable to add %s to cache: %s\n", result.textz, err_str(err)); - fprintf(stderr, "when processing .d file: %s\n", buf_ptr(dep_file_path)); - } - goto finish; - } - } - - finish: - stage2_DepTokenizer_deinit(&it); - return err; -} - -static Error write_manifest_file(CacheHash *ch) { - Error err; - Buf contents = BUF_INIT; - buf_resize(&contents, 0); - uint8_t encoded_digest[65]; - encoded_digest[64] = 0; - for (size_t i = 0; i < ch->files.length; i += 1) { - CacheHashFile *chf = &ch->files.at(i); - base64_encode({encoded_digest, 64}, {chf->bin_digest, 48}); - buf_appendf(&contents, "%" ZIG_PRI_u64 " %" ZIG_PRI_u64 " %" ZIG_PRI_u64 " %s %s\n", - chf->attr.inode, chf->attr.mtime.sec, chf->attr.mtime.nsec, encoded_digest, buf_ptr(chf->path)); - } - if ((err = os_file_overwrite(ch->manifest_file, &contents))) - return err; - - return ErrorNone; -} - -Error cache_final(CacheHash *ch, Buf *out_digest) { - assert(ch->manifest_file_path != nullptr); - - // We don't close the manifest file yet, because we want to - // keep it locked until the API user is done using it. - // We also don't write out the manifest yet, because until - // cache_release is called we still might be working on creating - // the artifacts to cache. - - uint8_t bin_digest[48]; - int rc = blake2b_final(&ch->blake, bin_digest, 48); - assert(rc == 0); - buf_resize(out_digest, 64); - base64_encode(buf_to_slice(out_digest), {bin_digest, 48}); - - return ErrorNone; -} - -void cache_release(CacheHash *ch) { - assert(ch->manifest_file_path != nullptr); - - Error err; - - if (ch->manifest_dirty) { - if ((err = write_manifest_file(ch))) { - fprintf(stderr, "Warning: Unable to write cache file '%s': %s\n", - buf_ptr(ch->manifest_file_path), err_str(err)); - } - } - - os_file_close(&ch->manifest_file); -} - diff --git a/src/cache_hash.hpp b/src/cache_hash.hpp deleted file mode 100644 index ba2434076a..0000000000 --- a/src/cache_hash.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2018 Andrew Kelley - * - * This file is part of zig, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#ifndef ZIG_CACHE_HASH_HPP -#define ZIG_CACHE_HASH_HPP - -#include "blake2.h" -#include "os.hpp" - -struct LinkLib; - -struct CacheHashFile { - Buf *path; - OsFileAttr attr; - uint8_t bin_digest[48]; - Buf *contents; -}; - -struct CacheHash { - blake2b_state blake; - ZigList files; - Buf *manifest_dir; - Buf *manifest_file_path; - Buf b64_digest; - OsFile manifest_file; - bool manifest_dirty; - bool force_check_manifest; -}; - -// Always call this first to set up. -void cache_init(CacheHash *ch, Buf *manifest_dir); - -// Next, use the hash population functions to add the initial parameters. -void cache_mem(CacheHash *ch, const char *ptr, size_t len); -void cache_slice(CacheHash *ch, Slice slice); -void cache_str(CacheHash *ch, const char *ptr); -void cache_int(CacheHash *ch, int x); -void cache_bool(CacheHash *ch, bool x); -void cache_usize(CacheHash *ch, size_t x); -void cache_buf(CacheHash *ch, Buf *buf); -void cache_buf_opt(CacheHash *ch, Buf *buf); -void cache_list_of_link_lib(CacheHash *ch, LinkLib **ptr, size_t len); -void cache_list_of_buf(CacheHash *ch, Buf **ptr, size_t len); -void cache_list_of_file(CacheHash *ch, Buf **ptr, size_t len); -void cache_list_of_str(CacheHash *ch, const char **ptr, size_t len); -void cache_file(CacheHash *ch, Buf *path); -void cache_file_opt(CacheHash *ch, Buf *path); - -// Then call cache_hit when you're ready to see if you can skip the next step. -// out_b64_digest will be left unchanged if it was a cache miss. -// If you got a cache hit, the next step is cache_release. -// From this point on, there is a lock on the input params. Release -// the lock with cache_release. -// Set force_check_manifest if you plan to add files later, but have not -// added any files before calling cache_hit. CacheHash::b64_digest becomes -// available for use after this call, even in the case of a miss, and it -// is a hash of the input parameters only. -// If this function returns ErrorInvalidFormat, that error may be treated -// as a cache miss. -Error ATTRIBUTE_MUST_USE cache_hit(CacheHash *ch, Buf *out_b64_digest); - -// If you did not get a cache hit, call this function for every file -// that is depended on, and then finish with cache_final. -Error ATTRIBUTE_MUST_USE cache_add_file(CacheHash *ch, Buf *path); -// This opens a file created by -MD -MF args to Clang -Error ATTRIBUTE_MUST_USE cache_add_dep_file(CacheHash *ch, Buf *path, bool verbose); - -// This variant of cache_add_file returns the file contents. -// Also the file path argument must be already resolved. -Error ATTRIBUTE_MUST_USE cache_add_file_fetch(CacheHash *ch, Buf *resolved_path, Buf *contents); - -// out_b64_digest will be the same thing that cache_hit returns if you got a cache hit -Error ATTRIBUTE_MUST_USE cache_final(CacheHash *ch, Buf *out_b64_digest); - -// Until this function is called, no one will be able to get a lock on your input params. -void cache_release(CacheHash *ch); - - -#endif diff --git a/src/codegen.cpp b/src/codegen.cpp index ce6eeb1def..07728ef06e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8,7 +8,6 @@ #include "analyze.hpp" #include "ast_render.hpp" #include "codegen.hpp" -#include "compiler.hpp" #include "config.h" #include "errmsg.hpp" #include "error.hpp" @@ -21,7 +20,6 @@ #include "stage2.h" #include "dump_analysis.hpp" #include "softfloat.hpp" -#include "mem_profile.hpp" #include #include @@ -72,39 +70,6 @@ static const char *symbols_that_llvm_depends_on[] = { // TODO probably all of compiler-rt needs to go here }; -void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) { - g->clang_argv = args; - g->clang_argv_len = len; -} - -void codegen_set_llvm_argv(CodeGen *g, const char **args, size_t len) { - g->llvm_argv = args; - g->llvm_argv_len = len; -} - -void codegen_set_test_filter(CodeGen *g, Buf *filter) { - g->test_filter = filter; -} - -void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix) { - g->test_name_prefix = prefix; -} - -void codegen_set_lib_version(CodeGen *g, bool is_versioned, size_t major, size_t minor, size_t patch) { - g->is_versioned = is_versioned; - g->version_major = major; - g->version_minor = minor; - g->version_patch = patch; -} - -void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) { - g->each_lib_rpath = each_lib_rpath; -} - -void codegen_set_errmsg_color(CodeGen *g, ErrColor err_color) { - g->err_color = err_color; -} - void codegen_set_strip(CodeGen *g, bool strip) { g->strip_debug_symbols = strip; if (!target_has_debug_info(g->zig_target)) { @@ -112,39 +77,6 @@ void codegen_set_strip(CodeGen *g, bool strip) { } } -void codegen_set_out_name(CodeGen *g, Buf *out_name) { - g->root_out_name = out_name; -} - -void codegen_add_lib_dir(CodeGen *g, const char *dir) { - g->lib_dirs.append(dir); -} - -void codegen_add_rpath(CodeGen *g, const char *name) { - g->rpath_list.append(buf_create_from_str(name)); -} - -LinkLib *codegen_add_link_lib(CodeGen *g, Buf *name) { - return add_link_lib(g, name); -} - -void codegen_add_forbidden_lib(CodeGen *codegen, Buf *lib) { - codegen->forbidden_libs.append(lib); -} - -void codegen_add_framework(CodeGen *g, const char *framework) { - g->darwin_frameworks.append(buf_create_from_str(framework)); -} - -void codegen_set_rdynamic(CodeGen *g, bool rdynamic) { - g->linker_rdynamic = rdynamic; -} - -void codegen_set_linker_script(CodeGen *g, const char *linker_script) { - g->linker_script = linker_script; -} - - static void render_const_val(CodeGen *g, ZigValue *const_val, const char *name); static void render_const_val_global(CodeGen *g, ZigValue *const_val, const char *name); static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *name); @@ -155,7 +87,6 @@ static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *na static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr, LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type, LLVMValueRef result_loc, bool non_async); -static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix); static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) { unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); @@ -389,7 +320,7 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) { } static void maybe_export_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) { - if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows && g->is_dynamic) { + if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows && g->dll_export_fns) { LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass); } } @@ -541,7 +472,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { g->build_mode != BuildModeSmallRelease && !fn->def_scope->safety_off; if (want_fn_safety) { - if (g->libc_link_lib != nullptr) { + if (g->link_libc) { addLLVMFnAttr(llvm_fn, "sspstrong"); addLLVMFnAttrStr(llvm_fn, "stack-protector-buffer-size", "4"); } @@ -3859,20 +3790,6 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default zig_unreachable(); } -static bool want_valgrind_support(CodeGen *g) { - if (!target_has_valgrind_support(g->zig_target)) - return false; - switch (g->valgrind_support) { - case ValgrindSupportDisabled: - return false; - case ValgrindSupportEnabled: - return true; - case ValgrindSupportAuto: - return g->build_mode == BuildModeDebug; - } - zig_unreachable(); -} - static void gen_valgrind_undef(CodeGen *g, LLVMValueRef dest_ptr, LLVMValueRef byte_count) { static const uint32_t VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545; ZigType *usize = g->builtin_types.entry_usize; @@ -3895,7 +3812,7 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_ LLVMValueRef byte_count = LLVMConstInt(usize->llvm_type, size_bytes, false); ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, ptr_align_bytes, false); // then tell valgrind that the memory is undefined even though we just memset it - if (want_valgrind_support(g)) { + if (g->valgrind_enabled) { gen_valgrind_undef(g, dest_ptr, byte_count); } } @@ -5598,7 +5515,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutableGen *executable, Ir ZigLLVMBuildMemSet(g->builder, dest_ptr_casted, fill_char, len_val, get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile); - if (val_is_undef && want_valgrind_support(g)) { + if (val_is_undef && g->valgrind_enabled) { gen_valgrind_undef(g, dest_ptr_casted, len_val); } return nullptr; @@ -8350,13 +8267,6 @@ static void zig_llvm_emit_output(CodeGen *g) { exit(1); } - if (g->emit_bin) { - g->link_objects.append(&g->o_file_output_path); - if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))) { - zig_link_add_compiler_rt(g, g->sub_progress_node); - } - } - LLVMDisposeModule(g->module); g->module = nullptr; LLVMDisposeTargetData(g->target_data_ref); @@ -8751,75 +8661,12 @@ static const char *subsystem_to_str(TargetSubsystem subsystem) { zig_unreachable(); } -static bool detect_dynamic_link(CodeGen *g) { - if (g->is_dynamic) - return true; - if (g->zig_target->os == OsFreestanding) - return false; - if (target_os_requires_libc(g->zig_target->os)) - return true; - if (g->libc_link_lib != nullptr && target_is_glibc(g->zig_target)) - return true; - // If there are no dynamic libraries then we can disable dynamic linking. - for (size_t i = 0; i < g->link_libs_list.length; i += 1) { - LinkLib *link_lib = g->link_libs_list.at(i); - if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) - continue; - if (target_is_libcpp_lib_name(g->zig_target, buf_ptr(link_lib->name))) - continue; - return true; - } - return false; -} - -static bool detect_pic(CodeGen *g) { - if (target_requires_pic(g->zig_target, g->libc_link_lib != nullptr)) - return true; - switch (g->want_pic) { - case WantPICDisabled: - return false; - case WantPICEnabled: - return true; - case WantPICAuto: - return g->have_dynamic_link; - } - zig_unreachable(); -} - -static bool detect_stack_probing(CodeGen *g) { - if (!target_supports_stack_probing(g->zig_target)) - return false; - switch (g->want_stack_check) { - case WantStackCheckDisabled: - return false; - case WantStackCheckEnabled: - return true; - case WantStackCheckAuto: - return g->build_mode == BuildModeSafeRelease || g->build_mode == BuildModeDebug; - } - zig_unreachable(); -} - -static bool detect_sanitize_c(CodeGen *g) { - if (!target_supports_sanitize_c(g->zig_target)) - return false; - switch (g->want_sanitize_c) { - case WantCSanitizeDisabled: - return false; - case WantCSanitizeEnabled: - return true; - case WantCSanitizeAuto: - return g->build_mode == BuildModeSafeRelease || g->build_mode == BuildModeDebug; - } - zig_unreachable(); -} - // Returns TargetSubsystemAuto to mean "no subsystem" TargetSubsystem detect_subsystem(CodeGen *g) { if (g->subsystem != TargetSubsystemAuto) return g->subsystem; if (g->zig_target->os == OsWindows) { - if (g->have_dllmain_crt_startup || (g->out_type == OutTypeLib && g->is_dynamic)) + if (g->have_dllmain_crt_startup) return TargetSubsystemAuto; if (g->have_c_main || g->is_test_build || g->have_winmain_crt_startup || g->have_wwinmain_crt_startup) return TargetSubsystemConsole; @@ -8831,15 +8678,6 @@ TargetSubsystem detect_subsystem(CodeGen *g) { return TargetSubsystemAuto; } -static bool detect_single_threaded(CodeGen *g) { - if (g->want_single_threaded) - return true; - if (target_is_single_threaded(g->zig_target)) { - return true; - } - return false; -} - static bool detect_err_ret_tracing(CodeGen *g) { return !g->strip_debug_symbols && g->build_mode != BuildModeFastRelease && @@ -8847,30 +8685,30 @@ static bool detect_err_ret_tracing(CodeGen *g) { } static LLVMCodeModel to_llvm_code_model(CodeGen *g) { - switch (g->code_model) { - case CodeModelDefault: - return LLVMCodeModelDefault; - case CodeModelTiny: - return LLVMCodeModelTiny; - case CodeModelSmall: - return LLVMCodeModelSmall; - case CodeModelKernel: - return LLVMCodeModelKernel; - case CodeModelMedium: - return LLVMCodeModelMedium; - case CodeModelLarge: - return LLVMCodeModelLarge; - } + switch (g->code_model) { + case CodeModelDefault: + return LLVMCodeModelDefault; + case CodeModelTiny: + return LLVMCodeModelTiny; + case CodeModelSmall: + return LLVMCodeModelSmall; + case CodeModelKernel: + return LLVMCodeModelKernel; + case CodeModelMedium: + return LLVMCodeModelMedium; + case CodeModelLarge: + return LLVMCodeModelLarge; + } - zig_unreachable(); + zig_unreachable(); } Buf *codegen_generate_builtin_source(CodeGen *g) { - g->have_dynamic_link = detect_dynamic_link(g); - g->have_pic = detect_pic(g); - g->have_stack_probing = detect_stack_probing(g); - g->have_sanitize_c = detect_sanitize_c(g); - g->is_single_threaded = detect_single_threaded(g); + // Note that this only runs when zig0 is building the self-hosted zig compiler code, + // so it makes a few assumption that are always true for that case. Once we have + // built the stage2 zig components then zig is in charge of generating the builtin.zig + // file. + g->have_err_ret_tracing = detect_err_ret_tracing(g); Buf *contents = buf_alloc(); @@ -8884,7 +8722,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { const char *name = target_os_name(os_type); if (os_type == g->zig_target->os) { - g->target_os_index = i; cur_os = name; } } @@ -8898,7 +8735,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { ZigLLVM_ArchType arch = target_arch_enum(arch_i); const char *arch_name = target_arch_name(arch); if (arch == g->zig_target->arch) { - g->target_arch_index = arch_i; cur_arch = arch_name; } } @@ -8913,7 +8749,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { const char *name = target_abi_name(abi); if (abi == g->zig_target->abi) { - g->target_abi_index = i; cur_abi = name; } } @@ -8929,7 +8764,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { ZigLLVM_ObjectFormatType target_oformat = target_object_format(g->zig_target); if (oformat == target_oformat) { - g->target_oformat_index = i; cur_obj_fmt = name; } } @@ -8979,23 +8813,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little"; buf_appendf(contents, "pub const endian = %s;\n", endian_str); } - const char *out_type = nullptr; - switch (g->out_type) { - case OutTypeExe: - out_type = "Exe"; - break; - case OutTypeLib: - out_type = "Lib"; - break; - case OutTypeObj: - case OutTypeUnknown: // This happens when running the `zig builtin` command. - out_type = "Obj"; - break; - } - buf_appendf(contents, "pub const output_mode = OutputMode.%s;\n", out_type); - const char *link_type = g->have_dynamic_link ? "Dynamic" : "Static"; - buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", link_type); - buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); + buf_appendf(contents, "pub const output_mode = OutputMode.Obj;\n"); + buf_appendf(contents, "pub const link_mode = LinkMode.Static;\n"); + buf_appendf(contents, "pub const is_test = false;\n"); buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); buf_append_str(contents, "/// Deprecated: use `std.Target.cpu.arch`\n"); buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch); @@ -9018,40 +8838,13 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { } buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); - buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->libc_link_lib != nullptr)); - buf_appendf(contents, "pub const link_libcpp = %s;\n", bool_to_str(g->libcpp_link_lib != nullptr)); + buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->link_libc)); + buf_appendf(contents, "pub const link_libcpp = %s;\n", bool_to_str(g->link_libcpp)); buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing)); - buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g))); + buf_appendf(contents, "pub const valgrind_support = false;\n"); buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic)); buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols)); - - { - const char *code_model; - switch (g->code_model) { - case CodeModelDefault: - code_model = "default"; - break; - case CodeModelTiny: - code_model = "tiny"; - break; - case CodeModelSmall: - code_model = "small"; - break; - case CodeModelKernel: - code_model = "kernel"; - break; - case CodeModelMedium: - code_model = "medium"; - break; - case CodeModelLarge: - code_model = "large"; - break; - default: - zig_unreachable(); - } - - buf_appendf(contents, "pub const code_model = CodeModel.%s;\n", code_model); - } + buf_appendf(contents, "pub const code_model = CodeModel.default;\n"); { TargetSubsystem detected_subsystem = detect_subsystem(g); @@ -9060,15 +8853,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { } } - if (g->is_test_build) { - buf_appendf(contents, - "pub var test_functions: []TestFn = undefined; // overwritten later\n" - ); - - buf_appendf(contents, "pub const test_io_mode = %s;\n", - g->test_is_evented ? ".evented" : ".blocking"); - } - return contents; } @@ -9077,95 +8861,35 @@ static ZigPackage *create_test_runner_pkg(CodeGen *g) { } static Error define_builtin_compile_vars(CodeGen *g) { - if (g->std_package == nullptr) - return ErrorNone; - Error err; - Buf *manifest_dir = buf_alloc(); - os_path_join(get_global_cache_dir(), buf_create_from_str("builtin"), manifest_dir); - - CacheHash cache_hash; - cache_init(&cache_hash, manifest_dir); - - Buf *compiler_id; - if ((err = get_compiler_id(&compiler_id))) - return err; - - // Only a few things affect builtin.zig - cache_buf(&cache_hash, compiler_id); - cache_int(&cache_hash, g->build_mode); - cache_bool(&cache_hash, g->strip_debug_symbols); - cache_int(&cache_hash, g->out_type); - cache_bool(&cache_hash, detect_dynamic_link(g)); - cache_bool(&cache_hash, g->is_test_build); - cache_bool(&cache_hash, g->is_single_threaded); - cache_bool(&cache_hash, g->test_is_evented); - cache_int(&cache_hash, g->code_model); - cache_int(&cache_hash, g->zig_target->is_native_os); - cache_int(&cache_hash, g->zig_target->is_native_cpu); - cache_int(&cache_hash, g->zig_target->arch); - cache_int(&cache_hash, g->zig_target->vendor); - cache_int(&cache_hash, g->zig_target->os); - cache_int(&cache_hash, g->zig_target->abi); - if (g->zig_target->cache_hash != nullptr) { - cache_mem(&cache_hash, g->zig_target->cache_hash, g->zig_target->cache_hash_len); - } - if (g->zig_target->glibc_or_darwin_version != nullptr) { - cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->major); - cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->minor); - cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->patch); - } - cache_bool(&cache_hash, g->have_err_ret_tracing); - cache_bool(&cache_hash, g->libc_link_lib != nullptr); - cache_bool(&cache_hash, g->libcpp_link_lib != nullptr); - cache_bool(&cache_hash, g->valgrind_support); - cache_bool(&cache_hash, g->link_eh_frame_hdr); - cache_int(&cache_hash, detect_subsystem(g)); - - Buf digest = BUF_INIT; - buf_resize(&digest, 0); - if ((err = cache_hit(&cache_hash, &digest))) { - // Treat an invalid format error as a cache miss. - if (err != ErrorInvalidFormat) - return err; - } - - // We should always get a cache hit because there are no - // files in the input hash. - assert(buf_len(&digest) != 0); - - Buf *this_dir = buf_alloc(); - os_path_join(manifest_dir, &digest, this_dir); - - if ((err = os_make_path(this_dir))) - return err; + if (g->std_package == nullptr) + return ErrorNone; const char *builtin_zig_basename = "builtin.zig"; - Buf *builtin_zig_path = buf_alloc(); - os_path_join(this_dir, buf_create_from_str(builtin_zig_basename), builtin_zig_path); - bool hit; - if ((err = os_file_exists(builtin_zig_path, &hit))) - return err; Buf *contents; - if (hit) { - contents = buf_alloc(); - if ((err = os_fetch_file_path(builtin_zig_path, contents))) { - fprintf(stderr, "Unable to open '%s': %s\n", buf_ptr(builtin_zig_path), err_str(err)); + if (g->builtin_zig_path == nullptr) { + // Then this is zig0 building stage2. We can make many assumptions about the compilation. + g->builtin_zig_path = buf_alloc(); + os_path_join(g->output_dir, buf_create_from_str(builtin_zig_basename), g->builtin_zig_path); + + contents = codegen_generate_builtin_source(g); + if ((err = os_write_file(g->builtin_zig_path, contents))) { + fprintf(stderr, "Unable to write file '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err)); exit(1); } } else { - contents = codegen_generate_builtin_source(g); - if ((err = os_write_file(builtin_zig_path, contents))) { - fprintf(stderr, "Unable to write file '%s': %s\n", buf_ptr(builtin_zig_path), err_str(err)); + contents = buf_alloc(); + if ((err = os_fetch_file_path(g->builtin_zig_path, contents))) { + fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err)); exit(1); } } assert(g->main_pkg); assert(g->std_package); - g->compile_var_package = new_package(buf_ptr(this_dir), builtin_zig_basename, "builtin"); + g->compile_var_package = new_package(buf_ptr(g->output_dir), builtin_zig_basename, "builtin"); if (g->is_test_build) { if (g->test_runner_package == nullptr) { g->test_runner_package = create_test_runner_pkg(g); @@ -9180,7 +8904,7 @@ static Error define_builtin_compile_vars(CodeGen *g) { g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package); g->std_package->package_table.put(buf_create_from_str("std"), g->std_package); g->std_package->package_table.put(buf_create_from_str("root"), g->root_pkg); - g->compile_var_import = add_source_file(g, g->compile_var_package, builtin_zig_path, contents, + g->compile_var_import = add_source_file(g, g->compile_var_package, g->builtin_zig_path, contents, SourceKindPkgMain); return ErrorNone; @@ -9190,17 +8914,8 @@ static void init(CodeGen *g) { if (g->module) return; - g->have_dynamic_link = detect_dynamic_link(g); - g->have_pic = detect_pic(g); - g->have_stack_probing = detect_stack_probing(g); - g->have_sanitize_c = detect_sanitize_c(g); - g->is_single_threaded = detect_single_threaded(g); g->have_err_ret_tracing = detect_err_ret_tracing(g); - if (target_is_single_threaded(g->zig_target)) { - g->is_single_threaded = true; - } - assert(g->root_out_name); g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name)); @@ -9230,7 +8945,7 @@ static void init(CodeGen *g) { LLVMRelocMode reloc_mode; if (g->have_pic) { reloc_mode = LLVMRelocPIC; - } else if (g->have_dynamic_link) { + } else if (g->link_mode_dynamic) { reloc_mode = LLVMRelocDynamicNoPic; } else { reloc_mode = LLVMRelocStatic; @@ -9336,1378 +9051,160 @@ static void init(CodeGen *g) { } } -static void detect_libc(CodeGen *g) { +static void update_test_functions_builtin_decl(CodeGen *g) { Error err; - if (g->libc != nullptr || g->libc_link_lib == nullptr) - return; + assert(g->is_test_build); - if (target_can_build_libc(g->zig_target)) { - const char *generic_name = target_libc_generic_name(g->zig_target); - const char *arch_name = target_arch_name(g->zig_target->arch); - const char *abi_name = target_abi_name(g->zig_target->abi); - if (target_is_musl(g->zig_target)) { - // musl has some overrides. its headers are ABI-agnostic and so they all have the "musl" ABI name. - abi_name = "musl"; - // some architectures are handled by the same set of headers - arch_name = target_arch_musl_name(g->zig_target->arch); - } - Buf *arch_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-%s", - buf_ptr(g->zig_lib_dir), arch_name, target_os_name(g->zig_target->os), abi_name); - Buf *generic_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "generic-%s", - buf_ptr(g->zig_lib_dir), generic_name); - Buf *arch_os_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-any", - buf_ptr(g->zig_lib_dir), target_arch_name(g->zig_target->arch), target_os_name(g->zig_target->os)); - Buf *generic_os_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "any-%s-any", - buf_ptr(g->zig_lib_dir), target_os_name(g->zig_target->os)); - - g->libc_include_dir_len = 4; - g->libc_include_dir_list = heap::c_allocator.allocate(g->libc_include_dir_len); - g->libc_include_dir_list[0] = buf_ptr(arch_include_dir); - g->libc_include_dir_list[1] = buf_ptr(generic_include_dir); - g->libc_include_dir_list[2] = buf_ptr(arch_os_include_dir); - g->libc_include_dir_list[3] = buf_ptr(generic_os_include_dir); - return; + if (g->test_fns.length == 0) { + fprintf(stderr, "No tests to run.\n"); + exit(0); } - if (g->zig_target->is_native_os) { - g->libc = heap::c_allocator.create(); - - if ((err = stage2_libc_find_native(g->libc))) { - fprintf(stderr, - "Unable to link against libc: Unable to find libc installation: %s\n" - "See `zig libc --help` for more details.\n", err_str(err)); - exit(1); - } - - bool want_sys_dir = !mem_eql_mem(g->libc->include_dir, g->libc->include_dir_len, - g->libc->sys_include_dir, g->libc->sys_include_dir_len); - size_t want_um_and_shared_dirs = (g->zig_target->os == OsWindows) ? 2 : 0; - size_t dir_count = 1 + want_sys_dir + want_um_and_shared_dirs; - g->libc_include_dir_len = 0; - g->libc_include_dir_list = heap::c_allocator.allocate(dir_count); - - g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_create_from_mem( - g->libc->include_dir, g->libc->include_dir_len)); - g->libc_include_dir_len += 1; + ZigType *fn_type = get_test_fn_type(g); - if (want_sys_dir) { - g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_create_from_mem( - g->libc->sys_include_dir, g->libc->sys_include_dir_len)); - g->libc_include_dir_len += 1; - } + ZigValue *test_fn_type_val = get_builtin_value(g, "TestFn"); + assert(test_fn_type_val->type->id == ZigTypeIdMetaType); + ZigType *struct_type = test_fn_type_val->data.x_type; + if ((err = type_resolve(g, struct_type, ResolveStatusSizeKnown))) + zig_unreachable(); - if (want_um_and_shared_dirs != 0) { - Buf *include_dir_parent = buf_alloc(); - os_path_join(buf_create_from_mem(g->libc->include_dir, g->libc->include_dir_len), - buf_create_from_str(".."), include_dir_parent); + ZigValue *test_fn_array = g->pass1_arena->create(); + test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length, nullptr); + test_fn_array->special = ConstValSpecialStatic; + test_fn_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate(g->test_fns.length); - Buf *buff1 = buf_alloc(); - os_path_join(include_dir_parent, buf_create_from_str("um"), buff1); - g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff1); - g->libc_include_dir_len += 1; + for (size_t i = 0; i < g->test_fns.length; i += 1) { + ZigFn *test_fn_entry = g->test_fns.at(i); - Buf *buff2 = buf_alloc(); - os_path_join(include_dir_parent, buf_create_from_str("shared"), buff2); - g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff2); - g->libc_include_dir_len += 1; - } - assert(g->libc_include_dir_len == dir_count); - } else if ((g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) && - !target_os_is_darwin(g->zig_target->os)) - { - Buf triple_buf = BUF_INIT; - target_triple_zig(&triple_buf, g->zig_target); - fprintf(stderr, - "Zig is unable to provide a libc for the chosen target '%s'.\n" - "The target is non-native, so Zig also cannot use the native libc installation.\n" - "Choose a target which has a libc available (see `zig targets`), or\n" - "provide a libc installation text file (see `zig libc --help`).\n", buf_ptr(&triple_buf)); - exit(1); - } -} + ZigValue *this_val = &test_fn_array->data.x_array.data.s_none.elements[i]; + this_val->special = ConstValSpecialStatic; + this_val->type = struct_type; + this_val->parent.id = ConstParentIdArray; + this_val->parent.data.p_array.array_val = test_fn_array; + this_val->parent.data.p_array.elem_index = i; + this_val->data.x_struct.fields = alloc_const_vals_ptrs(g, 3); -// does not add the "cc" arg -void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, - bool translate_c, FileExt source_kind) -{ - if (translate_c) { - args.append("-x"); - args.append("c"); - } + ZigValue *name_field = this_val->data.x_struct.fields[0]; + ZigValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name)->data.x_ptr.data.ref.pointee; + init_const_slice(g, name_field, name_array_val, 0, buf_len(&test_fn_entry->symbol_name), true); - args.append("-nostdinc"); - if (source_kind == FileExtCpp) { - args.append("-nostdinc++"); - } - args.append("-fno-spell-checking"); + ZigValue *fn_field = this_val->data.x_struct.fields[1]; + fn_field->type = fn_type; + fn_field->special = ConstValSpecialStatic; + fn_field->data.x_ptr.special = ConstPtrSpecialFunction; + fn_field->data.x_ptr.mut = ConstPtrMutComptimeConst; + fn_field->data.x_ptr.data.fn.fn_entry = test_fn_entry; - if (g->function_sections) { - args.append("-ffunction-sections"); - } + ZigValue *frame_size_field = this_val->data.x_struct.fields[2]; + frame_size_field->type = get_optional_type(g, g->builtin_types.entry_usize); + frame_size_field->special = ConstValSpecialStatic; + frame_size_field->data.x_optional = nullptr; - if (!translate_c) { - switch (g->err_color) { - case ErrColorAuto: - break; - case ErrColorOff: - args.append("-fno-color-diagnostics"); - args.append("-fno-caret-diagnostics"); - break; - case ErrColorOn: - args.append("-fcolor-diagnostics"); - args.append("-fcaret-diagnostics"); - break; + if (fn_is_async(test_fn_entry)) { + frame_size_field->data.x_optional = g->pass1_arena->create(); + frame_size_field->data.x_optional->special = ConstValSpecialStatic; + frame_size_field->data.x_optional->type = g->builtin_types.entry_usize; + bigint_init_unsigned(&frame_size_field->data.x_optional->data.x_bigint, + test_fn_entry->frame_type->abi_size); } } + report_errors_and_maybe_exit(g); - for (size_t i = 0; i < g->framework_dirs.length; i += 1) { - args.append("-iframework"); - args.append(g->framework_dirs.at(i)); - } + ZigValue *test_fn_slice = create_const_slice(g, test_fn_array, 0, g->test_fns.length, true); - if (g->libcpp_link_lib != nullptr) { - const char *libcxx_include_path = buf_ptr(buf_sprintf("%s" OS_SEP "libcxx" OS_SEP "include", - buf_ptr(g->zig_lib_dir))); + update_compile_var(g, buf_create_from_str("test_functions"), test_fn_slice); + assert(g->test_runner_package != nullptr); +} - const char *libcxxabi_include_path = buf_ptr(buf_sprintf("%s" OS_SEP "libcxxabi" OS_SEP "include", - buf_ptr(g->zig_lib_dir))); +static Buf *get_resolved_root_src_path(CodeGen *g) { + // TODO memoize + if (buf_len(&g->main_pkg->root_src_path) == 0) + return nullptr; - args.append("-isystem"); - args.append(libcxx_include_path); + Buf rel_full_path = BUF_INIT; + os_path_join(&g->main_pkg->root_src_dir, &g->main_pkg->root_src_path, &rel_full_path); - args.append("-isystem"); - args.append(libcxxabi_include_path); + Buf *resolved_path = buf_alloc(); + Buf *resolve_paths[] = {&rel_full_path}; + *resolved_path = os_path_resolve(resolve_paths, 1); - if (target_abi_is_musl(g->zig_target->abi)) { - args.append("-D_LIBCPP_HAS_MUSL_LIBC"); - } - args.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS"); - args.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); - } + return resolved_path; +} - args.append("-target"); - args.append(buf_ptr(&g->llvm_triple_str)); +static void gen_root_source(CodeGen *g) { + Buf *resolved_path = get_resolved_root_src_path(g); + if (resolved_path == nullptr) + return; - switch (source_kind) { - case FileExtC: - case FileExtCpp: - case FileExtHeader: - // According to Rich Felker libc headers are supposed to go before C language headers. - // However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics - // and other compiler specific items. - args.append("-isystem"); - args.append(buf_ptr(g->zig_c_headers_dir)); + Buf *source_code = buf_alloc(); + Error err; + // No need for using the caching system for this file fetch because it is handled + // separately. + if ((err = os_fetch_file_path(resolved_path, source_code))) { + fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(resolved_path), err_str(err)); + exit(1); + } - for (size_t i = 0; i < g->libc_include_dir_len; i += 1) { - const char *include_dir = g->libc_include_dir_list[i]; - args.append("-isystem"); - args.append(include_dir); - } + ZigType *root_import_alias = add_source_file(g, g->main_pkg, resolved_path, source_code, SourceKindRoot); + assert(root_import_alias == g->root_import); - if (g->zig_target->llvm_cpu_name != nullptr) { - args.append("-Xclang"); - args.append("-target-cpu"); - args.append("-Xclang"); - args.append(g->zig_target->llvm_cpu_name); - } - if (g->zig_target->llvm_cpu_features != nullptr) { - // https://github.com/ziglang/zig/issues/5017 - SplitIterator it = memSplit(str(g->zig_target->llvm_cpu_features), str(",")); - Optional> flag = SplitIterator_next(&it); - while (flag.is_some) { - args.append("-Xclang"); - args.append("-target-feature"); - args.append("-Xclang"); - args.append(buf_ptr(buf_create_from_slice(flag.value))); - flag = SplitIterator_next(&it); - } - } - if (translate_c) { - // this gives us access to preprocessing entities, presumably at - // the cost of performance - args.append("-Xclang"); - args.append("-detailed-preprocessing-record"); - } - if (out_dep_path != nullptr) { - args.append("-MD"); - args.append("-MV"); - args.append("-MF"); - args.append(out_dep_path); - } - break; - case FileExtAsm: - case FileExtLLVMIr: - case FileExtLLVMBitCode: - case FileExtUnknown: - break; - } - for (size_t i = 0; i < g->zig_target->llvm_cpu_features_asm_len; i += 1) { - args.append(g->zig_target->llvm_cpu_features_asm_ptr[i]); - } + assert(g->root_out_name); - if (g->zig_target->os == OsFreestanding) { - args.append("-ffreestanding"); + // Zig has lazy top level definitions. Here we semantically analyze the panic function. + Buf *import_target_path; + Buf full_path = BUF_INIT; + ZigType *std_import; + if ((err = analyze_import(g, g->root_import, buf_create_from_str("std"), &std_import, + &import_target_path, &full_path))) + { + if (err == ErrorFileNotFound) { + fprintf(stderr, "unable to find '%s'", buf_ptr(import_target_path)); + } else { + fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(&full_path), err_str(err)); + } + exit(1); } - // windows.h has files such as pshpack1.h which do #pragma packing, triggering a clang warning. - // So for this target, we disable this warning. - if (g->zig_target->os == OsWindows && target_abi_is_gnu(g->zig_target->abi)) { - args.append("-Wno-pragma-pack"); - } + Tld *builtin_tld = find_decl(g, &get_container_scope(std_import)->base, + buf_create_from_str("builtin")); + assert(builtin_tld != nullptr); + resolve_top_level_decl(g, builtin_tld, nullptr, false); + report_errors_and_maybe_exit(g); + assert(builtin_tld->id == TldIdVar); + TldVar *builtin_tld_var = (TldVar*)builtin_tld; + ZigValue *builtin_val = builtin_tld_var->var->const_value; + assert(builtin_val->type->id == ZigTypeIdMetaType); + ZigType *builtin_type = builtin_val->data.x_type; + + Tld *panic_tld = find_decl(g, &get_container_scope(builtin_type)->base, + buf_create_from_str("panic")); + assert(panic_tld != nullptr); + resolve_top_level_decl(g, panic_tld, nullptr, false); + report_errors_and_maybe_exit(g); + assert(panic_tld->id == TldIdVar); + TldVar *panic_tld_var = (TldVar*)panic_tld; + ZigValue *panic_fn_val = panic_tld_var->var->const_value; + assert(panic_fn_val->type->id == ZigTypeIdFn); + assert(panic_fn_val->data.x_ptr.special == ConstPtrSpecialFunction); + g->panic_fn = panic_fn_val->data.x_ptr.data.fn.fn_entry; + assert(g->panic_fn != nullptr); - if (!g->strip_debug_symbols) { - args.append("-g"); + if (!g->error_during_imports) { + semantic_analyze(g); } + report_errors_and_maybe_exit(g); - if (codegen_have_frame_pointer(g)) { - args.append("-fno-omit-frame-pointer"); - } else { - args.append("-fomit-frame-pointer"); + if (g->is_test_build) { + update_test_functions_builtin_decl(g); + if (!g->error_during_imports) { + semantic_analyze(g); + } } - if (g->have_sanitize_c) { - args.append("-fsanitize=undefined"); - args.append("-fsanitize-trap=undefined"); - } + report_errors_and_maybe_exit(g); - switch (g->build_mode) { - case BuildModeDebug: - // windows c runtime requires -D_DEBUG if using debug libraries - args.append("-D_DEBUG"); - args.append("-Og"); - - if (g->libc_link_lib != nullptr) { - args.append("-fstack-protector-strong"); - args.append("--param"); - args.append("ssp-buffer-size=4"); - } else { - args.append("-fno-stack-protector"); - } - break; - case BuildModeSafeRelease: - // See the comment in the BuildModeFastRelease case for why we pass -O2 rather - // than -O3 here. - args.append("-O2"); - if (g->libc_link_lib != nullptr) { - args.append("-D_FORTIFY_SOURCE=2"); - args.append("-fstack-protector-strong"); - args.append("--param"); - args.append("ssp-buffer-size=4"); - } else { - args.append("-fno-stack-protector"); - } - break; - case BuildModeFastRelease: - args.append("-DNDEBUG"); - // Here we pass -O2 rather than -O3 because, although we do the equivalent of - // -O3 in Zig code, the justification for the difference here is that Zig - // has better detection and prevention of undefined behavior, so -O3 is safer for - // Zig code than it is for C code. Also, C programmers are used to their code - // running in -O2 and thus the -O3 path has been tested less. - args.append("-O2"); - args.append("-fno-stack-protector"); - break; - case BuildModeSmallRelease: - args.append("-DNDEBUG"); - args.append("-Os"); - args.append("-fno-stack-protector"); - break; - } - - if (target_supports_fpic(g->zig_target) && g->have_pic) { - args.append("-fPIC"); - } - - for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { - args.append(g->clang_argv[arg_i]); - } - -} - -void codegen_translate_c(CodeGen *g, Buf *full_path) { - Error err; - - Buf *src_basename = buf_alloc(); - Buf *src_dirname = buf_alloc(); - os_path_split(full_path, src_dirname, src_basename); - - Buf noextname = BUF_INIT; - os_path_extname(src_basename, &noextname, nullptr); - - Buf *zig_basename = buf_sprintf("%s.zig", buf_ptr(&noextname)); - - detect_libc(g); - - Buf cache_digest = BUF_INIT; - buf_resize(&cache_digest, 0); - - CacheHash *cache_hash = nullptr; - if (g->enable_cache) { - if ((err = create_c_object_cache(g, &cache_hash, true))) { - // Already printed error; verbose = true - exit(1); - } - cache_file(cache_hash, full_path); - // to distinguish from generating a C object - cache_buf(cache_hash, buf_create_from_str("translate-c")); - - if ((err = cache_hit(cache_hash, &cache_digest))) { - if (err != ErrorInvalidFormat) { - fprintf(stderr, "unable to check cache: %s\n", err_str(err)); - exit(1); - } - } - if (cache_hash->manifest_file_path != nullptr) { - g->caches_to_release.append(cache_hash); - } - } - - if (g->enable_cache && buf_len(&cache_digest) != 0) { - // cache hit - Buf *cached_path = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s" OS_SEP "%s", - buf_ptr(g->cache_dir), buf_ptr(&cache_digest), buf_ptr(zig_basename)); - fprintf(stdout, "%s\n", buf_ptr(cached_path)); - return; - } - - // cache miss or cache disabled - init(g); - - Buf *out_dep_path = nullptr; - const char *out_dep_path_cstr = nullptr; - - if (g->enable_cache) { - buf_alloc();// we can't know the digest until we do the C compiler invocation, so we - // need a tmp filename. - out_dep_path = buf_alloc(); - if ((err = get_tmp_filename(g, out_dep_path, buf_sprintf("%s.d", buf_ptr(zig_basename))))) { - fprintf(stderr, "unable to create tmp dir: %s\n", err_str(err)); - exit(1); - } - out_dep_path_cstr = buf_ptr(out_dep_path); - } - - ZigList clang_argv = {0}; - add_cc_args(g, clang_argv, out_dep_path_cstr, true, FileExtC); - - clang_argv.append(buf_ptr(full_path)); - - if (g->verbose_cc) { - fprintf(stderr, "clang"); - for (size_t i = 0; i < clang_argv.length; i += 1) { - fprintf(stderr, " %s", clang_argv.at(i)); - } - fprintf(stderr, "\n"); - } - - clang_argv.append(nullptr); // to make the [start...end] argument work - - const char *resources_path = buf_ptr(g->zig_c_headers_dir); - Stage2ErrorMsg *errors_ptr; - size_t errors_len; - Stage2Ast *ast; - - err = stage2_translate_c(&ast, &errors_ptr, &errors_len, - &clang_argv.at(0), &clang_argv.last(), resources_path); - - if (err == ErrorCCompileErrors && errors_len > 0) { - for (size_t i = 0; i < errors_len; i += 1) { - Stage2ErrorMsg *clang_err = &errors_ptr[i]; - - ErrorMsg *err_msg = err_msg_create_with_offset( - clang_err->filename_ptr ? - buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : nullptr, - clang_err->line, clang_err->column, clang_err->offset, clang_err->source, - buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); - print_err_msg(err_msg, g->err_color); - } - exit(1); - } - - if (err) { - fprintf(stderr, "unable to parse C file: %s\n", err_str(err)); - exit(1); - } - - if (!g->enable_cache) { - stage2_render_ast(ast, stdout); - return; - } - - // add the files depended on to the cache system - if ((err = cache_add_dep_file(cache_hash, out_dep_path, true))) { - // Don't treat the absence of the .d file as a fatal error, the - // compiler may not produce one eg. when compiling .s files - if (err != ErrorFileNotFound) { - fprintf(stderr, "Failed to add C source dependencies to cache: %s\n", err_str(err)); - exit(1); - } - } - if (err != ErrorFileNotFound) { - os_delete_file(out_dep_path); - } - - if ((err = cache_final(cache_hash, &cache_digest))) { - fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err)); - exit(1); - } - - Buf *artifact_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s", - buf_ptr(g->cache_dir), buf_ptr(&cache_digest)); - - if ((err = os_make_path(artifact_dir))) { - fprintf(stderr, "Unable to make dir: %s\n", err_str(err)); - exit(1); - } - - Buf *cached_path = buf_sprintf("%s" OS_SEP "%s", buf_ptr(artifact_dir), buf_ptr(zig_basename)); - - FILE *out_file = fopen(buf_ptr(cached_path), "wb"); - if (out_file == nullptr) { - fprintf(stderr, "Unable to open output file: %s\n", strerror(errno)); - exit(1); - } - stage2_render_ast(ast, out_file); - if (fclose(out_file) != 0) { - fprintf(stderr, "Unable to write to output file: %s\n", strerror(errno)); - exit(1); - } - fprintf(stdout, "%s\n", buf_ptr(cached_path)); -} - -static void update_test_functions_builtin_decl(CodeGen *g) { - Error err; - - assert(g->is_test_build); - - if (g->test_fns.length == 0) { - fprintf(stderr, "No tests to run.\n"); - exit(0); - } - - ZigType *fn_type = get_test_fn_type(g); - - ZigValue *test_fn_type_val = get_builtin_value(g, "TestFn"); - assert(test_fn_type_val->type->id == ZigTypeIdMetaType); - ZigType *struct_type = test_fn_type_val->data.x_type; - if ((err = type_resolve(g, struct_type, ResolveStatusSizeKnown))) - zig_unreachable(); - - ZigValue *test_fn_array = g->pass1_arena->create(); - test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length, nullptr); - test_fn_array->special = ConstValSpecialStatic; - test_fn_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate(g->test_fns.length); - - for (size_t i = 0; i < g->test_fns.length; i += 1) { - ZigFn *test_fn_entry = g->test_fns.at(i); - - ZigValue *this_val = &test_fn_array->data.x_array.data.s_none.elements[i]; - this_val->special = ConstValSpecialStatic; - this_val->type = struct_type; - this_val->parent.id = ConstParentIdArray; - this_val->parent.data.p_array.array_val = test_fn_array; - this_val->parent.data.p_array.elem_index = i; - this_val->data.x_struct.fields = alloc_const_vals_ptrs(g, 3); - - ZigValue *name_field = this_val->data.x_struct.fields[0]; - ZigValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name)->data.x_ptr.data.ref.pointee; - init_const_slice(g, name_field, name_array_val, 0, buf_len(&test_fn_entry->symbol_name), true); - - ZigValue *fn_field = this_val->data.x_struct.fields[1]; - fn_field->type = fn_type; - fn_field->special = ConstValSpecialStatic; - fn_field->data.x_ptr.special = ConstPtrSpecialFunction; - fn_field->data.x_ptr.mut = ConstPtrMutComptimeConst; - fn_field->data.x_ptr.data.fn.fn_entry = test_fn_entry; - - ZigValue *frame_size_field = this_val->data.x_struct.fields[2]; - frame_size_field->type = get_optional_type(g, g->builtin_types.entry_usize); - frame_size_field->special = ConstValSpecialStatic; - frame_size_field->data.x_optional = nullptr; - - if (fn_is_async(test_fn_entry)) { - frame_size_field->data.x_optional = g->pass1_arena->create(); - frame_size_field->data.x_optional->special = ConstValSpecialStatic; - frame_size_field->data.x_optional->type = g->builtin_types.entry_usize; - bigint_init_unsigned(&frame_size_field->data.x_optional->data.x_bigint, - test_fn_entry->frame_type->abi_size); - } - } - report_errors_and_maybe_exit(g); - - ZigValue *test_fn_slice = create_const_slice(g, test_fn_array, 0, g->test_fns.length, true); - - update_compile_var(g, buf_create_from_str("test_functions"), test_fn_slice); - assert(g->test_runner_package != nullptr); -} - -static Buf *get_resolved_root_src_path(CodeGen *g) { - // TODO memoize - if (buf_len(&g->main_pkg->root_src_path) == 0) - return nullptr; - - Buf rel_full_path = BUF_INIT; - os_path_join(&g->main_pkg->root_src_dir, &g->main_pkg->root_src_path, &rel_full_path); - - Buf *resolved_path = buf_alloc(); - Buf *resolve_paths[] = {&rel_full_path}; - *resolved_path = os_path_resolve(resolve_paths, 1); - - return resolved_path; -} - -static void gen_root_source(CodeGen *g) { - Buf *resolved_path = get_resolved_root_src_path(g); - if (resolved_path == nullptr) - return; - - Buf *source_code = buf_alloc(); - Error err; - // No need for using the caching system for this file fetch because it is handled - // separately. - if ((err = os_fetch_file_path(resolved_path, source_code))) { - fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(resolved_path), err_str(err)); - exit(1); - } - - ZigType *root_import_alias = add_source_file(g, g->main_pkg, resolved_path, source_code, SourceKindRoot); - assert(root_import_alias == g->root_import); - - assert(g->root_out_name); - assert(g->out_type != OutTypeUnknown); - - if (!g->is_dummy_so) { - // Zig has lazy top level definitions. Here we semantically analyze the panic function. - Buf *import_target_path; - Buf full_path = BUF_INIT; - ZigType *std_import; - if ((err = analyze_import(g, g->root_import, buf_create_from_str("std"), &std_import, - &import_target_path, &full_path))) - { - if (err == ErrorFileNotFound) { - fprintf(stderr, "unable to find '%s'", buf_ptr(import_target_path)); - } else { - fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(&full_path), err_str(err)); - } - exit(1); - } - - Tld *builtin_tld = find_decl(g, &get_container_scope(std_import)->base, - buf_create_from_str("builtin")); - assert(builtin_tld != nullptr); - resolve_top_level_decl(g, builtin_tld, nullptr, false); - report_errors_and_maybe_exit(g); - assert(builtin_tld->id == TldIdVar); - TldVar *builtin_tld_var = (TldVar*)builtin_tld; - ZigValue *builtin_val = builtin_tld_var->var->const_value; - assert(builtin_val->type->id == ZigTypeIdMetaType); - ZigType *builtin_type = builtin_val->data.x_type; - - Tld *panic_tld = find_decl(g, &get_container_scope(builtin_type)->base, - buf_create_from_str("panic")); - assert(panic_tld != nullptr); - resolve_top_level_decl(g, panic_tld, nullptr, false); - report_errors_and_maybe_exit(g); - assert(panic_tld->id == TldIdVar); - TldVar *panic_tld_var = (TldVar*)panic_tld; - ZigValue *panic_fn_val = panic_tld_var->var->const_value; - assert(panic_fn_val->type->id == ZigTypeIdFn); - assert(panic_fn_val->data.x_ptr.special == ConstPtrSpecialFunction); - g->panic_fn = panic_fn_val->data.x_ptr.data.fn.fn_entry; - assert(g->panic_fn != nullptr); - } - - if (!g->error_during_imports) { - semantic_analyze(g); - } - report_errors_and_maybe_exit(g); - - if (g->is_test_build) { - update_test_functions_builtin_decl(g); - if (!g->error_during_imports) { - semantic_analyze(g); - } - } - - report_errors_and_maybe_exit(g); - -} - -static void print_zig_cc_cmd(ZigList *args) { - for (size_t arg_i = 0; arg_i < args->length; arg_i += 1) { - const char *space_str = (arg_i == 0) ? "" : " "; - fprintf(stderr, "%s%s", space_str, args->at(arg_i)); - } - fprintf(stderr, "\n"); -} - -// Caller should delete the file when done or rename it into a better location. -static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix) { - Error err; - buf_resize(out, 0); - os_path_join(g->cache_dir, buf_create_from_str("tmp" OS_SEP), out); - if ((err = os_make_path(out))) { - return err; - } - const char base64[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"; - assert(array_length(base64) == 64 + 1); - for (size_t i = 0; i < 12; i += 1) { - buf_append_char(out, base64[rand() % 64]); - } - buf_append_char(out, '-'); - buf_append_buf(out, suffix); - return ErrorNone; -} - -Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose) { - Error err; - CacheHash *cache_hash = heap::c_allocator.create(); - Buf *manifest_dir = buf_sprintf("%s" OS_SEP CACHE_HASH_SUBDIR, buf_ptr(g->cache_dir)); - cache_init(cache_hash, manifest_dir); - - Buf *compiler_id; - if ((err = get_compiler_id(&compiler_id))) { - if (verbose) { - fprintf(stderr, "unable to get compiler id: %s\n", err_str(err)); - } - return err; - } - cache_buf(cache_hash, compiler_id); - cache_int(cache_hash, g->err_color); - cache_list_of_str(cache_hash, g->framework_dirs.items, g->framework_dirs.length); - cache_bool(cache_hash, g->libcpp_link_lib != nullptr); - cache_buf(cache_hash, g->zig_lib_dir); - cache_buf(cache_hash, g->zig_c_headers_dir); - cache_list_of_str(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len); - cache_int(cache_hash, g->zig_target->is_native_os); - cache_int(cache_hash, g->zig_target->is_native_cpu); - cache_int(cache_hash, g->zig_target->arch); - cache_int(cache_hash, g->zig_target->vendor); - cache_int(cache_hash, g->zig_target->os); - cache_int(cache_hash, g->zig_target->abi); - cache_bool(cache_hash, g->strip_debug_symbols); - cache_int(cache_hash, g->build_mode); - cache_bool(cache_hash, g->have_pic); - cache_bool(cache_hash, g->have_sanitize_c); - cache_bool(cache_hash, want_valgrind_support(g)); - cache_bool(cache_hash, g->function_sections); - cache_int(cache_hash, g->code_model); - cache_bool(cache_hash, codegen_have_frame_pointer(g)); - cache_bool(cache_hash, g->libc_link_lib); - if (g->zig_target->cache_hash != nullptr) { - cache_mem(cache_hash, g->zig_target->cache_hash, g->zig_target->cache_hash_len); - } - - for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { - cache_str(cache_hash, g->clang_argv[arg_i]); - } - - *out_cache_hash = cache_hash; - return ErrorNone; -} - -static bool need_llvm_module(CodeGen *g) { - return buf_len(&g->main_pkg->root_src_path) != 0; -} - -// before gen_c_objects -static bool main_output_dir_is_just_one_c_object_pre(CodeGen *g) { - return g->enable_cache && g->c_source_files.length == 1 && !need_llvm_module(g) && - g->out_type == OutTypeObj && g->link_objects.length == 0; -} - -// after gen_c_objects -static bool main_output_dir_is_just_one_c_object_post(CodeGen *g) { - return g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g) && g->out_type == OutTypeObj; -} - -// returns true if it was a cache miss -static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { - Error err; - - Buf *artifact_dir; - Buf *o_final_path; - - Buf *o_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR, buf_ptr(g->cache_dir)); - - Buf *c_source_file = buf_create_from_str(c_file->source_path); - Buf *c_source_basename = buf_alloc(); - os_path_split(c_source_file, nullptr, c_source_basename); - - Stage2ProgressNode *child_prog_node = stage2_progress_start(g->sub_progress_node, buf_ptr(c_source_basename), - buf_len(c_source_basename), 0); - - Buf *final_o_basename = buf_alloc(); - if (c_file->preprocessor_only_basename == nullptr) { - // We special case when doing build-obj for just one C file - if (main_output_dir_is_just_one_c_object_pre(g)) { - buf_init_from_buf(final_o_basename, g->root_out_name); - } else { - os_path_extname(c_source_basename, final_o_basename, nullptr); - } - buf_append_str(final_o_basename, target_o_file_ext(g->zig_target)); - } else { - buf_init_from_str(final_o_basename, c_file->preprocessor_only_basename); - } - - CacheHash *cache_hash; - if ((err = create_c_object_cache(g, &cache_hash, true))) { - // Already printed error; verbose = true - exit(1); - } - cache_file(cache_hash, c_source_file); - - // Note: not directory args, just args that always have a file next - static const char *file_args[] = { - "-include", - }; - for (size_t arg_i = 0; arg_i < c_file->args.length; arg_i += 1) { - const char *arg = c_file->args.at(arg_i); - cache_str(cache_hash, arg); - for (size_t file_arg_i = 0; file_arg_i < array_length(file_args); file_arg_i += 1) { - if (strcmp(arg, file_args[file_arg_i]) == 0 && arg_i + 1 < c_file->args.length) { - arg_i += 1; - cache_file(cache_hash, buf_create_from_str(c_file->args.at(arg_i))); - } - } - } - - Buf digest = BUF_INIT; - buf_resize(&digest, 0); - if ((err = cache_hit(cache_hash, &digest))) { - if (err != ErrorInvalidFormat) { - if (err == ErrorCacheUnavailable) { - // already printed error - } else { - fprintf(stderr, "unable to check cache when compiling C object: %s\n", err_str(err)); - } - exit(1); - } - } - bool is_cache_miss = g->disable_c_depfile || (buf_len(&digest) == 0); - if (is_cache_miss) { - // we can't know the digest until we do the C compiler invocation, so we - // need a tmp filename. - Buf *out_obj_path = buf_alloc(); - if ((err = get_tmp_filename(g, out_obj_path, final_o_basename))) { - fprintf(stderr, "unable to create tmp dir: %s\n", err_str(err)); - exit(1); - } - - Termination term; - ZigList args = {}; - args.append(buf_ptr(self_exe_path)); - args.append("clang"); - - if (c_file->preprocessor_only_basename == nullptr) { - args.append("-c"); - } - - Buf *out_dep_path = g->disable_c_depfile ? nullptr : buf_sprintf("%s.d", buf_ptr(out_obj_path)); - const char *out_dep_path_cstr = (out_dep_path == nullptr) ? nullptr : buf_ptr(out_dep_path); - FileExt ext = classify_file_ext(buf_ptr(c_source_basename), buf_len(c_source_basename)); - add_cc_args(g, args, out_dep_path_cstr, false, ext); - - args.append("-o"); - args.append(buf_ptr(out_obj_path)); - - args.append(buf_ptr(c_source_file)); - - for (size_t arg_i = 0; arg_i < c_file->args.length; arg_i += 1) { - args.append(c_file->args.at(arg_i)); - } - - if (g->verbose_cc) { - print_zig_cc_cmd(&args); - } - os_spawn_process(args, &term); - if (term.how != TerminationIdClean || term.code != 0) { - fprintf(stderr, "\nThe following command failed:\n"); - print_zig_cc_cmd(&args); - exit(1); - } - - if (out_dep_path != nullptr) { - // add the files depended on to the cache system - if ((err = cache_add_dep_file(cache_hash, out_dep_path, true))) { - // Don't treat the absence of the .d file as a fatal error, the - // compiler may not produce one eg. when compiling .s files - if (err != ErrorFileNotFound) { - fprintf(stderr, "Failed to add C source dependencies to cache: %s\n", err_str(err)); - exit(1); - } - } - if (err != ErrorFileNotFound) { - os_delete_file(out_dep_path); - } - - if ((err = cache_final(cache_hash, &digest))) { - fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err)); - exit(1); - } - } - artifact_dir = buf_alloc(); - os_path_join(o_dir, &digest, artifact_dir); - if ((err = os_make_path(artifact_dir))) { - fprintf(stderr, "Unable to create output directory '%s': %s", - buf_ptr(artifact_dir), err_str(err)); - exit(1); - } - o_final_path = buf_alloc(); - os_path_join(artifact_dir, final_o_basename, o_final_path); - if ((err = os_rename(out_obj_path, o_final_path))) { - fprintf(stderr, "Unable to rename object: %s\n", err_str(err)); - exit(1); - } - } else { - // cache hit - artifact_dir = buf_alloc(); - os_path_join(o_dir, &digest, artifact_dir); - o_final_path = buf_alloc(); - os_path_join(artifact_dir, final_o_basename, o_final_path); - } - - g->c_artifact_dir = artifact_dir; - g->link_objects.append(o_final_path); - g->caches_to_release.append(cache_hash); - - stage2_progress_end(child_prog_node); -} - -// returns true if we had any cache misses -static void gen_c_objects(CodeGen *g) { - Error err; - - if (g->c_source_files.length == 0) - return; - - Buf *self_exe_path = buf_alloc(); - if ((err = os_self_exe_path(self_exe_path))) { - fprintf(stderr, "Unable to get self exe path: %s\n", err_str(err)); - exit(1); - } - - codegen_add_time_event(g, "Compile C Objects"); - const char *c_prog_name = "Compile C Objects"; - codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, c_prog_name, strlen(c_prog_name), - g->c_source_files.length)); - - for (size_t c_file_i = 0; c_file_i < g->c_source_files.length; c_file_i += 1) { - CFile *c_file = g->c_source_files.at(c_file_i); - gen_c_object(g, self_exe_path, c_file); - } -} - -void codegen_add_object(CodeGen *g, Buf *object_path) { - g->link_objects.append(object_path); -} - -// Must be coordinated with with CIntType enum -static const char *c_int_type_names[] = { - "short", - "unsigned short", - "int", - "unsigned int", - "long", - "unsigned long", - "long long", - "unsigned long long", -}; - -struct GenH { - ZigList types_to_declare; -}; - -static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_entry) { - if (type_entry->gen_h_loop_flag) - return; - type_entry->gen_h_loop_flag = true; - - switch (type_entry->id) { - case ZigTypeIdInvalid: - case ZigTypeIdMetaType: - case ZigTypeIdComptimeFloat: - case ZigTypeIdComptimeInt: - case ZigTypeIdEnumLiteral: - case ZigTypeIdUndefined: - case ZigTypeIdNull: - case ZigTypeIdBoundFn: - case ZigTypeIdErrorUnion: - case ZigTypeIdErrorSet: - case ZigTypeIdFnFrame: - case ZigTypeIdAnyFrame: - zig_unreachable(); - case ZigTypeIdVoid: - case ZigTypeIdUnreachable: - return; - case ZigTypeIdBool: - g->c_want_stdbool = true; - return; - case ZigTypeIdInt: - g->c_want_stdint = true; - return; - case ZigTypeIdFloat: - return; - case ZigTypeIdOpaque: - gen_h->types_to_declare.append(type_entry); - return; - case ZigTypeIdStruct: - if(type_entry->data.structure.layout == ContainerLayoutExtern) { - for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { - TypeStructField *field = type_entry->data.structure.fields[i]; - prepend_c_type_to_decl_list(g, gen_h, field->type_entry); - } - } - gen_h->types_to_declare.append(type_entry); - return; - case ZigTypeIdUnion: - for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) { - TypeUnionField *field = &type_entry->data.unionation.fields[i]; - prepend_c_type_to_decl_list(g, gen_h, field->type_entry); - } - gen_h->types_to_declare.append(type_entry); - return; - case ZigTypeIdEnum: - prepend_c_type_to_decl_list(g, gen_h, type_entry->data.enumeration.tag_int_type); - gen_h->types_to_declare.append(type_entry); - return; - case ZigTypeIdPointer: - prepend_c_type_to_decl_list(g, gen_h, type_entry->data.pointer.child_type); - return; - case ZigTypeIdArray: - prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type); - return; - case ZigTypeIdVector: - prepend_c_type_to_decl_list(g, gen_h, type_entry->data.vector.elem_type); - return; - case ZigTypeIdOptional: - prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type); - return; - case ZigTypeIdFn: - for (size_t i = 0; i < type_entry->data.fn.fn_type_id.param_count; i += 1) { - prepend_c_type_to_decl_list(g, gen_h, type_entry->data.fn.fn_type_id.param_info[i].type); - } - prepend_c_type_to_decl_list(g, gen_h, type_entry->data.fn.fn_type_id.return_type); - return; - } -} - -static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_buf) { - assert(type_entry); - - for (size_t i = 0; i < array_length(c_int_type_names); i += 1) { - if (type_entry == g->builtin_types.entry_c_int[i]) { - buf_init_from_str(out_buf, c_int_type_names[i]); - return; - } - } - if (type_entry == g->builtin_types.entry_c_longdouble) { - buf_init_from_str(out_buf, "long double"); - return; - } - if (type_entry == g->builtin_types.entry_c_void) { - buf_init_from_str(out_buf, "void"); - return; - } - if (type_entry == g->builtin_types.entry_isize) { - g->c_want_stdint = true; - buf_init_from_str(out_buf, "intptr_t"); - return; - } - if (type_entry == g->builtin_types.entry_usize) { - g->c_want_stdint = true; - buf_init_from_str(out_buf, "uintptr_t"); - return; - } - - prepend_c_type_to_decl_list(g, gen_h, type_entry); - - switch (type_entry->id) { - case ZigTypeIdVoid: - buf_init_from_str(out_buf, "void"); - break; - case ZigTypeIdBool: - buf_init_from_str(out_buf, "bool"); - break; - case ZigTypeIdUnreachable: - buf_init_from_str(out_buf, "__attribute__((__noreturn__)) void"); - break; - case ZigTypeIdFloat: - switch (type_entry->data.floating.bit_count) { - case 32: - buf_init_from_str(out_buf, "float"); - break; - case 64: - buf_init_from_str(out_buf, "double"); - break; - case 80: - buf_init_from_str(out_buf, "__float80"); - break; - case 128: - buf_init_from_str(out_buf, "__float128"); - break; - default: - zig_unreachable(); - } - break; - case ZigTypeIdInt: - buf_resize(out_buf, 0); - buf_appendf(out_buf, "%sint%" PRIu32 "_t", - type_entry->data.integral.is_signed ? "" : "u", - type_entry->data.integral.bit_count); - break; - case ZigTypeIdPointer: - { - Buf child_buf = BUF_INIT; - ZigType *child_type = type_entry->data.pointer.child_type; - get_c_type(g, gen_h, child_type, &child_buf); - - const char *const_str = type_entry->data.pointer.is_const ? "const " : ""; - buf_resize(out_buf, 0); - buf_appendf(out_buf, "%s%s *", const_str, buf_ptr(&child_buf)); - break; - } - case ZigTypeIdOptional: - { - ZigType *child_type = type_entry->data.maybe.child_type; - if (!type_has_bits(g, child_type)) { - buf_init_from_str(out_buf, "bool"); - return; - } else if (type_is_nonnull_ptr(g, child_type)) { - return get_c_type(g, gen_h, child_type, out_buf); - } else { - zig_unreachable(); - } - } - case ZigTypeIdStruct: - case ZigTypeIdOpaque: - { - buf_init_from_str(out_buf, "struct "); - buf_append_buf(out_buf, type_h_name(type_entry)); - return; - } - case ZigTypeIdUnion: - { - buf_init_from_str(out_buf, "union "); - buf_append_buf(out_buf, type_h_name(type_entry)); - return; - } - case ZigTypeIdEnum: - { - buf_init_from_str(out_buf, "enum "); - buf_append_buf(out_buf, type_h_name(type_entry)); - return; - } - case ZigTypeIdArray: - { - ZigTypeArray *array_data = &type_entry->data.array; - - Buf *child_buf = buf_alloc(); - get_c_type(g, gen_h, array_data->child_type, child_buf); - - buf_resize(out_buf, 0); - buf_appendf(out_buf, "%s", buf_ptr(child_buf)); - return; - } - case ZigTypeIdVector: - zig_panic("TODO implement get_c_type for vector types"); - case ZigTypeIdErrorUnion: - case ZigTypeIdErrorSet: - case ZigTypeIdFn: - zig_panic("TODO implement get_c_type for more types"); - case ZigTypeIdInvalid: - case ZigTypeIdMetaType: - case ZigTypeIdBoundFn: - case ZigTypeIdComptimeFloat: - case ZigTypeIdComptimeInt: - case ZigTypeIdEnumLiteral: - case ZigTypeIdUndefined: - case ZigTypeIdNull: - case ZigTypeIdFnFrame: - case ZigTypeIdAnyFrame: - zig_unreachable(); - } -} - -static const char *preprocessor_alphabet1 = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; -static const char *preprocessor_alphabet2 = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - -static bool need_to_preprocessor_mangle(Buf *src) { - for (size_t i = 0; i < buf_len(src); i += 1) { - const char *alphabet = (i == 0) ? preprocessor_alphabet1 : preprocessor_alphabet2; - uint8_t byte = buf_ptr(src)[i]; - if (strchr(alphabet, byte) == nullptr) { - return true; - } - } - return false; -} - -static Buf *preprocessor_mangle(Buf *src) { - if (!need_to_preprocessor_mangle(src)) { - return buf_create_from_buf(src); - } - Buf *result = buf_alloc(); - for (size_t i = 0; i < buf_len(src); i += 1) { - const char *alphabet = (i == 0) ? preprocessor_alphabet1 : preprocessor_alphabet2; - uint8_t byte = buf_ptr(src)[i]; - if (strchr(alphabet, byte) == nullptr) { - // perform escape - buf_appendf(result, "_%02x_", byte); - } else { - buf_append_char(result, byte); - } - } - return result; -} - -static void gen_h_file_types(CodeGen* g, GenH* gen_h, Buf* out_buf) { - for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) { - ZigType *type_entry = gen_h->types_to_declare.at(type_i); - switch (type_entry->id) { - case ZigTypeIdInvalid: - case ZigTypeIdMetaType: - case ZigTypeIdVoid: - case ZigTypeIdBool: - case ZigTypeIdUnreachable: - case ZigTypeIdInt: - case ZigTypeIdFloat: - case ZigTypeIdPointer: - case ZigTypeIdComptimeFloat: - case ZigTypeIdComptimeInt: - case ZigTypeIdEnumLiteral: - case ZigTypeIdArray: - case ZigTypeIdUndefined: - case ZigTypeIdNull: - case ZigTypeIdErrorUnion: - case ZigTypeIdErrorSet: - case ZigTypeIdBoundFn: - case ZigTypeIdOptional: - case ZigTypeIdFn: - case ZigTypeIdVector: - case ZigTypeIdFnFrame: - case ZigTypeIdAnyFrame: - zig_unreachable(); - - case ZigTypeIdEnum: - if (type_entry->data.enumeration.layout == ContainerLayoutExtern) { - buf_appendf(out_buf, "enum %s {\n", buf_ptr(type_h_name(type_entry))); - for (uint32_t field_i = 0; field_i < type_entry->data.enumeration.src_field_count; field_i += 1) { - TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i]; - Buf *value_buf = buf_alloc(); - bigint_append_buf(value_buf, &enum_field->value, 10); - buf_appendf(out_buf, " %s = %s", buf_ptr(enum_field->name), buf_ptr(value_buf)); - if (field_i != type_entry->data.enumeration.src_field_count - 1) { - buf_appendf(out_buf, ","); - } - buf_appendf(out_buf, "\n"); - } - buf_appendf(out_buf, "};\n\n"); - } else { - buf_appendf(out_buf, "enum %s;\n\n", buf_ptr(type_h_name(type_entry))); - } - break; - case ZigTypeIdStruct: - if (type_entry->data.structure.layout == ContainerLayoutExtern) { - buf_appendf(out_buf, "struct %s {\n", buf_ptr(type_h_name(type_entry))); - for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) { - TypeStructField *struct_field = type_entry->data.structure.fields[field_i]; - - Buf *type_name_buf = buf_alloc(); - get_c_type(g, gen_h, struct_field->type_entry, type_name_buf); - - if (struct_field->type_entry->id == ZigTypeIdArray) { - buf_appendf(out_buf, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf), - buf_ptr(struct_field->name), - struct_field->type_entry->data.array.len); - } else { - buf_appendf(out_buf, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name)); - } - - } - buf_appendf(out_buf, "};\n\n"); - } else { - buf_appendf(out_buf, "struct %s;\n\n", buf_ptr(type_h_name(type_entry))); - } - break; - case ZigTypeIdUnion: - if (type_entry->data.unionation.layout == ContainerLayoutExtern) { - buf_appendf(out_buf, "union %s {\n", buf_ptr(type_h_name(type_entry))); - for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) { - TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i]; - - Buf *type_name_buf = buf_alloc(); - get_c_type(g, gen_h, union_field->type_entry, type_name_buf); - buf_appendf(out_buf, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(union_field->name)); - } - buf_appendf(out_buf, "};\n\n"); - } else { - buf_appendf(out_buf, "union %s;\n\n", buf_ptr(type_h_name(type_entry))); - } - break; - case ZigTypeIdOpaque: - buf_appendf(out_buf, "struct %s;\n\n", buf_ptr(type_h_name(type_entry))); - break; - } - } -} - -static void gen_h_file_functions(CodeGen* g, GenH* gen_h, Buf* out_buf, Buf* export_macro) { - for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) { - ZigFn *fn_table_entry = g->fn_defs.at(fn_def_i); - - if (fn_table_entry->export_list.length == 0) - continue; - - FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id; - - Buf return_type_c = BUF_INIT; - get_c_type(g, gen_h, fn_type_id->return_type, &return_type_c); - - Buf *symbol_name; - if (fn_table_entry->export_list.length == 0) { - symbol_name = &fn_table_entry->symbol_name; - } else { - GlobalExport *fn_export = &fn_table_entry->export_list.items[0]; - symbol_name = &fn_export->name; - } - - if (export_macro != nullptr) { - buf_appendf(out_buf, "%s %s %s(", - buf_ptr(export_macro), - buf_ptr(&return_type_c), - buf_ptr(symbol_name)); - } else { - buf_appendf(out_buf, "%s %s(", - buf_ptr(&return_type_c), - buf_ptr(symbol_name)); - } - - Buf param_type_c = BUF_INIT; - if (fn_type_id->param_count > 0) { - for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) { - FnTypeParamInfo *param_info = &fn_type_id->param_info[param_i]; - AstNode *param_decl_node = get_param_decl_node(fn_table_entry, param_i); - Buf *param_name = param_decl_node->data.param_decl.name; - - const char *comma_str = (param_i == 0) ? "" : ", "; - const char *restrict_str = param_info->is_noalias ? "restrict" : ""; - get_c_type(g, gen_h, param_info->type, ¶m_type_c); - - if (param_info->type->id == ZigTypeIdArray) { - // Arrays decay to pointers - buf_appendf(out_buf, "%s%s%s %s[]", comma_str, buf_ptr(¶m_type_c), - restrict_str, buf_ptr(param_name)); - } else { - buf_appendf(out_buf, "%s%s%s %s", comma_str, buf_ptr(¶m_type_c), - restrict_str, buf_ptr(param_name)); - } - } - buf_appendf(out_buf, ")"); - } else { - buf_appendf(out_buf, "void)"); - } - - buf_appendf(out_buf, ";\n"); - } -} - -static void gen_h_file_variables(CodeGen* g, GenH* gen_h, Buf* h_buf, Buf* export_macro) { - for (size_t exp_var_i = 0; exp_var_i < g->global_vars.length; exp_var_i += 1) { - ZigVar* var = g->global_vars.at(exp_var_i)->var; - if (var->export_list.length == 0) - continue; - - Buf var_type_c = BUF_INIT; - get_c_type(g, gen_h, var->var_type, &var_type_c); - - if (export_macro != nullptr) { - buf_appendf(h_buf, "extern %s %s %s;\n", - buf_ptr(export_macro), - buf_ptr(&var_type_c), - var->name); - } else { - buf_appendf(h_buf, "extern %s %s;\n", - buf_ptr(&var_type_c), - var->name); - } - } -} - -static void gen_h_file(CodeGen *g) { - GenH gen_h_data = {0}; - GenH *gen_h = &gen_h_data; - - assert(!g->is_test_build); - assert(!g->disable_gen_h); - - Buf *out_h_path = buf_sprintf("%s" OS_SEP "%s.h", buf_ptr(g->output_dir), buf_ptr(g->root_out_name)); - - FILE *out_h = fopen(buf_ptr(out_h_path), "wb"); - if (!out_h) - zig_panic("unable to open %s: %s\n", buf_ptr(out_h_path), strerror(errno)); - - Buf *export_macro = nullptr; - if (g->is_dynamic) { - export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name))); - buf_upcase(export_macro); - } - - Buf fns_buf = BUF_INIT; - buf_resize(&fns_buf, 0); - gen_h_file_functions(g, gen_h, &fns_buf, export_macro); - - Buf vars_buf = BUF_INIT; - buf_resize(&vars_buf, 0); - gen_h_file_variables(g, gen_h, &vars_buf, export_macro); - - // Types will be populated by exported functions and variables so it has to run last. - Buf types_buf = BUF_INIT; - buf_resize(&types_buf, 0); - gen_h_file_types(g, gen_h, &types_buf); - - Buf *ifdef_dance_name = preprocessor_mangle(buf_sprintf("%s_H", buf_ptr(g->root_out_name))); - buf_upcase(ifdef_dance_name); - - fprintf(out_h, "#ifndef %s\n", buf_ptr(ifdef_dance_name)); - fprintf(out_h, "#define %s\n\n", buf_ptr(ifdef_dance_name)); - - if (g->c_want_stdbool) - fprintf(out_h, "#include \n"); - if (g->c_want_stdint) - fprintf(out_h, "#include \n"); - - fprintf(out_h, "\n"); - - if (g->is_dynamic) { - fprintf(out_h, "#if defined(_WIN32)\n"); - fprintf(out_h, "#define %s __declspec(dllimport)\n", buf_ptr(export_macro)); - fprintf(out_h, "#else\n"); - fprintf(out_h, "#define %s __attribute__((visibility (\"default\")))\n", - buf_ptr(export_macro)); - fprintf(out_h, "#endif\n"); - fprintf(out_h, "\n"); - } - - fprintf(out_h, "#ifdef __cplusplus\n"); - fprintf(out_h, "extern \"C\" {\n"); - fprintf(out_h, "#endif\n"); - fprintf(out_h, "\n"); - - fprintf(out_h, "%s", buf_ptr(&types_buf)); - fprintf(out_h, "%s\n", buf_ptr(&fns_buf)); - fprintf(out_h, "%s\n", buf_ptr(&vars_buf)); - - fprintf(out_h, "#ifdef __cplusplus\n"); - fprintf(out_h, "} // extern \"C\"\n"); - fprintf(out_h, "#endif\n\n"); - - fprintf(out_h, "#endif // %s\n", buf_ptr(ifdef_dance_name)); - - if (fclose(out_h)) - zig_panic("unable to close h file: %s", strerror(errno)); -} +} void codegen_print_timing_report(CodeGen *g, FILE *f) { double start_time = g->timing_events.at(0).time; @@ -10733,174 +9230,14 @@ void codegen_add_time_event(CodeGen *g, const char *name) { g->timing_events.append({seconds, name}); } -static void add_cache_pkg(CodeGen *g, CacheHash *ch, ZigPackage *pkg) { - if (buf_len(&pkg->root_src_path) == 0) - return; - pkg->added_to_cache = true; - - Buf *rel_full_path = buf_alloc(); - os_path_join(&pkg->root_src_dir, &pkg->root_src_path, rel_full_path); - cache_file(ch, rel_full_path); - - auto it = pkg->package_table.entry_iterator(); - for (;;) { - auto *entry = it.next(); - if (!entry) - break; - - if (!pkg->added_to_cache) { - cache_buf(ch, entry->key); - add_cache_pkg(g, ch, entry->value); - } - } -} - -// Called before init() -// is_cache_hit takes into account gen_c_objects -static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { - Error err; - - Buf *compiler_id; - if ((err = get_compiler_id(&compiler_id))) - return err; - - CacheHash *ch = &g->cache_hash; - cache_init(ch, manifest_dir); - - add_cache_pkg(g, ch, g->main_pkg); - if (g->linker_script != nullptr) { - cache_file(ch, buf_create_from_str(g->linker_script)); - } - cache_buf(ch, compiler_id); - cache_buf(ch, g->root_out_name); - cache_buf(ch, g->zig_lib_dir); - cache_buf(ch, g->zig_std_dir); - cache_list_of_link_lib(ch, g->link_libs_list.items, g->link_libs_list.length); - cache_list_of_buf(ch, g->darwin_frameworks.items, g->darwin_frameworks.length); - cache_list_of_buf(ch, g->rpath_list.items, g->rpath_list.length); - cache_list_of_buf(ch, g->forbidden_libs.items, g->forbidden_libs.length); - cache_int(ch, g->build_mode); - cache_int(ch, g->out_type); - cache_bool(ch, g->zig_target->is_native_os); - cache_bool(ch, g->zig_target->is_native_cpu); - cache_int(ch, g->zig_target->arch); - cache_int(ch, g->zig_target->vendor); - cache_int(ch, g->zig_target->os); - cache_int(ch, g->zig_target->abi); - if (g->zig_target->cache_hash != nullptr) { - cache_mem(ch, g->zig_target->cache_hash, g->zig_target->cache_hash_len); - } - if (g->zig_target->glibc_or_darwin_version != nullptr) { - cache_int(ch, g->zig_target->glibc_or_darwin_version->major); - cache_int(ch, g->zig_target->glibc_or_darwin_version->minor); - cache_int(ch, g->zig_target->glibc_or_darwin_version->patch); - } - if (g->zig_target->dynamic_linker != nullptr) { - cache_str(ch, g->zig_target->dynamic_linker); - } - cache_int(ch, detect_subsystem(g)); - cache_bool(ch, g->strip_debug_symbols); - cache_bool(ch, g->is_test_build); - if (g->is_test_build) { - cache_buf_opt(ch, g->test_filter); - cache_buf_opt(ch, g->test_name_prefix); - cache_bool(ch, g->test_is_evented); - } - cache_bool(ch, g->link_eh_frame_hdr); - cache_bool(ch, g->is_single_threaded); - cache_bool(ch, g->linker_rdynamic); - cache_bool(ch, g->each_lib_rpath); - cache_bool(ch, g->disable_gen_h); - cache_bool(ch, g->bundle_compiler_rt); - cache_bool(ch, want_valgrind_support(g)); - cache_bool(ch, g->have_pic); - cache_bool(ch, g->have_dynamic_link); - cache_bool(ch, g->have_stack_probing); - cache_bool(ch, g->have_sanitize_c); - cache_bool(ch, g->is_dummy_so); - cache_bool(ch, g->function_sections); - cache_bool(ch, g->enable_dump_analysis); - cache_bool(ch, g->enable_doc_generation); - cache_bool(ch, g->emit_bin); - cache_bool(ch, g->emit_llvm_ir); - cache_bool(ch, g->emit_asm); - cache_bool(ch, g->is_versioned); - cache_usize(ch, g->version_major); - cache_usize(ch, g->version_minor); - cache_usize(ch, g->version_patch); - cache_list_of_str(ch, g->llvm_argv, g->llvm_argv_len); - cache_list_of_str(ch, g->clang_argv, g->clang_argv_len); - cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length); - cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length); - if (g->libc) { - cache_slice(ch, Slice{g->libc->include_dir, g->libc->include_dir_len}); - cache_slice(ch, Slice{g->libc->sys_include_dir, g->libc->sys_include_dir_len}); - cache_slice(ch, Slice{g->libc->crt_dir, g->libc->crt_dir_len}); - cache_slice(ch, Slice{g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len}); - cache_slice(ch, Slice{g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len}); - } - cache_buf_opt(ch, g->version_script_path); - cache_buf_opt(ch, g->override_soname); - cache_buf_opt(ch, g->linker_optimization); - cache_int(ch, g->linker_gc_sections); - cache_int(ch, g->linker_allow_shlib_undefined); - cache_int(ch, g->linker_bind_global_refs_locally); - cache_bool(ch, g->linker_z_nodelete); - cache_bool(ch, g->linker_z_defs); - cache_usize(ch, g->stack_size_override); - - // gen_c_objects appends objects to g->link_objects which we want to include in the hash - gen_c_objects(g); - cache_list_of_file(ch, g->link_objects.items, g->link_objects.length); - - buf_resize(digest, 0); - if ((err = cache_hit(ch, digest))) { - if (err != ErrorInvalidFormat) - return err; - } - - if (ch->manifest_file_path != nullptr) { - g->caches_to_release.append(ch); - } - - return ErrorNone; -} - static void resolve_out_paths(CodeGen *g) { assert(g->output_dir != nullptr); assert(g->root_out_name != nullptr); if (g->emit_bin) { - Buf *out_basename = buf_create_from_buf(g->root_out_name); Buf *o_basename = buf_create_from_buf(g->root_out_name); - switch (g->out_type) { - case OutTypeUnknown: - zig_unreachable(); - case OutTypeObj: - if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache && - buf_eql_buf(o_basename, out_basename)) - { - // make it not collide with main output object - buf_append_str(o_basename, ".root"); - } - buf_append_str(o_basename, target_o_file_ext(g->zig_target)); - buf_append_str(out_basename, target_o_file_ext(g->zig_target)); - break; - case OutTypeExe: - buf_append_str(o_basename, target_o_file_ext(g->zig_target)); - buf_append_str(out_basename, target_exe_file_ext(g->zig_target)); - break; - case OutTypeLib: - buf_append_str(o_basename, target_o_file_ext(g->zig_target)); - buf_resize(out_basename, 0); - buf_append_str(out_basename, target_lib_file_prefix(g->zig_target)); - buf_append_buf(out_basename, g->root_out_name); - buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic, g->is_versioned, - g->version_major, g->version_minor, g->version_patch)); - break; - } + buf_append_str(o_basename, target_o_file_ext(g->zig_target)); os_path_join(g->output_dir, o_basename, &g->o_file_output_path); - os_path_join(g->output_dir, out_basename, &g->bin_file_output_path); } if (g->emit_asm) { Buf *asm_basename = buf_create_from_buf(g->root_out_name); @@ -10971,144 +9308,46 @@ static void output_type_information(CodeGen *g) { } } -static void init_output_dir(CodeGen *g, Buf *digest) { - if (main_output_dir_is_just_one_c_object_post(g)) { - g->output_dir = buf_alloc(); - os_path_dirname(g->link_objects.at(0), g->output_dir); - } else { - g->output_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s", - buf_ptr(g->cache_dir), buf_ptr(digest)); - } -} - -void codegen_build_and_link(CodeGen *g) { - Error err; - assert(g->out_type != OutTypeUnknown); - - if (!g->enable_cache) { - if (g->output_dir == nullptr) { - g->output_dir = buf_create_from_str("."); - } else if ((err = os_make_path(g->output_dir))) { - fprintf(stderr, "Unable to create output directory: %s\n", err_str(err)); - exit(1); - } - } +void codegen_build_object(CodeGen *g) { + assert(g->output_dir != nullptr); - g->have_dynamic_link = detect_dynamic_link(g); - g->have_pic = detect_pic(g); - g->is_single_threaded = detect_single_threaded(g); g->have_err_ret_tracing = detect_err_ret_tracing(g); - g->have_sanitize_c = detect_sanitize_c(g); - detect_libc(g); - - Buf digest = BUF_INIT; - if (g->enable_cache) { - Buf *manifest_dir = buf_alloc(); - os_path_join(g->cache_dir, buf_create_from_str(CACHE_HASH_SUBDIR), manifest_dir); - - if ((err = check_cache(g, manifest_dir, &digest))) { - if (err == ErrorCacheUnavailable) { - // message already printed - } else if (err == ErrorNotDir) { - fprintf(stderr, "Unable to check cache: %s is not a directory\n", - buf_ptr(manifest_dir)); - } else { - fprintf(stderr, "Unable to check cache: %s: %s\n", buf_ptr(manifest_dir), err_str(err)); - } - exit(1); - } - } else { - // There is a call to this in check_cache - gen_c_objects(g); - } - if (g->enable_cache && buf_len(&digest) != 0) { - init_output_dir(g, &digest); - resolve_out_paths(g); - } else { - if (need_llvm_module(g)) { - init(g); - - codegen_add_time_event(g, "Semantic Analysis"); - const char *progress_name = "Semantic Analysis"; - codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, - progress_name, strlen(progress_name), 0)); - - gen_root_source(g); - - } - if (g->enable_cache) { - if (buf_len(&digest) == 0) { - if ((err = cache_final(&g->cache_hash, &digest))) { - fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err)); - exit(1); - } - } - init_output_dir(g, &digest); + init(g); - if ((err = os_make_path(g->output_dir))) { - fprintf(stderr, "Unable to create output directory: %s\n", err_str(err)); - exit(1); - } - } - resolve_out_paths(g); + codegen_add_time_event(g, "Semantic Analysis"); + const char *progress_name = "Semantic Analysis"; + codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, + progress_name, strlen(progress_name), 0)); - if (g->enable_dump_analysis || g->enable_doc_generation) { - output_type_information(g); - } + gen_root_source(g); - if (need_llvm_module(g)) { - codegen_add_time_event(g, "Code Generation"); - { - const char *progress_name = "Code Generation"; - codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, - progress_name, strlen(progress_name), 0)); - } + resolve_out_paths(g); - do_code_gen(g); - codegen_add_time_event(g, "LLVM Emit Output"); - { - const char *progress_name = "LLVM Emit Output"; - codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, - progress_name, strlen(progress_name), 0)); - } - zig_llvm_emit_output(g); + if (g->enable_dump_analysis || g->enable_doc_generation) { + output_type_information(g); + } - if (!g->disable_gen_h && (g->out_type == OutTypeObj || g->out_type == OutTypeLib)) { - codegen_add_time_event(g, "Generate .h"); - { - const char *progress_name = "Generate .h"; - codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, - progress_name, strlen(progress_name), 0)); - } - gen_h_file(g); - } - } + codegen_add_time_event(g, "Code Generation"); + { + const char *progress_name = "Code Generation"; + codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, + progress_name, strlen(progress_name), 0)); + } - // If we're outputting assembly or llvm IR we skip linking. - // If we're making a library or executable we must link. - // If there is more than one object, we have to link them (with -r). - // Finally, if we didn't make an object from zig source, and we don't have caching enabled, - // then we have an object from C source that we must copy to the output dir which we do with a -r link. - if (g->emit_bin && - (g->out_type != OutTypeObj || g->link_objects.length > 1 || - (!need_llvm_module(g) && !g->enable_cache))) - { - codegen_link(g); - } + do_code_gen(g); + codegen_add_time_event(g, "LLVM Emit Output"); + { + const char *progress_name = "LLVM Emit Output"; + codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, + progress_name, strlen(progress_name), 0)); } + zig_llvm_emit_output(g); - codegen_release_caches(g); codegen_add_time_event(g, "Done"); codegen_switch_sub_prog_node(g, nullptr); } -void codegen_release_caches(CodeGen *g) { - while (g->caches_to_release.length != 0) { - cache_release(g->caches_to_release.pop()); - } -} - ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path, const char *pkg_path) { @@ -11125,43 +9364,17 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c return pkg; } -CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type, - Stage2LibCInstallation *libc, const char *name, Stage2ProgressNode *parent_progress_node) -{ - Stage2ProgressNode *child_progress_node = stage2_progress_start( - parent_progress_node ? parent_progress_node : parent_gen->sub_progress_node, - name, strlen(name), 0); - - CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type, - parent_gen->build_mode, parent_gen->zig_lib_dir, libc, get_global_cache_dir(), false, child_progress_node); - child_gen->root_out_name = buf_create_from_str(name); - child_gen->disable_gen_h = true; - child_gen->want_stack_check = WantStackCheckDisabled; - child_gen->want_sanitize_c = WantCSanitizeDisabled; - child_gen->verbose_tokenize = parent_gen->verbose_tokenize; - child_gen->verbose_ast = parent_gen->verbose_ast; - child_gen->verbose_link = parent_gen->verbose_link; - child_gen->verbose_ir = parent_gen->verbose_ir; - child_gen->verbose_llvm_ir = parent_gen->verbose_llvm_ir; - child_gen->verbose_cimport = parent_gen->verbose_cimport; - child_gen->verbose_cc = parent_gen->verbose_cc; - child_gen->verbose_llvm_cpu_features = parent_gen->verbose_llvm_cpu_features; - child_gen->llvm_argv = parent_gen->llvm_argv; - - codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); - child_gen->want_pic = parent_gen->have_pic ? WantPICEnabled : WantPICDisabled; - child_gen->valgrind_support = ValgrindSupportDisabled; - - codegen_set_errmsg_color(child_gen, parent_gen->err_color); - - child_gen->enable_cache = true; - - return child_gen; +void codegen_destroy(CodeGen *g) { + if (g->pass1_arena != nullptr) { + g->pass1_arena->destruct(&heap::c_allocator); + g->pass1_arena = nullptr; + } + heap::c_allocator.destroy(g); } CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, - OutType out_type, BuildMode build_mode, Buf *override_lib_dir, - Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node) + BuildMode build_mode, Buf *override_lib_dir, + bool is_test_build, Stage2ProgressNode *progress_node) { CodeGen *g = heap::c_allocator.create(); g->emit_bin = true; @@ -11176,24 +9389,15 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget } g->subsystem = TargetSubsystemAuto; - g->libc = libc; g->zig_target = target; - g->cache_dir = cache_dir; - if (override_lib_dir == nullptr) { - g->zig_lib_dir = get_zig_lib_dir(); - } else { - g->zig_lib_dir = override_lib_dir; - } + assert(override_lib_dir != nullptr); + g->zig_lib_dir = override_lib_dir; g->zig_std_dir = buf_alloc(); os_path_join(g->zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir); - g->zig_c_headers_dir = buf_alloc(); - os_path_join(g->zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir); - g->build_mode = build_mode; - g->out_type = out_type; g->import_table.init(32); g->builtin_fn_table.init(32); g->primitive_type_table.init(32); @@ -11256,18 +9460,6 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget g->zig_std_special_dir = buf_alloc(); os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir); - assert(target != nullptr); - if (!target->is_native_os) { - g->each_lib_rpath = false; - } else { - g->each_lib_rpath = true; - } - - if (target_os_requires_libc(g->zig_target->os)) { - g->libc_link_lib = create_link_lib(buf_create_from_str("c")); - g->link_libs_list.append(g->libc_link_lib); - } - target_triple_llvm(&g->llvm_triple_str, g->zig_target); g->pointer_size_bytes = target_arch_pointer_bit_width(g->zig_target->arch) / 8; @@ -11302,36 +9494,21 @@ void codegen_switch_sub_prog_node(CodeGen *g, Stage2ProgressNode *node) { } ZigValue *CodeGen::Intern::for_undefined() { -#ifdef ZIG_ENABLE_MEM_PROFILE - mem::intern_counters.x_undefined += 1; -#endif return &this->x_undefined; } ZigValue *CodeGen::Intern::for_void() { -#ifdef ZIG_ENABLE_MEM_PROFILE - mem::intern_counters.x_void += 1; -#endif return &this->x_void; } ZigValue *CodeGen::Intern::for_null() { -#ifdef ZIG_ENABLE_MEM_PROFILE - mem::intern_counters.x_null += 1; -#endif return &this->x_null; } ZigValue *CodeGen::Intern::for_unreachable() { -#ifdef ZIG_ENABLE_MEM_PROFILE - mem::intern_counters.x_unreachable += 1; -#endif return &this->x_unreachable; } ZigValue *CodeGen::Intern::for_zero_byte() { -#ifdef ZIG_ENABLE_MEM_PROFILE - mem::intern_counters.zero_byte += 1; -#endif return &this->zero_byte; } diff --git a/src/codegen.hpp b/src/codegen.hpp index 3139071d52..5b4317c992 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -16,47 +16,20 @@ #include CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, - OutType out_type, BuildMode build_mode, Buf *zig_lib_dir, - Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node); + BuildMode build_mode, Buf *zig_lib_dir, + bool is_test_build, Stage2ProgressNode *progress_node); -CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type, - Stage2LibCInstallation *libc, const char *name, Stage2ProgressNode *progress_node); +void codegen_build_object(CodeGen *g); +void codegen_destroy(CodeGen *); -void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); -void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len); -void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath); - -void codegen_set_strip(CodeGen *codegen, bool strip); -void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color); -void codegen_set_out_name(CodeGen *codegen, Buf *out_name); -void codegen_add_lib_dir(CodeGen *codegen, const char *dir); -void codegen_add_forbidden_lib(CodeGen *codegen, Buf *lib); -LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib); -void codegen_add_framework(CodeGen *codegen, const char *name); -void codegen_add_rpath(CodeGen *codegen, const char *name); -void codegen_set_rdynamic(CodeGen *g, bool rdynamic); -void codegen_set_linker_script(CodeGen *g, const char *linker_script); -void codegen_set_test_filter(CodeGen *g, Buf *filter); -void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); -void codegen_set_lib_version(CodeGen *g, bool is_versioned, size_t major, size_t minor, size_t patch); void codegen_add_time_event(CodeGen *g, const char *name); void codegen_print_timing_report(CodeGen *g, FILE *f); -void codegen_link(CodeGen *g); -void zig_link_add_compiler_rt(CodeGen *g, Stage2ProgressNode *progress_node); -void codegen_build_and_link(CodeGen *g); ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path, const char *pkg_path); -void codegen_add_assembly(CodeGen *g, Buf *path); -void codegen_add_object(CodeGen *g, Buf *object_path); - -void codegen_translate_c(CodeGen *g, Buf *full_path); - -Buf *codegen_generate_builtin_source(CodeGen *g); TargetSubsystem detect_subsystem(CodeGen *g); -void codegen_release_caches(CodeGen *codegen); bool codegen_fn_has_err_ret_tracing_arg(CodeGen *g, ZigType *return_type); bool codegen_fn_has_err_ret_tracing_stack(CodeGen *g, ZigFn *fn, bool is_async); diff --git a/src/compiler.cpp b/src/compiler.cpp deleted file mode 100644 index 6c477a1506..0000000000 --- a/src/compiler.cpp +++ /dev/null @@ -1,196 +0,0 @@ -#include "cache_hash.hpp" -#include "os.hpp" -#include "compiler.hpp" - -#include - -Error get_compiler_id(Buf **result) { - static Buf saved_compiler_id = BUF_INIT; - - if (saved_compiler_id.list.length != 0) { - *result = &saved_compiler_id; - return ErrorNone; - } - - Error err; - Buf *manifest_dir = buf_alloc(); - os_path_join(get_global_cache_dir(), buf_create_from_str("exe"), manifest_dir); - - CacheHash cache_hash; - CacheHash *ch = &cache_hash; - cache_init(ch, manifest_dir); - Buf self_exe_path = BUF_INIT; - if ((err = os_self_exe_path(&self_exe_path))) - return err; - - cache_file(ch, &self_exe_path); - - buf_resize(&saved_compiler_id, 0); - if ((err = cache_hit(ch, &saved_compiler_id))) { - if (err != ErrorInvalidFormat) - return err; - } - if (buf_len(&saved_compiler_id) != 0) { - cache_release(ch); - *result = &saved_compiler_id; - return ErrorNone; - } - ZigList lib_paths = {}; - if ((err = os_self_exe_shared_libs(lib_paths))) - return err; - #if defined(ZIG_OS_DARWIN) - // only add the self exe path on mac os - Buf *lib_path = lib_paths.at(0); - if ((err = cache_add_file(ch, lib_path))) - return err; - #else - for (size_t i = 0; i < lib_paths.length; i += 1) { - Buf *lib_path = lib_paths.at(i); - if ((err = cache_add_file(ch, lib_path))) - return err; - } - #endif - - if ((err = cache_final(ch, &saved_compiler_id))) - return err; - - cache_release(ch); - - *result = &saved_compiler_id; - return ErrorNone; -} - -static bool test_zig_install_prefix(Buf *test_path, Buf *out_zig_lib_dir) { - { - Buf *test_zig_dir = buf_sprintf("%s" OS_SEP "lib" OS_SEP "zig", buf_ptr(test_path)); - Buf *test_index_file = buf_sprintf("%s" OS_SEP "std" OS_SEP "std.zig", buf_ptr(test_zig_dir)); - int err; - bool exists; - if ((err = os_file_exists(test_index_file, &exists))) { - exists = false; - } - if (exists) { - buf_init_from_buf(out_zig_lib_dir, test_zig_dir); - return true; - } - } - - // Also try without "zig" - { - Buf *test_zig_dir = buf_sprintf("%s" OS_SEP "lib", buf_ptr(test_path)); - Buf *test_index_file = buf_sprintf("%s" OS_SEP "std" OS_SEP "std.zig", buf_ptr(test_zig_dir)); - int err; - bool exists; - if ((err = os_file_exists(test_index_file, &exists))) { - exists = false; - } - if (exists) { - buf_init_from_buf(out_zig_lib_dir, test_zig_dir); - return true; - } - } - - return false; -} - -static int find_zig_lib_dir(Buf *out_path) { - int err; - - Buf self_exe_path = BUF_INIT; - buf_resize(&self_exe_path, 0); - if (!(err = os_self_exe_path(&self_exe_path))) { - Buf *cur_path = &self_exe_path; - - for (;;) { - Buf *test_dir = buf_alloc(); - os_path_dirname(cur_path, test_dir); - - if (buf_eql_buf(test_dir, cur_path)) { - break; - } - - if (test_zig_install_prefix(test_dir, out_path)) { - return 0; - } - - cur_path = test_dir; - } - } - - return ErrorFileNotFound; -} - -Buf *get_zig_lib_dir(void) { - static Buf saved_lib_dir = BUF_INIT; - if (saved_lib_dir.list.length != 0) - return &saved_lib_dir; - buf_resize(&saved_lib_dir, 0); - - int err; - if ((err = find_zig_lib_dir(&saved_lib_dir))) { - fprintf(stderr, "Unable to find zig lib directory\n"); - exit(EXIT_FAILURE); - } - return &saved_lib_dir; -} - -Buf *get_zig_std_dir(Buf *zig_lib_dir) { - static Buf saved_std_dir = BUF_INIT; - if (saved_std_dir.list.length != 0) - return &saved_std_dir; - buf_resize(&saved_std_dir, 0); - - os_path_join(zig_lib_dir, buf_create_from_str("std"), &saved_std_dir); - - return &saved_std_dir; -} - -Buf *get_zig_special_dir(Buf *zig_lib_dir) { - static Buf saved_special_dir = BUF_INIT; - if (saved_special_dir.list.length != 0) - return &saved_special_dir; - buf_resize(&saved_special_dir, 0); - - os_path_join(get_zig_std_dir(zig_lib_dir), buf_sprintf("special"), &saved_special_dir); - - return &saved_special_dir; -} - -Buf *get_global_cache_dir(void) { - static Buf saved_global_cache_dir = BUF_INIT; - if (saved_global_cache_dir.list.length != 0) - return &saved_global_cache_dir; - buf_resize(&saved_global_cache_dir, 0); - - Buf app_data_dir = BUF_INIT; - Error err; - if ((err = os_get_app_data_dir(&app_data_dir, "zig"))) { - fprintf(stderr, "Unable to get application data dir: %s\n", err_str(err)); - exit(1); - } - os_path_join(&app_data_dir, buf_create_from_str("stage1"), &saved_global_cache_dir); - buf_deinit(&app_data_dir); - return &saved_global_cache_dir; -} - -FileExt classify_file_ext(const char *filename_ptr, size_t filename_len) { - if (mem_ends_with_str(filename_ptr, filename_len, ".c")) { - return FileExtC; - } else if (mem_ends_with_str(filename_ptr, filename_len, ".C") || - mem_ends_with_str(filename_ptr, filename_len, ".cc") || - mem_ends_with_str(filename_ptr, filename_len, ".cpp") || - mem_ends_with_str(filename_ptr, filename_len, ".cxx")) - { - return FileExtCpp; - } else if (mem_ends_with_str(filename_ptr, filename_len, ".ll")) { - return FileExtLLVMIr; - } else if (mem_ends_with_str(filename_ptr, filename_len, ".bc")) { - return FileExtLLVMBitCode; - } else if (mem_ends_with_str(filename_ptr, filename_len, ".s") || - mem_ends_with_str(filename_ptr, filename_len, ".S")) - { - return FileExtAsm; - } - // TODO look for .so, .so.X, .so.X.Y, .so.X.Y.Z - return FileExtUnknown; -} diff --git a/src/compiler.hpp b/src/compiler.hpp deleted file mode 100644 index ae2e6e9c5e..0000000000 --- a/src/compiler.hpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2018 Andrew Kelley - * - * This file is part of zig, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#ifndef ZIG_COMPILER_HPP -#define ZIG_COMPILER_HPP - -#include "all_types.hpp" - -Error get_compiler_id(Buf **result); - -Buf *get_zig_lib_dir(void); -Buf *get_zig_special_dir(Buf *zig_lib_dir); -Buf *get_zig_std_dir(Buf *zig_lib_dir); - -Buf *get_global_cache_dir(void); - - -FileExt classify_file_ext(const char *filename_ptr, size_t filename_len); - -#endif diff --git a/src/config.h.in b/src/config.h.in index 2ec6c25b38..8c147e7d65 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -22,6 +22,4 @@ #define ZIG_LLVM_CONFIG_EXE "@LLVM_CONFIG_EXE@" #define ZIG_DIA_GUIDS_LIB "@ZIG_DIA_GUIDS_LIB_ESCAPED@" -#cmakedefine ZIG_ENABLE_MEM_PROFILE - #endif diff --git a/src/config.zig.in b/src/config.zig.in index a44149111e..9e574bc1e8 100644 --- a/src/config.zig.in +++ b/src/config.zig.in @@ -3,3 +3,4 @@ pub const version: []const u8 = "@ZIG_VERSION@"; pub const log_scopes: []const []const u8 = &[_][]const u8{}; pub const zir_dumps: []const []const u8 = &[_][]const u8{}; pub const enable_tracy = false; +pub const is_stage1 = true; diff --git a/src/dump_analysis.cpp b/src/dump_analysis.cpp index 2f41341b14..df0d6f3ca2 100644 --- a/src/dump_analysis.cpp +++ b/src/dump_analysis.cpp @@ -6,11 +6,11 @@ */ #include "dump_analysis.hpp" -#include "compiler.hpp" #include "analyze.hpp" #include "config.h" #include "ir.hpp" #include "codegen.hpp" +#include "os.hpp" enum JsonWriterState { JsonWriterStateInvalid, @@ -1173,7 +1173,6 @@ static void anal_dump_fn(AnalDumpCtx *ctx, ZigFn *fn) { } void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const char *nl) { - Error err; AnalDumpCtx ctx = {}; ctx.g = g; JsonWriter *jw = &ctx.jw; @@ -1199,15 +1198,6 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const jw_object_field(jw, "params"); jw_begin_object(jw); { - jw_object_field(jw, "zigId"); - - Buf *compiler_id; - if ((err = get_compiler_id(&compiler_id))) { - fprintf(stderr, "Unable to determine compiler id: %s\n", err_str(err)); - exit(1); - } - jw_string(jw, buf_ptr(compiler_id)); - jw_object_field(jw, "zigVersion"); jw_string(jw, ZIG_VERSION_STRING); diff --git a/src/empty.cpp b/src/empty.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/errmsg.hpp b/src/errmsg.hpp index e8b2f5872d..73cbd4e0d9 100644 --- a/src/errmsg.hpp +++ b/src/errmsg.hpp @@ -10,12 +10,7 @@ #include "buffer.hpp" #include "list.hpp" - -enum ErrColor { - ErrColorAuto, - ErrColorOff, - ErrColorOn, -}; +#include "stage1.h" struct ErrorMsg { size_t line_start; diff --git a/src/glibc.cpp b/src/glibc.cpp deleted file mode 100644 index 62f5604ba7..0000000000 --- a/src/glibc.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (c) 2019 Andrew Kelley - * - * This file is part of zig, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#include "glibc.hpp" -#include "compiler.hpp" -#include "cache_hash.hpp" -#include "codegen.hpp" - -static const ZigGLibCLib glibc_libs[] = { - {"c", 6}, - {"m", 6}, - {"pthread", 0}, - {"dl", 2}, - {"rt", 1}, - {"ld", 2}, - {"util", 1}, -}; - -Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbose) { - Error err; - - ZigGLibCAbi *glibc_abi = heap::c_allocator.create(); - glibc_abi->vers_txt_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "glibc" OS_SEP "vers.txt", buf_ptr(zig_lib_dir)); - glibc_abi->fns_txt_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "glibc" OS_SEP "fns.txt", buf_ptr(zig_lib_dir)); - glibc_abi->abi_txt_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "glibc" OS_SEP "abi.txt", buf_ptr(zig_lib_dir)); - glibc_abi->version_table.init(16); - - Buf *vers_txt_contents = buf_alloc(); - if ((err = os_fetch_file_path(glibc_abi->vers_txt_path, vers_txt_contents))) { - if (verbose) { - fprintf(stderr, "Unable to read %s: %s\n", buf_ptr(glibc_abi->vers_txt_path), err_str(err)); - } - return err; - } - Buf *fns_txt_contents = buf_alloc(); - if ((err = os_fetch_file_path(glibc_abi->fns_txt_path, fns_txt_contents))) { - if (verbose) { - fprintf(stderr, "Unable to read %s: %s\n", buf_ptr(glibc_abi->fns_txt_path), err_str(err)); - } - return err; - } - Buf *abi_txt_contents = buf_alloc(); - if ((err = os_fetch_file_path(glibc_abi->abi_txt_path, abi_txt_contents))) { - if (verbose) { - fprintf(stderr, "Unable to read %s: %s\n", buf_ptr(glibc_abi->abi_txt_path), err_str(err)); - } - return err; - } - - { - SplitIterator it = memSplit(buf_to_slice(vers_txt_contents), str("\r\n")); - for (;;) { - Optional> opt_component = SplitIterator_next(&it); - if (!opt_component.is_some) break; - Buf *ver_buf = buf_create_from_slice(opt_component.value); - Stage2SemVer *this_ver = glibc_abi->all_versions.add_one(); - if ((err = target_parse_glibc_version(this_ver, buf_ptr(ver_buf)))) { - if (verbose) { - fprintf(stderr, "Unable to parse glibc version '%s': %s\n", buf_ptr(ver_buf), err_str(err)); - } - return err; - } - } - } - { - SplitIterator it = memSplit(buf_to_slice(fns_txt_contents), str("\r\n")); - for (;;) { - Optional> opt_component = SplitIterator_next(&it); - if (!opt_component.is_some) break; - SplitIterator line_it = memSplit(opt_component.value, str(" ")); - Optional> opt_fn_name = SplitIterator_next(&line_it); - if (!opt_fn_name.is_some) { - if (verbose) { - fprintf(stderr, "%s: Expected function name\n", buf_ptr(glibc_abi->fns_txt_path)); - } - return ErrorInvalidFormat; - } - Optional> opt_lib_name = SplitIterator_next(&line_it); - if (!opt_lib_name.is_some) { - if (verbose) { - fprintf(stderr, "%s: Expected lib name\n", buf_ptr(glibc_abi->fns_txt_path)); - } - return ErrorInvalidFormat; - } - - Buf *this_fn_name = buf_create_from_slice(opt_fn_name.value); - Buf *this_lib_name = buf_create_from_slice(opt_lib_name.value); - glibc_abi->all_functions.append({ this_fn_name, glibc_lib_find(buf_ptr(this_lib_name)) }); - } - } - { - SplitIterator it = memSplit(buf_to_slice(abi_txt_contents), str("\r\n")); - ZigGLibCVerList *ver_list_base = nullptr; - int line_num = 0; - for (;;) { - if (ver_list_base == nullptr) { - line_num += 1; - Optional> opt_line = SplitIterator_next_separate(&it); - if (!opt_line.is_some) break; - - ver_list_base = heap::c_allocator.allocate(glibc_abi->all_functions.length); - SplitIterator line_it = memSplit(opt_line.value, str(" ")); - for (;;) { - ZigTarget *target = heap::c_allocator.create(); - Optional> opt_target = SplitIterator_next(&line_it); - if (!opt_target.is_some) break; - - SplitIterator component_it = memSplit(opt_target.value, str("-")); - Optional> opt_arch = SplitIterator_next(&component_it); - assert(opt_arch.is_some); - Optional> opt_os = SplitIterator_next(&component_it); - assert(opt_os.is_some); // it's always "linux" so we ignore it - Optional> opt_abi = SplitIterator_next(&component_it); - assert(opt_abi.is_some); - - - err = target_parse_arch(&target->arch, (char*)opt_arch.value.ptr, opt_arch.value.len); - assert(err == ErrorNone); - - target->os = OsLinux; - - err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len); - if (err != ErrorNone) { - fprintf(stderr, "Error parsing %s:%d: %s\n", buf_ptr(glibc_abi->abi_txt_path), - line_num, err_str(err)); - fprintf(stderr, "arch: '%.*s', os: '%.*s', abi: '%.*s'\n", - (int)opt_arch.value.len, (const char*)opt_arch.value.ptr, - (int)opt_os.value.len, (const char*)opt_os.value.ptr, - (int)opt_abi.value.len, (const char*)opt_abi.value.ptr); - fprintf(stderr, "parsed from target: '%.*s'\n", - (int)opt_target.value.len, (const char*)opt_target.value.ptr); - fprintf(stderr, "parsed from line:\n%.*s\n", (int)opt_line.value.len, opt_line.value.ptr); - fprintf(stderr, "Zig installation appears to be corrupted.\n"); - exit(1); - } - - glibc_abi->version_table.put(target, ver_list_base); - } - continue; - } - for (size_t fn_i = 0; fn_i < glibc_abi->all_functions.length; fn_i += 1) { - ZigGLibCVerList *ver_list = &ver_list_base[fn_i]; - line_num += 1; - Optional> opt_line = SplitIterator_next_separate(&it); - assert(opt_line.is_some); - - SplitIterator line_it = memSplit(opt_line.value, str(" ")); - for (;;) { - Optional> opt_ver = SplitIterator_next(&line_it); - if (!opt_ver.is_some) break; - assert(ver_list->len < 8); // increase the array len in the type - - unsigned long ver_index = strtoul(buf_ptr(buf_create_from_slice(opt_ver.value)), nullptr, 10); - assert(ver_index < 255); // use a bigger integer in the type - ver_list->versions[ver_list->len] = ver_index; - ver_list->len += 1; - } - } - ver_list_base = nullptr; - } - } - - *out_result = glibc_abi; - return ErrorNone; -} - -Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, const ZigTarget *target, - Buf **out_dir, bool verbose, Stage2ProgressNode *progress_node) -{ - Error err; - - Buf *cache_dir = get_global_cache_dir(); - CacheHash *cache_hash = heap::c_allocator.create(); - Buf *manifest_dir = buf_sprintf("%s" OS_SEP CACHE_HASH_SUBDIR, buf_ptr(cache_dir)); - cache_init(cache_hash, manifest_dir); - - Buf *compiler_id; - if ((err = get_compiler_id(&compiler_id))) { - if (verbose) { - fprintf(stderr, "unable to get compiler id: %s\n", err_str(err)); - } - return err; - } - cache_buf(cache_hash, compiler_id); - cache_int(cache_hash, target->arch); - cache_int(cache_hash, target->abi); - cache_int(cache_hash, target->glibc_or_darwin_version->major); - cache_int(cache_hash, target->glibc_or_darwin_version->minor); - cache_int(cache_hash, target->glibc_or_darwin_version->patch); - - Buf digest = BUF_INIT; - buf_resize(&digest, 0); - if ((err = cache_hit(cache_hash, &digest))) { - // Treat an invalid format error as a cache miss. - if (err != ErrorInvalidFormat) - return err; - } - // We should always get a cache hit because there are no - // files in the input hash. - assert(buf_len(&digest) != 0); - - Buf *dummy_dir = buf_alloc(); - os_path_join(manifest_dir, &digest, dummy_dir); - - if ((err = os_make_path(dummy_dir))) - return err; - - Buf *test_if_exists_path = buf_alloc(); - os_path_join(dummy_dir, buf_create_from_str("ok"), test_if_exists_path); - - bool hit; - if ((err = os_file_exists(test_if_exists_path, &hit))) - return err; - - if (hit) { - *out_dir = dummy_dir; - return ErrorNone; - } - - - ZigGLibCVerList *ver_list_base = glibc_abi->version_table.get(target); - - uint8_t target_ver_index = 0; - for (;target_ver_index < glibc_abi->all_versions.length; target_ver_index += 1) { - const Stage2SemVer *this_ver = &glibc_abi->all_versions.at(target_ver_index); - if (this_ver->major == target->glibc_or_darwin_version->major && - this_ver->minor == target->glibc_or_darwin_version->minor && - this_ver->patch == target->glibc_or_darwin_version->patch) - { - break; - } - } - if (target_ver_index == glibc_abi->all_versions.length) { - if (verbose) { - fprintf(stderr, "Unrecognized glibc version: %d.%d.%d\n", - target->glibc_or_darwin_version->major, - target->glibc_or_darwin_version->minor, - target->glibc_or_darwin_version->patch); - } - return ErrorUnknownABI; - } - - Buf *map_file_path = buf_sprintf("%s" OS_SEP "all.map", buf_ptr(dummy_dir)); - Buf *map_contents = buf_alloc(); - - for (uint8_t ver_i = 0; ver_i < glibc_abi->all_versions.length; ver_i += 1) { - const Stage2SemVer *ver = &glibc_abi->all_versions.at(ver_i); - if (ver->patch == 0) { - buf_appendf(map_contents, "GLIBC_%d.%d { };\n", ver->major, ver->minor); - } else { - buf_appendf(map_contents, "GLIBC_%d.%d.%d { };\n", ver->major, ver->minor, ver->patch); - } - } - - if ((err = os_write_file(map_file_path, map_contents))) { - if (verbose) { - fprintf(stderr, "unable to write %s: %s", buf_ptr(map_file_path), err_str(err)); - } - return err; - } - - - for (size_t lib_i = 0; lib_i < array_length(glibc_libs); lib_i += 1) { - const ZigGLibCLib *lib = &glibc_libs[lib_i]; - Buf *zig_file_path = buf_sprintf("%s" OS_SEP "%s.zig", buf_ptr(dummy_dir), lib->name); - Buf *zig_body = buf_alloc(); - Buf *zig_footer = buf_alloc(); - - buf_appendf(zig_body, "comptime {\n"); - buf_appendf(zig_body, " asm (\n"); - - for (size_t fn_i = 0; fn_i < glibc_abi->all_functions.length; fn_i += 1) { - const ZigGLibCFn *libc_fn = &glibc_abi->all_functions.at(fn_i); - if (libc_fn->lib != lib) continue; - ZigGLibCVerList *ver_list = &ver_list_base[fn_i]; - // Pick the default symbol version: - // - If there are no versions, don't emit it - // - Take the greatest one <= than the target one - // - If none of them is <= than the - // specified one don't pick any default version - if (ver_list->len == 0) continue; - uint8_t chosen_def_ver_index = 255; - for (uint8_t ver_i = 0; ver_i < ver_list->len; ver_i += 1) { - uint8_t ver_index = ver_list->versions[ver_i]; - if ((chosen_def_ver_index == 255 || ver_index > chosen_def_ver_index) && - target_ver_index >= ver_index) - { - chosen_def_ver_index = ver_index; - } - } - for (uint8_t ver_i = 0; ver_i < ver_list->len; ver_i += 1) { - uint8_t ver_index = ver_list->versions[ver_i]; - - Buf *stub_name; - const Stage2SemVer *ver = &glibc_abi->all_versions.at(ver_index); - const char *sym_name = buf_ptr(libc_fn->name); - if (ver->patch == 0) { - stub_name = buf_sprintf("%s_%d_%d", sym_name, ver->major, ver->minor); - } else { - stub_name = buf_sprintf("%s_%d_%d_%d", sym_name, ver->major, ver->minor, ver->patch); - } - - buf_appendf(zig_footer, "export fn %s() void {}\n", buf_ptr(stub_name)); - - // Default symbol version definition vs normal symbol version definition - const char *at_sign_str = (chosen_def_ver_index != 255 && - ver_index == chosen_def_ver_index) ? "@@" : "@"; - if (ver->patch == 0) { - buf_appendf(zig_body, " \\\\ .symver %s, %s%sGLIBC_%d.%d\n", - buf_ptr(stub_name), sym_name, at_sign_str, ver->major, ver->minor); - } else { - buf_appendf(zig_body, " \\\\ .symver %s, %s%sGLIBC_%d.%d.%d\n", - buf_ptr(stub_name), sym_name, at_sign_str, ver->major, ver->minor, ver->patch); - } - // Hide the stub to keep the symbol table clean - buf_appendf(zig_body, " \\\\ .hidden %s\n", buf_ptr(stub_name)); - } - } - - buf_appendf(zig_body, " );\n"); - buf_appendf(zig_body, "}\n"); - buf_append_buf(zig_body, zig_footer); - - if ((err = os_write_file(zig_file_path, zig_body))) { - if (verbose) { - fprintf(stderr, "unable to write %s: %s", buf_ptr(zig_file_path), err_str(err)); - } - return err; - } - - bool is_ld = (strcmp(lib->name, "ld") == 0); - - CodeGen *child_gen = create_child_codegen(g, zig_file_path, OutTypeLib, nullptr, lib->name, progress_node); - codegen_set_lib_version(child_gen, true, lib->sover, 0, 0); - child_gen->is_dynamic = true; - child_gen->is_dummy_so = true; - child_gen->version_script_path = map_file_path; - child_gen->enable_cache = false; - child_gen->output_dir = dummy_dir; - if (is_ld) { - assert(g->zig_target->standard_dynamic_linker_path != nullptr); - Buf *ld_basename = buf_alloc(); - os_path_split(buf_create_from_str(g->zig_target->standard_dynamic_linker_path), - nullptr, ld_basename); - child_gen->override_soname = ld_basename; - } - codegen_build_and_link(child_gen); - } - - if ((err = os_write_file(test_if_exists_path, buf_alloc()))) { - if (verbose) { - fprintf(stderr, "unable to write %s: %s", buf_ptr(test_if_exists_path), err_str(err)); - } - return err; - } - *out_dir = dummy_dir; - return ErrorNone; -} - -uint32_t hash_glibc_target(const ZigTarget *x) { - return x->arch * (uint32_t)3250106448 + - x->os * (uint32_t)542534372 + - x->abi * (uint32_t)59162639; -} - -bool eql_glibc_target(const ZigTarget *a, const ZigTarget *b) { - return a->arch == b->arch && - a->os == b->os && - a->abi == b->abi; -} - -size_t glibc_lib_count(void) { - return array_length(glibc_libs); -} - -const ZigGLibCLib *glibc_lib_enum(size_t index) { - assert(index < array_length(glibc_libs)); - return &glibc_libs[index]; -} - -const ZigGLibCLib *glibc_lib_find(const char *name) { - for (size_t i = 0; i < array_length(glibc_libs); i += 1) { - if (strcmp(glibc_libs[i].name, name) == 0) { - return &glibc_libs[i]; - } - } - return nullptr; -} diff --git a/src/glibc.hpp b/src/glibc.hpp deleted file mode 100644 index c04dcb4629..0000000000 --- a/src/glibc.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019 Andrew Kelley - * - * This file is part of zig, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#ifndef ZIG_GLIBC_HPP -#define ZIG_GLIBC_HPP - -#include "all_types.hpp" - -struct ZigGLibCLib { - const char *name; - uint8_t sover; -}; - -struct ZigGLibCFn { - Buf *name; - const ZigGLibCLib *lib; -}; - -struct ZigGLibCVerList { - uint8_t versions[8]; // 8 is just the max number, we know statically it's big enough - uint8_t len; -}; - -uint32_t hash_glibc_target(const ZigTarget *x); -bool eql_glibc_target(const ZigTarget *a, const ZigTarget *b); - -struct ZigGLibCAbi { - Buf *abi_txt_path; - Buf *vers_txt_path; - Buf *fns_txt_path; - ZigList all_versions; - ZigList all_functions; - // The value is a pointer to all_functions.length items and each item is an index - // into all_functions. - HashMap version_table; -}; - -Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbose); -Error glibc_build_dummies_and_maps(CodeGen *codegen, const ZigGLibCAbi *glibc_abi, const ZigTarget *target, - Buf **out_dir, bool verbose, Stage2ProgressNode *progress_node); - -size_t glibc_lib_count(void); -const ZigGLibCLib *glibc_lib_enum(size_t index); -const ZigGLibCLib *glibc_lib_find(const char *name); - -#endif diff --git a/src/heap.cpp b/src/heap.cpp index 79c44d13dc..7e7a171bde 100644 --- a/src/heap.cpp +++ b/src/heap.cpp @@ -10,7 +10,6 @@ #include "config.h" #include "heap.hpp" -#include "mem_profile.hpp" namespace heap { @@ -48,21 +47,9 @@ void BootstrapAllocator::internal_deallocate(const mem::TypeInfo &info, void *pt mem::os::free(ptr); } -void CAllocator::init(const char *name) { -#ifdef ZIG_ENABLE_MEM_PROFILE - this->profile = bootstrap_allocator.create(); - this->profile->init(name, "CAllocator"); -#endif -} +void CAllocator::init(const char *name) { } -void CAllocator::deinit() { -#ifdef ZIG_ENABLE_MEM_PROFILE - assert(this->profile); - this->profile->deinit(); - bootstrap_allocator.destroy(this->profile); - this->profile = nullptr; -#endif -} +void CAllocator::deinit() { } CAllocator *CAllocator::construct(mem::Allocator *allocator, const char *name) { auto p = new(allocator->create()) CAllocator(); @@ -75,23 +62,11 @@ void CAllocator::destruct(mem::Allocator *allocator) { allocator->destroy(this); } -#ifdef ZIG_ENABLE_MEM_PROFILE -void CAllocator::print_report(FILE *file) { - this->profile->print_report(file); -} -#endif - void *CAllocator::internal_allocate(const mem::TypeInfo &info, size_t count) { -#ifdef ZIG_ENABLE_MEM_PROFILE - this->profile->record_alloc(info, count); -#endif return mem::os::calloc(count, info.size); } void *CAllocator::internal_allocate_nonzero(const mem::TypeInfo &info, size_t count) { -#ifdef ZIG_ENABLE_MEM_PROFILE - this->profile->record_alloc(info, count); -#endif return mem::os::malloc(count * info.size); } @@ -103,17 +78,10 @@ void *CAllocator::internal_reallocate(const mem::TypeInfo &info, void *old_ptr, } void *CAllocator::internal_reallocate_nonzero(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) { -#ifdef ZIG_ENABLE_MEM_PROFILE - this->profile->record_dealloc(info, old_count); - this->profile->record_alloc(info, new_count); -#endif return mem::os::realloc(old_ptr, new_count * info.size); } void CAllocator::internal_deallocate(const mem::TypeInfo &info, void *ptr, size_t count) { -#ifdef ZIG_ENABLE_MEM_PROFILE - this->profile->record_dealloc(info, count); -#endif mem::os::free(ptr); } @@ -249,10 +217,6 @@ void ArenaAllocator::Impl::track_object(Object object) { } void ArenaAllocator::init(Allocator *backing, const char *name) { -#ifdef ZIG_ENABLE_MEM_PROFILE - this->profile = bootstrap_allocator.create(); - this->profile->init(name, "ArenaAllocator"); -#endif this->impl = bootstrap_allocator.create(); { auto &r = *this->impl; @@ -309,13 +273,6 @@ void ArenaAllocator::deinit() { t = prev; } } - -#ifdef ZIG_ENABLE_MEM_PROFILE - assert(this->profile); - this->profile->deinit(); - bootstrap_allocator.destroy(this->profile); - this->profile = nullptr; -#endif } ArenaAllocator *ArenaAllocator::construct(mem::Allocator *allocator, mem::Allocator *backing, const char *name) { @@ -329,23 +286,11 @@ void ArenaAllocator::destruct(mem::Allocator *allocator) { allocator->destroy(this); } -#ifdef ZIG_ENABLE_MEM_PROFILE -void ArenaAllocator::print_report(FILE *file) { - this->profile->print_report(file); -} -#endif - void *ArenaAllocator::internal_allocate(const mem::TypeInfo &info, size_t count) { -#ifdef ZIG_ENABLE_MEM_PROFILE - this->profile->record_alloc(info, count); -#endif return this->impl->allocate(info, count); } void *ArenaAllocator::internal_allocate_nonzero(const mem::TypeInfo &info, size_t count) { -#ifdef ZIG_ENABLE_MEM_PROFILE - this->profile->record_alloc(info, count); -#endif return this->impl->allocate(info, count); } @@ -354,17 +299,10 @@ void *ArenaAllocator::internal_reallocate(const mem::TypeInfo &info, void *old_p } void *ArenaAllocator::internal_reallocate_nonzero(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) { -#ifdef ZIG_ENABLE_MEM_PROFILE - this->profile->record_dealloc(info, old_count); - this->profile->record_alloc(info, new_count); -#endif return this->impl->reallocate(info, old_ptr, old_count, new_count); } void ArenaAllocator::internal_deallocate(const mem::TypeInfo &info, void *ptr, size_t count) { -#ifdef ZIG_ENABLE_MEM_PROFILE - this->profile->record_dealloc(info, count); -#endif // noop } diff --git a/src/heap.hpp b/src/heap.hpp index e22ec42967..ec5c81026d 100644 --- a/src/heap.hpp +++ b/src/heap.hpp @@ -12,12 +12,6 @@ #include "util_base.hpp" #include "mem.hpp" -#ifdef ZIG_ENABLE_MEM_PROFILE -namespace mem { - struct Profile; -} -#endif - namespace heap { struct BootstrapAllocator final : mem::Allocator { @@ -40,9 +34,6 @@ struct CAllocator final : mem::Allocator { static CAllocator *construct(mem::Allocator *allocator, const char *name); void destruct(mem::Allocator *allocator) final; -#ifdef ZIG_ENABLE_MEM_PROFILE - void print_report(FILE *file = nullptr); -#endif private: ATTRIBUTE_RETURNS_NOALIAS void *internal_allocate(const mem::TypeInfo &info, size_t count) final; @@ -51,9 +42,6 @@ private: void *internal_reallocate_nonzero(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) final; void internal_deallocate(const mem::TypeInfo &info, void *ptr, size_t count) final; -#ifdef ZIG_ENABLE_MEM_PROFILE - mem::Profile *profile; -#endif }; // @@ -71,9 +59,6 @@ struct ArenaAllocator final : mem::Allocator { static ArenaAllocator *construct(mem::Allocator *allocator, mem::Allocator *backing, const char *name); void destruct(mem::Allocator *allocator) final; -#ifdef ZIG_ENABLE_MEM_PROFILE - void print_report(FILE *file = nullptr); -#endif private: ATTRIBUTE_RETURNS_NOALIAS void *internal_allocate(const mem::TypeInfo &info, size_t count) final; @@ -82,10 +67,6 @@ private: void *internal_reallocate_nonzero(const mem::TypeInfo &info, void *old_ptr, size_t old_count, size_t new_count) final; void internal_deallocate(const mem::TypeInfo &info, void *ptr, size_t count) final; -#ifdef ZIG_ENABLE_MEM_PROFILE - mem::Profile *profile; -#endif - struct Impl; Impl *impl; }; diff --git a/src/install_files.h b/src/install_files.h deleted file mode 100644 index 8e7431145e..0000000000 --- a/src/install_files.h +++ /dev/null @@ -1,1907 +0,0 @@ -#ifndef ZIG_INSTALL_FILES_H -#define ZIG_INSTALL_FILES_H -static const char *ZIG_MUSL_SRC_FILES[] = { -"musl/src/aio/aio.c", -"musl/src/aio/aio_suspend.c", -"musl/src/aio/lio_listio.c", -"musl/src/complex/__cexp.c", -"musl/src/complex/__cexpf.c", -"musl/src/complex/cabs.c", -"musl/src/complex/cabsf.c", -"musl/src/complex/cabsl.c", -"musl/src/complex/cacos.c", -"musl/src/complex/cacosf.c", -"musl/src/complex/cacosh.c", -"musl/src/complex/cacoshf.c", -"musl/src/complex/cacoshl.c", -"musl/src/complex/cacosl.c", -"musl/src/complex/carg.c", -"musl/src/complex/cargf.c", -"musl/src/complex/cargl.c", -"musl/src/complex/casin.c", -"musl/src/complex/casinf.c", -"musl/src/complex/casinh.c", -"musl/src/complex/casinhf.c", -"musl/src/complex/casinhl.c", -"musl/src/complex/casinl.c", -"musl/src/complex/catan.c", -"musl/src/complex/catanf.c", -"musl/src/complex/catanh.c", -"musl/src/complex/catanhf.c", -"musl/src/complex/catanhl.c", -"musl/src/complex/catanl.c", -"musl/src/complex/ccos.c", -"musl/src/complex/ccosf.c", -"musl/src/complex/ccosh.c", -"musl/src/complex/ccoshf.c", -"musl/src/complex/ccoshl.c", -"musl/src/complex/ccosl.c", -"musl/src/complex/cexp.c", -"musl/src/complex/cexpf.c", -"musl/src/complex/cexpl.c", -"musl/src/complex/cimag.c", -"musl/src/complex/cimagf.c", -"musl/src/complex/cimagl.c", -"musl/src/complex/clog.c", -"musl/src/complex/clogf.c", -"musl/src/complex/clogl.c", -"musl/src/complex/conj.c", -"musl/src/complex/conjf.c", -"musl/src/complex/conjl.c", -"musl/src/complex/cpow.c", -"musl/src/complex/cpowf.c", -"musl/src/complex/cpowl.c", -"musl/src/complex/cproj.c", -"musl/src/complex/cprojf.c", -"musl/src/complex/cprojl.c", -"musl/src/complex/creal.c", -"musl/src/complex/crealf.c", -"musl/src/complex/creall.c", -"musl/src/complex/csin.c", -"musl/src/complex/csinf.c", -"musl/src/complex/csinh.c", -"musl/src/complex/csinhf.c", -"musl/src/complex/csinhl.c", -"musl/src/complex/csinl.c", -"musl/src/complex/csqrt.c", -"musl/src/complex/csqrtf.c", -"musl/src/complex/csqrtl.c", -"musl/src/complex/ctan.c", -"musl/src/complex/ctanf.c", -"musl/src/complex/ctanh.c", -"musl/src/complex/ctanhf.c", -"musl/src/complex/ctanhl.c", -"musl/src/complex/ctanl.c", -"musl/src/conf/confstr.c", -"musl/src/conf/fpathconf.c", -"musl/src/conf/legacy.c", -"musl/src/conf/pathconf.c", -"musl/src/conf/sysconf.c", -"musl/src/crypt/crypt.c", -"musl/src/crypt/crypt_blowfish.c", -"musl/src/crypt/crypt_des.c", -"musl/src/crypt/crypt_md5.c", -"musl/src/crypt/crypt_r.c", -"musl/src/crypt/crypt_sha256.c", -"musl/src/crypt/crypt_sha512.c", -"musl/src/crypt/encrypt.c", -"musl/src/ctype/__ctype_b_loc.c", -"musl/src/ctype/__ctype_get_mb_cur_max.c", -"musl/src/ctype/__ctype_tolower_loc.c", -"musl/src/ctype/__ctype_toupper_loc.c", -"musl/src/ctype/isalnum.c", -"musl/src/ctype/isalpha.c", -"musl/src/ctype/isascii.c", -"musl/src/ctype/isblank.c", -"musl/src/ctype/iscntrl.c", -"musl/src/ctype/isdigit.c", -"musl/src/ctype/isgraph.c", -"musl/src/ctype/islower.c", -"musl/src/ctype/isprint.c", -"musl/src/ctype/ispunct.c", -"musl/src/ctype/isspace.c", -"musl/src/ctype/isupper.c", -"musl/src/ctype/iswalnum.c", -"musl/src/ctype/iswalpha.c", -"musl/src/ctype/iswblank.c", -"musl/src/ctype/iswcntrl.c", -"musl/src/ctype/iswctype.c", -"musl/src/ctype/iswdigit.c", -"musl/src/ctype/iswgraph.c", -"musl/src/ctype/iswlower.c", -"musl/src/ctype/iswprint.c", -"musl/src/ctype/iswpunct.c", -"musl/src/ctype/iswspace.c", -"musl/src/ctype/iswupper.c", -"musl/src/ctype/iswxdigit.c", -"musl/src/ctype/isxdigit.c", -"musl/src/ctype/toascii.c", -"musl/src/ctype/tolower.c", -"musl/src/ctype/toupper.c", -"musl/src/ctype/towctrans.c", -"musl/src/ctype/wcswidth.c", -"musl/src/ctype/wctrans.c", -"musl/src/ctype/wcwidth.c", -"musl/src/dirent/alphasort.c", -"musl/src/dirent/closedir.c", -"musl/src/dirent/dirfd.c", -"musl/src/dirent/fdopendir.c", -"musl/src/dirent/opendir.c", -"musl/src/dirent/readdir.c", -"musl/src/dirent/readdir_r.c", -"musl/src/dirent/rewinddir.c", -"musl/src/dirent/scandir.c", -"musl/src/dirent/seekdir.c", -"musl/src/dirent/telldir.c", -"musl/src/dirent/versionsort.c", -"musl/src/env/__environ.c", -"musl/src/env/__init_tls.c", -"musl/src/env/__libc_start_main.c", -"musl/src/env/__reset_tls.c", -"musl/src/env/__stack_chk_fail.c", -"musl/src/env/clearenv.c", -"musl/src/env/getenv.c", -"musl/src/env/putenv.c", -"musl/src/env/secure_getenv.c", -"musl/src/env/setenv.c", -"musl/src/env/unsetenv.c", -"musl/src/errno/__errno_location.c", -"musl/src/errno/strerror.c", -"musl/src/exit/_Exit.c", -"musl/src/exit/abort.c", -"musl/src/exit/arm/__aeabi_atexit.c", -"musl/src/exit/assert.c", -"musl/src/exit/at_quick_exit.c", -"musl/src/exit/atexit.c", -"musl/src/exit/exit.c", -"musl/src/exit/quick_exit.c", -"musl/src/fcntl/creat.c", -"musl/src/fcntl/fcntl.c", -"musl/src/fcntl/open.c", -"musl/src/fcntl/openat.c", -"musl/src/fcntl/posix_fadvise.c", -"musl/src/fcntl/posix_fallocate.c", -"musl/src/fenv/__flt_rounds.c", -"musl/src/fenv/aarch64/fenv.s", -"musl/src/fenv/arm/fenv-hf.S", -"musl/src/fenv/arm/fenv.c", -"musl/src/fenv/fegetexceptflag.c", -"musl/src/fenv/feholdexcept.c", -"musl/src/fenv/fenv.c", -"musl/src/fenv/fesetexceptflag.c", -"musl/src/fenv/fesetround.c", -"musl/src/fenv/feupdateenv.c", -"musl/src/fenv/i386/fenv.s", -"musl/src/fenv/m68k/fenv.c", -"musl/src/fenv/mips/fenv-sf.c", -"musl/src/fenv/mips/fenv.S", -"musl/src/fenv/mips64/fenv-sf.c", -"musl/src/fenv/mips64/fenv.S", -"musl/src/fenv/mipsn32/fenv-sf.c", -"musl/src/fenv/mipsn32/fenv.S", -"musl/src/fenv/powerpc/fenv-sf.c", -"musl/src/fenv/powerpc/fenv.S", -"musl/src/fenv/powerpc64/fenv.c", -"musl/src/fenv/riscv64/fenv-sf.c", -"musl/src/fenv/riscv64/fenv.S", -"musl/src/fenv/s390x/fenv.c", -"musl/src/fenv/sh/fenv-nofpu.c", -"musl/src/fenv/sh/fenv.S", -"musl/src/fenv/x32/fenv.s", -"musl/src/fenv/x86_64/fenv.s", -"musl/src/internal/defsysinfo.c", -"musl/src/internal/floatscan.c", -"musl/src/internal/i386/defsysinfo.s", -"musl/src/internal/intscan.c", -"musl/src/internal/libc.c", -"musl/src/internal/procfdname.c", -"musl/src/internal/sh/__shcall.c", -"musl/src/internal/shgetc.c", -"musl/src/internal/syscall_ret.c", -"musl/src/internal/vdso.c", -"musl/src/internal/version.c", -"musl/src/ipc/ftok.c", -"musl/src/ipc/msgctl.c", -"musl/src/ipc/msgget.c", -"musl/src/ipc/msgrcv.c", -"musl/src/ipc/msgsnd.c", -"musl/src/ipc/semctl.c", -"musl/src/ipc/semget.c", -"musl/src/ipc/semop.c", -"musl/src/ipc/semtimedop.c", -"musl/src/ipc/shmat.c", -"musl/src/ipc/shmctl.c", -"musl/src/ipc/shmdt.c", -"musl/src/ipc/shmget.c", -"musl/src/ldso/__dlsym.c", -"musl/src/ldso/aarch64/dlsym.s", -"musl/src/ldso/aarch64/tlsdesc.s", -"musl/src/ldso/arm/dlsym.s", -"musl/src/ldso/arm/dlsym_time64.S", -"musl/src/ldso/arm/find_exidx.c", -"musl/src/ldso/arm/tlsdesc.S", -"musl/src/ldso/dl_iterate_phdr.c", -"musl/src/ldso/dladdr.c", -"musl/src/ldso/dlclose.c", -"musl/src/ldso/dlerror.c", -"musl/src/ldso/dlinfo.c", -"musl/src/ldso/dlopen.c", -"musl/src/ldso/dlsym.c", -"musl/src/ldso/i386/dlsym.s", -"musl/src/ldso/i386/dlsym_time64.S", -"musl/src/ldso/i386/tlsdesc.s", -"musl/src/ldso/m68k/dlsym.s", -"musl/src/ldso/m68k/dlsym_time64.S", -"musl/src/ldso/microblaze/dlsym.s", -"musl/src/ldso/microblaze/dlsym_time64.S", -"musl/src/ldso/mips/dlsym.s", -"musl/src/ldso/mips/dlsym_time64.S", -"musl/src/ldso/mips64/dlsym.s", -"musl/src/ldso/mipsn32/dlsym.s", -"musl/src/ldso/mipsn32/dlsym_time64.S", -"musl/src/ldso/or1k/dlsym.s", -"musl/src/ldso/or1k/dlsym_time64.S", -"musl/src/ldso/powerpc/dlsym.s", -"musl/src/ldso/powerpc/dlsym_time64.S", -"musl/src/ldso/powerpc64/dlsym.s", -"musl/src/ldso/riscv64/dlsym.s", -"musl/src/ldso/s390x/dlsym.s", -"musl/src/ldso/sh/dlsym.s", -"musl/src/ldso/sh/dlsym_time64.S", -"musl/src/ldso/tlsdesc.c", -"musl/src/ldso/x32/dlsym.s", -"musl/src/ldso/x86_64/dlsym.s", -"musl/src/ldso/x86_64/tlsdesc.s", -"musl/src/legacy/cuserid.c", -"musl/src/legacy/daemon.c", -"musl/src/legacy/err.c", -"musl/src/legacy/euidaccess.c", -"musl/src/legacy/ftw.c", -"musl/src/legacy/futimes.c", -"musl/src/legacy/getdtablesize.c", -"musl/src/legacy/getloadavg.c", -"musl/src/legacy/getpagesize.c", -"musl/src/legacy/getpass.c", -"musl/src/legacy/getusershell.c", -"musl/src/legacy/isastream.c", -"musl/src/legacy/lutimes.c", -"musl/src/legacy/ulimit.c", -"musl/src/legacy/utmpx.c", -"musl/src/legacy/valloc.c", -"musl/src/linux/adjtime.c", -"musl/src/linux/adjtimex.c", -"musl/src/linux/arch_prctl.c", -"musl/src/linux/brk.c", -"musl/src/linux/cache.c", -"musl/src/linux/cap.c", -"musl/src/linux/chroot.c", -"musl/src/linux/clock_adjtime.c", -"musl/src/linux/clone.c", -"musl/src/linux/copy_file_range.c", -"musl/src/linux/epoll.c", -"musl/src/linux/eventfd.c", -"musl/src/linux/fallocate.c", -"musl/src/linux/fanotify.c", -"musl/src/linux/flock.c", -"musl/src/linux/getdents.c", -"musl/src/linux/getrandom.c", -"musl/src/linux/inotify.c", -"musl/src/linux/ioperm.c", -"musl/src/linux/iopl.c", -"musl/src/linux/klogctl.c", -"musl/src/linux/membarrier.c", -"musl/src/linux/memfd_create.c", -"musl/src/linux/mlock2.c", -"musl/src/linux/module.c", -"musl/src/linux/mount.c", -"musl/src/linux/name_to_handle_at.c", -"musl/src/linux/open_by_handle_at.c", -"musl/src/linux/personality.c", -"musl/src/linux/pivot_root.c", -"musl/src/linux/ppoll.c", -"musl/src/linux/prctl.c", -"musl/src/linux/prlimit.c", -"musl/src/linux/process_vm.c", -"musl/src/linux/ptrace.c", -"musl/src/linux/quotactl.c", -"musl/src/linux/readahead.c", -"musl/src/linux/reboot.c", -"musl/src/linux/remap_file_pages.c", -"musl/src/linux/sbrk.c", -"musl/src/linux/sendfile.c", -"musl/src/linux/setfsgid.c", -"musl/src/linux/setfsuid.c", -"musl/src/linux/setgroups.c", -"musl/src/linux/sethostname.c", -"musl/src/linux/setns.c", -"musl/src/linux/settimeofday.c", -"musl/src/linux/signalfd.c", -"musl/src/linux/splice.c", -"musl/src/linux/stime.c", -"musl/src/linux/swap.c", -"musl/src/linux/sync_file_range.c", -"musl/src/linux/syncfs.c", -"musl/src/linux/sysinfo.c", -"musl/src/linux/tee.c", -"musl/src/linux/timerfd.c", -"musl/src/linux/unshare.c", -"musl/src/linux/utimes.c", -"musl/src/linux/vhangup.c", -"musl/src/linux/vmsplice.c", -"musl/src/linux/wait3.c", -"musl/src/linux/wait4.c", -"musl/src/linux/x32/sysinfo.c", -"musl/src/linux/xattr.c", -"musl/src/locale/__lctrans.c", -"musl/src/locale/__mo_lookup.c", -"musl/src/locale/bind_textdomain_codeset.c", -"musl/src/locale/c_locale.c", -"musl/src/locale/catclose.c", -"musl/src/locale/catgets.c", -"musl/src/locale/catopen.c", -"musl/src/locale/dcngettext.c", -"musl/src/locale/duplocale.c", -"musl/src/locale/freelocale.c", -"musl/src/locale/iconv.c", -"musl/src/locale/iconv_close.c", -"musl/src/locale/langinfo.c", -"musl/src/locale/locale_map.c", -"musl/src/locale/localeconv.c", -"musl/src/locale/newlocale.c", -"musl/src/locale/pleval.c", -"musl/src/locale/setlocale.c", -"musl/src/locale/strcoll.c", -"musl/src/locale/strfmon.c", -"musl/src/locale/strxfrm.c", -"musl/src/locale/textdomain.c", -"musl/src/locale/uselocale.c", -"musl/src/locale/wcscoll.c", -"musl/src/locale/wcsxfrm.c", -"musl/src/malloc/aligned_alloc.c", -"musl/src/malloc/expand_heap.c", -"musl/src/malloc/lite_malloc.c", -"musl/src/malloc/malloc.c", -"musl/src/malloc/malloc_usable_size.c", -"musl/src/malloc/memalign.c", -"musl/src/malloc/posix_memalign.c", -"musl/src/math/__cos.c", -"musl/src/math/__cosdf.c", -"musl/src/math/__cosl.c", -"musl/src/math/__expo2.c", -"musl/src/math/__expo2f.c", -"musl/src/math/__fpclassify.c", -"musl/src/math/__fpclassifyf.c", -"musl/src/math/__fpclassifyl.c", -"musl/src/math/__invtrigl.c", -"musl/src/math/__math_divzero.c", -"musl/src/math/__math_divzerof.c", -"musl/src/math/__math_invalid.c", -"musl/src/math/__math_invalidf.c", -"musl/src/math/__math_oflow.c", -"musl/src/math/__math_oflowf.c", -"musl/src/math/__math_uflow.c", -"musl/src/math/__math_uflowf.c", -"musl/src/math/__math_xflow.c", -"musl/src/math/__math_xflowf.c", -"musl/src/math/__polevll.c", -"musl/src/math/__rem_pio2.c", -"musl/src/math/__rem_pio2_large.c", -"musl/src/math/__rem_pio2f.c", -"musl/src/math/__rem_pio2l.c", -"musl/src/math/__signbit.c", -"musl/src/math/__signbitf.c", -"musl/src/math/__signbitl.c", -"musl/src/math/__sin.c", -"musl/src/math/__sindf.c", -"musl/src/math/__sinl.c", -"musl/src/math/__tan.c", -"musl/src/math/__tandf.c", -"musl/src/math/__tanl.c", -"musl/src/math/aarch64/ceil.c", -"musl/src/math/aarch64/ceilf.c", -"musl/src/math/aarch64/fabs.c", -"musl/src/math/aarch64/fabsf.c", -"musl/src/math/aarch64/floor.c", -"musl/src/math/aarch64/floorf.c", -"musl/src/math/aarch64/fma.c", -"musl/src/math/aarch64/fmaf.c", -"musl/src/math/aarch64/fmax.c", -"musl/src/math/aarch64/fmaxf.c", -"musl/src/math/aarch64/fmin.c", -"musl/src/math/aarch64/fminf.c", -"musl/src/math/aarch64/llrint.c", -"musl/src/math/aarch64/llrintf.c", -"musl/src/math/aarch64/llround.c", -"musl/src/math/aarch64/llroundf.c", -"musl/src/math/aarch64/lrint.c", -"musl/src/math/aarch64/lrintf.c", -"musl/src/math/aarch64/lround.c", -"musl/src/math/aarch64/lroundf.c", -"musl/src/math/aarch64/nearbyint.c", -"musl/src/math/aarch64/nearbyintf.c", -"musl/src/math/aarch64/rint.c", -"musl/src/math/aarch64/rintf.c", -"musl/src/math/aarch64/round.c", -"musl/src/math/aarch64/roundf.c", -"musl/src/math/aarch64/sqrt.c", -"musl/src/math/aarch64/sqrtf.c", -"musl/src/math/aarch64/trunc.c", -"musl/src/math/aarch64/truncf.c", -"musl/src/math/acos.c", -"musl/src/math/acosf.c", -"musl/src/math/acosh.c", -"musl/src/math/acoshf.c", -"musl/src/math/acoshl.c", -"musl/src/math/acosl.c", -"musl/src/math/arm/fabs.c", -"musl/src/math/arm/fabsf.c", -"musl/src/math/arm/fma.c", -"musl/src/math/arm/fmaf.c", -"musl/src/math/arm/sqrt.c", -"musl/src/math/arm/sqrtf.c", -"musl/src/math/asin.c", -"musl/src/math/asinf.c", -"musl/src/math/asinh.c", -"musl/src/math/asinhf.c", -"musl/src/math/asinhl.c", -"musl/src/math/asinl.c", -"musl/src/math/atan.c", -"musl/src/math/atan2.c", -"musl/src/math/atan2f.c", -"musl/src/math/atan2l.c", -"musl/src/math/atanf.c", -"musl/src/math/atanh.c", -"musl/src/math/atanhf.c", -"musl/src/math/atanhl.c", -"musl/src/math/atanl.c", -"musl/src/math/cbrt.c", -"musl/src/math/cbrtf.c", -"musl/src/math/cbrtl.c", -"musl/src/math/ceil.c", -"musl/src/math/ceilf.c", -"musl/src/math/ceill.c", -"musl/src/math/copysign.c", -"musl/src/math/copysignf.c", -"musl/src/math/copysignl.c", -"musl/src/math/cos.c", -"musl/src/math/cosf.c", -"musl/src/math/cosh.c", -"musl/src/math/coshf.c", -"musl/src/math/coshl.c", -"musl/src/math/cosl.c", -"musl/src/math/erf.c", -"musl/src/math/erff.c", -"musl/src/math/erfl.c", -"musl/src/math/exp.c", -"musl/src/math/exp10.c", -"musl/src/math/exp10f.c", -"musl/src/math/exp10l.c", -"musl/src/math/exp2.c", -"musl/src/math/exp2f.c", -"musl/src/math/exp2f_data.c", -"musl/src/math/exp2l.c", -"musl/src/math/exp_data.c", -"musl/src/math/expf.c", -"musl/src/math/expl.c", -"musl/src/math/expm1.c", -"musl/src/math/expm1f.c", -"musl/src/math/expm1l.c", -"musl/src/math/fabs.c", -"musl/src/math/fabsf.c", -"musl/src/math/fabsl.c", -"musl/src/math/fdim.c", -"musl/src/math/fdimf.c", -"musl/src/math/fdiml.c", -"musl/src/math/finite.c", -"musl/src/math/finitef.c", -"musl/src/math/floor.c", -"musl/src/math/floorf.c", -"musl/src/math/floorl.c", -"musl/src/math/fma.c", -"musl/src/math/fmaf.c", -"musl/src/math/fmal.c", -"musl/src/math/fmax.c", -"musl/src/math/fmaxf.c", -"musl/src/math/fmaxl.c", -"musl/src/math/fmin.c", -"musl/src/math/fminf.c", -"musl/src/math/fminl.c", -"musl/src/math/fmod.c", -"musl/src/math/fmodf.c", -"musl/src/math/fmodl.c", -"musl/src/math/frexp.c", -"musl/src/math/frexpf.c", -"musl/src/math/frexpl.c", -"musl/src/math/hypot.c", -"musl/src/math/hypotf.c", -"musl/src/math/hypotl.c", -"musl/src/math/i386/__invtrigl.s", -"musl/src/math/i386/acos.s", -"musl/src/math/i386/acosf.s", -"musl/src/math/i386/acosl.s", -"musl/src/math/i386/asin.s", -"musl/src/math/i386/asinf.s", -"musl/src/math/i386/asinl.s", -"musl/src/math/i386/atan.s", -"musl/src/math/i386/atan2.s", -"musl/src/math/i386/atan2f.s", -"musl/src/math/i386/atan2l.s", -"musl/src/math/i386/atanf.s", -"musl/src/math/i386/atanl.s", -"musl/src/math/i386/ceil.s", -"musl/src/math/i386/ceilf.s", -"musl/src/math/i386/ceill.s", -"musl/src/math/i386/exp2l.s", -"musl/src/math/i386/exp_ld.s", -"musl/src/math/i386/expl.s", -"musl/src/math/i386/expm1l.s", -"musl/src/math/i386/fabs.s", -"musl/src/math/i386/fabsf.s", -"musl/src/math/i386/fabsl.s", -"musl/src/math/i386/floor.s", -"musl/src/math/i386/floorf.s", -"musl/src/math/i386/floorl.s", -"musl/src/math/i386/fmod.s", -"musl/src/math/i386/fmodf.s", -"musl/src/math/i386/fmodl.s", -"musl/src/math/i386/hypot.s", -"musl/src/math/i386/hypotf.s", -"musl/src/math/i386/ldexp.s", -"musl/src/math/i386/ldexpf.s", -"musl/src/math/i386/ldexpl.s", -"musl/src/math/i386/llrint.s", -"musl/src/math/i386/llrintf.s", -"musl/src/math/i386/llrintl.s", -"musl/src/math/i386/log.s", -"musl/src/math/i386/log10.s", -"musl/src/math/i386/log10f.s", -"musl/src/math/i386/log10l.s", -"musl/src/math/i386/log1p.s", -"musl/src/math/i386/log1pf.s", -"musl/src/math/i386/log1pl.s", -"musl/src/math/i386/log2.s", -"musl/src/math/i386/log2f.s", -"musl/src/math/i386/log2l.s", -"musl/src/math/i386/logf.s", -"musl/src/math/i386/logl.s", -"musl/src/math/i386/lrint.s", -"musl/src/math/i386/lrintf.s", -"musl/src/math/i386/lrintl.s", -"musl/src/math/i386/remainder.s", -"musl/src/math/i386/remainderf.s", -"musl/src/math/i386/remainderl.s", -"musl/src/math/i386/remquo.s", -"musl/src/math/i386/remquof.s", -"musl/src/math/i386/remquol.s", -"musl/src/math/i386/rint.s", -"musl/src/math/i386/rintf.s", -"musl/src/math/i386/rintl.s", -"musl/src/math/i386/scalbln.s", -"musl/src/math/i386/scalblnf.s", -"musl/src/math/i386/scalblnl.s", -"musl/src/math/i386/scalbn.s", -"musl/src/math/i386/scalbnf.s", -"musl/src/math/i386/scalbnl.s", -"musl/src/math/i386/sqrt.s", -"musl/src/math/i386/sqrtf.s", -"musl/src/math/i386/sqrtl.s", -"musl/src/math/i386/trunc.s", -"musl/src/math/i386/truncf.s", -"musl/src/math/i386/truncl.s", -"musl/src/math/ilogb.c", -"musl/src/math/ilogbf.c", -"musl/src/math/ilogbl.c", -"musl/src/math/j0.c", -"musl/src/math/j0f.c", -"musl/src/math/j1.c", -"musl/src/math/j1f.c", -"musl/src/math/jn.c", -"musl/src/math/jnf.c", -"musl/src/math/ldexp.c", -"musl/src/math/ldexpf.c", -"musl/src/math/ldexpl.c", -"musl/src/math/lgamma.c", -"musl/src/math/lgamma_r.c", -"musl/src/math/lgammaf.c", -"musl/src/math/lgammaf_r.c", -"musl/src/math/lgammal.c", -"musl/src/math/llrint.c", -"musl/src/math/llrintf.c", -"musl/src/math/llrintl.c", -"musl/src/math/llround.c", -"musl/src/math/llroundf.c", -"musl/src/math/llroundl.c", -"musl/src/math/log.c", -"musl/src/math/log10.c", -"musl/src/math/log10f.c", -"musl/src/math/log10l.c", -"musl/src/math/log1p.c", -"musl/src/math/log1pf.c", -"musl/src/math/log1pl.c", -"musl/src/math/log2.c", -"musl/src/math/log2_data.c", -"musl/src/math/log2f.c", -"musl/src/math/log2f_data.c", -"musl/src/math/log2l.c", -"musl/src/math/log_data.c", -"musl/src/math/logb.c", -"musl/src/math/logbf.c", -"musl/src/math/logbl.c", -"musl/src/math/logf.c", -"musl/src/math/logf_data.c", -"musl/src/math/logl.c", -"musl/src/math/lrint.c", -"musl/src/math/lrintf.c", -"musl/src/math/lrintl.c", -"musl/src/math/lround.c", -"musl/src/math/lroundf.c", -"musl/src/math/lroundl.c", -"musl/src/math/mips/fabs.c", -"musl/src/math/mips/fabsf.c", -"musl/src/math/mips/sqrt.c", -"musl/src/math/mips/sqrtf.c", -"musl/src/math/modf.c", -"musl/src/math/modff.c", -"musl/src/math/modfl.c", -"musl/src/math/nan.c", -"musl/src/math/nanf.c", -"musl/src/math/nanl.c", -"musl/src/math/nearbyint.c", -"musl/src/math/nearbyintf.c", -"musl/src/math/nearbyintl.c", -"musl/src/math/nextafter.c", -"musl/src/math/nextafterf.c", -"musl/src/math/nextafterl.c", -"musl/src/math/nexttoward.c", -"musl/src/math/nexttowardf.c", -"musl/src/math/nexttowardl.c", -"musl/src/math/pow.c", -"musl/src/math/pow_data.c", -"musl/src/math/powerpc/fabs.c", -"musl/src/math/powerpc/fabsf.c", -"musl/src/math/powerpc/fma.c", -"musl/src/math/powerpc/fmaf.c", -"musl/src/math/powerpc/sqrt.c", -"musl/src/math/powerpc/sqrtf.c", -"musl/src/math/powerpc64/ceil.c", -"musl/src/math/powerpc64/ceilf.c", -"musl/src/math/powerpc64/fabs.c", -"musl/src/math/powerpc64/fabsf.c", -"musl/src/math/powerpc64/floor.c", -"musl/src/math/powerpc64/floorf.c", -"musl/src/math/powerpc64/fma.c", -"musl/src/math/powerpc64/fmaf.c", -"musl/src/math/powerpc64/fmax.c", -"musl/src/math/powerpc64/fmaxf.c", -"musl/src/math/powerpc64/fmin.c", -"musl/src/math/powerpc64/fminf.c", -"musl/src/math/powerpc64/lrint.c", -"musl/src/math/powerpc64/lrintf.c", -"musl/src/math/powerpc64/lround.c", -"musl/src/math/powerpc64/lroundf.c", -"musl/src/math/powerpc64/round.c", -"musl/src/math/powerpc64/roundf.c", -"musl/src/math/powerpc64/sqrt.c", -"musl/src/math/powerpc64/sqrtf.c", -"musl/src/math/powerpc64/trunc.c", -"musl/src/math/powerpc64/truncf.c", -"musl/src/math/powf.c", -"musl/src/math/powf_data.c", -"musl/src/math/powl.c", -"musl/src/math/remainder.c", -"musl/src/math/remainderf.c", -"musl/src/math/remainderl.c", -"musl/src/math/remquo.c", -"musl/src/math/remquof.c", -"musl/src/math/remquol.c", -"musl/src/math/rint.c", -"musl/src/math/rintf.c", -"musl/src/math/rintl.c", -"musl/src/math/riscv64/copysign.c", -"musl/src/math/riscv64/copysignf.c", -"musl/src/math/riscv64/fabs.c", -"musl/src/math/riscv64/fabsf.c", -"musl/src/math/riscv64/fma.c", -"musl/src/math/riscv64/fmaf.c", -"musl/src/math/riscv64/fmax.c", -"musl/src/math/riscv64/fmaxf.c", -"musl/src/math/riscv64/fmin.c", -"musl/src/math/riscv64/fminf.c", -"musl/src/math/riscv64/sqrt.c", -"musl/src/math/riscv64/sqrtf.c", -"musl/src/math/round.c", -"musl/src/math/roundf.c", -"musl/src/math/roundl.c", -"musl/src/math/s390x/ceil.c", -"musl/src/math/s390x/ceilf.c", -"musl/src/math/s390x/ceill.c", -"musl/src/math/s390x/fabs.c", -"musl/src/math/s390x/fabsf.c", -"musl/src/math/s390x/fabsl.c", -"musl/src/math/s390x/floor.c", -"musl/src/math/s390x/floorf.c", -"musl/src/math/s390x/floorl.c", -"musl/src/math/s390x/fma.c", -"musl/src/math/s390x/fmaf.c", -"musl/src/math/s390x/nearbyint.c", -"musl/src/math/s390x/nearbyintf.c", -"musl/src/math/s390x/nearbyintl.c", -"musl/src/math/s390x/rint.c", -"musl/src/math/s390x/rintf.c", -"musl/src/math/s390x/rintl.c", -"musl/src/math/s390x/round.c", -"musl/src/math/s390x/roundf.c", -"musl/src/math/s390x/roundl.c", -"musl/src/math/s390x/sqrt.c", -"musl/src/math/s390x/sqrtf.c", -"musl/src/math/s390x/sqrtl.c", -"musl/src/math/s390x/trunc.c", -"musl/src/math/s390x/truncf.c", -"musl/src/math/s390x/truncl.c", -"musl/src/math/scalb.c", -"musl/src/math/scalbf.c", -"musl/src/math/scalbln.c", -"musl/src/math/scalblnf.c", -"musl/src/math/scalblnl.c", -"musl/src/math/scalbn.c", -"musl/src/math/scalbnf.c", -"musl/src/math/scalbnl.c", -"musl/src/math/signgam.c", -"musl/src/math/significand.c", -"musl/src/math/significandf.c", -"musl/src/math/sin.c", -"musl/src/math/sincos.c", -"musl/src/math/sincosf.c", -"musl/src/math/sincosl.c", -"musl/src/math/sinf.c", -"musl/src/math/sinh.c", -"musl/src/math/sinhf.c", -"musl/src/math/sinhl.c", -"musl/src/math/sinl.c", -"musl/src/math/sqrt.c", -"musl/src/math/sqrtf.c", -"musl/src/math/sqrtl.c", -"musl/src/math/tan.c", -"musl/src/math/tanf.c", -"musl/src/math/tanh.c", -"musl/src/math/tanhf.c", -"musl/src/math/tanhl.c", -"musl/src/math/tanl.c", -"musl/src/math/tgamma.c", -"musl/src/math/tgammaf.c", -"musl/src/math/tgammal.c", -"musl/src/math/trunc.c", -"musl/src/math/truncf.c", -"musl/src/math/truncl.c", -"musl/src/math/x32/__invtrigl.s", -"musl/src/math/x32/acosl.s", -"musl/src/math/x32/asinl.s", -"musl/src/math/x32/atan2l.s", -"musl/src/math/x32/atanl.s", -"musl/src/math/x32/ceill.s", -"musl/src/math/x32/exp2l.s", -"musl/src/math/x32/expl.s", -"musl/src/math/x32/expm1l.s", -"musl/src/math/x32/fabs.s", -"musl/src/math/x32/fabsf.s", -"musl/src/math/x32/fabsl.s", -"musl/src/math/x32/floorl.s", -"musl/src/math/x32/fma.c", -"musl/src/math/x32/fmaf.c", -"musl/src/math/x32/fmodl.s", -"musl/src/math/x32/llrint.s", -"musl/src/math/x32/llrintf.s", -"musl/src/math/x32/llrintl.s", -"musl/src/math/x32/log10l.s", -"musl/src/math/x32/log1pl.s", -"musl/src/math/x32/log2l.s", -"musl/src/math/x32/logl.s", -"musl/src/math/x32/lrint.s", -"musl/src/math/x32/lrintf.s", -"musl/src/math/x32/lrintl.s", -"musl/src/math/x32/remainderl.s", -"musl/src/math/x32/rintl.s", -"musl/src/math/x32/sqrt.s", -"musl/src/math/x32/sqrtf.s", -"musl/src/math/x32/sqrtl.s", -"musl/src/math/x32/truncl.s", -"musl/src/math/x86_64/__invtrigl.s", -"musl/src/math/x86_64/acosl.s", -"musl/src/math/x86_64/asinl.s", -"musl/src/math/x86_64/atan2l.s", -"musl/src/math/x86_64/atanl.s", -"musl/src/math/x86_64/ceill.s", -"musl/src/math/x86_64/exp2l.s", -"musl/src/math/x86_64/expl.s", -"musl/src/math/x86_64/expm1l.s", -"musl/src/math/x86_64/fabs.s", -"musl/src/math/x86_64/fabsf.s", -"musl/src/math/x86_64/fabsl.s", -"musl/src/math/x86_64/floorl.s", -"musl/src/math/x86_64/fma.c", -"musl/src/math/x86_64/fmaf.c", -"musl/src/math/x86_64/fmodl.s", -"musl/src/math/x86_64/llrint.s", -"musl/src/math/x86_64/llrintf.s", -"musl/src/math/x86_64/llrintl.s", -"musl/src/math/x86_64/log10l.s", -"musl/src/math/x86_64/log1pl.s", -"musl/src/math/x86_64/log2l.s", -"musl/src/math/x86_64/logl.s", -"musl/src/math/x86_64/lrint.s", -"musl/src/math/x86_64/lrintf.s", -"musl/src/math/x86_64/lrintl.s", -"musl/src/math/x86_64/remainderl.s", -"musl/src/math/x86_64/rintl.s", -"musl/src/math/x86_64/sqrt.s", -"musl/src/math/x86_64/sqrtf.s", -"musl/src/math/x86_64/sqrtl.s", -"musl/src/math/x86_64/truncl.s", -"musl/src/misc/a64l.c", -"musl/src/misc/basename.c", -"musl/src/misc/dirname.c", -"musl/src/misc/ffs.c", -"musl/src/misc/ffsl.c", -"musl/src/misc/ffsll.c", -"musl/src/misc/fmtmsg.c", -"musl/src/misc/forkpty.c", -"musl/src/misc/get_current_dir_name.c", -"musl/src/misc/getauxval.c", -"musl/src/misc/getdomainname.c", -"musl/src/misc/getentropy.c", -"musl/src/misc/gethostid.c", -"musl/src/misc/getopt.c", -"musl/src/misc/getopt_long.c", -"musl/src/misc/getpriority.c", -"musl/src/misc/getresgid.c", -"musl/src/misc/getresuid.c", -"musl/src/misc/getrlimit.c", -"musl/src/misc/getrusage.c", -"musl/src/misc/getsubopt.c", -"musl/src/misc/initgroups.c", -"musl/src/misc/ioctl.c", -"musl/src/misc/issetugid.c", -"musl/src/misc/lockf.c", -"musl/src/misc/login_tty.c", -"musl/src/misc/mntent.c", -"musl/src/misc/nftw.c", -"musl/src/misc/openpty.c", -"musl/src/misc/ptsname.c", -"musl/src/misc/pty.c", -"musl/src/misc/realpath.c", -"musl/src/misc/setdomainname.c", -"musl/src/misc/setpriority.c", -"musl/src/misc/setrlimit.c", -"musl/src/misc/syscall.c", -"musl/src/misc/syslog.c", -"musl/src/misc/uname.c", -"musl/src/misc/wordexp.c", -"musl/src/mman/madvise.c", -"musl/src/mman/mincore.c", -"musl/src/mman/mlock.c", -"musl/src/mman/mlockall.c", -"musl/src/mman/mmap.c", -"musl/src/mman/mprotect.c", -"musl/src/mman/mremap.c", -"musl/src/mman/msync.c", -"musl/src/mman/munlock.c", -"musl/src/mman/munlockall.c", -"musl/src/mman/munmap.c", -"musl/src/mman/posix_madvise.c", -"musl/src/mman/shm_open.c", -"musl/src/mq/mq_close.c", -"musl/src/mq/mq_getattr.c", -"musl/src/mq/mq_notify.c", -"musl/src/mq/mq_open.c", -"musl/src/mq/mq_receive.c", -"musl/src/mq/mq_send.c", -"musl/src/mq/mq_setattr.c", -"musl/src/mq/mq_timedreceive.c", -"musl/src/mq/mq_timedsend.c", -"musl/src/mq/mq_unlink.c", -"musl/src/multibyte/btowc.c", -"musl/src/multibyte/c16rtomb.c", -"musl/src/multibyte/c32rtomb.c", -"musl/src/multibyte/internal.c", -"musl/src/multibyte/mblen.c", -"musl/src/multibyte/mbrlen.c", -"musl/src/multibyte/mbrtoc16.c", -"musl/src/multibyte/mbrtoc32.c", -"musl/src/multibyte/mbrtowc.c", -"musl/src/multibyte/mbsinit.c", -"musl/src/multibyte/mbsnrtowcs.c", -"musl/src/multibyte/mbsrtowcs.c", -"musl/src/multibyte/mbstowcs.c", -"musl/src/multibyte/mbtowc.c", -"musl/src/multibyte/wcrtomb.c", -"musl/src/multibyte/wcsnrtombs.c", -"musl/src/multibyte/wcsrtombs.c", -"musl/src/multibyte/wcstombs.c", -"musl/src/multibyte/wctob.c", -"musl/src/multibyte/wctomb.c", -"musl/src/network/accept.c", -"musl/src/network/accept4.c", -"musl/src/network/bind.c", -"musl/src/network/connect.c", -"musl/src/network/dn_comp.c", -"musl/src/network/dn_expand.c", -"musl/src/network/dn_skipname.c", -"musl/src/network/dns_parse.c", -"musl/src/network/ent.c", -"musl/src/network/ether.c", -"musl/src/network/freeaddrinfo.c", -"musl/src/network/gai_strerror.c", -"musl/src/network/getaddrinfo.c", -"musl/src/network/gethostbyaddr.c", -"musl/src/network/gethostbyaddr_r.c", -"musl/src/network/gethostbyname.c", -"musl/src/network/gethostbyname2.c", -"musl/src/network/gethostbyname2_r.c", -"musl/src/network/gethostbyname_r.c", -"musl/src/network/getifaddrs.c", -"musl/src/network/getnameinfo.c", -"musl/src/network/getpeername.c", -"musl/src/network/getservbyname.c", -"musl/src/network/getservbyname_r.c", -"musl/src/network/getservbyport.c", -"musl/src/network/getservbyport_r.c", -"musl/src/network/getsockname.c", -"musl/src/network/getsockopt.c", -"musl/src/network/h_errno.c", -"musl/src/network/herror.c", -"musl/src/network/hstrerror.c", -"musl/src/network/htonl.c", -"musl/src/network/htons.c", -"musl/src/network/if_freenameindex.c", -"musl/src/network/if_indextoname.c", -"musl/src/network/if_nameindex.c", -"musl/src/network/if_nametoindex.c", -"musl/src/network/in6addr_any.c", -"musl/src/network/in6addr_loopback.c", -"musl/src/network/inet_addr.c", -"musl/src/network/inet_aton.c", -"musl/src/network/inet_legacy.c", -"musl/src/network/inet_ntoa.c", -"musl/src/network/inet_ntop.c", -"musl/src/network/inet_pton.c", -"musl/src/network/listen.c", -"musl/src/network/lookup_ipliteral.c", -"musl/src/network/lookup_name.c", -"musl/src/network/lookup_serv.c", -"musl/src/network/netlink.c", -"musl/src/network/netname.c", -"musl/src/network/ns_parse.c", -"musl/src/network/ntohl.c", -"musl/src/network/ntohs.c", -"musl/src/network/proto.c", -"musl/src/network/recv.c", -"musl/src/network/recvfrom.c", -"musl/src/network/recvmmsg.c", -"musl/src/network/recvmsg.c", -"musl/src/network/res_init.c", -"musl/src/network/res_mkquery.c", -"musl/src/network/res_msend.c", -"musl/src/network/res_query.c", -"musl/src/network/res_querydomain.c", -"musl/src/network/res_send.c", -"musl/src/network/res_state.c", -"musl/src/network/resolvconf.c", -"musl/src/network/send.c", -"musl/src/network/sendmmsg.c", -"musl/src/network/sendmsg.c", -"musl/src/network/sendto.c", -"musl/src/network/serv.c", -"musl/src/network/setsockopt.c", -"musl/src/network/shutdown.c", -"musl/src/network/sockatmark.c", -"musl/src/network/socket.c", -"musl/src/network/socketpair.c", -"musl/src/passwd/fgetgrent.c", -"musl/src/passwd/fgetpwent.c", -"musl/src/passwd/fgetspent.c", -"musl/src/passwd/getgr_a.c", -"musl/src/passwd/getgr_r.c", -"musl/src/passwd/getgrent.c", -"musl/src/passwd/getgrent_a.c", -"musl/src/passwd/getgrouplist.c", -"musl/src/passwd/getpw_a.c", -"musl/src/passwd/getpw_r.c", -"musl/src/passwd/getpwent.c", -"musl/src/passwd/getpwent_a.c", -"musl/src/passwd/getspent.c", -"musl/src/passwd/getspnam.c", -"musl/src/passwd/getspnam_r.c", -"musl/src/passwd/lckpwdf.c", -"musl/src/passwd/nscd_query.c", -"musl/src/passwd/putgrent.c", -"musl/src/passwd/putpwent.c", -"musl/src/passwd/putspent.c", -"musl/src/prng/__rand48_step.c", -"musl/src/prng/__seed48.c", -"musl/src/prng/drand48.c", -"musl/src/prng/lcong48.c", -"musl/src/prng/lrand48.c", -"musl/src/prng/mrand48.c", -"musl/src/prng/rand.c", -"musl/src/prng/rand_r.c", -"musl/src/prng/random.c", -"musl/src/prng/seed48.c", -"musl/src/prng/srand48.c", -"musl/src/process/arm/vfork.s", -"musl/src/process/execl.c", -"musl/src/process/execle.c", -"musl/src/process/execlp.c", -"musl/src/process/execv.c", -"musl/src/process/execve.c", -"musl/src/process/execvp.c", -"musl/src/process/fexecve.c", -"musl/src/process/fork.c", -"musl/src/process/i386/vfork.s", -"musl/src/process/posix_spawn.c", -"musl/src/process/posix_spawn_file_actions_addchdir.c", -"musl/src/process/posix_spawn_file_actions_addclose.c", -"musl/src/process/posix_spawn_file_actions_adddup2.c", -"musl/src/process/posix_spawn_file_actions_addfchdir.c", -"musl/src/process/posix_spawn_file_actions_addopen.c", -"musl/src/process/posix_spawn_file_actions_destroy.c", -"musl/src/process/posix_spawn_file_actions_init.c", -"musl/src/process/posix_spawnattr_destroy.c", -"musl/src/process/posix_spawnattr_getflags.c", -"musl/src/process/posix_spawnattr_getpgroup.c", -"musl/src/process/posix_spawnattr_getsigdefault.c", -"musl/src/process/posix_spawnattr_getsigmask.c", -"musl/src/process/posix_spawnattr_init.c", -"musl/src/process/posix_spawnattr_sched.c", -"musl/src/process/posix_spawnattr_setflags.c", -"musl/src/process/posix_spawnattr_setpgroup.c", -"musl/src/process/posix_spawnattr_setsigdefault.c", -"musl/src/process/posix_spawnattr_setsigmask.c", -"musl/src/process/posix_spawnp.c", -"musl/src/process/s390x/vfork.s", -"musl/src/process/sh/vfork.s", -"musl/src/process/system.c", -"musl/src/process/vfork.c", -"musl/src/process/wait.c", -"musl/src/process/waitid.c", -"musl/src/process/waitpid.c", -"musl/src/process/x32/vfork.s", -"musl/src/process/x86_64/vfork.s", -"musl/src/regex/fnmatch.c", -"musl/src/regex/glob.c", -"musl/src/regex/regcomp.c", -"musl/src/regex/regerror.c", -"musl/src/regex/regexec.c", -"musl/src/regex/tre-mem.c", -"musl/src/sched/affinity.c", -"musl/src/sched/sched_cpucount.c", -"musl/src/sched/sched_get_priority_max.c", -"musl/src/sched/sched_getcpu.c", -"musl/src/sched/sched_getparam.c", -"musl/src/sched/sched_getscheduler.c", -"musl/src/sched/sched_rr_get_interval.c", -"musl/src/sched/sched_setparam.c", -"musl/src/sched/sched_setscheduler.c", -"musl/src/sched/sched_yield.c", -"musl/src/search/hsearch.c", -"musl/src/search/insque.c", -"musl/src/search/lsearch.c", -"musl/src/search/tdelete.c", -"musl/src/search/tdestroy.c", -"musl/src/search/tfind.c", -"musl/src/search/tsearch.c", -"musl/src/search/twalk.c", -"musl/src/select/poll.c", -"musl/src/select/pselect.c", -"musl/src/select/select.c", -"musl/src/setjmp/aarch64/longjmp.s", -"musl/src/setjmp/aarch64/setjmp.s", -"musl/src/setjmp/arm/longjmp.S", -"musl/src/setjmp/arm/setjmp.S", -"musl/src/setjmp/i386/longjmp.s", -"musl/src/setjmp/i386/setjmp.s", -"musl/src/setjmp/longjmp.c", -"musl/src/setjmp/m68k/longjmp.s", -"musl/src/setjmp/m68k/setjmp.s", -"musl/src/setjmp/microblaze/longjmp.s", -"musl/src/setjmp/microblaze/setjmp.s", -"musl/src/setjmp/mips/longjmp.S", -"musl/src/setjmp/mips/setjmp.S", -"musl/src/setjmp/mips64/longjmp.S", -"musl/src/setjmp/mips64/setjmp.S", -"musl/src/setjmp/mipsn32/longjmp.S", -"musl/src/setjmp/mipsn32/setjmp.S", -"musl/src/setjmp/or1k/longjmp.s", -"musl/src/setjmp/or1k/setjmp.s", -"musl/src/setjmp/powerpc/longjmp.S", -"musl/src/setjmp/powerpc/setjmp.S", -"musl/src/setjmp/powerpc64/longjmp.s", -"musl/src/setjmp/powerpc64/setjmp.s", -"musl/src/setjmp/riscv64/longjmp.S", -"musl/src/setjmp/riscv64/setjmp.S", -"musl/src/setjmp/s390x/longjmp.s", -"musl/src/setjmp/s390x/setjmp.s", -"musl/src/setjmp/setjmp.c", -"musl/src/setjmp/sh/longjmp.S", -"musl/src/setjmp/sh/setjmp.S", -"musl/src/setjmp/x32/longjmp.s", -"musl/src/setjmp/x32/setjmp.s", -"musl/src/setjmp/x86_64/longjmp.s", -"musl/src/setjmp/x86_64/setjmp.s", -"musl/src/signal/aarch64/restore.s", -"musl/src/signal/aarch64/sigsetjmp.s", -"musl/src/signal/arm/restore.s", -"musl/src/signal/arm/sigsetjmp.s", -"musl/src/signal/block.c", -"musl/src/signal/getitimer.c", -"musl/src/signal/i386/restore.s", -"musl/src/signal/i386/sigsetjmp.s", -"musl/src/signal/kill.c", -"musl/src/signal/killpg.c", -"musl/src/signal/m68k/sigsetjmp.s", -"musl/src/signal/microblaze/restore.s", -"musl/src/signal/microblaze/sigsetjmp.s", -"musl/src/signal/mips/restore.s", -"musl/src/signal/mips/sigsetjmp.s", -"musl/src/signal/mips64/restore.s", -"musl/src/signal/mips64/sigsetjmp.s", -"musl/src/signal/mipsn32/restore.s", -"musl/src/signal/mipsn32/sigsetjmp.s", -"musl/src/signal/or1k/sigsetjmp.s", -"musl/src/signal/powerpc/restore.s", -"musl/src/signal/powerpc/sigsetjmp.s", -"musl/src/signal/powerpc64/restore.s", -"musl/src/signal/powerpc64/sigsetjmp.s", -"musl/src/signal/psiginfo.c", -"musl/src/signal/psignal.c", -"musl/src/signal/raise.c", -"musl/src/signal/restore.c", -"musl/src/signal/riscv64/restore.s", -"musl/src/signal/riscv64/sigsetjmp.s", -"musl/src/signal/s390x/restore.s", -"musl/src/signal/s390x/sigsetjmp.s", -"musl/src/signal/setitimer.c", -"musl/src/signal/sh/restore.s", -"musl/src/signal/sh/sigsetjmp.s", -"musl/src/signal/sigaction.c", -"musl/src/signal/sigaddset.c", -"musl/src/signal/sigaltstack.c", -"musl/src/signal/sigandset.c", -"musl/src/signal/sigdelset.c", -"musl/src/signal/sigemptyset.c", -"musl/src/signal/sigfillset.c", -"musl/src/signal/sighold.c", -"musl/src/signal/sigignore.c", -"musl/src/signal/siginterrupt.c", -"musl/src/signal/sigisemptyset.c", -"musl/src/signal/sigismember.c", -"musl/src/signal/siglongjmp.c", -"musl/src/signal/signal.c", -"musl/src/signal/sigorset.c", -"musl/src/signal/sigpause.c", -"musl/src/signal/sigpending.c", -"musl/src/signal/sigprocmask.c", -"musl/src/signal/sigqueue.c", -"musl/src/signal/sigrelse.c", -"musl/src/signal/sigrtmax.c", -"musl/src/signal/sigrtmin.c", -"musl/src/signal/sigset.c", -"musl/src/signal/sigsetjmp.c", -"musl/src/signal/sigsetjmp_tail.c", -"musl/src/signal/sigsuspend.c", -"musl/src/signal/sigtimedwait.c", -"musl/src/signal/sigwait.c", -"musl/src/signal/sigwaitinfo.c", -"musl/src/signal/x32/getitimer.c", -"musl/src/signal/x32/restore.s", -"musl/src/signal/x32/setitimer.c", -"musl/src/signal/x32/sigsetjmp.s", -"musl/src/signal/x86_64/restore.s", -"musl/src/signal/x86_64/sigsetjmp.s", -"musl/src/stat/__xstat.c", -"musl/src/stat/chmod.c", -"musl/src/stat/fchmod.c", -"musl/src/stat/fchmodat.c", -"musl/src/stat/fstat.c", -"musl/src/stat/fstatat.c", -"musl/src/stat/futimens.c", -"musl/src/stat/futimesat.c", -"musl/src/stat/lchmod.c", -"musl/src/stat/lstat.c", -"musl/src/stat/mkdir.c", -"musl/src/stat/mkdirat.c", -"musl/src/stat/mkfifo.c", -"musl/src/stat/mkfifoat.c", -"musl/src/stat/mknod.c", -"musl/src/stat/mknodat.c", -"musl/src/stat/stat.c", -"musl/src/stat/statvfs.c", -"musl/src/stat/umask.c", -"musl/src/stat/utimensat.c", -"musl/src/stdio/__fclose_ca.c", -"musl/src/stdio/__fdopen.c", -"musl/src/stdio/__fmodeflags.c", -"musl/src/stdio/__fopen_rb_ca.c", -"musl/src/stdio/__lockfile.c", -"musl/src/stdio/__overflow.c", -"musl/src/stdio/__stdio_close.c", -"musl/src/stdio/__stdio_exit.c", -"musl/src/stdio/__stdio_read.c", -"musl/src/stdio/__stdio_seek.c", -"musl/src/stdio/__stdio_write.c", -"musl/src/stdio/__stdout_write.c", -"musl/src/stdio/__string_read.c", -"musl/src/stdio/__toread.c", -"musl/src/stdio/__towrite.c", -"musl/src/stdio/__uflow.c", -"musl/src/stdio/asprintf.c", -"musl/src/stdio/clearerr.c", -"musl/src/stdio/dprintf.c", -"musl/src/stdio/ext.c", -"musl/src/stdio/ext2.c", -"musl/src/stdio/fclose.c", -"musl/src/stdio/feof.c", -"musl/src/stdio/ferror.c", -"musl/src/stdio/fflush.c", -"musl/src/stdio/fgetc.c", -"musl/src/stdio/fgetln.c", -"musl/src/stdio/fgetpos.c", -"musl/src/stdio/fgets.c", -"musl/src/stdio/fgetwc.c", -"musl/src/stdio/fgetws.c", -"musl/src/stdio/fileno.c", -"musl/src/stdio/flockfile.c", -"musl/src/stdio/fmemopen.c", -"musl/src/stdio/fopen.c", -"musl/src/stdio/fopencookie.c", -"musl/src/stdio/fprintf.c", -"musl/src/stdio/fputc.c", -"musl/src/stdio/fputs.c", -"musl/src/stdio/fputwc.c", -"musl/src/stdio/fputws.c", -"musl/src/stdio/fread.c", -"musl/src/stdio/freopen.c", -"musl/src/stdio/fscanf.c", -"musl/src/stdio/fseek.c", -"musl/src/stdio/fsetpos.c", -"musl/src/stdio/ftell.c", -"musl/src/stdio/ftrylockfile.c", -"musl/src/stdio/funlockfile.c", -"musl/src/stdio/fwide.c", -"musl/src/stdio/fwprintf.c", -"musl/src/stdio/fwrite.c", -"musl/src/stdio/fwscanf.c", -"musl/src/stdio/getc.c", -"musl/src/stdio/getc_unlocked.c", -"musl/src/stdio/getchar.c", -"musl/src/stdio/getchar_unlocked.c", -"musl/src/stdio/getdelim.c", -"musl/src/stdio/getline.c", -"musl/src/stdio/gets.c", -"musl/src/stdio/getw.c", -"musl/src/stdio/getwc.c", -"musl/src/stdio/getwchar.c", -"musl/src/stdio/ofl.c", -"musl/src/stdio/ofl_add.c", -"musl/src/stdio/open_memstream.c", -"musl/src/stdio/open_wmemstream.c", -"musl/src/stdio/pclose.c", -"musl/src/stdio/perror.c", -"musl/src/stdio/popen.c", -"musl/src/stdio/printf.c", -"musl/src/stdio/putc.c", -"musl/src/stdio/putc_unlocked.c", -"musl/src/stdio/putchar.c", -"musl/src/stdio/putchar_unlocked.c", -"musl/src/stdio/puts.c", -"musl/src/stdio/putw.c", -"musl/src/stdio/putwc.c", -"musl/src/stdio/putwchar.c", -"musl/src/stdio/remove.c", -"musl/src/stdio/rename.c", -"musl/src/stdio/rewind.c", -"musl/src/stdio/scanf.c", -"musl/src/stdio/setbuf.c", -"musl/src/stdio/setbuffer.c", -"musl/src/stdio/setlinebuf.c", -"musl/src/stdio/setvbuf.c", -"musl/src/stdio/snprintf.c", -"musl/src/stdio/sprintf.c", -"musl/src/stdio/sscanf.c", -"musl/src/stdio/stderr.c", -"musl/src/stdio/stdin.c", -"musl/src/stdio/stdout.c", -"musl/src/stdio/swprintf.c", -"musl/src/stdio/swscanf.c", -"musl/src/stdio/tempnam.c", -"musl/src/stdio/tmpfile.c", -"musl/src/stdio/tmpnam.c", -"musl/src/stdio/ungetc.c", -"musl/src/stdio/ungetwc.c", -"musl/src/stdio/vasprintf.c", -"musl/src/stdio/vdprintf.c", -"musl/src/stdio/vfprintf.c", -"musl/src/stdio/vfscanf.c", -"musl/src/stdio/vfwprintf.c", -"musl/src/stdio/vfwscanf.c", -"musl/src/stdio/vprintf.c", -"musl/src/stdio/vscanf.c", -"musl/src/stdio/vsnprintf.c", -"musl/src/stdio/vsprintf.c", -"musl/src/stdio/vsscanf.c", -"musl/src/stdio/vswprintf.c", -"musl/src/stdio/vswscanf.c", -"musl/src/stdio/vwprintf.c", -"musl/src/stdio/vwscanf.c", -"musl/src/stdio/wprintf.c", -"musl/src/stdio/wscanf.c", -"musl/src/stdlib/abs.c", -"musl/src/stdlib/atof.c", -"musl/src/stdlib/atoi.c", -"musl/src/stdlib/atol.c", -"musl/src/stdlib/atoll.c", -"musl/src/stdlib/bsearch.c", -"musl/src/stdlib/div.c", -"musl/src/stdlib/ecvt.c", -"musl/src/stdlib/fcvt.c", -"musl/src/stdlib/gcvt.c", -"musl/src/stdlib/imaxabs.c", -"musl/src/stdlib/imaxdiv.c", -"musl/src/stdlib/labs.c", -"musl/src/stdlib/ldiv.c", -"musl/src/stdlib/llabs.c", -"musl/src/stdlib/lldiv.c", -"musl/src/stdlib/qsort.c", -"musl/src/stdlib/strtod.c", -"musl/src/stdlib/strtol.c", -"musl/src/stdlib/wcstod.c", -"musl/src/stdlib/wcstol.c", -"musl/src/string/arm/__aeabi_memcpy.s", -"musl/src/string/arm/__aeabi_memset.s", -"musl/src/string/arm/memcpy.c", -"musl/src/string/arm/memcpy_le.S", -"musl/src/string/bcmp.c", -"musl/src/string/bcopy.c", -"musl/src/string/bzero.c", -"musl/src/string/explicit_bzero.c", -"musl/src/string/i386/memcpy.s", -"musl/src/string/i386/memmove.s", -"musl/src/string/i386/memset.s", -"musl/src/string/index.c", -"musl/src/string/memccpy.c", -"musl/src/string/memchr.c", -"musl/src/string/memcmp.c", -"musl/src/string/memcpy.c", -"musl/src/string/memmem.c", -"musl/src/string/memmove.c", -"musl/src/string/mempcpy.c", -"musl/src/string/memrchr.c", -"musl/src/string/memset.c", -"musl/src/string/rindex.c", -"musl/src/string/stpcpy.c", -"musl/src/string/stpncpy.c", -"musl/src/string/strcasecmp.c", -"musl/src/string/strcasestr.c", -"musl/src/string/strcat.c", -"musl/src/string/strchr.c", -"musl/src/string/strchrnul.c", -"musl/src/string/strcmp.c", -"musl/src/string/strcpy.c", -"musl/src/string/strcspn.c", -"musl/src/string/strdup.c", -"musl/src/string/strerror_r.c", -"musl/src/string/strlcat.c", -"musl/src/string/strlcpy.c", -"musl/src/string/strlen.c", -"musl/src/string/strncasecmp.c", -"musl/src/string/strncat.c", -"musl/src/string/strncmp.c", -"musl/src/string/strncpy.c", -"musl/src/string/strndup.c", -"musl/src/string/strnlen.c", -"musl/src/string/strpbrk.c", -"musl/src/string/strrchr.c", -"musl/src/string/strsep.c", -"musl/src/string/strsignal.c", -"musl/src/string/strspn.c", -"musl/src/string/strstr.c", -"musl/src/string/strtok.c", -"musl/src/string/strtok_r.c", -"musl/src/string/strverscmp.c", -"musl/src/string/swab.c", -"musl/src/string/wcpcpy.c", -"musl/src/string/wcpncpy.c", -"musl/src/string/wcscasecmp.c", -"musl/src/string/wcscasecmp_l.c", -"musl/src/string/wcscat.c", -"musl/src/string/wcschr.c", -"musl/src/string/wcscmp.c", -"musl/src/string/wcscpy.c", -"musl/src/string/wcscspn.c", -"musl/src/string/wcsdup.c", -"musl/src/string/wcslen.c", -"musl/src/string/wcsncasecmp.c", -"musl/src/string/wcsncasecmp_l.c", -"musl/src/string/wcsncat.c", -"musl/src/string/wcsncmp.c", -"musl/src/string/wcsncpy.c", -"musl/src/string/wcsnlen.c", -"musl/src/string/wcspbrk.c", -"musl/src/string/wcsrchr.c", -"musl/src/string/wcsspn.c", -"musl/src/string/wcsstr.c", -"musl/src/string/wcstok.c", -"musl/src/string/wcswcs.c", -"musl/src/string/wmemchr.c", -"musl/src/string/wmemcmp.c", -"musl/src/string/wmemcpy.c", -"musl/src/string/wmemmove.c", -"musl/src/string/wmemset.c", -"musl/src/string/x86_64/memcpy.s", -"musl/src/string/x86_64/memmove.s", -"musl/src/string/x86_64/memset.s", -"musl/src/temp/__randname.c", -"musl/src/temp/mkdtemp.c", -"musl/src/temp/mkostemp.c", -"musl/src/temp/mkostemps.c", -"musl/src/temp/mkstemp.c", -"musl/src/temp/mkstemps.c", -"musl/src/temp/mktemp.c", -"musl/src/termios/cfgetospeed.c", -"musl/src/termios/cfmakeraw.c", -"musl/src/termios/cfsetospeed.c", -"musl/src/termios/tcdrain.c", -"musl/src/termios/tcflow.c", -"musl/src/termios/tcflush.c", -"musl/src/termios/tcgetattr.c", -"musl/src/termios/tcgetsid.c", -"musl/src/termios/tcsendbreak.c", -"musl/src/termios/tcsetattr.c", -"musl/src/thread/__lock.c", -"musl/src/thread/__set_thread_area.c", -"musl/src/thread/__syscall_cp.c", -"musl/src/thread/__timedwait.c", -"musl/src/thread/__tls_get_addr.c", -"musl/src/thread/__unmapself.c", -"musl/src/thread/__wait.c", -"musl/src/thread/aarch64/__set_thread_area.s", -"musl/src/thread/aarch64/__unmapself.s", -"musl/src/thread/aarch64/clone.s", -"musl/src/thread/aarch64/syscall_cp.s", -"musl/src/thread/arm/__aeabi_read_tp.s", -"musl/src/thread/arm/__set_thread_area.c", -"musl/src/thread/arm/__unmapself.s", -"musl/src/thread/arm/atomics.s", -"musl/src/thread/arm/clone.s", -"musl/src/thread/arm/syscall_cp.s", -"musl/src/thread/call_once.c", -"musl/src/thread/clone.c", -"musl/src/thread/cnd_broadcast.c", -"musl/src/thread/cnd_destroy.c", -"musl/src/thread/cnd_init.c", -"musl/src/thread/cnd_signal.c", -"musl/src/thread/cnd_timedwait.c", -"musl/src/thread/cnd_wait.c", -"musl/src/thread/default_attr.c", -"musl/src/thread/i386/__set_thread_area.s", -"musl/src/thread/i386/__unmapself.s", -"musl/src/thread/i386/clone.s", -"musl/src/thread/i386/syscall_cp.s", -"musl/src/thread/i386/tls.s", -"musl/src/thread/lock_ptc.c", -"musl/src/thread/m68k/__m68k_read_tp.s", -"musl/src/thread/m68k/clone.s", -"musl/src/thread/m68k/syscall_cp.s", -"musl/src/thread/microblaze/__set_thread_area.s", -"musl/src/thread/microblaze/__unmapself.s", -"musl/src/thread/microblaze/clone.s", -"musl/src/thread/microblaze/syscall_cp.s", -"musl/src/thread/mips/__unmapself.s", -"musl/src/thread/mips/clone.s", -"musl/src/thread/mips/syscall_cp.s", -"musl/src/thread/mips64/__unmapself.s", -"musl/src/thread/mips64/clone.s", -"musl/src/thread/mips64/syscall_cp.s", -"musl/src/thread/mipsn32/__unmapself.s", -"musl/src/thread/mipsn32/clone.s", -"musl/src/thread/mipsn32/syscall_cp.s", -"musl/src/thread/mtx_destroy.c", -"musl/src/thread/mtx_init.c", -"musl/src/thread/mtx_lock.c", -"musl/src/thread/mtx_timedlock.c", -"musl/src/thread/mtx_trylock.c", -"musl/src/thread/mtx_unlock.c", -"musl/src/thread/or1k/__set_thread_area.s", -"musl/src/thread/or1k/__unmapself.s", -"musl/src/thread/or1k/clone.s", -"musl/src/thread/or1k/syscall_cp.s", -"musl/src/thread/powerpc/__set_thread_area.s", -"musl/src/thread/powerpc/__unmapself.s", -"musl/src/thread/powerpc/clone.s", -"musl/src/thread/powerpc/syscall_cp.s", -"musl/src/thread/powerpc64/__set_thread_area.s", -"musl/src/thread/powerpc64/__unmapself.s", -"musl/src/thread/powerpc64/clone.s", -"musl/src/thread/powerpc64/syscall_cp.s", -"musl/src/thread/pthread_atfork.c", -"musl/src/thread/pthread_attr_destroy.c", -"musl/src/thread/pthread_attr_get.c", -"musl/src/thread/pthread_attr_init.c", -"musl/src/thread/pthread_attr_setdetachstate.c", -"musl/src/thread/pthread_attr_setguardsize.c", -"musl/src/thread/pthread_attr_setinheritsched.c", -"musl/src/thread/pthread_attr_setschedparam.c", -"musl/src/thread/pthread_attr_setschedpolicy.c", -"musl/src/thread/pthread_attr_setscope.c", -"musl/src/thread/pthread_attr_setstack.c", -"musl/src/thread/pthread_attr_setstacksize.c", -"musl/src/thread/pthread_barrier_destroy.c", -"musl/src/thread/pthread_barrier_init.c", -"musl/src/thread/pthread_barrier_wait.c", -"musl/src/thread/pthread_barrierattr_destroy.c", -"musl/src/thread/pthread_barrierattr_init.c", -"musl/src/thread/pthread_barrierattr_setpshared.c", -"musl/src/thread/pthread_cancel.c", -"musl/src/thread/pthread_cleanup_push.c", -"musl/src/thread/pthread_cond_broadcast.c", -"musl/src/thread/pthread_cond_destroy.c", -"musl/src/thread/pthread_cond_init.c", -"musl/src/thread/pthread_cond_signal.c", -"musl/src/thread/pthread_cond_timedwait.c", -"musl/src/thread/pthread_cond_wait.c", -"musl/src/thread/pthread_condattr_destroy.c", -"musl/src/thread/pthread_condattr_init.c", -"musl/src/thread/pthread_condattr_setclock.c", -"musl/src/thread/pthread_condattr_setpshared.c", -"musl/src/thread/pthread_create.c", -"musl/src/thread/pthread_detach.c", -"musl/src/thread/pthread_equal.c", -"musl/src/thread/pthread_getattr_np.c", -"musl/src/thread/pthread_getconcurrency.c", -"musl/src/thread/pthread_getcpuclockid.c", -"musl/src/thread/pthread_getschedparam.c", -"musl/src/thread/pthread_getspecific.c", -"musl/src/thread/pthread_join.c", -"musl/src/thread/pthread_key_create.c", -"musl/src/thread/pthread_kill.c", -"musl/src/thread/pthread_mutex_consistent.c", -"musl/src/thread/pthread_mutex_destroy.c", -"musl/src/thread/pthread_mutex_getprioceiling.c", -"musl/src/thread/pthread_mutex_init.c", -"musl/src/thread/pthread_mutex_lock.c", -"musl/src/thread/pthread_mutex_setprioceiling.c", -"musl/src/thread/pthread_mutex_timedlock.c", -"musl/src/thread/pthread_mutex_trylock.c", -"musl/src/thread/pthread_mutex_unlock.c", -"musl/src/thread/pthread_mutexattr_destroy.c", -"musl/src/thread/pthread_mutexattr_init.c", -"musl/src/thread/pthread_mutexattr_setprotocol.c", -"musl/src/thread/pthread_mutexattr_setpshared.c", -"musl/src/thread/pthread_mutexattr_setrobust.c", -"musl/src/thread/pthread_mutexattr_settype.c", -"musl/src/thread/pthread_once.c", -"musl/src/thread/pthread_rwlock_destroy.c", -"musl/src/thread/pthread_rwlock_init.c", -"musl/src/thread/pthread_rwlock_rdlock.c", -"musl/src/thread/pthread_rwlock_timedrdlock.c", -"musl/src/thread/pthread_rwlock_timedwrlock.c", -"musl/src/thread/pthread_rwlock_tryrdlock.c", -"musl/src/thread/pthread_rwlock_trywrlock.c", -"musl/src/thread/pthread_rwlock_unlock.c", -"musl/src/thread/pthread_rwlock_wrlock.c", -"musl/src/thread/pthread_rwlockattr_destroy.c", -"musl/src/thread/pthread_rwlockattr_init.c", -"musl/src/thread/pthread_rwlockattr_setpshared.c", -"musl/src/thread/pthread_self.c", -"musl/src/thread/pthread_setattr_default_np.c", -"musl/src/thread/pthread_setcancelstate.c", -"musl/src/thread/pthread_setcanceltype.c", -"musl/src/thread/pthread_setconcurrency.c", -"musl/src/thread/pthread_setname_np.c", -"musl/src/thread/pthread_setschedparam.c", -"musl/src/thread/pthread_setschedprio.c", -"musl/src/thread/pthread_setspecific.c", -"musl/src/thread/pthread_sigmask.c", -"musl/src/thread/pthread_spin_destroy.c", -"musl/src/thread/pthread_spin_init.c", -"musl/src/thread/pthread_spin_lock.c", -"musl/src/thread/pthread_spin_trylock.c", -"musl/src/thread/pthread_spin_unlock.c", -"musl/src/thread/pthread_testcancel.c", -"musl/src/thread/riscv64/__set_thread_area.s", -"musl/src/thread/riscv64/__unmapself.s", -"musl/src/thread/riscv64/clone.s", -"musl/src/thread/riscv64/syscall_cp.s", -"musl/src/thread/s390x/__set_thread_area.s", -"musl/src/thread/s390x/__tls_get_offset.s", -"musl/src/thread/s390x/__unmapself.s", -"musl/src/thread/s390x/clone.s", -"musl/src/thread/s390x/syscall_cp.s", -"musl/src/thread/sem_destroy.c", -"musl/src/thread/sem_getvalue.c", -"musl/src/thread/sem_init.c", -"musl/src/thread/sem_open.c", -"musl/src/thread/sem_post.c", -"musl/src/thread/sem_timedwait.c", -"musl/src/thread/sem_trywait.c", -"musl/src/thread/sem_unlink.c", -"musl/src/thread/sem_wait.c", -"musl/src/thread/sh/__set_thread_area.c", -"musl/src/thread/sh/__unmapself.c", -"musl/src/thread/sh/__unmapself_mmu.s", -"musl/src/thread/sh/atomics.s", -"musl/src/thread/sh/clone.s", -"musl/src/thread/sh/syscall_cp.s", -"musl/src/thread/synccall.c", -"musl/src/thread/syscall_cp.c", -"musl/src/thread/thrd_create.c", -"musl/src/thread/thrd_exit.c", -"musl/src/thread/thrd_join.c", -"musl/src/thread/thrd_sleep.c", -"musl/src/thread/thrd_yield.c", -"musl/src/thread/tls.c", -"musl/src/thread/tss_create.c", -"musl/src/thread/tss_delete.c", -"musl/src/thread/tss_set.c", -"musl/src/thread/vmlock.c", -"musl/src/thread/x32/__set_thread_area.s", -"musl/src/thread/x32/__unmapself.s", -"musl/src/thread/x32/clone.s", -"musl/src/thread/x32/syscall_cp.s", -"musl/src/thread/x86_64/__set_thread_area.s", -"musl/src/thread/x86_64/__unmapself.s", -"musl/src/thread/x86_64/clone.s", -"musl/src/thread/x86_64/syscall_cp.s", -"musl/src/time/__map_file.c", -"musl/src/time/__month_to_secs.c", -"musl/src/time/__secs_to_tm.c", -"musl/src/time/__tm_to_secs.c", -"musl/src/time/__tz.c", -"musl/src/time/__year_to_secs.c", -"musl/src/time/asctime.c", -"musl/src/time/asctime_r.c", -"musl/src/time/clock.c", -"musl/src/time/clock_getcpuclockid.c", -"musl/src/time/clock_getres.c", -"musl/src/time/clock_gettime.c", -"musl/src/time/clock_nanosleep.c", -"musl/src/time/clock_settime.c", -"musl/src/time/ctime.c", -"musl/src/time/ctime_r.c", -"musl/src/time/difftime.c", -"musl/src/time/ftime.c", -"musl/src/time/getdate.c", -"musl/src/time/gettimeofday.c", -"musl/src/time/gmtime.c", -"musl/src/time/gmtime_r.c", -"musl/src/time/localtime.c", -"musl/src/time/localtime_r.c", -"musl/src/time/mktime.c", -"musl/src/time/nanosleep.c", -"musl/src/time/strftime.c", -"musl/src/time/strptime.c", -"musl/src/time/time.c", -"musl/src/time/timegm.c", -"musl/src/time/timer_create.c", -"musl/src/time/timer_delete.c", -"musl/src/time/timer_getoverrun.c", -"musl/src/time/timer_gettime.c", -"musl/src/time/timer_settime.c", -"musl/src/time/times.c", -"musl/src/time/timespec_get.c", -"musl/src/time/utime.c", -"musl/src/time/wcsftime.c", -"musl/src/unistd/_exit.c", -"musl/src/unistd/access.c", -"musl/src/unistd/acct.c", -"musl/src/unistd/alarm.c", -"musl/src/unistd/chdir.c", -"musl/src/unistd/chown.c", -"musl/src/unistd/close.c", -"musl/src/unistd/ctermid.c", -"musl/src/unistd/dup.c", -"musl/src/unistd/dup2.c", -"musl/src/unistd/dup3.c", -"musl/src/unistd/faccessat.c", -"musl/src/unistd/fchdir.c", -"musl/src/unistd/fchown.c", -"musl/src/unistd/fchownat.c", -"musl/src/unistd/fdatasync.c", -"musl/src/unistd/fsync.c", -"musl/src/unistd/ftruncate.c", -"musl/src/unistd/getcwd.c", -"musl/src/unistd/getegid.c", -"musl/src/unistd/geteuid.c", -"musl/src/unistd/getgid.c", -"musl/src/unistd/getgroups.c", -"musl/src/unistd/gethostname.c", -"musl/src/unistd/getlogin.c", -"musl/src/unistd/getlogin_r.c", -"musl/src/unistd/getpgid.c", -"musl/src/unistd/getpgrp.c", -"musl/src/unistd/getpid.c", -"musl/src/unistd/getppid.c", -"musl/src/unistd/getsid.c", -"musl/src/unistd/getuid.c", -"musl/src/unistd/isatty.c", -"musl/src/unistd/lchown.c", -"musl/src/unistd/link.c", -"musl/src/unistd/linkat.c", -"musl/src/unistd/lseek.c", -"musl/src/unistd/mips/pipe.s", -"musl/src/unistd/mips64/pipe.s", -"musl/src/unistd/mipsn32/lseek.c", -"musl/src/unistd/mipsn32/pipe.s", -"musl/src/unistd/nice.c", -"musl/src/unistd/pause.c", -"musl/src/unistd/pipe.c", -"musl/src/unistd/pipe2.c", -"musl/src/unistd/posix_close.c", -"musl/src/unistd/pread.c", -"musl/src/unistd/preadv.c", -"musl/src/unistd/pwrite.c", -"musl/src/unistd/pwritev.c", -"musl/src/unistd/read.c", -"musl/src/unistd/readlink.c", -"musl/src/unistd/readlinkat.c", -"musl/src/unistd/readv.c", -"musl/src/unistd/renameat.c", -"musl/src/unistd/rmdir.c", -"musl/src/unistd/setegid.c", -"musl/src/unistd/seteuid.c", -"musl/src/unistd/setgid.c", -"musl/src/unistd/setpgid.c", -"musl/src/unistd/setpgrp.c", -"musl/src/unistd/setregid.c", -"musl/src/unistd/setresgid.c", -"musl/src/unistd/setresuid.c", -"musl/src/unistd/setreuid.c", -"musl/src/unistd/setsid.c", -"musl/src/unistd/setuid.c", -"musl/src/unistd/setxid.c", -"musl/src/unistd/sh/pipe.s", -"musl/src/unistd/sleep.c", -"musl/src/unistd/symlink.c", -"musl/src/unistd/symlinkat.c", -"musl/src/unistd/sync.c", -"musl/src/unistd/tcgetpgrp.c", -"musl/src/unistd/tcsetpgrp.c", -"musl/src/unistd/truncate.c", -"musl/src/unistd/ttyname.c", -"musl/src/unistd/ttyname_r.c", -"musl/src/unistd/ualarm.c", -"musl/src/unistd/unlink.c", -"musl/src/unistd/unlinkat.c", -"musl/src/unistd/usleep.c", -"musl/src/unistd/write.c", -"musl/src/unistd/writev.c", -"musl/src/unistd/x32/lseek.c", -}; -static const char *ZIG_MUSL_COMPAT_TIME32_FILES[] = { -"musl/compat/time32/__xstat.c", -"musl/compat/time32/adjtime32.c", -"musl/compat/time32/adjtimex_time32.c", -"musl/compat/time32/aio_suspend_time32.c", -"musl/compat/time32/clock_adjtime32.c", -"musl/compat/time32/clock_getres_time32.c", -"musl/compat/time32/clock_gettime32.c", -"musl/compat/time32/clock_nanosleep_time32.c", -"musl/compat/time32/clock_settime32.c", -"musl/compat/time32/cnd_timedwait_time32.c", -"musl/compat/time32/ctime32.c", -"musl/compat/time32/ctime32_r.c", -"musl/compat/time32/difftime32.c", -"musl/compat/time32/fstat_time32.c", -"musl/compat/time32/fstatat_time32.c", -"musl/compat/time32/ftime32.c", -"musl/compat/time32/futimens_time32.c", -"musl/compat/time32/futimes_time32.c", -"musl/compat/time32/futimesat_time32.c", -"musl/compat/time32/getitimer_time32.c", -"musl/compat/time32/getrusage_time32.c", -"musl/compat/time32/gettimeofday_time32.c", -"musl/compat/time32/gmtime32.c", -"musl/compat/time32/gmtime32_r.c", -"musl/compat/time32/localtime32.c", -"musl/compat/time32/localtime32_r.c", -"musl/compat/time32/lstat_time32.c", -"musl/compat/time32/lutimes_time32.c", -"musl/compat/time32/mktime32.c", -"musl/compat/time32/mq_timedreceive_time32.c", -"musl/compat/time32/mq_timedsend_time32.c", -"musl/compat/time32/mtx_timedlock_time32.c", -"musl/compat/time32/nanosleep_time32.c", -"musl/compat/time32/ppoll_time32.c", -"musl/compat/time32/pselect_time32.c", -"musl/compat/time32/pthread_cond_timedwait_time32.c", -"musl/compat/time32/pthread_mutex_timedlock_time32.c", -"musl/compat/time32/pthread_rwlock_timedrdlock_time32.c", -"musl/compat/time32/pthread_rwlock_timedwrlock_time32.c", -"musl/compat/time32/pthread_timedjoin_np_time32.c", -"musl/compat/time32/recvmmsg_time32.c", -"musl/compat/time32/sched_rr_get_interval_time32.c", -"musl/compat/time32/select_time32.c", -"musl/compat/time32/sem_timedwait_time32.c", -"musl/compat/time32/semtimedop_time32.c", -"musl/compat/time32/setitimer_time32.c", -"musl/compat/time32/settimeofday_time32.c", -"musl/compat/time32/sigtimedwait_time32.c", -"musl/compat/time32/stat_time32.c", -"musl/compat/time32/stime32.c", -"musl/compat/time32/thrd_sleep_time32.c", -"musl/compat/time32/time32.c", -"musl/compat/time32/time32gm.c", -"musl/compat/time32/timer_gettime32.c", -"musl/compat/time32/timer_settime32.c", -"musl/compat/time32/timerfd_gettime32.c", -"musl/compat/time32/timerfd_settime32.c", -"musl/compat/time32/timespec_get_time32.c", -"musl/compat/time32/utime_time32.c", -"musl/compat/time32/utimensat_time32.c", -"musl/compat/time32/utimes_time32.c", -"musl/compat/time32/wait3_time32.c", -"musl/compat/time32/wait4_time32.c", -}; -static const char *ZIG_LIBCXXABI_FILES[] = { -"src/abort_message.cpp", -"src/cxa_aux_runtime.cpp", -"src/cxa_default_handlers.cpp", -"src/cxa_demangle.cpp", -"src/cxa_exception.cpp", -"src/cxa_exception_storage.cpp", -"src/cxa_guard.cpp", -"src/cxa_handlers.cpp", -"src/cxa_noexception.cpp", -"src/cxa_personality.cpp", -"src/cxa_thread_atexit.cpp", -"src/cxa_unexpected.cpp", -"src/cxa_vector.cpp", -"src/cxa_virtual.cpp", -"src/fallback_malloc.cpp", -"src/private_typeinfo.cpp", -"src/stdlib_exception.cpp", -"src/stdlib_stdexcept.cpp", -"src/stdlib_typeinfo.cpp", -}; -static const char *ZIG_LIBCXX_FILES[] = { -"src/algorithm.cpp", -"src/any.cpp", -"src/bind.cpp", -"src/charconv.cpp", -"src/chrono.cpp", -"src/condition_variable.cpp", -"src/condition_variable_destructor.cpp", -"src/debug.cpp", -"src/exception.cpp", -"src/experimental/memory_resource.cpp", -"src/filesystem/directory_iterator.cpp", -"src/filesystem/operations.cpp", -"src/functional.cpp", -"src/future.cpp", -"src/hash.cpp", -"src/ios.cpp", -"src/iostream.cpp", -"src/locale.cpp", -"src/memory.cpp", -"src/mutex.cpp", -"src/mutex_destructor.cpp", -"src/new.cpp", -"src/optional.cpp", -"src/random.cpp", -"src/regex.cpp", -"src/shared_mutex.cpp", -"src/stdexcept.cpp", -"src/string.cpp", -"src/strstream.cpp", -"src/support/solaris/xlocale.cpp", -"src/support/win32/locale_win32.cpp", -"src/support/win32/support.cpp", -"src/support/win32/thread_win32.cpp", -"src/system_error.cpp", -"src/thread.cpp", -"src/typeinfo.cpp", -"src/utility.cpp", -"src/valarray.cpp", -"src/variant.cpp", -"src/vector.cpp", -}; -#endif diff --git a/src/ir.cpp b/src/ir.cpp index 6cb5d8bc2d..50076f9a86 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -22570,38 +22570,12 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name } static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { - bool is_libc = target_is_libc_lib_name(ira->codegen->zig_target, buf_ptr(lib_name)); - if (is_libc && ira->codegen->libc_link_lib == nullptr && !ira->codegen->reported_bad_link_libc_error) { - ir_add_error_node(ira, source_node, - buf_sprintf("dependency on library c must be explicitly specified in the build command")); - ira->codegen->reported_bad_link_libc_error = true; - } - - LinkLib *link_lib = add_link_lib(ira->codegen, lib_name); - for (size_t i = 0; i < link_lib->symbols.length; i += 1) { - Buf *existing_symbol_name = link_lib->symbols.at(i); - if (buf_eql_buf(existing_symbol_name, symbol_name)) { - return; - } - } - - if (!is_libc && !target_is_wasm(ira->codegen->zig_target) && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) { - ErrorMsg *msg = ir_add_error_node(ira, source_node, - buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code", - buf_ptr(lib_name))); - add_error_note(ira->codegen, msg, source_node, - buf_sprintf("fixed by `--library %s` or `-fPIC`", buf_ptr(lib_name))); + const char *msg = stage2_add_link_lib(&ira->codegen->stage1, buf_ptr(lib_name), buf_len(lib_name), + buf_ptr(symbol_name), buf_len(symbol_name)); + if (msg != nullptr) { + ir_add_error_node(ira, source_node, buf_create_from_str(msg)); ira->codegen->reported_bad_link_libc_error = true; } - - for (size_t i = 0; i < ira->codegen->forbidden_libs.length; i += 1) { - Buf *forbidden_lib_name = ira->codegen->forbidden_libs.at(i); - if (buf_eql_buf(lib_name, forbidden_lib_name)) { - ir_add_error_node(ira, source_node, - buf_sprintf("linking against forbidden library '%s'", buf_ptr(symbol_name))); - } - } - link_lib->symbols.append(symbol_name); } static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst* source_instr) { @@ -26355,13 +26329,6 @@ static IrInstGen *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstSrcType return result; } -static void ir_cimport_cache_paths(Buf *cache_dir, Buf *tmp_c_file_digest, Buf *out_zig_dir, Buf *out_zig_path) { - buf_resize(out_zig_dir, 0); - buf_resize(out_zig_path, 0); - buf_appendf(out_zig_dir, "%s" OS_SEP "o" OS_SEP "%s", - buf_ptr(cache_dir), buf_ptr(tmp_c_file_digest)); - buf_appendf(out_zig_path, "%s" OS_SEP "cimport.zig", buf_ptr(out_zig_dir)); -} static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImport *instruction) { Error err; AstNode *node = instruction->base.base.source_node; @@ -26393,145 +26360,7 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo cimport_pkg->package_table.put(buf_create_from_str("std"), ira->codegen->std_package); buf_init_from_buf(&cimport_pkg->pkg_path, namespace_name); - CacheHash *cache_hash; - if ((err = create_c_object_cache(ira->codegen, &cache_hash, false))) { - ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to create cache: %s", err_str(err))); - return ira->codegen->invalid_inst_gen; - } - cache_buf(cache_hash, &cimport_scope->buf); - - // Set this because we're not adding any files before checking for a hit. - cache_hash->force_check_manifest = true; - - Buf tmp_c_file_digest = BUF_INIT; - buf_resize(&tmp_c_file_digest, 0); - if ((err = cache_hit(cache_hash, &tmp_c_file_digest))) { - if (err != ErrorInvalidFormat) { - ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to check cache: %s", err_str(err))); - return ira->codegen->invalid_inst_gen; - } - } - ira->codegen->caches_to_release.append(cache_hash); - - Buf *out_zig_dir = buf_alloc(); - Buf *out_zig_path = buf_alloc(); - if (buf_len(&tmp_c_file_digest) == 0 || cache_hash->files.length == 0) { - // Cache Miss - Buf *tmp_c_file_dir = buf_sprintf("%s" OS_SEP "o" OS_SEP "%s", - buf_ptr(ira->codegen->cache_dir), buf_ptr(&cache_hash->b64_digest)); - Buf *resolve_paths[] = { - tmp_c_file_dir, - buf_create_from_str("cimport.h"), - }; - Buf tmp_c_file_path = os_path_resolve(resolve_paths, 2); - - if ((err = os_make_path(tmp_c_file_dir))) { - ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); - return ira->codegen->invalid_inst_gen; - } - - if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { - ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); - return ira->codegen->invalid_inst_gen; - } - if (ira->codegen->verbose_cimport) { - fprintf(stderr, "@cImport source: %s\n", buf_ptr(&tmp_c_file_path)); - } - - Buf *tmp_dep_file = buf_sprintf("%s.d", buf_ptr(&tmp_c_file_path)); - - ZigList clang_argv = {0}; - - add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true, FileExtC); - - clang_argv.append(buf_ptr(&tmp_c_file_path)); - - if (ira->codegen->verbose_cc) { - fprintf(stderr, "clang"); - for (size_t i = 0; i < clang_argv.length; i += 1) { - fprintf(stderr, " %s", clang_argv.at(i)); - } - fprintf(stderr, "\n"); - } - - clang_argv.append(nullptr); // to make the [start...end] argument work - - Stage2ErrorMsg *errors_ptr; - size_t errors_len; - Stage2Ast *ast; - - const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir); - - if ((err = stage2_translate_c(&ast, &errors_ptr, &errors_len, - &clang_argv.at(0), &clang_argv.last(), resources_path))) - { - if (err != ErrorCCompileErrors) { - ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); - return ira->codegen->invalid_inst_gen; - } - - ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed")); - if (ira->codegen->libc_link_lib == nullptr) { - add_error_note(ira->codegen, parent_err_msg, node, - buf_sprintf("libc headers not available; compilation does not link against libc")); - } - for (size_t i = 0; i < errors_len; i += 1) { - Stage2ErrorMsg *clang_err = &errors_ptr[i]; - // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null - if (clang_err->source && clang_err->filename_ptr) { - ErrorMsg *err_msg = err_msg_create_with_offset( - clang_err->filename_ptr ? - buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), - clang_err->line, clang_err->column, clang_err->offset, clang_err->source, - buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); - err_msg_add_note(parent_err_msg, err_msg); - } - } - - return ira->codegen->invalid_inst_gen; - } - if (ira->codegen->verbose_cimport) { - fprintf(stderr, "@cImport .d file: %s\n", buf_ptr(tmp_dep_file)); - } - - if ((err = cache_add_dep_file(cache_hash, tmp_dep_file, false))) { - ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to parse .d file: %s", err_str(err))); - return ira->codegen->invalid_inst_gen; - } - if ((err = cache_final(cache_hash, &tmp_c_file_digest))) { - ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to finalize cache: %s", err_str(err))); - return ira->codegen->invalid_inst_gen; - } - - ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); - if ((err = os_make_path(out_zig_dir))) { - ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make output dir: %s", err_str(err))); - return ira->codegen->invalid_inst_gen; - } - FILE *out_file = fopen(buf_ptr(out_zig_path), "wb"); - if (out_file == nullptr) { - ir_add_error_node(ira, node, - buf_sprintf("C import failed: unable to open output file: %s", strerror(errno))); - return ira->codegen->invalid_inst_gen; - } - stage2_render_ast(ast, out_file); - if (fclose(out_file) != 0) { - ir_add_error_node(ira, node, - buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno))); - return ira->codegen->invalid_inst_gen; - } - - if (ira->codegen->verbose_cimport) { - fprintf(stderr, "@cImport output: %s\n", buf_ptr(out_zig_path)); - } - - } else { - // Cache Hit - ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); - if (ira->codegen->verbose_cimport) { - fprintf(stderr, "@cImport cache hit: %s\n", buf_ptr(out_zig_path)); - } - } + Buf *out_zig_path = buf_create_from_str(stage2_cimport(&ira->codegen->stage1)); Buf *import_code = buf_alloc(); if ((err = file_fetch(ira->codegen, out_zig_path, import_code))) { diff --git a/src/link.cpp b/src/link.cpp deleted file mode 100644 index 3983b48b42..0000000000 --- a/src/link.cpp +++ /dev/null @@ -1,2985 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Kelley - * - * This file is part of zig, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#include "os.hpp" -#include "config.h" -#include "codegen.hpp" -#include "analyze.hpp" -#include "compiler.hpp" -#include "install_files.h" -#include "glibc.hpp" - -static const char *msvcrt_common_src[] = { - "misc" OS_SEP "_create_locale.c", - "misc" OS_SEP "_free_locale.c", - "misc" OS_SEP "onexit_table.c", - "misc" OS_SEP "register_tls_atexit.c", - "stdio" OS_SEP "acrt_iob_func.c", - "misc" OS_SEP "_configthreadlocale.c", - "misc" OS_SEP "_get_current_locale.c", - "misc" OS_SEP "invalid_parameter_handler.c", - "misc" OS_SEP "output_format.c", - "misc" OS_SEP "purecall.c", - "secapi" OS_SEP "_access_s.c", - "secapi" OS_SEP "_cgets_s.c", - "secapi" OS_SEP "_cgetws_s.c", - "secapi" OS_SEP "_chsize_s.c", - "secapi" OS_SEP "_controlfp_s.c", - "secapi" OS_SEP "_cprintf_s.c", - "secapi" OS_SEP "_cprintf_s_l.c", - "secapi" OS_SEP "_ctime32_s.c", - "secapi" OS_SEP "_ctime64_s.c", - "secapi" OS_SEP "_cwprintf_s.c", - "secapi" OS_SEP "_cwprintf_s_l.c", - "secapi" OS_SEP "_gmtime32_s.c", - "secapi" OS_SEP "_gmtime64_s.c", - "secapi" OS_SEP "_localtime32_s.c", - "secapi" OS_SEP "_localtime64_s.c", - "secapi" OS_SEP "_mktemp_s.c", - "secapi" OS_SEP "_sopen_s.c", - "secapi" OS_SEP "_strdate_s.c", - "secapi" OS_SEP "_strtime_s.c", - "secapi" OS_SEP "_umask_s.c", - "secapi" OS_SEP "_vcprintf_s.c", - "secapi" OS_SEP "_vcprintf_s_l.c", - "secapi" OS_SEP "_vcwprintf_s.c", - "secapi" OS_SEP "_vcwprintf_s_l.c", - "secapi" OS_SEP "_vscprintf_p.c", - "secapi" OS_SEP "_vscwprintf_p.c", - "secapi" OS_SEP "_vswprintf_p.c", - "secapi" OS_SEP "_waccess_s.c", - "secapi" OS_SEP "_wasctime_s.c", - "secapi" OS_SEP "_wctime32_s.c", - "secapi" OS_SEP "_wctime64_s.c", - "secapi" OS_SEP "_wstrtime_s.c", - "secapi" OS_SEP "_wmktemp_s.c", - "secapi" OS_SEP "_wstrdate_s.c", - "secapi" OS_SEP "asctime_s.c", - "secapi" OS_SEP "memcpy_s.c", - "secapi" OS_SEP "memmove_s.c", - "secapi" OS_SEP "rand_s.c", - "secapi" OS_SEP "sprintf_s.c", - "secapi" OS_SEP "strerror_s.c", - "secapi" OS_SEP "vsprintf_s.c", - "secapi" OS_SEP "wmemcpy_s.c", - "secapi" OS_SEP "wmemmove_s.c", - "stdio" OS_SEP "mingw_lock.c", -}; - -static const char *msvcrt_i386_src[] = { - "misc" OS_SEP "lc_locale_func.c", - "misc" OS_SEP "___mb_cur_max_func.c", -}; - -static const char *msvcrt_other_src[] = { - "misc" OS_SEP "__p___argv.c", - "misc" OS_SEP "__p__acmdln.c", - "misc" OS_SEP "__p__fmode.c", - "misc" OS_SEP "__p__wcmdln.c", -}; - -static const char *mingwex_generic_src[] = { - "complex" OS_SEP "_cabs.c", - "complex" OS_SEP "cabs.c", - "complex" OS_SEP "cabsf.c", - "complex" OS_SEP "cabsl.c", - "complex" OS_SEP "cacos.c", - "complex" OS_SEP "cacosf.c", - "complex" OS_SEP "cacosl.c", - "complex" OS_SEP "carg.c", - "complex" OS_SEP "cargf.c", - "complex" OS_SEP "cargl.c", - "complex" OS_SEP "casin.c", - "complex" OS_SEP "casinf.c", - "complex" OS_SEP "casinl.c", - "complex" OS_SEP "catan.c", - "complex" OS_SEP "catanf.c", - "complex" OS_SEP "catanl.c", - "complex" OS_SEP "ccos.c", - "complex" OS_SEP "ccosf.c", - "complex" OS_SEP "ccosl.c", - "complex" OS_SEP "cexp.c", - "complex" OS_SEP "cexpf.c", - "complex" OS_SEP "cexpl.c", - "complex" OS_SEP "cimag.c", - "complex" OS_SEP "cimagf.c", - "complex" OS_SEP "cimagl.c", - "complex" OS_SEP "clog.c", - "complex" OS_SEP "clog10.c", - "complex" OS_SEP "clog10f.c", - "complex" OS_SEP "clog10l.c", - "complex" OS_SEP "clogf.c", - "complex" OS_SEP "clogl.c", - "complex" OS_SEP "conj.c", - "complex" OS_SEP "conjf.c", - "complex" OS_SEP "conjl.c", - "complex" OS_SEP "cpow.c", - "complex" OS_SEP "cpowf.c", - "complex" OS_SEP "cpowl.c", - "complex" OS_SEP "cproj.c", - "complex" OS_SEP "cprojf.c", - "complex" OS_SEP "cprojl.c", - "complex" OS_SEP "creal.c", - "complex" OS_SEP "crealf.c", - "complex" OS_SEP "creall.c", - "complex" OS_SEP "csin.c", - "complex" OS_SEP "csinf.c", - "complex" OS_SEP "csinl.c", - "complex" OS_SEP "csqrt.c", - "complex" OS_SEP "csqrtf.c", - "complex" OS_SEP "csqrtl.c", - "complex" OS_SEP "ctan.c", - "complex" OS_SEP "ctanf.c", - "complex" OS_SEP "ctanl.c", - "crt" OS_SEP "dllentry.c", - "crt" OS_SEP "dllmain.c", - "gdtoa" OS_SEP "arithchk.c", - "gdtoa" OS_SEP "dmisc.c", - "gdtoa" OS_SEP "dtoa.c", - "gdtoa" OS_SEP "g__fmt.c", - "gdtoa" OS_SEP "g_dfmt.c", - "gdtoa" OS_SEP "g_ffmt.c", - "gdtoa" OS_SEP "g_xfmt.c", - "gdtoa" OS_SEP "gdtoa.c", - "gdtoa" OS_SEP "gethex.c", - "gdtoa" OS_SEP "gmisc.c", - "gdtoa" OS_SEP "hd_init.c", - "gdtoa" OS_SEP "hexnan.c", - "gdtoa" OS_SEP "misc.c", - "gdtoa" OS_SEP "qnan.c", - "gdtoa" OS_SEP "smisc.c", - "gdtoa" OS_SEP "strtodg.c", - "gdtoa" OS_SEP "strtodnrp.c", - "gdtoa" OS_SEP "strtof.c", - "gdtoa" OS_SEP "strtopx.c", - "gdtoa" OS_SEP "sum.c", - "gdtoa" OS_SEP "ulp.c", - "math" OS_SEP "abs64.c", - "math" OS_SEP "cbrt.c", - "math" OS_SEP "cbrtf.c", - "math" OS_SEP "cbrtl.c", - "math" OS_SEP "cephes_emath.c", - "math" OS_SEP "copysign.c", - "math" OS_SEP "copysignf.c", - "math" OS_SEP "coshf.c", - "math" OS_SEP "coshl.c", - "math" OS_SEP "erfl.c", - "math" OS_SEP "expf.c", - "math" OS_SEP "fabs.c", - "math" OS_SEP "fabsf.c", - "math" OS_SEP "fabsl.c", - "math" OS_SEP "fdim.c", - "math" OS_SEP "fdimf.c", - "math" OS_SEP "fdiml.c", - "math" OS_SEP "fma.c", - "math" OS_SEP "fmaf.c", - "math" OS_SEP "fmal.c", - "math" OS_SEP "fmax.c", - "math" OS_SEP "fmaxf.c", - "math" OS_SEP "fmaxl.c", - "math" OS_SEP "fmin.c", - "math" OS_SEP "fminf.c", - "math" OS_SEP "fminl.c", - "math" OS_SEP "fp_consts.c", - "math" OS_SEP "fp_constsf.c", - "math" OS_SEP "fp_constsl.c", - "math" OS_SEP "fpclassify.c", - "math" OS_SEP "fpclassifyf.c", - "math" OS_SEP "fpclassifyl.c", - "math" OS_SEP "frexpf.c", - "math" OS_SEP "hypot.c", - "math" OS_SEP "hypotf.c", - "math" OS_SEP "hypotl.c", - "math" OS_SEP "isnan.c", - "math" OS_SEP "isnanf.c", - "math" OS_SEP "isnanl.c", - "math" OS_SEP "ldexpf.c", - "math" OS_SEP "lgamma.c", - "math" OS_SEP "lgammaf.c", - "math" OS_SEP "lgammal.c", - "math" OS_SEP "llrint.c", - "math" OS_SEP "llrintf.c", - "math" OS_SEP "llrintl.c", - "math" OS_SEP "llround.c", - "math" OS_SEP "llroundf.c", - "math" OS_SEP "llroundl.c", - "math" OS_SEP "log10f.c", - "math" OS_SEP "logf.c", - "math" OS_SEP "lrint.c", - "math" OS_SEP "lrintf.c", - "math" OS_SEP "lrintl.c", - "math" OS_SEP "lround.c", - "math" OS_SEP "lroundf.c", - "math" OS_SEP "lroundl.c", - "math" OS_SEP "modf.c", - "math" OS_SEP "modff.c", - "math" OS_SEP "modfl.c", - "math" OS_SEP "nextafterf.c", - "math" OS_SEP "nextafterl.c", - "math" OS_SEP "nexttoward.c", - "math" OS_SEP "nexttowardf.c", - "math" OS_SEP "powf.c", - "math" OS_SEP "powi.c", - "math" OS_SEP "powif.c", - "math" OS_SEP "powil.c", - "math" OS_SEP "rint.c", - "math" OS_SEP "rintf.c", - "math" OS_SEP "rintl.c", - "math" OS_SEP "round.c", - "math" OS_SEP "roundf.c", - "math" OS_SEP "roundl.c", - "math" OS_SEP "s_erf.c", - "math" OS_SEP "sf_erf.c", - "math" OS_SEP "signbit.c", - "math" OS_SEP "signbitf.c", - "math" OS_SEP "signbitl.c", - "math" OS_SEP "signgam.c", - "math" OS_SEP "sinhf.c", - "math" OS_SEP "sinhl.c", - "math" OS_SEP "sqrt.c", - "math" OS_SEP "sqrtf.c", - "math" OS_SEP "sqrtl.c", - "math" OS_SEP "tanhf.c", - "math" OS_SEP "tanhl.c", - "math" OS_SEP "tgamma.c", - "math" OS_SEP "tgammaf.c", - "math" OS_SEP "tgammal.c", - "math" OS_SEP "truncl.c", - "misc" OS_SEP "alarm.c", - "misc" OS_SEP "basename.c", - "misc" OS_SEP "btowc.c", - "misc" OS_SEP "delay-f.c", - "misc" OS_SEP "delay-n.c", - "misc" OS_SEP "delayimp.c", - "misc" OS_SEP "dirent.c", - "misc" OS_SEP "dirname.c", - "misc" OS_SEP "feclearexcept.c", - "misc" OS_SEP "fegetenv.c", - "misc" OS_SEP "fegetexceptflag.c", - "misc" OS_SEP "fegetround.c", - "misc" OS_SEP "feholdexcept.c", - "misc" OS_SEP "feraiseexcept.c", - "misc" OS_SEP "fesetenv.c", - "misc" OS_SEP "fesetexceptflag.c", - "misc" OS_SEP "fesetround.c", - "misc" OS_SEP "fetestexcept.c", - "misc" OS_SEP "feupdateenv.c", - "misc" OS_SEP "ftruncate.c", - "misc" OS_SEP "ftw.c", - "misc" OS_SEP "ftw64.c", - "misc" OS_SEP "fwide.c", - "misc" OS_SEP "getlogin.c", - "misc" OS_SEP "getopt.c", - "misc" OS_SEP "gettimeofday.c", - "misc" OS_SEP "imaxabs.c", - "misc" OS_SEP "imaxdiv.c", - "misc" OS_SEP "isblank.c", - "misc" OS_SEP "iswblank.c", - "misc" OS_SEP "mbrtowc.c", - "misc" OS_SEP "mbsinit.c", - "misc" OS_SEP "mempcpy.c", - "misc" OS_SEP "mingw-aligned-malloc.c", - "misc" OS_SEP "mingw-fseek.c", - "misc" OS_SEP "mingw_getsp.S", - "misc" OS_SEP "mingw_matherr.c", - "misc" OS_SEP "mingw_mbwc_convert.c", - "misc" OS_SEP "mingw_usleep.c", - "misc" OS_SEP "mingw_wcstod.c", - "misc" OS_SEP "mingw_wcstof.c", - "misc" OS_SEP "mingw_wcstold.c", - "misc" OS_SEP "mkstemp.c", - "misc" OS_SEP "seterrno.c", - "misc" OS_SEP "sleep.c", - "misc" OS_SEP "strnlen.c", - "misc" OS_SEP "strsafe.c", - "misc" OS_SEP "strtoimax.c", - "misc" OS_SEP "strtold.c", - "misc" OS_SEP "strtoumax.c", - "misc" OS_SEP "tdelete.c", - "misc" OS_SEP "tfind.c", - "misc" OS_SEP "tsearch.c", - "misc" OS_SEP "twalk.c", - "misc" OS_SEP "uchar_c16rtomb.c", - "misc" OS_SEP "uchar_c32rtomb.c", - "misc" OS_SEP "uchar_mbrtoc16.c", - "misc" OS_SEP "uchar_mbrtoc32.c", - "misc" OS_SEP "wassert.c", - "misc" OS_SEP "wcrtomb.c", - "misc" OS_SEP "wcsnlen.c", - "misc" OS_SEP "wcstof.c", - "misc" OS_SEP "wcstoimax.c", - "misc" OS_SEP "wcstold.c", - "misc" OS_SEP "wcstoumax.c", - "misc" OS_SEP "wctob.c", - "misc" OS_SEP "wctrans.c", - "misc" OS_SEP "wctype.c", - "misc" OS_SEP "wdirent.c", - "misc" OS_SEP "winbs_uint64.c", - "misc" OS_SEP "winbs_ulong.c", - "misc" OS_SEP "winbs_ushort.c", - "misc" OS_SEP "wmemchr.c", - "misc" OS_SEP "wmemcmp.c", - "misc" OS_SEP "wmemcpy.c", - "misc" OS_SEP "wmemmove.c", - "misc" OS_SEP "wmempcpy.c", - "misc" OS_SEP "wmemset.c", - "stdio" OS_SEP "_Exit.c", - "stdio" OS_SEP "_findfirst64i32.c", - "stdio" OS_SEP "_findnext64i32.c", - "stdio" OS_SEP "_fstat.c", - "stdio" OS_SEP "_fstat64i32.c", - "stdio" OS_SEP "_ftime.c", - "stdio" OS_SEP "_getc_nolock.c", - "stdio" OS_SEP "_getwc_nolock.c", - "stdio" OS_SEP "_putc_nolock.c", - "stdio" OS_SEP "_putwc_nolock.c", - "stdio" OS_SEP "_stat.c", - "stdio" OS_SEP "_stat64i32.c", - "stdio" OS_SEP "_wfindfirst64i32.c", - "stdio" OS_SEP "_wfindnext64i32.c", - "stdio" OS_SEP "_wstat.c", - "stdio" OS_SEP "_wstat64i32.c", - "stdio" OS_SEP "asprintf.c", - "stdio" OS_SEP "atoll.c", - "stdio" OS_SEP "fgetpos64.c", - "stdio" OS_SEP "fopen64.c", - "stdio" OS_SEP "fseeko32.c", - "stdio" OS_SEP "fseeko64.c", - "stdio" OS_SEP "fsetpos64.c", - "stdio" OS_SEP "ftello.c", - "stdio" OS_SEP "ftello64.c", - "stdio" OS_SEP "ftruncate64.c", - "stdio" OS_SEP "lltoa.c", - "stdio" OS_SEP "lltow.c", - "stdio" OS_SEP "lseek64.c", - "stdio" OS_SEP "mingw_asprintf.c", - "stdio" OS_SEP "mingw_fprintf.c", - "stdio" OS_SEP "mingw_fprintfw.c", - "stdio" OS_SEP "mingw_fscanf.c", - "stdio" OS_SEP "mingw_fwscanf.c", - "stdio" OS_SEP "mingw_pformat.c", - "stdio" OS_SEP "mingw_pformatw.c", - "stdio" OS_SEP "mingw_printf.c", - "stdio" OS_SEP "mingw_printfw.c", - "stdio" OS_SEP "mingw_scanf.c", - "stdio" OS_SEP "mingw_snprintf.c", - "stdio" OS_SEP "mingw_snprintfw.c", - "stdio" OS_SEP "mingw_sprintf.c", - "stdio" OS_SEP "mingw_sprintfw.c", - "stdio" OS_SEP "mingw_sscanf.c", - "stdio" OS_SEP "mingw_swscanf.c", - "stdio" OS_SEP "mingw_vasprintf.c", - "stdio" OS_SEP "mingw_vfprintf.c", - "stdio" OS_SEP "mingw_vfprintfw.c", - "stdio" OS_SEP "mingw_vfscanf.c", - "stdio" OS_SEP "mingw_vprintf.c", - "stdio" OS_SEP "mingw_vprintfw.c", - "stdio" OS_SEP "mingw_vsnprintf.c", - "stdio" OS_SEP "mingw_vsnprintfw.c", - "stdio" OS_SEP "mingw_vsprintf.c", - "stdio" OS_SEP "mingw_vsprintfw.c", - "stdio" OS_SEP "mingw_wscanf.c", - "stdio" OS_SEP "mingw_wvfscanf.c", - "stdio" OS_SEP "scanf.S", - "stdio" OS_SEP "snprintf.c", - "stdio" OS_SEP "snwprintf.c", - "stdio" OS_SEP "strtof.c", - "stdio" OS_SEP "strtok_r.c", - "stdio" OS_SEP "truncate.c", - "stdio" OS_SEP "ulltoa.c", - "stdio" OS_SEP "ulltow.c", - "stdio" OS_SEP "vasprintf.c", - "stdio" OS_SEP "vfscanf.c", - "stdio" OS_SEP "vfscanf2.S", - "stdio" OS_SEP "vfwscanf.c", - "stdio" OS_SEP "vfwscanf2.S", - "stdio" OS_SEP "vscanf.c", - "stdio" OS_SEP "vscanf2.S", - "stdio" OS_SEP "vsnprintf.c", - "stdio" OS_SEP "vsnwprintf.c", - "stdio" OS_SEP "vsscanf.c", - "stdio" OS_SEP "vsscanf2.S", - "stdio" OS_SEP "vswscanf.c", - "stdio" OS_SEP "vswscanf2.S", - "stdio" OS_SEP "vwscanf.c", - "stdio" OS_SEP "vwscanf2.S", - "stdio" OS_SEP "wtoll.c", -}; - -static const char *mingwex_x86_src[] = { - "math" OS_SEP "x86" OS_SEP "acosf.c", - "math" OS_SEP "x86" OS_SEP "acosh.c", - "math" OS_SEP "x86" OS_SEP "acoshf.c", - "math" OS_SEP "x86" OS_SEP "acoshl.c", - "math" OS_SEP "x86" OS_SEP "acosl.c", - "math" OS_SEP "x86" OS_SEP "asinf.c", - "math" OS_SEP "x86" OS_SEP "asinh.c", - "math" OS_SEP "x86" OS_SEP "asinhf.c", - "math" OS_SEP "x86" OS_SEP "asinhl.c", - "math" OS_SEP "x86" OS_SEP "asinl.c", - "math" OS_SEP "x86" OS_SEP "atan2.c", - "math" OS_SEP "x86" OS_SEP "atan2f.c", - "math" OS_SEP "x86" OS_SEP "atan2l.c", - "math" OS_SEP "x86" OS_SEP "atanf.c", - "math" OS_SEP "x86" OS_SEP "atanh.c", - "math" OS_SEP "x86" OS_SEP "atanhf.c", - "math" OS_SEP "x86" OS_SEP "atanhl.c", - "math" OS_SEP "x86" OS_SEP "atanl.c", - "math" OS_SEP "x86" OS_SEP "ceilf.S", - "math" OS_SEP "x86" OS_SEP "ceill.S", - "math" OS_SEP "x86" OS_SEP "ceil.S", - "math" OS_SEP "x86" OS_SEP "_chgsignl.S", - "math" OS_SEP "x86" OS_SEP "copysignl.S", - "math" OS_SEP "x86" OS_SEP "cos.c", - "math" OS_SEP "x86" OS_SEP "cosf.c", - "math" OS_SEP "x86" OS_SEP "cosl.c", - "math" OS_SEP "x86" OS_SEP "cosl_internal.S", - "math" OS_SEP "x86" OS_SEP "cossin.c", - "math" OS_SEP "x86" OS_SEP "exp2f.S", - "math" OS_SEP "x86" OS_SEP "exp2l.S", - "math" OS_SEP "x86" OS_SEP "exp2.S", - "math" OS_SEP "x86" OS_SEP "exp.c", - "math" OS_SEP "x86" OS_SEP "expl.c", - "math" OS_SEP "x86" OS_SEP "expm1.c", - "math" OS_SEP "x86" OS_SEP "expm1f.c", - "math" OS_SEP "x86" OS_SEP "expm1l.c", - "math" OS_SEP "x86" OS_SEP "floorf.S", - "math" OS_SEP "x86" OS_SEP "floorl.S", - "math" OS_SEP "x86" OS_SEP "floor.S", - "math" OS_SEP "x86" OS_SEP "fmod.c", - "math" OS_SEP "x86" OS_SEP "fmodf.c", - "math" OS_SEP "x86" OS_SEP "fmodl.c", - "math" OS_SEP "x86" OS_SEP "fucom.c", - "math" OS_SEP "x86" OS_SEP "ilogbf.S", - "math" OS_SEP "x86" OS_SEP "ilogbl.S", - "math" OS_SEP "x86" OS_SEP "ilogb.S", - "math" OS_SEP "x86" OS_SEP "internal_logl.S", - "math" OS_SEP "x86" OS_SEP "ldexp.c", - "math" OS_SEP "x86" OS_SEP "ldexpl.c", - "math" OS_SEP "x86" OS_SEP "log10l.S", - "math" OS_SEP "x86" OS_SEP "log1pf.S", - "math" OS_SEP "x86" OS_SEP "log1pl.S", - "math" OS_SEP "x86" OS_SEP "log1p.S", - "math" OS_SEP "x86" OS_SEP "log2f.S", - "math" OS_SEP "x86" OS_SEP "log2l.S", - "math" OS_SEP "x86" OS_SEP "log2.S", - "math" OS_SEP "x86" OS_SEP "logb.c", - "math" OS_SEP "x86" OS_SEP "logbf.c", - "math" OS_SEP "x86" OS_SEP "logbl.c", - "math" OS_SEP "x86" OS_SEP "log.c", - "math" OS_SEP "x86" OS_SEP "logl.c", - "math" OS_SEP "x86" OS_SEP "nearbyintf.S", - "math" OS_SEP "x86" OS_SEP "nearbyintl.S", - "math" OS_SEP "x86" OS_SEP "nearbyint.S", - "math" OS_SEP "x86" OS_SEP "pow.c", - "math" OS_SEP "x86" OS_SEP "powl.c", - "math" OS_SEP "x86" OS_SEP "remainderf.S", - "math" OS_SEP "x86" OS_SEP "remainderl.S", - "math" OS_SEP "x86" OS_SEP "remainder.S", - "math" OS_SEP "x86" OS_SEP "remquof.S", - "math" OS_SEP "x86" OS_SEP "remquol.S", - "math" OS_SEP "x86" OS_SEP "remquo.S", - "math" OS_SEP "x86" OS_SEP "scalbnf.S", - "math" OS_SEP "x86" OS_SEP "scalbnl.S", - "math" OS_SEP "x86" OS_SEP "scalbn.S", - "math" OS_SEP "x86" OS_SEP "sin.c", - "math" OS_SEP "x86" OS_SEP "sinf.c", - "math" OS_SEP "x86" OS_SEP "sinl.c", - "math" OS_SEP "x86" OS_SEP "sinl_internal.S", - "math" OS_SEP "x86" OS_SEP "tanf.c", - "math" OS_SEP "x86" OS_SEP "tanl.S", - "math" OS_SEP "x86" OS_SEP "truncf.S", - "math" OS_SEP "x86" OS_SEP "trunc.S", -}; - -static const char *mingwex_arm32_src[] = { - "math" OS_SEP "arm" OS_SEP "_chgsignl.S", - "math" OS_SEP "arm" OS_SEP "exp2.c", - "math" OS_SEP "arm" OS_SEP "nearbyint.S", - "math" OS_SEP "arm" OS_SEP "nearbyintf.S", - "math" OS_SEP "arm" OS_SEP "nearbyintl.S", - "math" OS_SEP "arm" OS_SEP "trunc.S", - "math" OS_SEP "arm" OS_SEP "truncf.S", -}; - -static const char *mingwex_arm64_src[] = { - "math" OS_SEP "arm64" OS_SEP "_chgsignl.S", - "math" OS_SEP "arm64" OS_SEP "exp2f.S", - "math" OS_SEP "arm64" OS_SEP "exp2.S", - "math" OS_SEP "arm64" OS_SEP "nearbyintf.S", - "math" OS_SEP "arm64" OS_SEP "nearbyintl.S", - "math" OS_SEP "arm64" OS_SEP "nearbyint.S", - "math" OS_SEP "arm64" OS_SEP "truncf.S", - "math" OS_SEP "arm64" OS_SEP "trunc.S", -}; - -static const char *mingw_uuid_src[] = { - "libsrc/ativscp-uuid.c", - "libsrc/atsmedia-uuid.c", - "libsrc/bth-uuid.c", - "libsrc/cguid-uuid.c", - "libsrc/comcat-uuid.c", - "libsrc/devguid.c", - "libsrc/docobj-uuid.c", - "libsrc/dxva-uuid.c", - "libsrc/exdisp-uuid.c", - "libsrc/extras-uuid.c", - "libsrc/fwp-uuid.c", - "libsrc/guid_nul.c", - "libsrc/hlguids-uuid.c", - "libsrc/hlink-uuid.c", - "libsrc/mlang-uuid.c", - "libsrc/msctf-uuid.c", - "libsrc/mshtmhst-uuid.c", - "libsrc/mshtml-uuid.c", - "libsrc/msxml-uuid.c", - "libsrc/netcon-uuid.c", - "libsrc/ntddkbd-uuid.c", - "libsrc/ntddmou-uuid.c", - "libsrc/ntddpar-uuid.c", - "libsrc/ntddscsi-uuid.c", - "libsrc/ntddser-uuid.c", - "libsrc/ntddstor-uuid.c", - "libsrc/ntddvdeo-uuid.c", - "libsrc/oaidl-uuid.c", - "libsrc/objidl-uuid.c", - "libsrc/objsafe-uuid.c", - "libsrc/ocidl-uuid.c", - "libsrc/oleacc-uuid.c", - "libsrc/olectlid-uuid.c", - "libsrc/oleidl-uuid.c", - "libsrc/power-uuid.c", - "libsrc/powrprof-uuid.c", - "libsrc/uianimation-uuid.c", - "libsrc/usbcamdi-uuid.c", - "libsrc/usbiodef-uuid.c", - "libsrc/uuid.c", - "libsrc/vds-uuid.c", - "libsrc/virtdisk-uuid.c", - "libsrc/wia-uuid.c", -}; - -struct MinGWDef { - const char *name; - bool always_link; -}; -static const MinGWDef mingw_def_list[] = { - {"advapi32",true}, - {"bcrypt", false}, - {"comctl32",false}, - {"comdlg32",false}, - {"crypt32", false}, - {"cryptnet",false}, - {"gdi32", false}, - {"imm32", false}, - {"kernel32",true}, - {"lz32", false}, - {"mpr", false}, - {"msvcrt", true}, - {"mswsock", false}, - {"ncrypt", false}, - {"netapi32",false}, - {"ntdll", true}, - {"ole32", false}, - {"oleaut32",false}, - {"opengl32",false}, - {"psapi", false}, - {"rpcns4", false}, - {"rpcrt4", false}, - {"scarddlg",false}, - {"setupapi",false}, - {"shell32", true}, - {"shlwapi", false}, - {"urlmon", false}, - {"user32", true}, - {"version", false}, - {"winmm", false}, - {"winscard",false}, - {"winspool",false}, - {"wintrust",false}, - {"ws2_32", false}, -}; - -struct LinkJob { - CodeGen *codegen; - ZigList args; - bool link_in_crt; - HashMap rpath_table; - Stage2ProgressNode *build_dep_prog_node; -}; - -static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFile *c_file, - Stage2ProgressNode *progress_node) -{ - CodeGen *child_gen = create_child_codegen(parent_gen, nullptr, OutTypeObj, nullptr, name, progress_node); - child_gen->root_out_name = buf_create_from_str(name); - ZigList c_source_files = {0}; - c_source_files.append(c_file); - child_gen->c_source_files = c_source_files; - codegen_build_and_link(child_gen); - return buf_ptr(&child_gen->bin_file_output_path); -} - -static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) { - Buf *dir1 = buf_alloc(); - os_path_join(g->zig_lib_dir, buf_create_from_str(dir), dir1); - Buf *result = buf_alloc(); - os_path_join(dir1, buf_create_from_str(subpath), result); - return buf_ptr(result); -} - -static const char *path_from_libc(CodeGen *g, const char *subpath) { - return path_from_zig_lib(g, "libc", subpath); -} - -static const char *path_from_libunwind(CodeGen *g, const char *subpath) { - return path_from_zig_lib(g, "libunwind", subpath); -} - -static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress_node) { - CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "unwind", progress_node); - LinkLib *new_link_lib = codegen_add_link_lib(child_gen, buf_create_from_str("c")); - new_link_lib->provided_explicitly = false; - enum SrcKind { - SrcCpp, - SrcC, - SrcAsm, - }; - static const struct { - const char *path; - SrcKind kind; - } unwind_src[] = { - {"src" OS_SEP "libunwind.cpp", SrcCpp}, - {"src" OS_SEP "Unwind-EHABI.cpp", SrcCpp}, - {"src" OS_SEP "Unwind-seh.cpp", SrcCpp}, - - {"src" OS_SEP "UnwindLevel1.c", SrcC}, - {"src" OS_SEP "UnwindLevel1-gcc-ext.c", SrcC}, - {"src" OS_SEP "Unwind-sjlj.c", SrcC}, - - {"src" OS_SEP "UnwindRegistersRestore.S", SrcAsm}, - {"src" OS_SEP "UnwindRegistersSave.S", SrcAsm}, - }; - ZigList c_source_files = {0}; - for (size_t i = 0; i < array_length(unwind_src); i += 1) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = path_from_libunwind(parent, unwind_src[i].path); - switch (unwind_src[i].kind) { - case SrcC: - c_file->args.append("-std=c99"); - break; - case SrcCpp: - c_file->args.append("-fno-rtti"); - c_file->args.append("-I"); - c_file->args.append(path_from_zig_lib(parent, "libcxx", "include")); - break; - case SrcAsm: - break; - } - c_file->args.append("-I"); - c_file->args.append(path_from_libunwind(parent, "include")); - if (target_supports_fpic(parent->zig_target)) { - c_file->args.append("-fPIC"); - } - c_file->args.append("-D_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS"); - c_file->args.append("-Wa,--noexecstack"); - - // This is intentionally always defined because the macro definition means, should it only - // build for the target specified by compiler defines. Since we pass -target the compiler - // defines will be correct. - c_file->args.append("-D_LIBUNWIND_IS_NATIVE_ONLY"); - - if (parent->build_mode == BuildModeDebug) { - c_file->args.append("-D_DEBUG"); - } - if (parent->is_single_threaded) { - c_file->args.append("-D_LIBUNWIND_HAS_NO_THREADS"); - } - c_file->args.append("-Wno-bitwise-conditional-parentheses"); - c_source_files.append(c_file); - } - child_gen->c_source_files = c_source_files; - codegen_build_and_link(child_gen); - return buf_ptr(&child_gen->bin_file_output_path); -} - -static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) { - c_file->args.append("-DHAVE_CONFIG_H"); - - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "include", - buf_ptr(parent->zig_lib_dir)))); - - c_file->args.append("-isystem"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "any-windows-any", - buf_ptr(parent->zig_lib_dir)))); - - if (target_is_arm(parent->zig_target) && - target_arch_pointer_bit_width(parent->zig_target->arch) == 32) - { - c_file->args.append("-mfpu=vfp"); - } - - c_file->args.append("-std=gnu11"); - c_file->args.append("-D_CRTBLD"); - c_file->args.append("-D_WIN32_WINNT=0x0f00"); - c_file->args.append("-D__MSVCRT_VERSION__=0x700"); -} - -static void glibc_add_include_dirs_arch(CFile *c_file, ZigLLVM_ArchType arch, const char *nptl, const char *dir) { - bool is_x86 = arch == ZigLLVM_x86 || arch == ZigLLVM_x86_64; - bool is_aarch64 = arch == ZigLLVM_aarch64 || arch == ZigLLVM_aarch64_be; - bool is_mips = arch == ZigLLVM_mips || arch == ZigLLVM_mipsel || - arch == ZigLLVM_mips64el || arch == ZigLLVM_mips64; - bool is_arm = arch == ZigLLVM_arm || arch == ZigLLVM_armeb; - bool is_ppc = arch == ZigLLVM_ppc || arch == ZigLLVM_ppc64 || arch == ZigLLVM_ppc64le; - bool is_riscv = arch == ZigLLVM_riscv32 || arch == ZigLLVM_riscv64; - bool is_sparc = arch == ZigLLVM_sparc || arch == ZigLLVM_sparcel || arch == ZigLLVM_sparcv9; - bool is_64 = target_arch_pointer_bit_width(arch) == 64; - - if (is_x86) { - if (arch == ZigLLVM_x86_64) { - if (nptl != nullptr) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86_64" OS_SEP "%s", dir, nptl))); - } else { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86_64", dir))); - } - } else if (arch == ZigLLVM_x86) { - if (nptl != nullptr) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "i386" OS_SEP "%s", dir, nptl))); - } else { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "i386", dir))); - } - } - if (nptl != nullptr) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86" OS_SEP "%s", dir, nptl))); - } else { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86", dir))); - } - } else if (is_arm) { - if (nptl != nullptr) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "arm" OS_SEP "%s", dir, nptl))); - } else { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "arm", dir))); - } - } else if (is_mips) { - if (nptl != nullptr) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips" OS_SEP "%s", dir, nptl))); - } else { - if (is_64) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips" OS_SEP "mips64", dir))); - } else { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips" OS_SEP "mips32", dir))); - } - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips", dir))); - } - } else if (is_sparc) { - if (nptl != nullptr) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc" OS_SEP "%s", dir, nptl))); - } else { - if (is_64) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc" OS_SEP "sparc64", dir))); - } else { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc" OS_SEP "sparc32", dir))); - } - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc", dir))); - } - } else if (is_aarch64) { - if (nptl != nullptr) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "aarch64" OS_SEP "%s", dir, nptl))); - } else { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "aarch64", dir))); - } - } else if (is_ppc) { - if (nptl != nullptr) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc" OS_SEP "%s", dir, nptl))); - } else { - if (is_64) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc" OS_SEP "powerpc64", dir))); - } else { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc" OS_SEP "powerpc32", dir))); - } - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc", dir))); - } - } else if (is_riscv) { - if (nptl != nullptr) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "riscv" OS_SEP "%s", dir, nptl))); - } else { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "riscv", dir))); - } - } -} - -static void glibc_add_include_dirs(CodeGen *parent, CFile *c_file) { - ZigLLVM_ArchType arch = parent->zig_target->arch; - const char *nptl = (parent->zig_target->os == OsLinux) ? "nptl" : "htl"; - const char *glibc = path_from_libc(parent, "glibc"); - - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "include", glibc))); - - if (parent->zig_target->os == OsLinux) { - glibc_add_include_dirs_arch(c_file, arch, nullptr, - path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix" OS_SEP "sysv" OS_SEP "linux")); - } - - if (nptl != nullptr) { - glibc_add_include_dirs_arch(c_file, arch, nptl, path_from_libc(parent, "glibc" OS_SEP "sysdeps")); - } - - if (parent->zig_target->os == OsLinux) { - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP - "unix" OS_SEP "sysv" OS_SEP "linux" OS_SEP "generic")); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP - "unix" OS_SEP "sysv" OS_SEP "linux" OS_SEP "include")); - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP - "unix" OS_SEP "sysv" OS_SEP "linux")); - } - if (nptl != nullptr) { - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sysdeps" OS_SEP "%s", glibc, nptl))); - } - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "pthread")); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix" OS_SEP "sysv")); - - glibc_add_include_dirs_arch(c_file, arch, nullptr, - path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix")); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix")); - - glibc_add_include_dirs_arch(c_file, arch, nullptr, path_from_libc(parent, "glibc" OS_SEP "sysdeps")); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "generic")); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "glibc")); - - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-%s", - buf_ptr(parent->zig_lib_dir), target_arch_name(parent->zig_target->arch), - target_os_name(parent->zig_target->os), target_abi_name(parent->zig_target->abi)))); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "include" OS_SEP "generic-glibc")); - - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-linux-any", - buf_ptr(parent->zig_lib_dir), target_arch_name(parent->zig_target->arch)))); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-linux-any")); -} - -static const char *glibc_start_asm_path(CodeGen *parent, const char *file) { - ZigLLVM_ArchType arch = parent->zig_target->arch; - bool is_aarch64 = arch == ZigLLVM_aarch64 || arch == ZigLLVM_aarch64_be; - bool is_mips = arch == ZigLLVM_mips || arch == ZigLLVM_mipsel || - arch == ZigLLVM_mips64el || arch == ZigLLVM_mips64; - bool is_arm = arch == ZigLLVM_arm || arch == ZigLLVM_armeb; - bool is_ppc = arch == ZigLLVM_ppc || arch == ZigLLVM_ppc64 || arch == ZigLLVM_ppc64le; - bool is_riscv = arch == ZigLLVM_riscv32 || arch == ZigLLVM_riscv64; - bool is_sparc = arch == ZigLLVM_sparc || arch == ZigLLVM_sparcel || arch == ZigLLVM_sparcv9; - bool is_64 = target_arch_pointer_bit_width(arch) == 64; - - Buf result = BUF_INIT; - buf_resize(&result, 0); - buf_append_buf(&result, parent->zig_lib_dir); - buf_append_str(&result, OS_SEP "libc" OS_SEP "glibc" OS_SEP "sysdeps" OS_SEP); - if (is_sparc) { - if (is_64) { - buf_append_str(&result, "sparc" OS_SEP "sparc64"); - } else { - buf_append_str(&result, "sparc" OS_SEP "sparc32"); - } - } else if (is_arm) { - buf_append_str(&result, "arm"); - } else if (is_mips) { - buf_append_str(&result, "mips"); - } else if (arch == ZigLLVM_x86_64) { - buf_append_str(&result, "x86_64"); - } else if (arch == ZigLLVM_x86) { - buf_append_str(&result, "i386"); - } else if (is_aarch64) { - buf_append_str(&result, "aarch64"); - } else if (is_riscv) { - buf_append_str(&result, "riscv"); - } else if (is_ppc) { - if (is_64) { - buf_append_str(&result, "powerpc" OS_SEP "powerpc64"); - } else { - buf_append_str(&result, "powerpc" OS_SEP "powerpc32"); - } - } - - buf_append_str(&result, OS_SEP); - buf_append_str(&result, file); - return buf_ptr(&result); -} - -static const char *musl_start_asm_path(CodeGen *parent, const char *file) { - Buf *result = buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "crt" OS_SEP "%s" OS_SEP "%s", - buf_ptr(parent->zig_lib_dir), target_arch_musl_name(parent->zig_target->arch), file); - return buf_ptr(result); -} - -static void musl_add_cc_args(CodeGen *parent, CFile *c_file, bool want_O3) { - c_file->args.append("-std=c99"); - c_file->args.append("-ffreestanding"); - // Musl adds these args to builds with gcc but clang does not support them. - //c_file->args.append("-fexcess-precision=standard"); - //c_file->args.append("-frounding-math"); - c_file->args.append("-Wa,--noexecstack"); - c_file->args.append("-D_XOPEN_SOURCE=700"); - - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "arch" OS_SEP "%s", - buf_ptr(parent->zig_lib_dir), target_arch_musl_name(parent->zig_target->arch)))); - - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "arch" OS_SEP "generic", - buf_ptr(parent->zig_lib_dir)))); - - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "src" OS_SEP "include", - buf_ptr(parent->zig_lib_dir)))); - - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "src" OS_SEP "internal", - buf_ptr(parent->zig_lib_dir)))); - - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "include", - buf_ptr(parent->zig_lib_dir)))); - - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf( - "%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-musl", - buf_ptr(parent->zig_lib_dir), - target_arch_musl_name(parent->zig_target->arch), - target_os_name(parent->zig_target->os)))); - - c_file->args.append("-I"); - c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "generic-musl", - buf_ptr(parent->zig_lib_dir)))); - - if (want_O3) - c_file->args.append("-O3"); - else - c_file->args.append("-Os"); - - c_file->args.append("-fomit-frame-pointer"); - c_file->args.append("-fno-unwind-tables"); - c_file->args.append("-fno-asynchronous-unwind-tables"); - c_file->args.append("-ffunction-sections"); - c_file->args.append("-fdata-sections"); -} - -static const char *musl_arch_names[] = { - "aarch64", - "arm", - "generic", - "i386", - "m68k", - "microblaze", - "mips", - "mips64", - "mipsn32", - "or1k", - "powerpc", - "powerpc64", - "riscv64", - "s390x", - "sh", - "x32", - "x86_64", -}; - -static bool is_musl_arch_name(const char *name) { - for (size_t i = 0; i < array_length(musl_arch_names); i += 1) { - if (strcmp(name, musl_arch_names[i]) == 0) - return true; - } - return false; -} - -enum MuslSrc { - MuslSrcAsm, - MuslSrcNormal, - MuslSrcO3, -}; - -static void add_musl_src_file(HashMap &source_table, - const char *file_path) -{ - Buf *src_file = buf_create_from_str(file_path); - - MuslSrc src_kind; - if (buf_ends_with_str(src_file, ".c")) { - bool want_O3 = buf_starts_with_str(src_file, "musl/src/malloc/") || - buf_starts_with_str(src_file, "musl/src/string/") || - buf_starts_with_str(src_file, "musl/src/internal/"); - src_kind = want_O3 ? MuslSrcO3 : MuslSrcNormal; - } else if (buf_ends_with_str(src_file, ".s") || buf_ends_with_str(src_file, ".S")) { - src_kind = MuslSrcAsm; - } else { - zig_unreachable(); - } - if (ZIG_OS_SEP_CHAR != '/') { - buf_replace(src_file, '/', ZIG_OS_SEP_CHAR); - } - source_table.put_unique(src_file, src_kind); -} - -static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node) { - CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c", progress_node); - - // When there is a src//foo.* then it should substitute for src/foo.* - // Even a .s file can substitute for a .c file. - - const char *target_musl_arch_name = target_arch_musl_name(parent->zig_target->arch); - - HashMap source_table = {}; - source_table.init(2000); - - for (size_t i = 0; i < array_length(ZIG_MUSL_SRC_FILES); i += 1) { - add_musl_src_file(source_table, ZIG_MUSL_SRC_FILES[i]); - } - - static const char *time32_compat_arch_list[] = {"arm", "i386", "mips", "powerpc"}; - for (size_t arch_i = 0; arch_i < array_length(time32_compat_arch_list); arch_i += 1) { - if (strcmp(target_musl_arch_name, time32_compat_arch_list[arch_i]) == 0) { - for (size_t i = 0; i < array_length(ZIG_MUSL_COMPAT_TIME32_FILES); i += 1) { - add_musl_src_file(source_table, ZIG_MUSL_COMPAT_TIME32_FILES[i]); - } - } - } - - - ZigList c_source_files = {0}; - - Buf dirname = BUF_INIT; - Buf basename = BUF_INIT; - Buf noextbasename = BUF_INIT; - Buf dirbasename = BUF_INIT; - Buf before_arch_dir = BUF_INIT; - - auto source_it = source_table.entry_iterator(); - for (;;) { - auto *entry = source_it.next(); - if (!entry) break; - - Buf *src_file = entry->key; - MuslSrc src_kind = entry->value; - - os_path_split(src_file, &dirname, &basename); - os_path_extname(&basename, &noextbasename, nullptr); - os_path_split(&dirname, &before_arch_dir, &dirbasename); - - bool is_arch_specific = false; - // Architecture-specific implementations are under a / folder. - if (is_musl_arch_name(buf_ptr(&dirbasename))) { - // Not the architecture we're compiling for. - if (strcmp(buf_ptr(&dirbasename), target_musl_arch_name) != 0) - continue; - is_arch_specific = true; - } - - if (!is_arch_specific) { - Buf override_path = BUF_INIT; - - // Look for an arch specific override. - buf_resize(&override_path, 0); - buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.s", - buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); - if (source_table.maybe_get(&override_path) != nullptr) - continue; - - buf_resize(&override_path, 0); - buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.S", - buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); - if (source_table.maybe_get(&override_path) != nullptr) - continue; - - buf_resize(&override_path, 0); - buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.c", - buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); - if (source_table.maybe_get(&override_path) != nullptr) - continue; - } - - Buf *full_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "%s", - buf_ptr(parent->zig_lib_dir), buf_ptr(src_file)); - - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = buf_ptr(full_path); - - musl_add_cc_args(parent, c_file, src_kind == MuslSrcO3); - c_file->args.append("-Qunused-arguments"); - c_file->args.append("-w"); // disable all warnings - - c_source_files.append(c_file); - } - - child_gen->c_source_files = c_source_files; - codegen_build_and_link(child_gen); - return buf_ptr(&child_gen->bin_file_output_path); -} - -static const char *build_libcxxabi(CodeGen *parent, Stage2ProgressNode *progress_node) { - CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c++abi", progress_node); - codegen_add_link_lib(child_gen, buf_create_from_str("c")); - - ZigList c_source_files = {0}; - - const char *cxxabi_include_path = buf_ptr(buf_sprintf("%s" OS_SEP "libcxxabi" OS_SEP "include", - buf_ptr(parent->zig_lib_dir))); - const char *cxx_include_path = buf_ptr(buf_sprintf("%s" OS_SEP "libcxx" OS_SEP "include", - buf_ptr(parent->zig_lib_dir))); - - for (size_t i = 0; i < array_length(ZIG_LIBCXXABI_FILES); i += 1) { - const char *rel_src_path = ZIG_LIBCXXABI_FILES[i]; - - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libcxxabi" OS_SEP "%s", - buf_ptr(parent->zig_lib_dir), rel_src_path)); - - c_file->args.append("-DHAVE___CXA_THREAD_ATEXIT_IMPL"); - c_file->args.append("-D_LIBCPP_DISABLE_EXTERN_TEMPLATE"); - c_file->args.append("-D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS"); - c_file->args.append("-D_LIBCXXABI_BUILDING_LIBRARY"); - c_file->args.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); - c_file->args.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS"); - - if (target_abi_is_musl(parent->zig_target->abi)) { - c_file->args.append("-D_LIBCPP_HAS_MUSL_LIBC"); - } - - c_file->args.append("-I"); - c_file->args.append(cxxabi_include_path); - - c_file->args.append("-I"); - c_file->args.append(cxx_include_path); - - c_file->args.append("-O3"); - c_file->args.append("-DNDEBUG"); - if (target_supports_fpic(parent->zig_target)) { - c_file->args.append("-fPIC"); - } - c_file->args.append("-nostdinc++"); - c_file->args.append("-fstrict-aliasing"); - c_file->args.append("-funwind-tables"); - c_file->args.append("-D_DEBUG"); - c_file->args.append("-UNDEBUG"); - c_file->args.append("-std=c++11"); - - c_source_files.append(c_file); - } - - - child_gen->c_source_files = c_source_files; - codegen_build_and_link(child_gen); - return buf_ptr(&child_gen->bin_file_output_path); -} - -static const char *build_libcxx(CodeGen *parent, Stage2ProgressNode *progress_node) { - CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c++", progress_node); - codegen_add_link_lib(child_gen, buf_create_from_str("c")); - - ZigList c_source_files = {0}; - - const char *cxxabi_include_path = buf_ptr(buf_sprintf("%s" OS_SEP "libcxxabi" OS_SEP "include", - buf_ptr(parent->zig_lib_dir))); - const char *cxx_include_path = buf_ptr(buf_sprintf("%s" OS_SEP "libcxx" OS_SEP "include", - buf_ptr(parent->zig_lib_dir))); - - for (size_t i = 0; i < array_length(ZIG_LIBCXX_FILES); i += 1) { - const char *rel_src_path = ZIG_LIBCXX_FILES[i]; - - Buf *src_path_buf = buf_create_from_str(rel_src_path); - if (parent->zig_target->os == OsWindows) { - // filesystem stuff isn't supported on Windows - if (buf_starts_with_str(src_path_buf, "src/filesystem/")) { - continue; - } - } else { - if (buf_starts_with_str(src_path_buf, "src/support/win32/")) { - continue; - } - } - - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libcxx" OS_SEP "%s", - buf_ptr(parent->zig_lib_dir), rel_src_path)); - - c_file->args.append("-DNDEBUG"); - c_file->args.append("-D_LIBCPP_BUILDING_LIBRARY"); - c_file->args.append("-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER"); - c_file->args.append("-DLIBCXX_BUILDING_LIBCXXABI"); - c_file->args.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); - c_file->args.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS"); - - if (target_abi_is_musl(parent->zig_target->abi)) { - c_file->args.append("-D_LIBCPP_HAS_MUSL_LIBC"); - } - - c_file->args.append("-I"); - c_file->args.append(cxx_include_path); - - c_file->args.append("-I"); - c_file->args.append(cxxabi_include_path); - - c_file->args.append("-O3"); - c_file->args.append("-DNDEBUG"); - if (target_supports_fpic(parent->zig_target)) { - c_file->args.append("-fPIC"); - } - c_file->args.append("-nostdinc++"); - c_file->args.append("-fvisibility-inlines-hidden"); - c_file->args.append("-std=c++14"); - c_file->args.append("-Wno-user-defined-literals"); - - c_source_files.append(c_file); - } - - - child_gen->c_source_files = c_source_files; - codegen_build_and_link(child_gen); - return buf_ptr(&child_gen->bin_file_output_path); -} - -static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s", - buf_ptr(parent->zig_lib_dir), src_path)); - c_file->args.append("-DHAVE_CONFIG_H"); - c_file->args.append("-D__LIBMSVCRT__"); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include")); - - c_file->args.append("-std=gnu99"); - c_file->args.append("-D_CRTBLD"); - c_file->args.append("-D_WIN32_WINNT=0x0f00"); - c_file->args.append("-D__MSVCRT_VERSION__=0x700"); - - c_file->args.append("-isystem"); - c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any")); - - c_file->args.append("-g"); - c_file->args.append("-O2"); - - child_gen->c_source_files.append(c_file); -} - -static void add_mingwex_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s", - buf_ptr(parent->zig_lib_dir), src_path)); - c_file->args.append("-DHAVE_CONFIG_H"); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "mingw")); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include")); - - c_file->args.append("-std=gnu99"); - c_file->args.append("-D_CRTBLD"); - c_file->args.append("-D_WIN32_WINNT=0x0f00"); - c_file->args.append("-D__MSVCRT_VERSION__=0x700"); - c_file->args.append("-g"); - c_file->args.append("-O2"); - - c_file->args.append("-isystem"); - c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any")); - - child_gen->c_source_files.append(c_file); -} - -static void add_mingw_uuid_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s", - buf_ptr(parent->zig_lib_dir), src_path)); - c_file->args.append("-DHAVE_CONFIG_H"); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "mingw")); - - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include")); - - c_file->args.append("-std=gnu99"); - c_file->args.append("-D_CRTBLD"); - c_file->args.append("-D_WIN32_WINNT=0x0f00"); - c_file->args.append("-D__MSVCRT_VERSION__=0x700"); - c_file->args.append("-g"); - c_file->args.append("-O2"); - - c_file->args.append("-isystem"); - c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any")); - - child_gen->c_source_files.append(c_file); -} - -static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2ProgressNode *progress_node) { - if (parent->libc == nullptr && parent->zig_target->os == OsWindows) { - if (strcmp(file, "crt2.o") == 0) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = buf_ptr(buf_sprintf( - "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "crt" OS_SEP "crtexe.c", buf_ptr(parent->zig_lib_dir))); - mingw_add_cc_args(parent, c_file); - c_file->args.append("-U__CRTDLL__"); - c_file->args.append("-D__MSVCRT__"); - // Uncomment these 3 things for crtu - //c_file->args.append("-DUNICODE"); - //c_file->args.append("-D_UNICODE"); - //c_file->args.append("-DWPRFLAG=1"); - return build_libc_object(parent, "crt2", c_file, progress_node); - } else if (strcmp(file, "dllcrt2.o") == 0) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = buf_ptr(buf_sprintf( - "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "crt" OS_SEP "crtdll.c", buf_ptr(parent->zig_lib_dir))); - mingw_add_cc_args(parent, c_file); - c_file->args.append("-U__CRTDLL__"); - c_file->args.append("-D__MSVCRT__"); - return build_libc_object(parent, "dllcrt2", c_file, progress_node); - } else if (strcmp(file, "mingw32.lib") == 0) { - CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingw32", progress_node); - - static const char *deps[] = { - "mingw" OS_SEP "crt" OS_SEP "crt0_c.c", - "mingw" OS_SEP "crt" OS_SEP "dll_argv.c", - "mingw" OS_SEP "crt" OS_SEP "gccmain.c", - "mingw" OS_SEP "crt" OS_SEP "natstart.c", - "mingw" OS_SEP "crt" OS_SEP "pseudo-reloc-list.c", - "mingw" OS_SEP "crt" OS_SEP "wildcard.c", - "mingw" OS_SEP "crt" OS_SEP "charmax.c", - "mingw" OS_SEP "crt" OS_SEP "crt0_w.c", - "mingw" OS_SEP "crt" OS_SEP "dllargv.c", - "mingw" OS_SEP "crt" OS_SEP "gs_support.c", - "mingw" OS_SEP "crt" OS_SEP "_newmode.c", - "mingw" OS_SEP "crt" OS_SEP "tlssup.c", - "mingw" OS_SEP "crt" OS_SEP "xncommod.c", - "mingw" OS_SEP "crt" OS_SEP "cinitexe.c", - "mingw" OS_SEP "crt" OS_SEP "merr.c", - "mingw" OS_SEP "crt" OS_SEP "usermatherr.c", - "mingw" OS_SEP "crt" OS_SEP "pesect.c", - "mingw" OS_SEP "crt" OS_SEP "udllargc.c", - "mingw" OS_SEP "crt" OS_SEP "xthdloc.c", - "mingw" OS_SEP "crt" OS_SEP "CRT_fp10.c", - "mingw" OS_SEP "crt" OS_SEP "mingw_helpers.c", - "mingw" OS_SEP "crt" OS_SEP "pseudo-reloc.c", - "mingw" OS_SEP "crt" OS_SEP "udll_argv.c", - "mingw" OS_SEP "crt" OS_SEP "xtxtmode.c", - "mingw" OS_SEP "crt" OS_SEP "crt_handler.c", - "mingw" OS_SEP "crt" OS_SEP "tlsthrd.c", - "mingw" OS_SEP "crt" OS_SEP "tlsmthread.c", - "mingw" OS_SEP "crt" OS_SEP "tlsmcrt.c", - "mingw" OS_SEP "crt" OS_SEP "cxa_atexit.c", - }; - for (size_t i = 0; i < array_length(deps); i += 1) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = path_from_libc(parent, deps[i]); - c_file->args.append("-DHAVE_CONFIG_H"); - c_file->args.append("-D_SYSCRT=1"); - c_file->args.append("-DCRTDLL=1"); - - c_file->args.append("-isystem"); - c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any")); - - c_file->args.append("-isystem"); - c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include")); - - c_file->args.append("-std=gnu99"); - c_file->args.append("-D_CRTBLD"); - c_file->args.append("-D_WIN32_WINNT=0x0f00"); - c_file->args.append("-D__MSVCRT_VERSION__=0x700"); - c_file->args.append("-g"); - c_file->args.append("-O2"); - - child_gen->c_source_files.append(c_file); - } - codegen_build_and_link(child_gen); - return buf_ptr(&child_gen->bin_file_output_path); - } else if (strcmp(file, "msvcrt-os.lib") == 0) { - CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node); - - for (size_t i = 0; i < array_length(msvcrt_common_src); i += 1) { - add_msvcrt_os_dep(parent, child_gen, msvcrt_common_src[i]); - } - if (parent->zig_target->arch == ZigLLVM_x86) { - for (size_t i = 0; i < array_length(msvcrt_i386_src); i += 1) { - add_msvcrt_os_dep(parent, child_gen, msvcrt_i386_src[i]); - } - } else { - for (size_t i = 0; i < array_length(msvcrt_other_src); i += 1) { - add_msvcrt_os_dep(parent, child_gen, msvcrt_other_src[i]); - } - } - codegen_build_and_link(child_gen); - return buf_ptr(&child_gen->bin_file_output_path); - } else if (strcmp(file, "mingwex.lib") == 0) { - CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node); - - for (size_t i = 0; i < array_length(mingwex_generic_src); i += 1) { - add_mingwex_dep(parent, child_gen, mingwex_generic_src[i]); - } - if (parent->zig_target->arch == ZigLLVM_x86 || parent->zig_target->arch == ZigLLVM_x86_64) { - for (size_t i = 0; i < array_length(mingwex_x86_src); i += 1) { - add_mingwex_dep(parent, child_gen, mingwex_x86_src[i]); - } - } else if (target_is_arm(parent->zig_target)) { - if (target_arch_pointer_bit_width(parent->zig_target->arch) == 32) { - for (size_t i = 0; i < array_length(mingwex_arm32_src); i += 1) { - add_mingwex_dep(parent, child_gen, mingwex_arm32_src[i]); - } - } else { - for (size_t i = 0; i < array_length(mingwex_arm64_src); i += 1) { - add_mingwex_dep(parent, child_gen, mingwex_arm64_src[i]); - } - } - } else { - zig_unreachable(); - } - codegen_build_and_link(child_gen); - return buf_ptr(&child_gen->bin_file_output_path); - } else if (strcmp(file, "uuid.lib") == 0) { - CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "uuid", progress_node); - for (size_t i = 0; i < array_length(mingw_uuid_src); i += 1) { - add_mingw_uuid_dep(parent, child_gen, mingw_uuid_src[i]); - } - codegen_build_and_link(child_gen); - return buf_ptr(&child_gen->bin_file_output_path); - } else { - zig_unreachable(); - } - } else if (parent->libc == nullptr && target_is_glibc(parent->zig_target)) { - if (strcmp(file, "crti.o") == 0) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = glibc_start_asm_path(parent, "crti.S"); - glibc_add_include_dirs(parent, c_file); - c_file->args.append("-D_LIBC_REENTRANT"); - c_file->args.append("-include"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h")); - c_file->args.append("-DMODULE_NAME=libc"); - c_file->args.append("-Wno-nonportable-include-path"); - c_file->args.append("-include"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h")); - c_file->args.append("-DTOP_NAMESPACE=glibc"); - c_file->args.append("-DASSEMBLER"); - c_file->args.append("-g"); - c_file->args.append("-Wa,--noexecstack"); - return build_libc_object(parent, "crti", c_file, progress_node); - } else if (strcmp(file, "crtn.o") == 0) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = glibc_start_asm_path(parent, "crtn.S"); - glibc_add_include_dirs(parent, c_file); - c_file->args.append("-D_LIBC_REENTRANT"); - c_file->args.append("-DMODULE_NAME=libc"); - c_file->args.append("-DTOP_NAMESPACE=glibc"); - c_file->args.append("-DASSEMBLER"); - c_file->args.append("-g"); - c_file->args.append("-Wa,--noexecstack"); - return build_libc_object(parent, "crtn", c_file, progress_node); - } else if (strcmp(file, "start.os") == 0) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = glibc_start_asm_path(parent, "start.S"); - glibc_add_include_dirs(parent, c_file); - c_file->args.append("-D_LIBC_REENTRANT"); - c_file->args.append("-include"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h")); - c_file->args.append("-DMODULE_NAME=libc"); - c_file->args.append("-Wno-nonportable-include-path"); - c_file->args.append("-include"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h")); - c_file->args.append("-DPIC"); - c_file->args.append("-DSHARED"); - c_file->args.append("-DTOP_NAMESPACE=glibc"); - c_file->args.append("-DASSEMBLER"); - c_file->args.append("-g"); - c_file->args.append("-Wa,--noexecstack"); - return build_libc_object(parent, "start", c_file, progress_node); - } else if (strcmp(file, "abi-note.o") == 0) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "abi-note.S"); - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "csu")); - glibc_add_include_dirs(parent, c_file); - c_file->args.append("-D_LIBC_REENTRANT"); - c_file->args.append("-DMODULE_NAME=libc"); - c_file->args.append("-DTOP_NAMESPACE=glibc"); - c_file->args.append("-DASSEMBLER"); - c_file->args.append("-g"); - c_file->args.append("-Wa,--noexecstack"); - return build_libc_object(parent, "abi-note", c_file, progress_node); - } else if (strcmp(file, "Scrt1.o") == 0) { - const char *start_os = get_libc_crt_file(parent, "start.os", progress_node); - const char *abi_note_o = get_libc_crt_file(parent, "abi-note.o", progress_node); - CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeObj, nullptr, "Scrt1", progress_node); - codegen_add_object(child_gen, buf_create_from_str(start_os)); - codegen_add_object(child_gen, buf_create_from_str(abi_note_o)); - codegen_build_and_link(child_gen); - return buf_ptr(&child_gen->bin_file_output_path); - } else if (strcmp(file, "libc_nonshared.a") == 0) { - CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node); - { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "elf-init.c"); - c_file->args.append("-std=gnu11"); - c_file->args.append("-fgnu89-inline"); - c_file->args.append("-g"); - c_file->args.append("-O2"); - c_file->args.append("-fmerge-all-constants"); - c_file->args.append("-fno-stack-protector"); - c_file->args.append("-fmath-errno"); - c_file->args.append("-fno-stack-protector"); - c_file->args.append("-I"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "csu")); - glibc_add_include_dirs(parent, c_file); - c_file->args.append("-DSTACK_PROTECTOR_LEVEL=0"); - c_file->args.append("-fPIC"); - c_file->args.append("-fno-stack-protector"); - c_file->args.append("-ftls-model=initial-exec"); - c_file->args.append("-D_LIBC_REENTRANT"); - c_file->args.append("-include"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h")); - c_file->args.append("-DMODULE_NAME=libc"); - c_file->args.append("-Wno-nonportable-include-path"); - c_file->args.append("-include"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h")); - c_file->args.append("-DPIC"); - c_file->args.append("-DLIBC_NONSHARED=1"); - c_file->args.append("-DTOP_NAMESPACE=glibc"); - codegen_add_object(child_gen, buf_create_from_str( - build_libc_object(parent, "elf-init", c_file, progress_node))); - } - static const struct { - const char *name; - const char *path; - } deps[] = { - {"atexit", "glibc" OS_SEP "stdlib" OS_SEP "atexit.c"}, - {"at_quick_exit", "glibc" OS_SEP "stdlib" OS_SEP "at_quick_exit.c"}, - {"stat", "glibc" OS_SEP "io" OS_SEP "stat.c"}, - {"fstat", "glibc" OS_SEP "io" OS_SEP "fstat.c"}, - {"lstat", "glibc" OS_SEP "io" OS_SEP "lstat.c"}, - {"stat64", "glibc" OS_SEP "io" OS_SEP "stat64.c"}, - {"fstat64", "glibc" OS_SEP "io" OS_SEP "fstat64.c"}, - {"lstat64", "glibc" OS_SEP "io" OS_SEP "lstat64.c"}, - {"fstatat", "glibc" OS_SEP "io" OS_SEP "fstatat.c"}, - {"fstatat64", "glibc" OS_SEP "io" OS_SEP "fstatat64.c"}, - {"mknod", "glibc" OS_SEP "io" OS_SEP "mknod.c"}, - {"mknodat", "glibc" OS_SEP "io" OS_SEP "mknodat.c"}, - {"pthread_atfork", "glibc" OS_SEP "nptl" OS_SEP "pthread_atfork.c"}, - {"stack_chk_fail_local", "glibc" OS_SEP "debug" OS_SEP "stack_chk_fail_local.c"}, - }; - for (size_t i = 0; i < array_length(deps); i += 1) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = path_from_libc(parent, deps[i].path); - c_file->args.append("-std=gnu11"); - c_file->args.append("-fgnu89-inline"); - c_file->args.append("-g"); - c_file->args.append("-O2"); - c_file->args.append("-fmerge-all-constants"); - c_file->args.append("-fno-stack-protector"); - c_file->args.append("-fmath-errno"); - c_file->args.append("-ftls-model=initial-exec"); - c_file->args.append("-Wno-ignored-attributes"); - glibc_add_include_dirs(parent, c_file); - c_file->args.append("-D_LIBC_REENTRANT"); - c_file->args.append("-include"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h")); - c_file->args.append("-DMODULE_NAME=libc"); - c_file->args.append("-Wno-nonportable-include-path"); - c_file->args.append("-include"); - c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h")); - c_file->args.append("-DPIC"); - c_file->args.append("-DLIBC_NONSHARED=1"); - c_file->args.append("-DTOP_NAMESPACE=glibc"); - codegen_add_object(child_gen, buf_create_from_str( - build_libc_object(parent, deps[i].name, c_file, progress_node))); - } - codegen_build_and_link(child_gen); - return buf_ptr(&child_gen->bin_file_output_path); - } else { - zig_unreachable(); - } - } else if (parent->libc == nullptr && target_is_musl(parent->zig_target)) { - if (strcmp(file, "crti.o") == 0) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = musl_start_asm_path(parent, "crti.s"); - musl_add_cc_args(parent, c_file, false); - c_file->args.append("-Qunused-arguments"); - return build_libc_object(parent, "crti", c_file, progress_node); - } else if (strcmp(file, "crtn.o") == 0) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = musl_start_asm_path(parent, "crtn.s"); - c_file->args.append("-Qunused-arguments"); - musl_add_cc_args(parent, c_file, false); - return build_libc_object(parent, "crtn", c_file, progress_node); - } else if (strcmp(file, "crt1.o") == 0) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "crt1.c"); - musl_add_cc_args(parent, c_file, false); - c_file->args.append("-fno-stack-protector"); - c_file->args.append("-DCRT"); - return build_libc_object(parent, "crt1", c_file, progress_node); - } else if (strcmp(file, "Scrt1.o") == 0) { - CFile *c_file = heap::c_allocator.create(); - c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "Scrt1.c"); - musl_add_cc_args(parent, c_file, false); - c_file->args.append("-fPIC"); - c_file->args.append("-fno-stack-protector"); - c_file->args.append("-DCRT"); - return build_libc_object(parent, "Scrt1", c_file, progress_node); - } else { - zig_unreachable(); - } - } else { - assert(parent->libc != nullptr); - Buf *out_buf = buf_alloc(); - os_path_join(buf_create_from_mem(parent->libc->crt_dir, parent->libc->crt_dir_len), - buf_create_from_str(file), out_buf); - return buf_ptr(out_buf); - } -} - -static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, OutType child_out_type, - Stage2ProgressNode *progress_node) -{ - CodeGen *child_gen = create_child_codegen(parent_gen, full_path, child_out_type, parent_gen->libc, aname, - progress_node); - - // This is so that compiler_rt and libc.zig libraries know whether they - // will eventually be linked with libc. They make different decisions - // about what to export depending on whether libc is linked. - if (parent_gen->libc_link_lib != nullptr) { - LinkLib *new_link_lib = codegen_add_link_lib(child_gen, parent_gen->libc_link_lib->name); - new_link_lib->provided_explicitly = parent_gen->libc_link_lib->provided_explicitly; - } - - // Override the inherited build mode parameter - if (!parent_gen->is_test_build) { - switch (parent_gen->build_mode) { - case BuildModeDebug: - case BuildModeFastRelease: - case BuildModeSafeRelease: - child_gen->build_mode = BuildModeFastRelease; - break; - case BuildModeSmallRelease: - break; - } - } - - child_gen->function_sections = true; - child_gen->want_stack_check = WantStackCheckDisabled; - - codegen_build_and_link(child_gen); - return &child_gen->bin_file_output_path; -} - -static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) { - Buf *full_path = buf_alloc(); - os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path); - - return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type, progress_node); -} - -static Buf *build_c(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) { - Buf *full_path = buf_alloc(); - os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("c.zig"), full_path); - - return build_a_raw(parent_gen, "c", full_path, child_out_type, progress_node); -} - -static const char *get_darwin_arch_string(const ZigTarget *t) { - switch (t->arch) { - case ZigLLVM_aarch64: - return "arm64"; - case ZigLLVM_thumb: - case ZigLLVM_arm: - return "arm"; - case ZigLLVM_ppc: - return "ppc"; - case ZigLLVM_ppc64: - return "ppc64"; - case ZigLLVM_ppc64le: - return "ppc64le"; - default: - return ZigLLVMGetArchTypeName(t->arch); - } -} - - -static const char *getLDMOption(const ZigTarget *t) { - switch (t->arch) { - case ZigLLVM_x86: - return "elf_i386"; - case ZigLLVM_aarch64: - return "aarch64linux"; - case ZigLLVM_aarch64_be: - return "aarch64_be_linux"; - case ZigLLVM_arm: - case ZigLLVM_thumb: - return "armelf_linux_eabi"; - case ZigLLVM_armeb: - case ZigLLVM_thumbeb: - return "armebelf_linux_eabi"; - case ZigLLVM_ppc: - return "elf32ppclinux"; - case ZigLLVM_ppc64: - return "elf64ppc"; - case ZigLLVM_ppc64le: - return "elf64lppc"; - case ZigLLVM_sparc: - case ZigLLVM_sparcel: - return "elf32_sparc"; - case ZigLLVM_sparcv9: - return "elf64_sparc"; - case ZigLLVM_mips: - return "elf32btsmip"; - case ZigLLVM_mipsel: - return "elf32ltsmip"; - case ZigLLVM_mips64: - return "elf64btsmip"; - case ZigLLVM_mips64el: - return "elf64ltsmip"; - case ZigLLVM_systemz: - return "elf64_s390"; - case ZigLLVM_x86_64: - if (t->abi == ZigLLVM_GNUX32) { - return "elf32_x86_64"; - } - // Any target elf will use the freebsd osabi if suffixed with "_fbsd". - if (t->os == OsFreeBSD) { - return "elf_x86_64_fbsd"; - } - return "elf_x86_64"; - case ZigLLVM_riscv32: - return "elf32lriscv"; - case ZigLLVM_riscv64: - return "elf64lriscv"; - default: - zig_unreachable(); - } -} - -static void add_rpath(LinkJob *lj, Buf *rpath) { - if (lj->rpath_table.maybe_get(rpath) != nullptr) - return; - - lj->args.append("-rpath"); - lj->args.append(buf_ptr(rpath)); - - lj->rpath_table.put(rpath, true); -} - -static void add_glibc_libs(LinkJob *lj) { - Error err; - ZigGLibCAbi *glibc_abi; - if ((err = glibc_load_metadata(&glibc_abi, lj->codegen->zig_lib_dir, true))) { - fprintf(stderr, "%s\n", err_str(err)); - exit(1); - } - - Buf *artifact_dir; - if ((err = glibc_build_dummies_and_maps(lj->codegen, glibc_abi, lj->codegen->zig_target, - &artifact_dir, true, lj->build_dep_prog_node))) - { - fprintf(stderr, "%s\n", err_str(err)); - exit(1); - } - - size_t lib_count = glibc_lib_count(); - for (size_t i = 0; i < lib_count; i += 1) { - const ZigGLibCLib *lib = glibc_lib_enum(i); - Buf *so_path = buf_sprintf("%s" OS_SEP "lib%s.so.%d.0.0", buf_ptr(artifact_dir), lib->name, lib->sover); - lj->args.append(buf_ptr(so_path)); - } -} - -static void construct_linker_job_elf(LinkJob *lj) { - CodeGen *g = lj->codegen; - - lj->args.append("-error-limit=0"); - - if (g->out_type == OutTypeExe) { - lj->args.append("-z"); - size_t stack_size = (g->stack_size_override == 0) ? 16777216 : g->stack_size_override; - lj->args.append(buf_ptr(buf_sprintf("stack-size=%" ZIG_PRI_usize, stack_size))); - } - - if (g->linker_script) { - lj->args.append("-T"); - lj->args.append(g->linker_script); - } - - switch (g->linker_gc_sections) { - case OptionalBoolNull: - if (g->out_type != OutTypeObj) { - lj->args.append("--gc-sections"); - } - break; - case OptionalBoolTrue: - lj->args.append("--gc-sections"); - break; - case OptionalBoolFalse: - break; - } - - if (g->link_eh_frame_hdr) { - lj->args.append("--eh-frame-hdr"); - } - - if (g->linker_rdynamic) { - lj->args.append("--export-dynamic"); - } - - if (g->linker_optimization != nullptr) { - lj->args.append(buf_ptr(g->linker_optimization)); - } - - if (g->linker_z_nodelete) { - lj->args.append("-z"); - lj->args.append("nodelete"); - } - if (g->linker_z_defs) { - lj->args.append("-z"); - lj->args.append("defs"); - } - - lj->args.append("-m"); - lj->args.append(getLDMOption(g->zig_target)); - - bool is_lib = g->out_type == OutTypeLib; - bool is_dyn_lib = g->is_dynamic && is_lib; - if (!g->have_dynamic_link) { - if (g->zig_target->arch == ZigLLVM_arm || g->zig_target->arch == ZigLLVM_armeb || - g->zig_target->arch == ZigLLVM_thumb || g->zig_target->arch == ZigLLVM_thumbeb) - { - lj->args.append("-Bstatic"); - } else { - lj->args.append("-static"); - } - } else if (is_dyn_lib) { - lj->args.append("-shared"); - } - - if (target_requires_pie(g->zig_target) && g->out_type == OutTypeExe) { - lj->args.append("-pie"); - } - - assert(buf_len(&g->bin_file_output_path) != 0); - lj->args.append("-o"); - lj->args.append(buf_ptr(&g->bin_file_output_path)); - - if (lj->link_in_crt) { - const char *crt1o; - if (g->zig_target->os == OsNetBSD) { - crt1o = "crt0.o"; - } else if (target_is_android(g->zig_target)) { - if (g->have_dynamic_link) { - crt1o = "crtbegin_dynamic.o"; - } else { - crt1o = "crtbegin_static.o"; - } - } else if (!g->have_dynamic_link) { - crt1o = "crt1.o"; - } else { - crt1o = "Scrt1.o"; - } - lj->args.append(get_libc_crt_file(g, crt1o, lj->build_dep_prog_node)); - if (target_libc_needs_crti_crtn(g->zig_target)) { - lj->args.append(get_libc_crt_file(g, "crti.o", lj->build_dep_prog_node)); - } - } - - for (size_t i = 0; i < g->rpath_list.length; i += 1) { - Buf *rpath = g->rpath_list.at(i); - add_rpath(lj, rpath); - } - if (g->each_lib_rpath) { - for (size_t i = 0; i < g->lib_dirs.length; i += 1) { - const char *lib_dir = g->lib_dirs.at(i); - for (size_t i = 0; i < g->link_libs_list.length; i += 1) { - LinkLib *link_lib = g->link_libs_list.at(i); - if (buf_eql_str(link_lib->name, "c")) { - continue; - } - bool does_exist; - Buf *test_path = buf_sprintf("%s/lib%s.so", lib_dir, buf_ptr(link_lib->name)); - if (os_file_exists(test_path, &does_exist) != ErrorNone) { - zig_panic("link: unable to check if file exists: %s", buf_ptr(test_path)); - } - if (does_exist) { - add_rpath(lj, buf_create_from_str(lib_dir)); - break; - } - } - } - } - - for (size_t i = 0; i < g->lib_dirs.length; i += 1) { - const char *lib_dir = g->lib_dirs.at(i); - lj->args.append("-L"); - lj->args.append(lib_dir); - } - - if (g->libc_link_lib != nullptr) { - if (g->libc != nullptr) { - lj->args.append("-L"); - lj->args.append(buf_ptr(buf_create_from_mem(g->libc->crt_dir, g->libc->crt_dir_len))); - } - - if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) { - assert(g->zig_target->dynamic_linker != nullptr); - lj->args.append("-dynamic-linker"); - lj->args.append(g->zig_target->dynamic_linker); - } - } - - if (is_dyn_lib) { - Buf *soname = (g->override_soname == nullptr) ? - buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major) : - g->override_soname; - lj->args.append("-soname"); - lj->args.append(buf_ptr(soname)); - - if (g->version_script_path != nullptr) { - lj->args.append("-version-script"); - lj->args.append(buf_ptr(g->version_script_path)); - } - } - - // .o files - for (size_t i = 0; i < g->link_objects.length; i += 1) { - lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); - } - - if (!g->is_dummy_so && (g->out_type == OutTypeExe || is_dyn_lib)) { - if (g->libc_link_lib == nullptr) { - Buf *libc_a_path = build_c(g, OutTypeLib, lj->build_dep_prog_node); - lj->args.append(buf_ptr(libc_a_path)); - } - - Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib, lj->build_dep_prog_node); - lj->args.append(buf_ptr(compiler_rt_o_path)); - } - - // libraries - for (size_t i = 0; i < g->link_libs_list.length; i += 1) { - LinkLib *link_lib = g->link_libs_list.at(i); - if (buf_eql_str(link_lib->name, "c")) { - // libc is linked specially - continue; - } - if (target_is_libcpp_lib_name(g->zig_target, buf_ptr(link_lib->name))) { - // libc++ is linked specially - continue; - } - if (g->libc == nullptr && target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) { - // these libraries are always linked below when targeting glibc - continue; - } - Buf *arg; - if (buf_starts_with_str(link_lib->name, "/") || buf_ends_with_str(link_lib->name, ".a") || - buf_ends_with_str(link_lib->name, ".so")) - { - arg = link_lib->name; - } else { - arg = buf_sprintf("-l%s", buf_ptr(link_lib->name)); - } - lj->args.append(buf_ptr(arg)); - } - - // libc++ dep - if (g->libcpp_link_lib != nullptr && g->out_type != OutTypeObj) { - lj->args.append(build_libcxxabi(g, lj->build_dep_prog_node)); - lj->args.append(build_libcxx(g, lj->build_dep_prog_node)); - } - - // libc dep - if (g->libc_link_lib != nullptr && g->out_type != OutTypeObj) { - if (g->libc != nullptr) { - if (!g->have_dynamic_link) { - lj->args.append("--start-group"); - lj->args.append("-lc"); - lj->args.append("-lm"); - lj->args.append("--end-group"); - } else { - lj->args.append("-lc"); - lj->args.append("-lm"); - } - - if (g->zig_target->os == OsFreeBSD || - g->zig_target->os == OsNetBSD) - { - lj->args.append("-lpthread"); - } - } else if (target_is_glibc(g->zig_target)) { - lj->args.append(build_libunwind(g, lj->build_dep_prog_node)); - add_glibc_libs(lj); - lj->args.append(get_libc_crt_file(g, "libc_nonshared.a", lj->build_dep_prog_node)); - } else if (target_is_musl(g->zig_target)) { - lj->args.append(build_libunwind(g, lj->build_dep_prog_node)); - lj->args.append(build_musl(g, lj->build_dep_prog_node)); - } else if (g->libcpp_link_lib != nullptr) { - lj->args.append(build_libunwind(g, lj->build_dep_prog_node)); - } else { - zig_unreachable(); - } - } - - // crt end - if (lj->link_in_crt) { - if (target_is_android(g->zig_target)) { - lj->args.append(get_libc_crt_file(g, "crtend_android.o", lj->build_dep_prog_node)); - } else if (target_libc_needs_crti_crtn(g->zig_target)) { - lj->args.append(get_libc_crt_file(g, "crtn.o", lj->build_dep_prog_node)); - } - } - - switch (g->linker_allow_shlib_undefined) { - case OptionalBoolNull: - if (!g->zig_target->is_native_os) { - lj->args.append("--allow-shlib-undefined"); - } - break; - case OptionalBoolFalse: - break; - case OptionalBoolTrue: - lj->args.append("--allow-shlib-undefined"); - break; - } - switch (g->linker_bind_global_refs_locally) { - case OptionalBoolNull: - case OptionalBoolFalse: - break; - case OptionalBoolTrue: - lj->args.append("-Bsymbolic"); - break; - } -} - -static void construct_linker_job_wasm(LinkJob *lj) { - CodeGen *g = lj->codegen; - - lj->args.append("-error-limit=0"); - // Increase the default stack size to a more reasonable value of 1MB instead of - // the default of 1 Wasm page being 64KB, unless overriden by the user. - size_t stack_size = (g->stack_size_override == 0) ? 1048576 : g->stack_size_override; - lj->args.append("-z"); - lj->args.append(buf_ptr(buf_sprintf("stack-size=%" ZIG_PRI_usize, stack_size))); - - // put stack before globals so that stack overflow results in segfault immediately before corrupting globals - // see https://github.com/ziglang/zig/issues/4496 - lj->args.append("--stack-first"); - - if (g->out_type != OutTypeExe) { - lj->args.append("--no-entry"); // So lld doesn't look for _start. - - // If there are any C source files we cannot rely on individual exports. - if (g->c_source_files.length != 0) { - lj->args.append("--export-all"); - } else { - auto export_it = g->exported_symbol_names.entry_iterator(); - decltype(g->exported_symbol_names)::Entry *curr_entry = nullptr; - while ((curr_entry = export_it.next()) != nullptr) { - Buf *arg = buf_sprintf("--export=%s", buf_ptr(curr_entry->key)); - lj->args.append(buf_ptr(arg)); - } - } - } - lj->args.append("--allow-undefined"); - lj->args.append("-o"); - lj->args.append(buf_ptr(&g->bin_file_output_path)); - - // .o files - for (size_t i = 0; i < g->link_objects.length; i += 1) { - lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); - } - - if (g->out_type != OutTypeObj) { - Buf *libc_o_path = build_c(g, OutTypeObj, lj->build_dep_prog_node); - lj->args.append(buf_ptr(libc_o_path)); - - Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj, lj->build_dep_prog_node); - lj->args.append(buf_ptr(compiler_rt_o_path)); - } -} - -static void coff_append_machine_arg(CodeGen *g, ZigList *list) { - if (g->zig_target->arch == ZigLLVM_x86) { - list->append("-MACHINE:X86"); - } else if (g->zig_target->arch == ZigLLVM_x86_64) { - list->append("-MACHINE:X64"); - } else if (target_is_arm(g->zig_target)) { - if (target_arch_pointer_bit_width(g->zig_target->arch) == 32) { - list->append("-MACHINE:ARM"); - } else { - list->append("-MACHINE:ARM64"); - } - } -} - -static void link_diag_callback(void *context, const char *ptr, size_t len) { - Buf *diag = reinterpret_cast(context); - buf_append_mem(diag, ptr, len); -} - -static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, - Buf *diag) -{ - Buf *stdout_diag = buf_alloc(); - buf_resize(diag, 0); - bool result = ZigLLDLink(oformat, args, arg_count, link_diag_callback, stdout_diag, diag); - buf_destroy(stdout_diag); - return result; -} - -static void add_uefi_link_args(LinkJob *lj) { - lj->args.append("-BASE:0"); - lj->args.append("-ENTRY:EfiMain"); - lj->args.append("-OPT:REF"); - lj->args.append("-SAFESEH:NO"); - lj->args.append("-MERGE:.rdata=.data"); - lj->args.append("-ALIGN:32"); - lj->args.append("-NODEFAULTLIB"); - lj->args.append("-SECTION:.xdata,D"); -} - -static void add_msvc_link_args(LinkJob *lj, bool is_library) { - CodeGen *g = lj->codegen; - - bool is_dynamic = g->is_dynamic; - const char *lib_str = is_dynamic ? "" : "lib"; - const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : ""; - - if (!is_dynamic) { - Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str); - lj->args.append(buf_ptr(cmt_lib_name)); - } else { - Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str); - lj->args.append(buf_ptr(msvcrt_lib_name)); - } - - Buf *vcruntime_lib_name = buf_sprintf("%svcruntime%s.lib", lib_str, d_str); - lj->args.append(buf_ptr(vcruntime_lib_name)); - - Buf *crt_lib_name = buf_sprintf("%sucrt%s.lib", lib_str, d_str); - lj->args.append(buf_ptr(crt_lib_name)); - - //Visual C++ 2015 Conformance Changes - //https://msdn.microsoft.com/en-us/library/bb531344.aspx - lj->args.append("legacy_stdio_definitions.lib"); - - // msvcrt depends on kernel32 and ntdll - lj->args.append("kernel32.lib"); - lj->args.append("ntdll.lib"); -} - -static void print_zig_cc_cmd(ZigList *args) { - for (size_t arg_i = 0; arg_i < args->length; arg_i += 1) { - const char *space_str = (arg_i == 0) ? "" : " "; - fprintf(stderr, "%s%s", space_str, args->at(arg_i)); - } - fprintf(stderr, "\n"); -} - -static const char *get_def_lib(CodeGen *parent, const char *name, Buf *def_in_file) { - Error err; - - Buf *self_exe_path = buf_alloc(); - if ((err = os_self_exe_path(self_exe_path))) { - fprintf(stderr, "Unable to get self exe path: %s\n", err_str(err)); - exit(1); - } - Buf *compiler_id; - if ((err = get_compiler_id(&compiler_id))) { - fprintf(stderr, "Unable to get compiler id: %s\n", err_str(err)); - exit(1); - } - - Buf *cache_dir = get_global_cache_dir(); - Buf *o_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR, buf_ptr(cache_dir)); - Buf *manifest_dir = buf_sprintf("%s" OS_SEP CACHE_HASH_SUBDIR, buf_ptr(cache_dir)); - - Buf *def_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "def-include", - buf_ptr(parent->zig_lib_dir)); - - CacheHash *cache_hash = heap::c_allocator.create(); - cache_init(cache_hash, manifest_dir); - - cache_buf(cache_hash, compiler_id); - cache_file(cache_hash, def_in_file); - cache_buf(cache_hash, def_include_dir); - cache_int(cache_hash, parent->zig_target->arch); - - Buf digest = BUF_INIT; - buf_resize(&digest, 0); - if ((err = cache_hit(cache_hash, &digest))) { - if (err != ErrorInvalidFormat) { - if (err == ErrorCacheUnavailable) { - // already printed error - } else { - fprintf(stderr, "unable to check cache when processing .def.in file: %s\n", err_str(err)); - } - exit(1); - } - } - - Buf *artifact_dir; - Buf *lib_final_path; - Buf *final_lib_basename = buf_sprintf("%s.lib", name); - - bool is_cache_miss = (buf_len(&digest) == 0); - if (is_cache_miss) { - if ((err = cache_final(cache_hash, &digest))) { - fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err)); - exit(1); - } - artifact_dir = buf_alloc(); - os_path_join(o_dir, &digest, artifact_dir); - if ((err = os_make_path(artifact_dir))) { - fprintf(stderr, "Unable to create output directory '%s': %s", - buf_ptr(artifact_dir), err_str(err)); - exit(1); - } - Buf *final_def_basename = buf_sprintf("%s.def", name); - Buf *def_final_path = buf_alloc(); - os_path_join(artifact_dir, final_def_basename, def_final_path); - - ZigList args = {}; - args.append(buf_ptr(self_exe_path)); - args.append("clang"); - args.append("-x"); - args.append("c"); - args.append(buf_ptr(def_in_file)); - args.append("-Wp,-w"); - args.append("-undef"); - args.append("-P"); - args.append("-I"); - args.append(buf_ptr(def_include_dir)); - if (target_is_arm(parent->zig_target)) { - if (target_arch_pointer_bit_width(parent->zig_target->arch) == 32) { - args.append("-DDEF_ARM32"); - } else { - args.append("-DDEF_ARM64"); - } - } else if (parent->zig_target->arch == ZigLLVM_x86) { - args.append("-DDEF_I386"); - } else if (parent->zig_target->arch == ZigLLVM_x86_64) { - args.append("-DDEF_X64"); - } else { - zig_unreachable(); - } - args.append("-E"); - args.append("-o"); - args.append(buf_ptr(def_final_path)); - - if (parent->verbose_cc) { - print_zig_cc_cmd(&args); - } - Termination term; - os_spawn_process(args, &term); - if (term.how != TerminationIdClean || term.code != 0) { - fprintf(stderr, "\nThe following command failed:\n"); - print_zig_cc_cmd(&args); - exit(1); - } - - lib_final_path = buf_alloc(); - os_path_join(artifact_dir, final_lib_basename, lib_final_path); - - if (ZigLLVMWriteImportLibrary(buf_ptr(def_final_path), - parent->zig_target->arch, - buf_ptr(lib_final_path), - /* kill_at */ true)) - { - zig_panic("link: could not emit %s", buf_ptr(lib_final_path)); - } - } else { - // cache hit - artifact_dir = buf_alloc(); - os_path_join(o_dir, &digest, artifact_dir); - lib_final_path = buf_alloc(); - os_path_join(artifact_dir, final_lib_basename, lib_final_path); - } - parent->caches_to_release.append(cache_hash); - - return buf_ptr(lib_final_path); -} - -static bool is_linking_system_lib(CodeGen *g, const char *name) { - for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) { - LinkLib *link_lib = g->link_libs_list.at(lib_i); - if (buf_eql_str(link_lib->name, name)) { - return true; - } - } - return false; -} - -static Error find_mingw_lib_def(LinkJob *lj, const char *name, Buf *out_path) { - CodeGen *g = lj->codegen; - Buf override_path = BUF_INIT; - Error err; - - char const *lib_path = nullptr; - if (g->zig_target->arch == ZigLLVM_x86) { - lib_path = "lib32"; - } else if (g->zig_target->arch == ZigLLVM_x86_64) { - lib_path = "lib64"; - } else if (target_is_arm(g->zig_target)) { - const bool is_32 = target_arch_pointer_bit_width(g->zig_target->arch) == 32; - lib_path = is_32 ? "libarm32" : "libarm64"; - } else { - zig_unreachable(); - } - - // Try the archtecture-specific path first - buf_resize(&override_path, 0); - buf_appendf(&override_path, "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s" OS_SEP "%s.def", buf_ptr(g->zig_lib_dir), lib_path, name); - - bool does_exist; - if ((err = os_file_exists(&override_path, &does_exist)) != ErrorNone) { - return err; - } - - if (!does_exist) { - // Try the generic version - buf_resize(&override_path, 0); - buf_appendf(&override_path, "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "lib-common" OS_SEP "%s.def", buf_ptr(g->zig_lib_dir), name); - - if ((err = os_file_exists(&override_path, &does_exist)) != ErrorNone) { - return err; - } - } - - if (!does_exist) { - // Try the generic version and preprocess it - buf_resize(&override_path, 0); - buf_appendf(&override_path, "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "lib-common" OS_SEP "%s.def.in", buf_ptr(g->zig_lib_dir), name); - - if ((err = os_file_exists(&override_path, &does_exist)) != ErrorNone) { - return err; - } - } - - if (!does_exist) { - return ErrorFileNotFound; - } - - buf_init_from_buf(out_path, &override_path); - return ErrorNone; -} - -static void add_mingw_link_args(LinkJob *lj, bool is_library) { - CodeGen *g = lj->codegen; - - lj->args.append("-lldmingw"); - - bool is_dll = g->out_type == OutTypeLib && g->is_dynamic; - - if (g->zig_target->arch == ZigLLVM_x86) { - lj->args.append("-ALTERNATENAME:__image_base__=___ImageBase"); - } else { - lj->args.append("-ALTERNATENAME:__image_base__=__ImageBase"); - } - - if (is_dll) { - lj->args.append(get_libc_crt_file(g, "dllcrt2.o", lj->build_dep_prog_node)); - } else { - lj->args.append(get_libc_crt_file(g, "crt2.o", lj->build_dep_prog_node)); - } - - lj->args.append(get_libc_crt_file(g, "mingw32.lib", lj->build_dep_prog_node)); - lj->args.append(get_libc_crt_file(g, "mingwex.lib", lj->build_dep_prog_node)); - lj->args.append(get_libc_crt_file(g, "msvcrt-os.lib", lj->build_dep_prog_node)); - - for (size_t def_i = 0; def_i < array_length(mingw_def_list); def_i += 1) { - const char *name = mingw_def_list[def_i].name; - const bool always_link = mingw_def_list[def_i].always_link; - - if (always_link || is_linking_system_lib(g, name)) { - Buf lib_path = BUF_INIT; - Error err = find_mingw_lib_def(lj, name, &lib_path); - - if (err == ErrorFileNotFound) { - zig_panic("link: could not find .def file to build %s\n", name); - } else if (err != ErrorNone) { - zig_panic("link: unable to check if .def file for %s exists: %s", - name, err_str(err)); - } - - lj->args.append(get_def_lib(g, name, &lib_path)); - } - } -} - -static void add_win_link_args(LinkJob *lj, bool is_library, bool *have_windows_dll_import_libs) { - if (lj->link_in_crt) { - if (target_abi_is_gnu(lj->codegen->zig_target->abi)) { - *have_windows_dll_import_libs = true; - add_mingw_link_args(lj, is_library); - } else { - add_msvc_link_args(lj, is_library); - } - } else { - lj->args.append("-NODEFAULTLIB"); - if (!is_library) { - if (lj->codegen->have_winmain) { - lj->args.append("-ENTRY:WinMain"); - } else if (lj->codegen->have_wwinmain) { - lj->args.append("-ENTRY:wWinMain"); - } else if (lj->codegen->have_wwinmain_crt_startup) { - lj->args.append("-ENTRY:wWinMainCRTStartup"); - } else { - lj->args.append("-ENTRY:WinMainCRTStartup"); - } - } - } -} - -static bool is_mingw_link_lib(Buf *name) { - for (size_t def_i = 0; def_i < array_length(mingw_def_list); def_i += 1) { - if (buf_eql_str_ignore_case(name, mingw_def_list[def_i].name)) { - return true; - } - } - return false; -} -static void construct_linker_job_coff(LinkJob *lj) { - Error err; - CodeGen *g = lj->codegen; - - lj->args.append("-ERRORLIMIT:0"); - - lj->args.append("-NOLOGO"); - - if (!g->strip_debug_symbols) { - lj->args.append("-DEBUG"); - } - - if (g->out_type == OutTypeExe) { - // TODO compile time stack upper bound detection - size_t stack_size = (g->stack_size_override == 0) ? 16777216 : g->stack_size_override; - lj->args.append(buf_ptr(buf_sprintf("-STACK:%" ZIG_PRI_usize, stack_size))); - } - - coff_append_machine_arg(g, &lj->args); - - bool is_library = g->out_type == OutTypeLib; - if (is_library && g->is_dynamic) { - lj->args.append("-DLL"); - } - - lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->bin_file_output_path)))); - - if (g->libc_link_lib != nullptr && g->libc != nullptr) { - Buf *buff0 = buf_create_from_str("-LIBPATH:"); - buf_append_mem(buff0, g->libc->crt_dir, g->libc->crt_dir_len); - lj->args.append(buf_ptr(buff0)); - - if (target_abi_is_gnu(g->zig_target->abi)) { - Buf *buff1 = buf_create_from_str("-LIBPATH:"); - buf_append_mem(buff1, g->libc->sys_include_dir, g->libc->sys_include_dir_len); - lj->args.append(buf_ptr(buff1)); - - Buf *buff2 = buf_create_from_str("-LIBPATH:"); - buf_append_mem(buff2, g->libc->include_dir, g->libc->include_dir_len); - lj->args.append(buf_ptr(buff2)); - } else { - Buf *buff1 = buf_create_from_str("-LIBPATH:"); - buf_append_mem(buff1, g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len); - lj->args.append(buf_ptr(buff1)); - - Buf *buff2 = buf_create_from_str("-LIBPATH:"); - buf_append_mem(buff2, g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len); - lj->args.append(buf_ptr(buff2)); - } - } - - for (size_t i = 0; i < g->lib_dirs.length; i += 1) { - const char *lib_dir = g->lib_dirs.at(i); - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir))); - } - - for (size_t i = 0; i < g->link_objects.length; i += 1) { - lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); - } - - bool have_windows_dll_import_libs = false; - switch (detect_subsystem(g)) { - case TargetSubsystemAuto: - if (g->zig_target->os == OsUefi) { - add_uefi_link_args(lj); - } else { - add_win_link_args(lj, is_library, &have_windows_dll_import_libs); - } - break; - case TargetSubsystemConsole: - lj->args.append("-SUBSYSTEM:console"); - add_win_link_args(lj, is_library, &have_windows_dll_import_libs); - break; - case TargetSubsystemEfiApplication: - lj->args.append("-SUBSYSTEM:efi_application"); - add_uefi_link_args(lj); - break; - case TargetSubsystemEfiBootServiceDriver: - lj->args.append("-SUBSYSTEM:efi_boot_service_driver"); - add_uefi_link_args(lj); - break; - case TargetSubsystemEfiRom: - lj->args.append("-SUBSYSTEM:efi_rom"); - add_uefi_link_args(lj); - break; - case TargetSubsystemEfiRuntimeDriver: - lj->args.append("-SUBSYSTEM:efi_runtime_driver"); - add_uefi_link_args(lj); - break; - case TargetSubsystemNative: - lj->args.append("-SUBSYSTEM:native"); - add_win_link_args(lj, is_library, &have_windows_dll_import_libs); - break; - case TargetSubsystemPosix: - lj->args.append("-SUBSYSTEM:posix"); - add_win_link_args(lj, is_library, &have_windows_dll_import_libs); - break; - case TargetSubsystemWindows: - lj->args.append("-SUBSYSTEM:windows"); - add_win_link_args(lj, is_library, &have_windows_dll_import_libs); - break; - } - - // libc++ dep - if (g->libcpp_link_lib != nullptr && g->out_type != OutTypeObj) { - lj->args.append(build_libcxxabi(g, lj->build_dep_prog_node)); - lj->args.append(build_libcxx(g, lj->build_dep_prog_node)); - lj->args.append(build_libunwind(g, lj->build_dep_prog_node)); - } - - if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) { - if (g->libc_link_lib == nullptr && !g->is_dummy_so) { - Buf *libc_a_path = build_c(g, OutTypeLib, lj->build_dep_prog_node); - lj->args.append(buf_ptr(libc_a_path)); - } - - // msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage - Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib, lj->build_dep_prog_node); - lj->args.append(buf_ptr(compiler_rt_o_path)); - } - - for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) { - LinkLib *link_lib = g->link_libs_list.at(lib_i); - if (buf_eql_str(link_lib->name, "c")) { - continue; - } - if (target_is_libcpp_lib_name(g->zig_target, buf_ptr(link_lib->name))) { - // libc++ is linked specially - continue; - } - if (g->libc == nullptr && target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) { - // these libraries are always linked below when targeting glibc - continue; - } - bool is_sys_lib = is_mingw_link_lib(link_lib->name); - if (have_windows_dll_import_libs && is_sys_lib) { - continue; - } - // If we're linking in the CRT or the libs are provided explictly we don't want to generate def/libs - if ((lj->link_in_crt && is_sys_lib) || link_lib->provided_explicitly) { - if (target_abi_is_gnu(lj->codegen->zig_target->abi)) { - if (buf_eql_str(link_lib->name, "uuid")) { - // mingw-w64 provides this lib - lj->args.append(get_libc_crt_file(g, "uuid.lib", lj->build_dep_prog_node)); - } else { - Buf* lib_name = buf_sprintf("lib%s.a", buf_ptr(link_lib->name)); - lj->args.append(buf_ptr(lib_name)); - } - } else { - Buf* lib_name = buf_sprintf("%s.lib", buf_ptr(link_lib->name)); - lj->args.append(buf_ptr(lib_name)); - } - continue; - } - - // This library may be a system one and we may have a suitable .lib file - - // Normalize the library name to lower case, the FS may be - // case-sensitive - char *name = strdup(buf_ptr(link_lib->name)); - assert(name != nullptr); - for (char *ch = name; *ch; ++ch) *ch = tolower(*ch); - - Buf lib_path = BUF_INIT; - err = find_mingw_lib_def(lj, name, &lib_path); - - if (err == ErrorFileNotFound) { - zig_panic("link: could not find .def file to build %s\n", name); - } else if (err != ErrorNone) { - zig_panic("link: unable to check if .def file for %s exists: %s", - name, err_str(err)); - } - - lj->args.append(get_def_lib(g, name, &lib_path)); - - mem::os::free(name); - } -} - -static void construct_linker_job_macho(LinkJob *lj) { - CodeGen *g = lj->codegen; - - lj->args.append("-error-limit"); - lj->args.append("0"); - lj->args.append("-demangle"); - - switch (g->linker_gc_sections) { - case OptionalBoolNull: - // TODO why do we not follow the same logic of elf here? - break; - case OptionalBoolTrue: - lj->args.append("--gc-sections"); - break; - case OptionalBoolFalse: - break; - } - - if (g->linker_rdynamic) { - lj->args.append("-export_dynamic"); - } - - if (g->linker_optimization != nullptr) { - lj->args.append(buf_ptr(g->linker_optimization)); - } - - if (g->linker_z_nodelete) { - lj->args.append("-z"); - lj->args.append("nodelete"); - } - if (g->linker_z_defs) { - lj->args.append("-z"); - lj->args.append("defs"); - } - - bool is_lib = g->out_type == OutTypeLib; - bool is_dyn_lib = g->is_dynamic && is_lib; - if (is_lib && !g->is_dynamic) { - lj->args.append("-static"); - } else { - lj->args.append("-dynamic"); - } - - if (is_dyn_lib) { - lj->args.append("-dylib"); - - Buf *compat_vers = buf_sprintf("%" ZIG_PRI_usize ".0.0", g->version_major); - lj->args.append("-compatibility_version"); - lj->args.append(buf_ptr(compat_vers)); - - Buf *cur_vers = buf_sprintf("%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize, - g->version_major, g->version_minor, g->version_patch); - lj->args.append("-current_version"); - lj->args.append(buf_ptr(cur_vers)); - - // TODO getting an error when running an executable when doing this rpath thing - //Buf *dylib_install_name = buf_sprintf("@rpath/lib%s.%" ZIG_PRI_usize ".dylib", - // buf_ptr(g->root_out_name), g->version_major); - //lj->args.append("-install_name"); - //lj->args.append(buf_ptr(dylib_install_name)); - - assert(buf_len(&g->bin_file_output_path) != 0); - } - - lj->args.append("-arch"); - lj->args.append(get_darwin_arch_string(g->zig_target)); - - if (g->zig_target->glibc_or_darwin_version != nullptr) { - if (g->zig_target->os == OsMacOSX) { - lj->args.append("-macosx_version_min"); - } else if (g->zig_target->os == OsIOS) { - if (g->zig_target->arch == ZigLLVM_x86 || g->zig_target->arch == ZigLLVM_x86_64) { - lj->args.append("-ios_simulator_version_min"); - } else { - lj->args.append("-iphoneos_version_min"); - } - } - - Buf *version_string = buf_sprintf("%d.%d.%d", - g->zig_target->glibc_or_darwin_version->major, - g->zig_target->glibc_or_darwin_version->minor, - g->zig_target->glibc_or_darwin_version->patch); - lj->args.append(buf_ptr(version_string)); - - lj->args.append("-sdk_version"); - lj->args.append(buf_ptr(version_string)); - } else if (stage2_is_zig0 && g->zig_target->os == OsMacOSX) { - // running `zig0`; `-pie` requires versions >= 10.5; select 10.13 - lj->args.append("-macosx_version_min"); - lj->args.append("10.13"); - lj->args.append("-sdk_version"); - lj->args.append("10.13"); - } - - if (g->out_type == OutTypeExe) { - lj->args.append("-pie"); - } - - lj->args.append("-o"); - lj->args.append(buf_ptr(&g->bin_file_output_path)); - - for (size_t i = 0; i < g->rpath_list.length; i += 1) { - Buf *rpath = g->rpath_list.at(i); - add_rpath(lj, rpath); - } - if (is_dyn_lib) { - add_rpath(lj, &g->bin_file_output_path); - } - - if (is_dyn_lib) { - if (g->system_linker_hack) { - lj->args.append("-headerpad_max_install_names"); - } - } - - for (size_t i = 0; i < g->lib_dirs.length; i += 1) { - const char *lib_dir = g->lib_dirs.at(i); - lj->args.append("-L"); - lj->args.append(lib_dir); - } - - // .o files - for (size_t i = 0; i < g->link_objects.length; i += 1) { - lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); - } - - // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce - if (g->out_type == OutTypeExe || is_dyn_lib) { - Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib, lj->build_dep_prog_node); - lj->args.append(buf_ptr(compiler_rt_o_path)); - } - - // libraries - for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) { - LinkLib *link_lib = g->link_libs_list.at(lib_i); - if (buf_eql_str(link_lib->name, "c")) { - // libc is linked specially - continue; - } - if (target_is_libcpp_lib_name(g->zig_target, buf_ptr(link_lib->name))) { - // libc++ is linked specially - continue; - } - if (g->zig_target->is_native_os && target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) { - // libSystem is linked specially - continue; - } - - Buf *arg; - if (buf_starts_with_str(link_lib->name, "/") || buf_ends_with_str(link_lib->name, ".a") || - buf_ends_with_str(link_lib->name, ".dylib")) - { - arg = link_lib->name; - } else { - arg = buf_sprintf("-l%s", buf_ptr(link_lib->name)); - } - lj->args.append(buf_ptr(arg)); - } - - // libc++ dep - if (g->libcpp_link_lib != nullptr && g->out_type != OutTypeObj) { - lj->args.append(build_libcxxabi(g, lj->build_dep_prog_node)); - lj->args.append(build_libcxx(g, lj->build_dep_prog_node)); - } - - // libc dep - if (g->zig_target->is_native_os || stage2_is_zig0) { - // on Darwin, libSystem has libc in it, but also you have to use it - // to make syscalls because the syscall numbers are not documented - // and change between versions. - // so we always link against libSystem - lj->args.append("-lSystem"); - } - - for (size_t i = 0; i < g->framework_dirs.length; i += 1) { - const char *framework_dir = g->framework_dirs.at(i); - lj->args.append("-F"); - lj->args.append(framework_dir); - } - - for (size_t i = 0; i < g->darwin_frameworks.length; i += 1) { - lj->args.append("-framework"); - lj->args.append(buf_ptr(g->darwin_frameworks.at(i))); - } - - switch (g->linker_allow_shlib_undefined) { - case OptionalBoolNull: - if (!g->zig_target->is_native_os && !stage2_is_zig0) { - // TODO https://github.com/ziglang/zig/issues/5059 - lj->args.append("-undefined"); - lj->args.append("dynamic_lookup"); - } - break; - case OptionalBoolFalse: - break; - case OptionalBoolTrue: - lj->args.append("-undefined"); - lj->args.append("dynamic_lookup"); - break; - } - switch (g->linker_bind_global_refs_locally) { - case OptionalBoolNull: - case OptionalBoolFalse: - break; - case OptionalBoolTrue: - lj->args.append("-Bsymbolic"); - break; - } -} - -static void construct_linker_job(LinkJob *lj) { - switch (target_object_format(lj->codegen->zig_target)) { - case ZigLLVM_UnknownObjectFormat: - case ZigLLVM_XCOFF: - zig_unreachable(); - - case ZigLLVM_COFF: - return construct_linker_job_coff(lj); - case ZigLLVM_ELF: - return construct_linker_job_elf(lj); - case ZigLLVM_MachO: - return construct_linker_job_macho(lj); - case ZigLLVM_Wasm: - return construct_linker_job_wasm(lj); - } -} - -void zig_link_add_compiler_rt(CodeGen *g, Stage2ProgressNode *progress_node) { - Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj, progress_node); - g->link_objects.append(compiler_rt_o_path); -} - -void codegen_link(CodeGen *g) { - codegen_add_time_event(g, "Build Dependencies"); - LinkJob lj = {0}; - - { - const char *progress_name = "Build Dependencies"; - codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, - progress_name, strlen(progress_name), 0)); - lj.build_dep_prog_node = g->sub_progress_node; - } - - - // even though we're calling LLD as a library it thinks the first - // argument is its own exe name - lj.args.append("lld"); - - lj.rpath_table.init(4); - lj.codegen = g; - - if (g->out_type == OutTypeObj) { - lj.args.append("-r"); - } - - if (g->out_type == OutTypeLib && !g->is_dynamic && !target_is_wasm(g->zig_target)) { - ZigList file_names = {}; - for (size_t i = 0; i < g->link_objects.length; i += 1) { - file_names.append(buf_ptr(g->link_objects.at(i))); - } - ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os); - codegen_add_time_event(g, "LLVM Link"); - { - const char *progress_name = "Link"; - codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, - progress_name, strlen(progress_name), 0)); - } - if (g->verbose_link) { - fprintf(stderr, "ar rcs %s", buf_ptr(&g->bin_file_output_path)); - for (size_t i = 0; i < file_names.length; i += 1) { - fprintf(stderr, " %s", file_names.at(i)); - } - fprintf(stderr, "\n"); - } - if (ZigLLVMWriteArchive(buf_ptr(&g->bin_file_output_path), file_names.items, file_names.length, os_type)) { - fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->bin_file_output_path)); - exit(1); - } - return; - } - - lj.link_in_crt = (g->libc_link_lib != nullptr && g->out_type == OutTypeExe); - - construct_linker_job(&lj); - - if (g->verbose_link) { - for (size_t i = 0; i < lj.args.length; i += 1) { - const char *space = (i != 0) ? " " : ""; - fprintf(stderr, "%s%s", space, lj.args.at(i)); - } - fprintf(stderr, "\n"); - } - - Buf diag = BUF_INIT; - - codegen_add_time_event(g, "LLVM Link"); - { - const char *progress_name = "Link"; - codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, - progress_name, strlen(progress_name), 0)); - } - if (g->system_linker_hack && g->zig_target->os == OsMacOSX) { - Termination term; - ZigList args = {}; - args.append("ld"); - for (size_t i = 1; i < lj.args.length; i += 1) { - args.append(lj.args.at(i)); - } - os_spawn_process(args, &term); - if (term.how != TerminationIdClean || term.code != 0) { - exit(1); - } - } else if (!zig_lld_link(target_object_format(g->zig_target), lj.args.items, lj.args.length, &diag)) { - fprintf(stderr, "%s\n", buf_ptr(&diag)); - exit(1); - } -} - diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 003ba6b7c6..0000000000 --- a/src/main.cpp +++ /dev/null @@ -1,1474 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Kelley - * - * This file is part of zig, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#include "ast_render.hpp" -#include "buffer.hpp" -#include "codegen.hpp" -#include "compiler.hpp" -#include "config.h" -#include "error.hpp" -#include "heap.hpp" -#include "os.hpp" -#include "target.hpp" -#include "stage2.h" -#include "glibc.hpp" -#include "dump_analysis.hpp" -#include "mem_profile.hpp" - -#include - -static int print_error_usage(const char *arg0) { - fprintf(stderr, "See `%s --help` for detailed usage information\n", arg0); - return EXIT_FAILURE; -} - -static int print_full_usage(const char *arg0, FILE *file, int return_code) { - fprintf(file, - "Usage: %s [command] [options]\n" - "\n" - "Commands:\n" - " build build project from build.zig\n" - " build-exe [source] create executable from source or object files\n" - " build-lib [source] create library from source or object files\n" - " build-obj [source] create object from source or assembly\n" - " builtin show the source code of @import(\"builtin\")\n" - " cc use Zig as a drop-in C compiler\n" - " c++ use Zig as a drop-in C++ compiler\n" - " env print lib path, std path, compiler id and version\n" - " fmt parse files and render in canonical zig format\n" - " id print the base64-encoded compiler id\n" - " init-exe initialize a `zig build` application in the cwd\n" - " init-lib initialize a `zig build` library in the cwd\n" - " libc [paths_file] Display native libc paths file or validate one\n" - " run [source] [-- [args]] create executable and run immediately\n" - " translate-c [source] convert c code to zig code\n" - " targets list available compilation targets\n" - " test [source] create and run a test build\n" - " version print version number and exit\n" - " zen print zen of zig and exit\n" - "\n" - "Compile Options:\n" - " --c-source [options] [file] compile C source code\n" - " --cache-dir [path] override the local cache directory\n" - " --cache [auto|off|on] build in cache, print output path to stdout\n" - " --color [auto|off|on] enable or disable colored error messages\n" - " --disable-valgrind omit valgrind client requests in debug builds\n" - " --eh-frame-hdr enable C++ exception handling by passing --eh-frame-hdr to linker\n" - " --enable-valgrind include valgrind client requests release builds\n" - " -fstack-check enable stack probing in unsafe builds\n" - " -fno-stack-check disable stack probing in safe builds\n" - " -fsanitize-c enable C undefined behavior detection in unsafe builds\n" - " -fno-sanitize-c disable C undefined behavior detection in safe builds\n" - " --emit [asm|bin|llvm-ir] (deprecated) emit a specific file format as compilation output\n" - " -fPIC enable Position Independent Code\n" - " -fno-PIC disable Position Independent Code\n" - " -ftime-report print timing diagnostics\n" - " -fstack-report print stack size diagnostics\n" - " -fmem-report print memory usage diagnostics\n" - " -fdump-analysis write analysis.json file with type information\n" - " -femit-docs create a docs/ dir with html documentation\n" - " -fno-emit-docs do not produce docs/ dir with html documentation\n" - " -femit-bin (default) output machine code\n" - " -fno-emit-bin do not output machine code\n" - " -femit-asm output .s (assembly code)\n" - " -fno-emit-asm (default) do not output .s (assembly code)\n" - " -femit-llvm-ir produce a .ll file with LLVM IR\n" - " -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n" - " -femit-h generate a C header file (.h)\n" - " -fno-emit-h (default) do not generate a C header file (.h)\n" - " --libc [file] Provide a file which specifies libc paths\n" - " --name [name] override output name\n" - " --output-dir [dir] override output directory (defaults to cwd)\n" - " --pkg-begin [name] [path] make pkg available to import and push current pkg\n" - " --pkg-end pop current pkg\n" - " --main-pkg-path set the directory of the root package\n" - " --release-fast build with optimizations on and safety off\n" - " --release-safe build with optimizations on and safety on\n" - " --release-small build with size optimizations on and safety off\n" - " --single-threaded source may assume it is only used single-threaded\n" - " -dynamic create a shared library (.so; .dll; .dylib)\n" - " --strip exclude debug symbols\n" - " -target [name] -- see the targets command\n" - " --verbose-tokenize enable compiler debug output for tokenization\n" - " --verbose-ast enable compiler debug output for AST parsing\n" - " --verbose-link enable compiler debug output for linking\n" - " --verbose-ir enable compiler debug output for Zig IR\n" - " --verbose-llvm-ir enable compiler debug output for LLVM IR\n" - " --verbose-cimport enable compiler debug output for C imports\n" - " --verbose-cc enable compiler debug output for C compilation\n" - " --verbose-llvm-cpu-features enable compiler debug output for LLVM CPU features\n" - " -dirafter [dir] add directory to AFTER include search path\n" - " -isystem [dir] add directory to SYSTEM include search path\n" - " -I[dir] add directory to include search path\n" - " -mllvm [arg] (unsupported) forward an arg to LLVM's option processing\n" - " --override-lib-dir [arg] override path to Zig lib directory\n" - " -ffunction-sections places each function in a separate section\n" - " -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n" - " -mcpu [cpu] specify target CPU and feature set\n" - " -code-model [default|tiny| set target code model\n" - " small|kernel|\n" - " medium|large]\n" - "\n" - "Link Options:\n" - " --bundle-compiler-rt for static libraries, include compiler-rt symbols\n" - " --dynamic-linker [path] set the path to ld.so\n" - " --each-lib-rpath add rpath for each used dynamic library\n" - " --library [lib] link against lib\n" - " --forbid-library [lib] make it an error to link against lib\n" - " --library-path [dir] add a directory to the library search path\n" - " --linker-script [path] use a custom linker script\n" - " --version-script [path] provide a version .map file\n" - " --object [obj] add object file to build\n" - " -L[dir] alias for --library-path\n" - " -l[lib] alias for --library\n" - " -rdynamic add all symbols to the dynamic symbol table\n" - " -rpath [path] add directory to the runtime library search path\n" - " --stack [size] (linux, windows, Wasm) override default stack size\n" - " --subsystem [subsystem] (windows) /SUBSYSTEM: to the linker\n" - " -F[dir] (darwin) add search path for frameworks\n" - " -framework [name] (darwin) link against framework\n" - " --ver-major [ver] dynamic library semver major version\n" - " --ver-minor [ver] dynamic library semver minor version\n" - " --ver-patch [ver] dynamic library semver patch version\n" - " -Bsymbolic bind global references locally\n" - "\n" - "Test Options:\n" - " --test-filter [text] skip tests that do not match filter\n" - " --test-name-prefix [text] add prefix to all tests\n" - " --test-cmd [arg] specify test execution command one arg at a time\n" - " --test-cmd-bin appends test binary path to test cmd args\n" - " --test-evented-io runs the test in evented I/O mode\n" - , arg0); - return return_code; -} - -static int print_libc_usage(const char *arg0, FILE *file, int return_code) { - fprintf(file, - "Usage: %s libc\n" - "\n" - "Detect the native libc installation and print the resulting paths to stdout.\n" - "You can save this into a file and then edit the paths to create a cross\n" - "compilation libc kit. Then you can pass `--libc [file]` for Zig to use it.\n" - "\n" - "When compiling natively and no `--libc` argument provided, Zig will create\n" - "`%s/native_libc.txt`\n" - "so that it does not have to detect libc on every invocation. You can remove\n" - "this file to have Zig re-detect the native libc.\n" - "\n\n" - "Usage: %s libc [file]\n" - "\n" - "Parse a libc installation text file and validate it.\n" - , arg0, buf_ptr(get_global_cache_dir()), arg0); - return return_code; -} - -enum Cmd { - CmdNone, - CmdBuild, - CmdBuiltin, - CmdRun, - CmdTargets, - CmdTest, - CmdTranslateC, - CmdVersion, - CmdZen, - CmdLibC, -}; - -static const char *default_zig_cache_name = "zig-cache"; - -struct CliPkg { - const char *name; - const char *path; - ZigList children; - CliPkg *parent; -}; - -static void add_package(CodeGen *g, CliPkg *cli_pkg, ZigPackage *pkg) { - for (size_t i = 0; i < cli_pkg->children.length; i += 1) { - CliPkg *child_cli_pkg = cli_pkg->children.at(i); - - Buf *dirname = buf_alloc(); - Buf *basename = buf_alloc(); - os_path_split(buf_create_from_str(child_cli_pkg->path), dirname, basename); - - ZigPackage *child_pkg = codegen_create_package(g, buf_ptr(dirname), buf_ptr(basename), - buf_ptr(buf_sprintf("%s.%s", buf_ptr(&pkg->pkg_path), child_cli_pkg->name))); - auto entry = pkg->package_table.put_unique(buf_create_from_str(child_cli_pkg->name), child_pkg); - if (entry) { - ZigPackage *existing_pkg = entry->value; - Buf *full_path = buf_alloc(); - os_path_join(&existing_pkg->root_src_dir, &existing_pkg->root_src_path, full_path); - fprintf(stderr, "Unable to add package '%s'->'%s': already exists as '%s'\n", - child_cli_pkg->name, child_cli_pkg->path, buf_ptr(full_path)); - exit(EXIT_FAILURE); - } - - add_package(g, child_cli_pkg, child_pkg); - } -} - -enum CacheOpt { - CacheOptAuto, - CacheOptOn, - CacheOptOff, -}; - -static bool get_cache_opt(CacheOpt opt, bool default_value) { - switch (opt) { - case CacheOptAuto: - return default_value; - case CacheOptOn: - return true; - case CacheOptOff: - return false; - } - zig_unreachable(); -} - -static int zig_error_no_build_file(void) { - fprintf(stderr, - "No 'build.zig' file found, in the current directory or any parent directories.\n" - "Initialize a 'build.zig' template file with `zig init-lib` or `zig init-exe`,\n" - "or see `zig --help` for more options.\n" - ); - return EXIT_FAILURE; -} - -static bool str_starts_with(const char *s1, const char *s2) { - size_t s2_len = strlen(s2); - if (strlen(s1) < s2_len) { - return false; - } - return memcmp(s1, s2, s2_len) == 0; -} - -extern "C" int ZigClang_main(int argc, char **argv); - -#ifdef ZIG_ENABLE_MEM_PROFILE -bool mem_report = false; -#endif - -int main_exit(Stage2ProgressNode *root_progress_node, int exit_code) { - if (root_progress_node != nullptr) { - stage2_progress_end(root_progress_node); - } - return exit_code; -} - -static int main0(int argc, char **argv) { - char *arg0 = argv[0]; - Error err; - - if (argc >= 2 && (strcmp(argv[1], "clang") == 0 || - strcmp(argv[1], "-cc1") == 0 || strcmp(argv[1], "-cc1as") == 0)) - { - return ZigClang_main(argc, argv); - } - - if (argc == 2 && strcmp(argv[1], "id") == 0) { - Buf *compiler_id; - if ((err = get_compiler_id(&compiler_id))) { - fprintf(stderr, "Unable to determine compiler id: %s\n", err_str(err)); - return EXIT_FAILURE; - } - printf("%s\n", buf_ptr(compiler_id)); - return EXIT_SUCCESS; - } - - enum InitKind { - InitKindNone, - InitKindExe, - InitKindLib, - }; - InitKind init_kind = InitKindNone; - if (argc >= 2) { - const char *init_cmd = argv[1]; - if (strcmp(init_cmd, "init-exe") == 0) { - init_kind = InitKindExe; - } else if (strcmp(init_cmd, "init-lib") == 0) { - init_kind = InitKindLib; - } - if (init_kind != InitKindNone) { - if (argc >= 3) { - fprintf(stderr, "Unexpected extra argument: %s\n", argv[2]); - return print_error_usage(arg0); - } - Buf *cmd_template_path = buf_alloc(); - os_path_join(get_zig_special_dir(get_zig_lib_dir()), buf_create_from_str(init_cmd), cmd_template_path); - Buf *build_zig_path = buf_alloc(); - os_path_join(cmd_template_path, buf_create_from_str("build.zig"), build_zig_path); - Buf *src_dir_path = buf_alloc(); - os_path_join(cmd_template_path, buf_create_from_str("src"), src_dir_path); - Buf *main_zig_path = buf_alloc(); - os_path_join(src_dir_path, buf_create_from_str("main.zig"), main_zig_path); - - Buf *cwd = buf_alloc(); - if ((err = os_get_cwd(cwd))) { - fprintf(stderr, "Unable to get cwd: %s\n", err_str(err)); - return EXIT_FAILURE; - } - Buf *cwd_basename = buf_alloc(); - os_path_split(cwd, nullptr, cwd_basename); - - Buf *build_zig_contents = buf_alloc(); - if ((err = os_fetch_file_path(build_zig_path, build_zig_contents))) { - fprintf(stderr, "Unable to read %s: %s\n", buf_ptr(build_zig_path), err_str(err)); - return EXIT_FAILURE; - } - Buf *modified_build_zig_contents = buf_alloc(); - for (size_t i = 0; i < buf_len(build_zig_contents); i += 1) { - char c = buf_ptr(build_zig_contents)[i]; - if (c == '$') { - buf_append_buf(modified_build_zig_contents, cwd_basename); - } else { - buf_append_char(modified_build_zig_contents, c); - } - } - - Buf *main_zig_contents = buf_alloc(); - if ((err = os_fetch_file_path(main_zig_path, main_zig_contents))) { - fprintf(stderr, "Unable to read %s: %s\n", buf_ptr(main_zig_path), err_str(err)); - return EXIT_FAILURE; - } - - Buf *out_build_zig_path = buf_create_from_str("build.zig"); - Buf *out_src_dir_path = buf_create_from_str("src"); - Buf *out_main_zig_path = buf_alloc(); - os_path_join(out_src_dir_path, buf_create_from_str("main.zig"), out_main_zig_path); - - bool already_exists; - if ((err = os_file_exists(out_build_zig_path, &already_exists))) { - fprintf(stderr, "Unable test existence of %s: %s\n", buf_ptr(out_build_zig_path), err_str(err)); - return EXIT_FAILURE; - } - if (already_exists) { - fprintf(stderr, "This file would be overwritten: %s\n", buf_ptr(out_build_zig_path)); - return EXIT_FAILURE; - } - - if ((err = os_make_dir(out_src_dir_path))) { - fprintf(stderr, "Unable to make directory: %s: %s\n", buf_ptr(out_src_dir_path), err_str(err)); - return EXIT_FAILURE; - } - if ((err = os_write_file(out_build_zig_path, modified_build_zig_contents))) { - fprintf(stderr, "Unable to write file: %s: %s\n", buf_ptr(out_build_zig_path), err_str(err)); - return EXIT_FAILURE; - } - if ((err = os_write_file(out_main_zig_path, main_zig_contents))) { - fprintf(stderr, "Unable to write file: %s: %s\n", buf_ptr(out_main_zig_path), err_str(err)); - return EXIT_FAILURE; - } - fprintf(stderr, "Created %s\n", buf_ptr(out_build_zig_path)); - fprintf(stderr, "Created %s\n", buf_ptr(out_main_zig_path)); - if (init_kind == InitKindExe) { - fprintf(stderr, "\nNext, try `zig build --help` or `zig build run`\n"); - } else if (init_kind == InitKindLib) { - fprintf(stderr, "\nNext, try `zig build --help` or `zig build test`\n"); - } else { - zig_unreachable(); - } - - return EXIT_SUCCESS; - } - } - - Cmd cmd = CmdNone; - const char *in_file = nullptr; - Buf *output_dir = nullptr; - bool strip = false; - bool is_dynamic = false; - OutType out_type = OutTypeUnknown; - const char *out_name = nullptr; - bool verbose_tokenize = false; - bool verbose_ast = false; - bool verbose_link = false; - bool verbose_ir = false; - bool verbose_llvm_ir = false; - bool verbose_cimport = false; - bool verbose_cc = false; - bool verbose_llvm_cpu_features = false; - bool link_eh_frame_hdr = false; - ErrColor color = ErrColorAuto; - CacheOpt enable_cache = CacheOptAuto; - const char *dynamic_linker = nullptr; - const char *libc_txt = nullptr; - ZigList clang_argv = {0}; - ZigList lib_dirs = {0}; - ZigList link_libs = {0}; - ZigList forbidden_link_libs = {0}; - ZigList framework_dirs = {0}; - ZigList frameworks = {0}; - bool have_libc = false; - const char *target_string = nullptr; - bool rdynamic = false; - const char *linker_script = nullptr; - Buf *version_script = nullptr; - ZigList rpath_list = {0}; - bool each_lib_rpath = false; - ZigList objects = {0}; - ZigList c_source_files = {0}; - const char *test_filter = nullptr; - const char *test_name_prefix = nullptr; - bool test_evented_io = false; - bool is_versioned = false; - size_t ver_major = 0; - size_t ver_minor = 0; - size_t ver_patch = 0; - bool timing_info = false; - bool stack_report = false; - bool enable_dump_analysis = false; - bool enable_doc_generation = false; - bool emit_bin = true; - const char *emit_bin_override_path = nullptr; - bool emit_asm = false; - bool emit_llvm_ir = false; - bool emit_h = false; - const char *cache_dir = nullptr; - CliPkg *cur_pkg = heap::c_allocator.create(); - BuildMode build_mode = BuildModeDebug; - ZigList test_exec_args = {0}; - int runtime_args_start = -1; - bool system_linker_hack = false; - TargetSubsystem subsystem = TargetSubsystemAuto; - bool want_single_threaded = false; - bool bundle_compiler_rt = false; - Buf *override_lib_dir = nullptr; - Buf *main_pkg_path = nullptr; - ValgrindSupport valgrind_support = ValgrindSupportAuto; - WantPIC want_pic = WantPICAuto; - WantStackCheck want_stack_check = WantStackCheckAuto; - WantCSanitize want_sanitize_c = WantCSanitizeAuto; - bool function_sections = false; - const char *mcpu = nullptr; - CodeModel code_model = CodeModelDefault; - bool want_native_include_dirs = false; - OptionalBool linker_bind_global_refs_locally = OptionalBoolNull; - size_t stack_size_override = 0; - - ZigList llvm_argv = {0}; - llvm_argv.append("zig (LLVM option parsing)"); - - if (argc >= 2 && strcmp(argv[1], "build") == 0) { - Buf zig_exe_path_buf = BUF_INIT; - if ((err = os_self_exe_path(&zig_exe_path_buf))) { - fprintf(stderr, "Unable to determine path to zig's own executable\n"); - return EXIT_FAILURE; - } - const char *zig_exe_path = buf_ptr(&zig_exe_path_buf); - const char *build_file = nullptr; - - init_all_targets(); - - ZigList args = {0}; - args.append(NULL); // placeholder - args.append(zig_exe_path); - args.append(NULL); // placeholder - args.append(NULL); // placeholder - for (int i = 2; i < argc; i += 1) { - if (strcmp(argv[i], "--help") == 0) { - args.append(argv[i]); - } else if (i + 1 < argc && strcmp(argv[i], "--build-file") == 0) { - build_file = argv[i + 1]; - i += 1; - } else if (i + 1 < argc && strcmp(argv[i], "--cache-dir") == 0) { - cache_dir = argv[i + 1]; - i += 1; - } else if (i + 1 < argc && strcmp(argv[i], "--override-lib-dir") == 0) { - override_lib_dir = buf_create_from_str(argv[i + 1]); - i += 1; - - args.append("--override-lib-dir"); - args.append(buf_ptr(override_lib_dir)); - } else { - args.append(argv[i]); - } - } - - Buf *zig_lib_dir = (override_lib_dir == nullptr) ? get_zig_lib_dir() : override_lib_dir; - - Buf *build_runner_path = buf_alloc(); - os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path); - - ZigTarget target; - if ((err = target_parse_triple(&target, "native", nullptr, nullptr))) { - fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); - return EXIT_FAILURE; - } - - Buf *build_file_buf = buf_create_from_str((build_file != nullptr) ? build_file : "build.zig"); - Buf build_file_abs = os_path_resolve(&build_file_buf, 1); - Buf build_file_basename = BUF_INIT; - Buf build_file_dirname = BUF_INIT; - os_path_split(&build_file_abs, &build_file_dirname, &build_file_basename); - - for (;;) { - bool build_file_exists; - if ((err = os_file_exists(&build_file_abs, &build_file_exists))) { - fprintf(stderr, "unable to check existence of '%s': %s\n", buf_ptr(&build_file_abs), err_str(err)); - return 1; - } - if (build_file_exists) - break; - - if (build_file != nullptr) { - // they asked for a specific build file path. only look for that one - return zig_error_no_build_file(); - } - - Buf *next_dir = buf_alloc(); - os_path_dirname(&build_file_dirname, next_dir); - if (buf_eql_buf(&build_file_dirname, next_dir)) { - // no more parent directories to search, give up - return zig_error_no_build_file(); - } - os_path_join(next_dir, &build_file_basename, &build_file_abs); - buf_init_from_buf(&build_file_dirname, next_dir); - } - - Buf full_cache_dir = BUF_INIT; - if (cache_dir == nullptr) { - os_path_join(&build_file_dirname, buf_create_from_str(default_zig_cache_name), &full_cache_dir); - } else { - Buf *cache_dir_buf = buf_create_from_str(cache_dir); - full_cache_dir = os_path_resolve(&cache_dir_buf, 1); - } - Stage2ProgressNode *root_progress_node = stage2_progress_start_root(stage2_progress_create(), "", 0, 0); - - CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe, - BuildModeDebug, override_lib_dir, nullptr, &full_cache_dir, false, root_progress_node); - g->valgrind_support = valgrind_support; - g->enable_time_report = timing_info; - codegen_set_out_name(g, buf_create_from_str("build")); - - args.items[2] = buf_ptr(&build_file_dirname); - args.items[3] = buf_ptr(&full_cache_dir); - - ZigPackage *build_pkg = codegen_create_package(g, buf_ptr(&build_file_dirname), - buf_ptr(&build_file_basename), "std.special"); - g->main_pkg->package_table.put(buf_create_from_str("@build"), build_pkg); - g->enable_cache = get_cache_opt(enable_cache, true); - codegen_build_and_link(g); - if (root_progress_node != nullptr) { - stage2_progress_end(root_progress_node); - root_progress_node = nullptr; - } - - Termination term; - args.items[0] = buf_ptr(&g->bin_file_output_path); - os_spawn_process(args, &term); - if (term.how != TerminationIdClean || term.code != 0) { - fprintf(stderr, "\nBuild failed. The following command failed:\n"); - const char *prefix = ""; - for (size_t i = 0; i < args.length; i += 1) { - fprintf(stderr, "%s%s", prefix, args.at(i)); - prefix = " "; - } - fprintf(stderr, "\n"); - } - return (term.how == TerminationIdClean) ? term.code : -1; - } else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) { - return stage2_fmt(argc, argv); - } else if (argc >= 2 && strcmp(argv[1], "env") == 0) { - return stage2_env(argc, argv); - } else if (argc >= 2 && strcmp(argv[1], "cc") == 0) { - return stage2_cc(argc, argv, false); - } else if (argc >= 2 && strcmp(argv[1], "c++") == 0) { - return stage2_cc(argc, argv, true); - } else for (int i = 1; i < argc; i += 1) { - char *arg = argv[i]; - - if (arg[0] == '-') { - if (strcmp(arg, "--") == 0) { - if (cmd == CmdRun) { - runtime_args_start = i + 1; - break; // rest of the args are for the program - } else { - fprintf(stderr, "Unexpected end-of-parameter mark: %s\n", arg); - } - } else if (strcmp(arg, "--release-fast") == 0) { - build_mode = BuildModeFastRelease; - } else if (strcmp(arg, "--release-safe") == 0) { - build_mode = BuildModeSafeRelease; - } else if (strcmp(arg, "--release-small") == 0) { - build_mode = BuildModeSmallRelease; - } else if (strcmp(arg, "--help") == 0) { - if (cmd == CmdLibC) { - return print_libc_usage(arg0, stdout, EXIT_SUCCESS); - } else { - return print_full_usage(arg0, stdout, EXIT_SUCCESS); - } - } else if (strcmp(arg, "--strip") == 0) { - strip = true; - } else if (strcmp(arg, "-dynamic") == 0) { - is_dynamic = true; - } else if (strcmp(arg, "--verbose-tokenize") == 0) { - verbose_tokenize = true; - } else if (strcmp(arg, "--verbose-ast") == 0) { - verbose_ast = true; - } else if (strcmp(arg, "--verbose-link") == 0) { - verbose_link = true; - } else if (strcmp(arg, "--verbose-ir") == 0) { - verbose_ir = true; - } else if (strcmp(arg, "--verbose-llvm-ir") == 0) { - verbose_llvm_ir = true; - } else if (strcmp(arg, "--verbose-cimport") == 0) { - verbose_cimport = true; - } else if (strcmp(arg, "--verbose-cc") == 0) { - verbose_cc = true; - } else if (strcmp(arg, "--verbose-llvm-cpu-features") == 0) { - verbose_llvm_cpu_features = true; - } else if (strcmp(arg, "-rdynamic") == 0) { - rdynamic = true; - } else if (strcmp(arg, "--each-lib-rpath") == 0) { - each_lib_rpath = true; - } else if (strcmp(arg, "-ftime-report") == 0) { - timing_info = true; - } else if (strcmp(arg, "-fstack-report") == 0) { - stack_report = true; - } else if (strcmp(arg, "-fmem-report") == 0) { -#ifdef ZIG_ENABLE_MEM_PROFILE - mem_report = true; - mem::report_print = true; -#else - fprintf(stderr, "-fmem-report requires configuring with -DZIG_ENABLE_MEM_PROFILE=ON\n"); - return print_error_usage(arg0); -#endif - } else if (strcmp(arg, "-fdump-analysis") == 0) { - enable_dump_analysis = true; - } else if (strcmp(arg, "-femit-docs") == 0) { - enable_doc_generation = true; - } else if (strcmp(arg, "--enable-valgrind") == 0) { - valgrind_support = ValgrindSupportEnabled; - } else if (strcmp(arg, "--disable-valgrind") == 0) { - valgrind_support = ValgrindSupportDisabled; - } else if (strcmp(arg, "--eh-frame-hdr") == 0) { - link_eh_frame_hdr = true; - } else if (strcmp(arg, "-fPIC") == 0) { - want_pic = WantPICEnabled; - } else if (strcmp(arg, "-fno-PIC") == 0) { - want_pic = WantPICDisabled; - } else if (strcmp(arg, "-fstack-check") == 0) { - want_stack_check = WantStackCheckEnabled; - } else if (strcmp(arg, "-fno-stack-check") == 0) { - want_stack_check = WantStackCheckDisabled; - } else if (strcmp(arg, "-fsanitize-c") == 0) { - want_sanitize_c = WantCSanitizeEnabled; - } else if (strcmp(arg, "-fno-sanitize-c") == 0) { - want_sanitize_c = WantCSanitizeDisabled; - } else if (strcmp(arg, "--system-linker-hack") == 0) { - system_linker_hack = true; - } else if (strcmp(arg, "--single-threaded") == 0) { - want_single_threaded = true;; - } else if (strcmp(arg, "--bundle-compiler-rt") == 0) { - bundle_compiler_rt = true; - } else if (strcmp(arg, "-Bsymbolic") == 0) { - linker_bind_global_refs_locally = OptionalBoolTrue; - } else if (strcmp(arg, "--test-cmd-bin") == 0) { - test_exec_args.append(nullptr); - } else if (arg[1] == 'D' && arg[2] != 0) { - clang_argv.append("-D"); - clang_argv.append(&arg[2]); - } else if (arg[1] == 'L' && arg[2] != 0) { - // alias for --library-path - lib_dirs.append(&arg[2]); - } else if (arg[1] == 'l' && arg[2] != 0) { - // alias for --library - const char *l = &arg[2]; - if (strcmp(l, "c") == 0) { - have_libc = true; - link_libs.append("c"); - } else if (strcmp(l, "c++") == 0 || strcmp(l, "stdc++") == 0) { - link_libs.append("c++"); - } else { - link_libs.append(l); - } - } else if (arg[1] == 'I' && arg[2] != 0) { - clang_argv.append("-I"); - clang_argv.append(&arg[2]); - } else if (arg[1] == 'F' && arg[2] != 0) { - framework_dirs.append(&arg[2]); - } else if (strcmp(arg, "--pkg-begin") == 0) { - if (i + 2 >= argc) { - fprintf(stderr, "Expected 2 arguments after --pkg-begin\n"); - return print_error_usage(arg0); - } - CliPkg *new_cur_pkg = heap::c_allocator.create(); - i += 1; - new_cur_pkg->name = argv[i]; - i += 1; - new_cur_pkg->path = argv[i]; - new_cur_pkg->parent = cur_pkg; - cur_pkg->children.append(new_cur_pkg); - cur_pkg = new_cur_pkg; - } else if (strcmp(arg, "--pkg-end") == 0) { - if (cur_pkg->parent == nullptr) { - fprintf(stderr, "Encountered --pkg-end with no matching --pkg-begin\n"); - return EXIT_FAILURE; - } - cur_pkg = cur_pkg->parent; - } else if (strcmp(arg, "-ffunction-sections") == 0) { - function_sections = true; - } else if (strcmp(arg, "--test-evented-io") == 0) { - test_evented_io = true; - } else if (strcmp(arg, "-femit-bin") == 0) { - emit_bin = true; - } else if (strcmp(arg, "-fno-emit-bin") == 0) { - emit_bin = false; - } else if (strcmp(arg, "-femit-asm") == 0) { - emit_asm = true; - } else if (strcmp(arg, "-fno-emit-asm") == 0) { - emit_asm = false; - } else if (strcmp(arg, "-femit-llvm-ir") == 0) { - emit_llvm_ir = true; - } else if (strcmp(arg, "-fno-emit-llvm-ir") == 0) { - emit_llvm_ir = false; - } else if (strcmp(arg, "-femit-h") == 0) { - emit_h = true; - } else if (strcmp(arg, "-fno-emit-h") == 0 || strcmp(arg, "--disable-gen-h") == 0) { - // the --disable-gen-h is there to support godbolt. once they upgrade to -fno-emit-h then we can remove this - emit_h = false; - } else if (str_starts_with(arg, "-mcpu=")) { - mcpu = arg + strlen("-mcpu="); - } else if (i + 1 >= argc) { - fprintf(stderr, "Expected another argument after %s\n", arg); - return print_error_usage(arg0); - } else { - i += 1; - if (strcmp(arg, "--output-dir") == 0) { - output_dir = buf_create_from_str(argv[i]); - } else if (strcmp(arg, "--color") == 0) { - if (strcmp(argv[i], "auto") == 0) { - color = ErrColorAuto; - } else if (strcmp(argv[i], "on") == 0) { - color = ErrColorOn; - } else if (strcmp(argv[i], "off") == 0) { - color = ErrColorOff; - } else { - fprintf(stderr, "--color options are 'auto', 'on', or 'off'\n"); - return print_error_usage(arg0); - } - } else if (strcmp(arg, "--cache") == 0) { - if (strcmp(argv[i], "auto") == 0) { - enable_cache = CacheOptAuto; - } else if (strcmp(argv[i], "on") == 0) { - enable_cache = CacheOptOn; - } else if (strcmp(argv[i], "off") == 0) { - enable_cache = CacheOptOff; - } else { - fprintf(stderr, "--cache options are 'auto', 'on', or 'off'\n"); - return print_error_usage(arg0); - } - } else if (strcmp(arg, "--emit") == 0) { - if (strcmp(argv[i], "asm") == 0) { - emit_asm = true; - emit_bin = false; - } else if (strcmp(argv[i], "bin") == 0) { - emit_bin = true; - } else if (strcmp(argv[i], "llvm-ir") == 0) { - emit_llvm_ir = true; - emit_bin = false; - } else { - fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n"); - return print_error_usage(arg0); - } - } else if (strcmp(arg, "--name") == 0) { - out_name = argv[i]; - } else if (strcmp(arg, "--dynamic-linker") == 0) { - dynamic_linker = argv[i]; - } else if (strcmp(arg, "--libc") == 0) { - libc_txt = argv[i]; - } else if (strcmp(arg, "-D") == 0) { - clang_argv.append("-D"); - clang_argv.append(argv[i]); - } else if (strcmp(arg, "-isystem") == 0) { - clang_argv.append("-isystem"); - clang_argv.append(argv[i]); - } else if (strcmp(arg, "-I") == 0) { - clang_argv.append("-I"); - clang_argv.append(argv[i]); - } else if (strcmp(arg, "-dirafter") == 0) { - clang_argv.append("-dirafter"); - clang_argv.append(argv[i]); - } else if (strcmp(arg, "-mllvm") == 0) { - clang_argv.append("-mllvm"); - clang_argv.append(argv[i]); - - llvm_argv.append(argv[i]); - } else if (strcmp(arg, "-code-model") == 0) { - if (strcmp(argv[i], "default") == 0) { - code_model = CodeModelDefault; - } else if (strcmp(argv[i], "tiny") == 0) { - code_model = CodeModelTiny; - } else if (strcmp(argv[i], "small") == 0) { - code_model = CodeModelSmall; - } else if (strcmp(argv[i], "kernel") == 0) { - code_model = CodeModelKernel; - } else if (strcmp(argv[i], "medium") == 0) { - code_model = CodeModelMedium; - } else if (strcmp(argv[i], "large") == 0) { - code_model = CodeModelLarge; - } else { - fprintf(stderr, "-code-model options are 'default', 'tiny', 'small', 'kernel', 'medium', or 'large'\n"); - return print_error_usage(arg0); - } - } else if (strcmp(arg, "--override-lib-dir") == 0) { - override_lib_dir = buf_create_from_str(argv[i]); - } else if (strcmp(arg, "--main-pkg-path") == 0) { - main_pkg_path = buf_create_from_str(argv[i]); - } else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) { - lib_dirs.append(argv[i]); - } else if (strcmp(arg, "-F") == 0) { - framework_dirs.append(argv[i]); - } else if (strcmp(arg, "--library") == 0 || strcmp(arg, "-l") == 0) { - if (strcmp(argv[i], "c") == 0) { - have_libc = true; - link_libs.append("c"); - } else if (strcmp(argv[i], "c++") == 0 || strcmp(argv[i], "stdc++") == 0) { - link_libs.append("c++"); - } else { - link_libs.append(argv[i]); - } - } else if (strcmp(arg, "--forbid-library") == 0) { - forbidden_link_libs.append(argv[i]); - } else if (strcmp(arg, "--object") == 0) { - objects.append(argv[i]); - } else if (strcmp(arg, "--c-source") == 0) { - CFile *c_file = heap::c_allocator.create(); - for (;;) { - if (argv[i][0] == '-') { - c_file->args.append(argv[i]); - i += 1; - if (i < argc) { - continue; - } - - break; - } else { - c_file->source_path = argv[i]; - c_source_files.append(c_file); - break; - } - } - } else if (strcmp(arg, "--cache-dir") == 0) { - cache_dir = argv[i]; - } else if (strcmp(arg, "-target") == 0) { - target_string = argv[i]; - } else if (strcmp(arg, "-framework") == 0) { - frameworks.append(argv[i]); - } else if (strcmp(arg, "--linker-script") == 0) { - linker_script = argv[i]; - } else if (strcmp(arg, "--version-script") == 0) { - version_script = buf_create_from_str(argv[i]); - } else if (strcmp(arg, "-rpath") == 0) { - rpath_list.append(argv[i]); - } else if (strcmp(arg, "--test-filter") == 0) { - test_filter = argv[i]; - } else if (strcmp(arg, "--test-name-prefix") == 0) { - test_name_prefix = argv[i]; - } else if (strcmp(arg, "--ver-major") == 0) { - is_versioned = true; - ver_major = atoi(argv[i]); - } else if (strcmp(arg, "--ver-minor") == 0) { - is_versioned = true; - ver_minor = atoi(argv[i]); - } else if (strcmp(arg, "--ver-patch") == 0) { - is_versioned = true; - ver_patch = atoi(argv[i]); - } else if (strcmp(arg, "--test-cmd") == 0) { - test_exec_args.append(argv[i]); - } else if (strcmp(arg, "--stack") == 0) { - stack_size_override = atoi(argv[i]); - } else if (strcmp(arg, "--subsystem") == 0) { - if (strcmp(argv[i], "console") == 0) { - subsystem = TargetSubsystemConsole; - } else if (strcmp(argv[i], "windows") == 0) { - subsystem = TargetSubsystemWindows; - } else if (strcmp(argv[i], "posix") == 0) { - subsystem = TargetSubsystemPosix; - } else if (strcmp(argv[i], "native") == 0) { - subsystem = TargetSubsystemNative; - } else if (strcmp(argv[i], "efi_application") == 0) { - subsystem = TargetSubsystemEfiApplication; - } else if (strcmp(argv[i], "efi_boot_service_driver") == 0) { - subsystem = TargetSubsystemEfiBootServiceDriver; - } else if (strcmp(argv[i], "efi_rom") == 0) { - subsystem = TargetSubsystemEfiRom; - } else if (strcmp(argv[i], "efi_runtime_driver") == 0) { - subsystem = TargetSubsystemEfiRuntimeDriver; - } else { - fprintf(stderr, "invalid: --subsystem %s\n" - "Options are:\n" - " console\n" - " windows\n" - " posix\n" - " native\n" - " efi_application\n" - " efi_boot_service_driver\n" - " efi_rom\n" - " efi_runtime_driver\n" - , argv[i]); - return EXIT_FAILURE; - } - } else if (strcmp(arg, "-mcpu") == 0) { - mcpu = argv[i]; - } else { - fprintf(stderr, "Invalid argument: %s\n", arg); - return print_error_usage(arg0); - } - } - } else if (cmd == CmdNone) { - if (strcmp(arg, "build-exe") == 0) { - cmd = CmdBuild; - out_type = OutTypeExe; - } else if (strcmp(arg, "build-obj") == 0) { - cmd = CmdBuild; - out_type = OutTypeObj; - } else if (strcmp(arg, "build-lib") == 0) { - cmd = CmdBuild; - out_type = OutTypeLib; - } else if (strcmp(arg, "run") == 0) { - cmd = CmdRun; - out_type = OutTypeExe; - } else if (strcmp(arg, "version") == 0) { - cmd = CmdVersion; - } else if (strcmp(arg, "zen") == 0) { - cmd = CmdZen; - } else if (strcmp(arg, "libc") == 0) { - cmd = CmdLibC; - } else if (strcmp(arg, "translate-c") == 0) { - cmd = CmdTranslateC; - } else if (strcmp(arg, "test") == 0) { - cmd = CmdTest; - out_type = OutTypeExe; - } else if (strcmp(arg, "targets") == 0) { - cmd = CmdTargets; - } else if (strcmp(arg, "builtin") == 0) { - cmd = CmdBuiltin; - } else { - fprintf(stderr, "Unrecognized command: %s\n", arg); - return print_error_usage(arg0); - } - } else { - switch (cmd) { - case CmdBuild: - case CmdRun: - case CmdTranslateC: - case CmdTest: - case CmdLibC: - if (!in_file) { - in_file = arg; - } else { - fprintf(stderr, "Unexpected extra parameter: %s\n", arg); - return print_error_usage(arg0); - } - break; - case CmdBuiltin: - case CmdVersion: - case CmdZen: - case CmdTargets: - fprintf(stderr, "Unexpected extra parameter: %s\n", arg); - return print_error_usage(arg0); - case CmdNone: - zig_unreachable(); - } - } - } - - if (cur_pkg->parent != nullptr) { - fprintf(stderr, "Unmatched --pkg-begin\n"); - return EXIT_FAILURE; - } - - Stage2Progress *progress = stage2_progress_create(); - Stage2ProgressNode *root_progress_node = stage2_progress_start_root(progress, "", 0, 0); - if (color == ErrColorOff) stage2_progress_disable_tty(progress); - - init_all_targets(); - - ZigTarget target; - if ((err = target_parse_triple(&target, target_string, mcpu, dynamic_linker))) { - fprintf(stderr, "invalid target: %s\n" - "See `%s targets` to display valid targets.\n", err_str(err), arg0); - return print_error_usage(arg0); - } - - Buf zig_triple_buf = BUF_INIT; - target_triple_zig(&zig_triple_buf, &target); - - // If both output_dir and enable_cache are provided, and doing build-lib, we - // will just do a file copy at the end. This helps when bootstrapping zig from zig0 - // because we want to pass something like this: - // zig0 build-lib --cache on --output-dir ${CMAKE_BINARY_DIR} - // And we don't have access to `zig0 build` because that would require detecting native libc - // on systems where we are not able to build a libc from source for them. - // But that's the only reason this works, so otherwise we give an error here. - Buf *final_output_dir_step = nullptr; - if (output_dir != nullptr && enable_cache == CacheOptOn) { - if (cmd == CmdBuild && out_type == OutTypeLib) { - final_output_dir_step = output_dir; - output_dir = nullptr; - } else { - fprintf(stderr, "`--output-dir` is incompatible with --cache on.\n"); - return print_error_usage(arg0); - } - } - - if (target_requires_pic(&target, have_libc) && want_pic == WantPICDisabled) { - fprintf(stderr, "`--disable-pic` is incompatible with target '%s'\n", buf_ptr(&zig_triple_buf)); - return print_error_usage(arg0); - } - - if ((emit_asm || emit_llvm_ir) && in_file == nullptr) { - fprintf(stderr, "A root source file is required when using `-femit-asm` or `-femit-llvm-ir`\n"); - return print_error_usage(arg0); - } - - if (llvm_argv.length > 1) { - llvm_argv.append(nullptr); - ZigLLVMParseCommandLineOptions(llvm_argv.length - 1, llvm_argv.items); - } - - switch (cmd) { - case CmdLibC: { - if (in_file) { - Stage2LibCInstallation libc; - if ((err = stage2_libc_parse(&libc, in_file))) { - fprintf(stderr, "unable to parse libc file: %s\n", err_str(err)); - return main_exit(root_progress_node, EXIT_FAILURE); - } - return main_exit(root_progress_node, EXIT_SUCCESS); - } - Stage2LibCInstallation libc; - if ((err = stage2_libc_find_native(&libc))) { - fprintf(stderr, "unable to find native libc file: %s\n", err_str(err)); - return main_exit(root_progress_node, EXIT_FAILURE); - } - if ((err = stage2_libc_render(&libc, stdout))) { - fprintf(stderr, "unable to print libc file: %s\n", err_str(err)); - return main_exit(root_progress_node, EXIT_FAILURE); - } - return main_exit(root_progress_node, EXIT_SUCCESS); - } - case CmdBuiltin: { - CodeGen *g = codegen_create(main_pkg_path, nullptr, &target, - out_type, build_mode, override_lib_dir, nullptr, nullptr, false, root_progress_node); - codegen_set_strip(g, strip); - for (size_t i = 0; i < link_libs.length; i += 1) { - LinkLib *link_lib = codegen_add_link_lib(g, buf_create_from_str(link_libs.at(i))); - link_lib->provided_explicitly = true; - } - g->subsystem = subsystem; - g->valgrind_support = valgrind_support; - g->want_pic = want_pic; - g->want_stack_check = want_stack_check; - g->want_sanitize_c = want_sanitize_c; - g->want_single_threaded = want_single_threaded; - g->test_is_evented = test_evented_io; - Buf *builtin_source = codegen_generate_builtin_source(g); - if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) { - fprintf(stderr, "unable to write to stdout: %s\n", strerror(ferror(stdout))); - return main_exit(root_progress_node, EXIT_FAILURE); - } - return main_exit(root_progress_node, EXIT_SUCCESS); - } - case CmdRun: - case CmdBuild: - case CmdTranslateC: - case CmdTest: - { - if (cmd == CmdBuild && !in_file && objects.length == 0 && - c_source_files.length == 0) - { - fprintf(stderr, - "Expected at least one of these things:\n" - " * Zig root source file argument\n" - " * --object argument\n" - " * --c-source argument\n"); - return print_error_usage(arg0); - } else if ((cmd == CmdTranslateC || - cmd == CmdTest || cmd == CmdRun) && !in_file) - { - fprintf(stderr, "Expected source file argument.\n"); - return print_error_usage(arg0); - } else if (cmd == CmdRun && !emit_bin) { - fprintf(stderr, "Cannot run without emitting a binary file.\n"); - return print_error_usage(arg0); - } - - bool any_system_lib_dependencies = false; - for (size_t i = 0; i < link_libs.length; i += 1) { - if (!target_is_libc_lib_name(&target, link_libs.at(i)) && - !target_is_libcpp_lib_name(&target, link_libs.at(i))) - { - any_system_lib_dependencies = true; - break; - } - } - - if (target.is_native_os && (any_system_lib_dependencies || want_native_include_dirs)) { - Error err; - Stage2NativePaths paths; - if ((err = stage2_detect_native_paths(&paths))) { - fprintf(stderr, "unable to detect native system paths: %s\n", err_str(err)); - exit(1); - } - for (size_t i = 0; i < paths.warnings_len; i += 1) { - const char *warning = paths.warnings_ptr[i]; - fprintf(stderr, "warning: %s\n", warning); - } - for (size_t i = 0; i < paths.include_dirs_len; i += 1) { - const char *include_dir = paths.include_dirs_ptr[i]; - clang_argv.append("-isystem"); - clang_argv.append(include_dir); - } - for (size_t i = 0; i < paths.lib_dirs_len; i += 1) { - const char *lib_dir = paths.lib_dirs_ptr[i]; - lib_dirs.append(lib_dir); - } - for (size_t i = 0; i < paths.rpaths_len; i += 1) { - const char *rpath = paths.rpaths_ptr[i]; - rpath_list.append(rpath); - } - } - - - assert(cmd != CmdBuild || out_type != OutTypeUnknown); - - bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC); - - if (cmd == CmdRun) { - out_name = "run"; - } - - Buf *in_file_buf = nullptr; - - Buf *buf_out_name = (cmd == CmdTest) ? buf_create_from_str("test") : - (out_name == nullptr) ? nullptr : buf_create_from_str(out_name); - - if (in_file) { - in_file_buf = buf_create_from_str(in_file); - - if (need_name && buf_out_name == nullptr) { - Buf basename = BUF_INIT; - os_path_split(in_file_buf, nullptr, &basename); - buf_out_name = buf_alloc(); - os_path_extname(&basename, buf_out_name, nullptr); - } - } - - if (need_name && buf_out_name == nullptr && c_source_files.length == 1) { - Buf basename = BUF_INIT; - os_path_split(buf_create_from_str(c_source_files.at(0)->source_path), nullptr, &basename); - buf_out_name = buf_alloc(); - os_path_extname(&basename, buf_out_name, nullptr); - } - if (need_name && buf_out_name == nullptr && objects.length == 1) { - Buf basename = BUF_INIT; - os_path_split(buf_create_from_str(objects.at(0)), nullptr, &basename); - buf_out_name = buf_alloc(); - os_path_extname(&basename, buf_out_name, nullptr); - } - if (need_name && buf_out_name == nullptr && emit_bin_override_path != nullptr) { - Buf basename = BUF_INIT; - os_path_split(buf_create_from_str(emit_bin_override_path), nullptr, &basename); - buf_out_name = buf_alloc(); - os_path_extname(&basename, buf_out_name, nullptr); - } - - if (need_name && buf_out_name == nullptr) { - fprintf(stderr, "--name [name] not provided and unable to infer\n\n"); - return print_error_usage(arg0); - } - - Buf *zig_root_source_file = (cmd == CmdTranslateC) ? nullptr : in_file_buf; - - if (cmd == CmdRun && buf_out_name == nullptr) { - buf_out_name = buf_create_from_str("run"); - } - Stage2LibCInstallation *libc = nullptr; - if (libc_txt != nullptr) { - libc = heap::c_allocator.create(); - if ((err = stage2_libc_parse(libc, libc_txt))) { - fprintf(stderr, "Unable to parse --libc text file: %s\n", err_str(err)); - return main_exit(root_progress_node, EXIT_FAILURE); - } - } - Buf *cache_dir_buf; - if (cache_dir == nullptr) { - if (cmd == CmdRun) { - cache_dir_buf = get_global_cache_dir(); - } else { - cache_dir_buf = buf_create_from_str(default_zig_cache_name); - } - } else { - cache_dir_buf = buf_create_from_str(cache_dir); - } - CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode, - override_lib_dir, libc, cache_dir_buf, cmd == CmdTest, root_progress_node); - if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2); - g->valgrind_support = valgrind_support; - g->link_eh_frame_hdr = link_eh_frame_hdr; - g->want_pic = want_pic; - g->want_stack_check = want_stack_check; - g->want_sanitize_c = want_sanitize_c; - g->subsystem = subsystem; - - g->enable_time_report = timing_info; - g->enable_stack_report = stack_report; - g->enable_dump_analysis = enable_dump_analysis; - g->enable_doc_generation = enable_doc_generation; - g->emit_bin = emit_bin; - g->emit_asm = emit_asm; - g->emit_llvm_ir = emit_llvm_ir; - - codegen_set_out_name(g, buf_out_name); - codegen_set_lib_version(g, is_versioned, ver_major, ver_minor, ver_patch); - g->want_single_threaded = want_single_threaded; - codegen_set_linker_script(g, linker_script); - g->version_script_path = version_script; - if (each_lib_rpath) - codegen_set_each_lib_rpath(g, each_lib_rpath); - - codegen_set_clang_argv(g, clang_argv.items, clang_argv.length); - - codegen_set_strip(g, strip); - g->is_dynamic = is_dynamic; - g->verbose_tokenize = verbose_tokenize; - g->verbose_ast = verbose_ast; - g->verbose_link = verbose_link; - g->verbose_ir = verbose_ir; - g->verbose_llvm_ir = verbose_llvm_ir; - g->verbose_cimport = verbose_cimport; - g->verbose_cc = verbose_cc; - g->verbose_llvm_cpu_features = verbose_llvm_cpu_features; - g->output_dir = output_dir; - g->disable_gen_h = !emit_h; - g->bundle_compiler_rt = bundle_compiler_rt; - codegen_set_errmsg_color(g, color); - g->system_linker_hack = system_linker_hack; - g->function_sections = function_sections; - g->code_model = code_model; - - g->linker_bind_global_refs_locally = linker_bind_global_refs_locally; - g->stack_size_override = stack_size_override; - - for (size_t i = 0; i < lib_dirs.length; i += 1) { - codegen_add_lib_dir(g, lib_dirs.at(i)); - } - for (size_t i = 0; i < framework_dirs.length; i += 1) { - g->framework_dirs.append(framework_dirs.at(i)); - } - for (size_t i = 0; i < link_libs.length; i += 1) { - LinkLib *link_lib = codegen_add_link_lib(g, buf_create_from_str(link_libs.at(i))); - link_lib->provided_explicitly = true; - } - for (size_t i = 0; i < forbidden_link_libs.length; i += 1) { - Buf *forbidden_link_lib = buf_create_from_str(forbidden_link_libs.at(i)); - codegen_add_forbidden_lib(g, forbidden_link_lib); - } - for (size_t i = 0; i < frameworks.length; i += 1) { - codegen_add_framework(g, frameworks.at(i)); - } - for (size_t i = 0; i < rpath_list.length; i += 1) { - codegen_add_rpath(g, rpath_list.at(i)); - } - - codegen_set_rdynamic(g, rdynamic); - - if (test_filter) { - codegen_set_test_filter(g, buf_create_from_str(test_filter)); - } - g->test_is_evented = test_evented_io; - - if (test_name_prefix) { - codegen_set_test_name_prefix(g, buf_create_from_str(test_name_prefix)); - } - - add_package(g, cur_pkg, g->main_pkg); - - if (cmd == CmdBuild || cmd == CmdRun || cmd == CmdTest) { - g->c_source_files = c_source_files; - for (size_t i = 0; i < objects.length; i += 1) { - codegen_add_object(g, buf_create_from_str(objects.at(i))); - } - } - - - if (cmd == CmdBuild || cmd == CmdRun) { - g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun); - codegen_build_and_link(g); - if (root_progress_node != nullptr) { - stage2_progress_end(root_progress_node); - root_progress_node = nullptr; - } - if (timing_info) - codegen_print_timing_report(g, stdout); - if (stack_report) - zig_print_stack_report(g, stdout); - - if (cmd == CmdRun) { -#ifdef ZIG_ENABLE_MEM_PROFILE - if (mem::report_print) - mem::print_report(); -#endif - - const char *exec_path = buf_ptr(&g->bin_file_output_path); - ZigList args = {0}; - - args.append(exec_path); - if (runtime_args_start != -1) { - for (int i = runtime_args_start; i < argc; ++i) { - args.append(argv[i]); - } - } - args.append(nullptr); - - os_execv(exec_path, args.items); - - args.pop(); - Termination term; - os_spawn_process(args, &term); - return term.code; - } else if (cmd == CmdBuild) { - if (emit_bin_override_path != nullptr) { -#if defined(ZIG_OS_WINDOWS) - buf_replace(g->output_dir, '/', '\\'); -#endif - Buf *dest_path = buf_create_from_str(emit_bin_override_path); - Buf *source_path = &g->bin_file_output_path; - if ((err = os_update_file(source_path, dest_path))) { - fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(source_path), - buf_ptr(dest_path), err_str(err)); - return main_exit(root_progress_node, EXIT_FAILURE); - } - } else if (g->enable_cache) { -#if defined(ZIG_OS_WINDOWS) - buf_replace(&g->bin_file_output_path, '/', '\\'); - buf_replace(g->output_dir, '/', '\\'); -#endif - if (final_output_dir_step != nullptr) { - Buf *dest_basename = buf_alloc(); - os_path_split(&g->bin_file_output_path, nullptr, dest_basename); - Buf *dest_path = buf_alloc(); - os_path_join(final_output_dir_step, dest_basename, dest_path); - - if ((err = os_update_file(&g->bin_file_output_path, dest_path))) { - fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->bin_file_output_path), - buf_ptr(dest_path), err_str(err)); - return main_exit(root_progress_node, EXIT_FAILURE); - } - } else { - if (printf("%s\n", buf_ptr(g->output_dir)) < 0) - return main_exit(root_progress_node, EXIT_FAILURE); - } - } - return main_exit(root_progress_node, EXIT_SUCCESS); - } else { - zig_unreachable(); - } - } else if (cmd == CmdTranslateC) { - g->enable_cache = get_cache_opt(enable_cache, false); - codegen_translate_c(g, in_file_buf); - if (timing_info) - codegen_print_timing_report(g, stderr); - return main_exit(root_progress_node, EXIT_SUCCESS); - } else if (cmd == CmdTest) { - ZigTarget native; - if ((err = target_parse_triple(&native, "native", nullptr, nullptr))) { - fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); - return EXIT_FAILURE; - } - - g->enable_cache = get_cache_opt(enable_cache, output_dir == nullptr); - codegen_build_and_link(g); - if (root_progress_node != nullptr) { - stage2_progress_end(root_progress_node); - root_progress_node = nullptr; - } - - if (timing_info) { - codegen_print_timing_report(g, stdout); - } - - if (stack_report) { - zig_print_stack_report(g, stdout); - } - - if (!g->emit_bin) { - fprintf(stderr, "Semantic analysis complete. No binary produced due to -fno-emit-bin.\n"); - return main_exit(root_progress_node, EXIT_SUCCESS); - } - - Buf *test_exe_path_unresolved = &g->bin_file_output_path; - Buf *test_exe_path = buf_alloc(); - *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1); - - if (!g->emit_bin) { - fprintf(stderr, "Created %s but skipping execution because no binary generated.\n", - buf_ptr(test_exe_path)); - return main_exit(root_progress_node, EXIT_SUCCESS); - } - - for (size_t i = 0; i < test_exec_args.length; i += 1) { - if (test_exec_args.items[i] == nullptr) { - test_exec_args.items[i] = buf_ptr(test_exe_path); - } - } - - if (!target_can_exec(&native, &target) && test_exec_args.length == 0) { - fprintf(stderr, "Created %s but skipping execution because it is non-native.\n", - buf_ptr(test_exe_path)); - return main_exit(root_progress_node, EXIT_SUCCESS); - } - - Termination term; - if (test_exec_args.length == 0) { - test_exec_args.append(buf_ptr(test_exe_path)); - } - os_spawn_process(test_exec_args, &term); - if (term.how != TerminationIdClean || term.code != 0) { - fprintf(stderr, "\nTests failed. Use the following command to reproduce the failure:\n"); - fprintf(stderr, "%s\n", buf_ptr(test_exe_path)); - } - return main_exit(root_progress_node, (term.how == TerminationIdClean) ? term.code : -1); - } else { - zig_unreachable(); - } - } - case CmdVersion: - printf("%s\n", ZIG_VERSION_STRING); - return main_exit(root_progress_node, EXIT_SUCCESS); - case CmdZen: { - const char *ptr; - size_t len; - stage2_zen(&ptr, &len); - fwrite(ptr, len, 1, stdout); - return main_exit(root_progress_node, EXIT_SUCCESS); - } - case CmdTargets: - return stage2_cmd_targets(target_string, mcpu, dynamic_linker); - case CmdNone: - return print_full_usage(arg0, stderr, EXIT_FAILURE); - } - zig_unreachable(); -} - -int main(int argc, char **argv) { - stage2_attach_segfault_handler(); - os_init(); - mem::init(); - - auto result = main0(argc, argv); - -#ifdef ZIG_ENABLE_MEM_PROFILE - if (mem::report_print) - mem::intern_counters.print_report(); -#endif - mem::deinit(); - return result; -} diff --git a/src/mem.cpp b/src/mem.cpp index 51ee9a27ee..48dbd791de 100644 --- a/src/mem.cpp +++ b/src/mem.cpp @@ -7,7 +7,6 @@ #include "config.h" #include "mem.hpp" -#include "mem_profile.hpp" #include "heap.hpp" namespace mem { @@ -22,16 +21,4 @@ void deinit() { heap::bootstrap_allocator_state.deinit(); } -#ifdef ZIG_ENABLE_MEM_PROFILE -void print_report(FILE *file) { - heap::c_allocator_state.print_report(file); - intern_counters.print_report(file); -} -#endif - -#ifdef ZIG_ENABLE_MEM_PROFILE -bool report_print = false; -FILE *report_file{nullptr}; -#endif - } // namespace mem diff --git a/src/mem.hpp b/src/mem.hpp index 9e262b7d53..3008febbde 100644 --- a/src/mem.hpp +++ b/src/mem.hpp @@ -135,15 +135,6 @@ protected: virtual void internal_deallocate(const TypeInfo &info, void *ptr, size_t count) = 0; }; -#ifdef ZIG_ENABLE_MEM_PROFILE -void print_report(FILE *file = nullptr); - -// global memory report flag -extern bool report_print; -// global memory report default destination -extern FILE *report_file; -#endif - } // namespace mem #endif diff --git a/src/mem_profile.cpp b/src/mem_profile.cpp deleted file mode 100644 index 13ba57f913..0000000000 --- a/src/mem_profile.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2020 Andrew Kelley - * - * This file is part of zig, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#include "config.h" - -#ifdef ZIG_ENABLE_MEM_PROFILE - -#include "mem.hpp" -#include "mem_list.hpp" -#include "mem_profile.hpp" -#include "heap.hpp" - -namespace mem { - -void Profile::init(const char *name, const char *kind) { - this->name = name; - this->kind = kind; - this->usage_table.init(heap::bootstrap_allocator, 1024); -} - -void Profile::deinit() { - assert(this->name != nullptr); - if (mem::report_print) - this->print_report(); - this->usage_table.deinit(heap::bootstrap_allocator); - this->name = nullptr; -} - -void Profile::record_alloc(const TypeInfo &info, size_t count) { - if (count == 0) return; - auto existing_entry = this->usage_table.put_unique( - heap::bootstrap_allocator, - UsageKey{info.name_ptr, info.name_len}, - Entry{info, 1, count, 0, 0} ); - if (existing_entry != nullptr) { - assert(existing_entry->value.info.size == info.size); // allocated name does not match type - existing_entry->value.alloc.calls += 1; - existing_entry->value.alloc.objects += count; - } -} - -void Profile::record_dealloc(const TypeInfo &info, size_t count) { - if (count == 0) return; - auto existing_entry = this->usage_table.maybe_get(UsageKey{info.name_ptr, info.name_len}); - if (existing_entry == nullptr) { - fprintf(stderr, "deallocated name '"); - for (size_t i = 0; i < info.name_len; ++i) - fputc(info.name_ptr[i], stderr); - zig_panic("' (size %zu) not found in allocated table; compromised memory usage stats", info.size); - } - if (existing_entry->value.info.size != info.size) { - fprintf(stderr, "deallocated name '"); - for (size_t i = 0; i < info.name_len; ++i) - fputc(info.name_ptr[i], stderr); - zig_panic("' does not match expected type size %zu", info.size); - } - assert(existing_entry->value.alloc.calls - existing_entry->value.dealloc.calls > 0); - assert(existing_entry->value.alloc.objects - existing_entry->value.dealloc.objects >= count); - existing_entry->value.dealloc.calls += 1; - existing_entry->value.dealloc.objects += count; -} - -static size_t entry_remain_total_bytes(const Profile::Entry *entry) { - return (entry->alloc.objects - entry->dealloc.objects) * entry->info.size; -} - -static int entry_compare(const void *a, const void *b) { - size_t total_a = entry_remain_total_bytes(*reinterpret_cast(a)); - size_t total_b = entry_remain_total_bytes(*reinterpret_cast(b)); - if (total_a > total_b) - return -1; - if (total_a < total_b) - return 1; - return 0; -}; - -void Profile::print_report(FILE *file) { - if (!file) { - file = report_file; - if (!file) - file = stderr; - } - fprintf(file, "\n--- MEMORY PROFILE REPORT [%s]: %s ---\n", this->kind, this->name); - - List list; - auto it = this->usage_table.entry_iterator(); - for (;;) { - auto entry = it.next(); - if (!entry) - break; - list.append(&heap::bootstrap_allocator, &entry->value); - } - - qsort(list.items, list.length, sizeof(const Entry *), entry_compare); - - size_t total_bytes_alloc = 0; - size_t total_bytes_dealloc = 0; - - size_t total_calls_alloc = 0; - size_t total_calls_dealloc = 0; - - for (size_t i = 0; i < list.length; i += 1) { - const Entry *entry = list.at(i); - fprintf(file, " "); - for (size_t j = 0; j < entry->info.name_len; ++j) - fputc(entry->info.name_ptr[j], file); - fprintf(file, ": %zu bytes each", entry->info.size); - - fprintf(file, ", alloc{ %zu calls, %zu objects, total ", entry->alloc.calls, entry->alloc.objects); - const auto alloc_num_bytes = entry->alloc.objects * entry->info.size; - zig_pretty_print_bytes(file, alloc_num_bytes); - - fprintf(file, " }, dealloc{ %zu calls, %zu objects, total ", entry->dealloc.calls, entry->dealloc.objects); - const auto dealloc_num_bytes = entry->dealloc.objects * entry->info.size; - zig_pretty_print_bytes(file, dealloc_num_bytes); - - fprintf(file, " }, remain{ %zu calls, %zu objects, total ", - entry->alloc.calls - entry->dealloc.calls, - entry->alloc.objects - entry->dealloc.objects ); - const auto remain_num_bytes = alloc_num_bytes - dealloc_num_bytes; - zig_pretty_print_bytes(file, remain_num_bytes); - - fprintf(file, " }\n"); - - total_bytes_alloc += alloc_num_bytes; - total_bytes_dealloc += dealloc_num_bytes; - - total_calls_alloc += entry->alloc.calls; - total_calls_dealloc += entry->dealloc.calls; - } - - fprintf(file, "\n Total bytes allocated: "); - zig_pretty_print_bytes(file, total_bytes_alloc); - fprintf(file, ", deallocated: "); - zig_pretty_print_bytes(file, total_bytes_dealloc); - fprintf(file, ", remaining: "); - zig_pretty_print_bytes(file, total_bytes_alloc - total_bytes_dealloc); - - fprintf(file, "\n Total calls alloc: %zu, dealloc: %zu, remain: %zu\n", - total_calls_alloc, total_calls_dealloc, (total_calls_alloc - total_calls_dealloc)); - - list.deinit(&heap::bootstrap_allocator); -} - -uint32_t Profile::usage_hash(UsageKey key) { - // FNV 32-bit hash - uint32_t h = 2166136261; - for (size_t i = 0; i < key.name_len; ++i) { - h = h ^ key.name_ptr[i]; - h = h * 16777619; - } - return h; -} - -bool Profile::usage_equal(UsageKey a, UsageKey b) { - return memcmp(a.name_ptr, b.name_ptr, a.name_len > b.name_len ? a.name_len : b.name_len) == 0; -} - -void InternCounters::print_report(FILE *file) { - if (!file) { - file = report_file; - if (!file) - file = stderr; - } - fprintf(file, "\n--- IR INTERNING REPORT ---\n"); - fprintf(file, " undefined: interned %zu times\n", intern_counters.x_undefined); - fprintf(file, " void: interned %zu times\n", intern_counters.x_void); - fprintf(file, " null: interned %zu times\n", intern_counters.x_null); - fprintf(file, " unreachable: interned %zu times\n", intern_counters.x_unreachable); - fprintf(file, " zero_byte: interned %zu times\n", intern_counters.zero_byte); -} - -InternCounters intern_counters; - -} // namespace mem - -#endif diff --git a/src/mem_profile.hpp b/src/mem_profile.hpp deleted file mode 100644 index 3b13b7680b..0000000000 --- a/src/mem_profile.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2020 Andrew Kelley - * - * This file is part of zig, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#ifndef ZIG_MEM_PROFILE_HPP -#define ZIG_MEM_PROFILE_HPP - -#include "config.h" - -#ifdef ZIG_ENABLE_MEM_PROFILE - -#include - -#include "mem.hpp" -#include "mem_hash_map.hpp" -#include "util.hpp" - -namespace mem { - -struct Profile { - void init(const char *name, const char *kind); - void deinit(); - - void record_alloc(const TypeInfo &info, size_t count); - void record_dealloc(const TypeInfo &info, size_t count); - - void print_report(FILE *file = nullptr); - - struct Entry { - TypeInfo info; - - struct Use { - size_t calls; - size_t objects; - } alloc, dealloc; - }; - -private: - const char *name; - const char *kind; - - struct UsageKey { - const char *name_ptr; - size_t name_len; - }; - - static uint32_t usage_hash(UsageKey key); - static bool usage_equal(UsageKey a, UsageKey b); - - HashMap usage_table; -}; - -struct InternCounters { - size_t x_undefined; - size_t x_void; - size_t x_null; - size_t x_unreachable; - size_t zero_byte; - - void print_report(FILE *file = nullptr); -}; - -extern InternCounters intern_counters; - -} // namespace mem - -#endif -#endif diff --git a/src/mem_type_info.hpp b/src/mem_type_info.hpp index 8698992ca0..d8a7933268 100644 --- a/src/mem_type_info.hpp +++ b/src/mem_type_info.hpp @@ -10,18 +10,8 @@ #include "config.h" -#ifndef ZIG_TYPE_INFO_IMPLEMENTATION -# ifdef ZIG_ENABLE_MEM_PROFILE -# define ZIG_TYPE_INFO_IMPLEMENTATION 1 -# else -# define ZIG_TYPE_INFO_IMPLEMENTATION 0 -# endif -#endif - namespace mem { -#if ZIG_TYPE_INFO_IMPLEMENTATION == 0 - struct TypeInfo { size_t size; size_t alignment; @@ -32,105 +22,6 @@ struct TypeInfo { } }; -#elif ZIG_TYPE_INFO_IMPLEMENTATION == 1 - -// -// A non-portable way to get a human-readable type-name compatible with -// non-RTTI C++ compiler mode; eg. `-fno-rtti`. -// -// Minimum requirements are c++11 and a compiler that has a constant for the -// current function's decorated name whereby a template-type name can be -// computed. eg. `__PRETTY_FUNCTION__` or `__FUNCSIG__`. -// -// given the following snippet: -// -// | #include -// | -// | struct Top {}; -// | namespace mynamespace { -// | using custom = unsigned int; -// | struct Foo { -// | struct Bar {}; -// | }; -// | }; -// | -// | template -// | void foobar() { -// | #ifdef _MSC_VER -// | fprintf(stderr, "--> %s\n", __FUNCSIG__); -// | #else -// | fprintf(stderr, "--> %s\n", __PRETTY_FUNCTION__); -// | #endif -// | } -// | -// | int main() { -// | foobar(); -// | foobar(); -// | foobar(); -// | foobar(); -// | foobar(); -// | } -// -// gcc 9.2.0 produces: -// --> void foobar() [with T = Top] -// --> void foobar() [with T = unsigned int] -// --> void foobar() [with T = unsigned int] -// --> void foobar() [with T = mynamespace::Foo*] -// --> void foobar() [with T = mynamespace::Foo::Bar*] -// -// xcode 11.3.1/clang produces: -// --> void foobar() [T = Top] -// --> void foobar() [T = unsigned int] -// --> void foobar() [T = unsigned int] -// --> void foobar() [T = mynamespace::Foo *] -// --> void foobar() [T = mynamespace::Foo::Bar *] -// -// VStudio 2019 16.5.0/msvc produces: -// --> void __cdecl foobar(void) -// --> void __cdecl foobar(void) -// --> void __cdecl foobar(void) -// --> void __cdecl foobar(void) -// --> void __cdecl foobar(void) -// -struct TypeInfo { - const char *name_ptr; - size_t name_len; - size_t size; - size_t alignment; - - static constexpr TypeInfo to_type_info(const char *str, size_t start, size_t end, size_t size, size_t alignment) { - return TypeInfo{str + start, end - start, size, alignment}; - } - - static constexpr size_t index_of(const char *str, char c) { - return *str == c ? 0 : 1 + index_of(str + 1, c); - } - - template - static constexpr const char *decorated_name() { -#ifdef _MSC_VER - return __FUNCSIG__; -#else - return __PRETTY_FUNCTION__; -#endif - } - - static constexpr TypeInfo extract(const char *decorated, size_t size, size_t alignment) { -#ifdef _MSC_VER - return to_type_info(decorated, index_of(decorated, '<') + 1, index_of(decorated, '>'), size, alignment); -#else - return to_type_info(decorated, index_of(decorated, '=') + 2, index_of(decorated, ']'), size, alignment); -#endif - } - - template - static constexpr TypeInfo make() { - return TypeInfo::extract(TypeInfo::decorated_name(), sizeof(T), alignof(T)); - } -}; - -#endif // ZIG_TYPE_INFO_IMPLEMENTATION - } // namespace mem #endif diff --git a/src/stage1.cpp b/src/stage1.cpp new file mode 100644 index 0000000000..417076aa99 --- /dev/null +++ b/src/stage1.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2020 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#include "stage1.h" +#include "os.hpp" +#include "all_types.hpp" +#include "codegen.hpp" + +void zig_stage1_os_init(void) { + os_init(); + mem::init(); + init_all_targets(); +} + +struct ZigStage1 *zig_stage1_create(BuildMode optimize_mode, + const char *main_pkg_path_ptr, size_t main_pkg_path_len, + const char *root_src_path_ptr, size_t root_src_path_len, + const char *zig_lib_dir_ptr, size_t zig_lib_dir_len, + const ZigTarget *target, bool is_test_build, Stage2ProgressNode *progress_node) +{ + Buf *main_pkg_path = buf_create_from_mem(main_pkg_path_ptr, main_pkg_path_len); + Buf *root_src_path = buf_create_from_mem(root_src_path_ptr, root_src_path_len); + Buf *zig_lib_dir = buf_create_from_mem(zig_lib_dir_ptr, zig_lib_dir_len); + CodeGen *g = codegen_create(main_pkg_path, root_src_path, target, optimize_mode, + zig_lib_dir, is_test_build, progress_node); + return &g->stage1; +} + +void zig_stage1_destroy(struct ZigStage1 *stage1) { + CodeGen *codegen = reinterpret_cast(stage1); + codegen_destroy(codegen); +} + +static void add_package(CodeGen *g, ZigStage1Pkg *stage1_pkg, ZigPackage *pkg) { + for (size_t i = 0; i < stage1_pkg->children_len; i += 1) { + ZigStage1Pkg *child_cli_pkg = stage1_pkg->children_ptr[i]; + + Buf *dirname = buf_alloc(); + Buf *basename = buf_alloc(); + os_path_split(buf_create_from_mem(child_cli_pkg->path_ptr, child_cli_pkg->path_len), dirname, basename); + + ZigPackage *child_pkg = codegen_create_package(g, buf_ptr(dirname), buf_ptr(basename), + buf_ptr(buf_sprintf("%s.%.*s", buf_ptr(&pkg->pkg_path), + (int)child_cli_pkg->name_len, child_cli_pkg->name_ptr))); + auto entry = pkg->package_table.put_unique( + buf_create_from_mem(child_cli_pkg->name_ptr, child_cli_pkg->name_len), + child_pkg); + if (entry) { + ZigPackage *existing_pkg = entry->value; + Buf *full_path = buf_alloc(); + os_path_join(&existing_pkg->root_src_dir, &existing_pkg->root_src_path, full_path); + fprintf(stderr, "Unable to add package '%.*s'->'%.*s': already exists as '%s'\n", + (int)child_cli_pkg->name_len, child_cli_pkg->name_ptr, + (int)child_cli_pkg->path_len, child_cli_pkg->path_ptr, + buf_ptr(full_path)); + exit(EXIT_FAILURE); + } + + add_package(g, child_cli_pkg, child_pkg); + } +} + +void zig_stage1_build_object(struct ZigStage1 *stage1) { + CodeGen *g = reinterpret_cast(stage1); + + g->root_out_name = buf_create_from_mem(stage1->root_name_ptr, stage1->root_name_len); + g->zig_lib_dir = buf_create_from_mem(stage1->zig_lib_dir_ptr, stage1->zig_lib_dir_len); + g->zig_std_dir = buf_create_from_mem(stage1->zig_std_dir_ptr, stage1->zig_std_dir_len); + g->output_dir = buf_create_from_mem(stage1->output_dir_ptr, stage1->output_dir_len); + if (stage1->builtin_zig_path_len != 0) { + g->builtin_zig_path = buf_create_from_mem(stage1->builtin_zig_path_ptr, stage1->builtin_zig_path_len); + } + if (stage1->test_filter_len != 0) { + g->test_filter = buf_create_from_mem(stage1->test_filter_ptr, stage1->test_filter_len); + } + if (stage1->test_name_prefix_len != 0) { + g->test_name_prefix = buf_create_from_mem(stage1->test_name_prefix_ptr, stage1->test_name_prefix_len); + } + + g->link_mode_dynamic = stage1->link_mode_dynamic; + g->dll_export_fns = stage1->dll_export_fns; + g->have_pic = stage1->pic; + g->have_stack_probing = stage1->enable_stack_probing; + g->is_single_threaded = stage1->is_single_threaded; + g->valgrind_enabled = stage1->valgrind_enabled; + g->link_libc = stage1->link_libc; + g->link_libcpp = stage1->link_libcpp; + g->function_sections = stage1->function_sections; + + g->subsystem = stage1->subsystem; + + g->enable_time_report = stage1->enable_time_report; + g->enable_stack_report = stage1->enable_stack_report; + g->enable_dump_analysis = stage1->dump_analysis; + g->enable_doc_generation = stage1->enable_doc_generation; + g->emit_bin = stage1->emit_bin; + g->emit_asm = stage1->emit_asm; + g->emit_llvm_ir = stage1->emit_llvm_ir; + g->test_is_evented = stage1->test_is_evented; + + g->verbose_tokenize = stage1->verbose_tokenize; + g->verbose_ast = stage1->verbose_ast; + g->verbose_link = stage1->verbose_link; + g->verbose_ir = stage1->verbose_ir; + g->verbose_llvm_ir = stage1->verbose_llvm_ir; + g->verbose_cimport = stage1->verbose_cimport; + g->verbose_cc = stage1->verbose_cc; + g->verbose_llvm_cpu_features = stage1->verbose_llvm_cpu_features; + + g->err_color = stage1->err_color; + g->code_model = stage1->code_model; + + { + g->strip_debug_symbols = stage1->strip; + if (!target_has_debug_info(g->zig_target)) { + g->strip_debug_symbols = true; + } + } + + add_package(g, stage1->root_pkg, g->main_pkg); + + codegen_build_object(g); +} diff --git a/src/stage1.h b/src/stage1.h new file mode 100644 index 0000000000..b7144d8409 --- /dev/null +++ b/src/stage1.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2020 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +// This file deals with exposing stage1 C++ code to stage2 Zig code. + +#ifndef ZIG_STAGE1_H +#define ZIG_STAGE1_H + +#include "zig_llvm.h" + +#include + +#ifdef __cplusplus +#define ZIG_EXTERN_C extern "C" +#else +#define ZIG_EXTERN_C +#endif + +// ABI warning +enum ErrColor { + ErrColorAuto, + ErrColorOff, + ErrColorOn, +}; + +// ABI warning +enum CodeModel { + CodeModelDefault, + CodeModelTiny, + CodeModelSmall, + CodeModelKernel, + CodeModelMedium, + CodeModelLarge, +}; + +// ABI warning +enum TargetSubsystem { + TargetSubsystemConsole, + TargetSubsystemWindows, + TargetSubsystemPosix, + TargetSubsystemNative, + TargetSubsystemEfiApplication, + TargetSubsystemEfiBootServiceDriver, + TargetSubsystemEfiRom, + TargetSubsystemEfiRuntimeDriver, + + // This means Zig should infer the subsystem. + // It's last so that the indexes of other items can line up + // with the enum in builtin.zig. + TargetSubsystemAuto +}; + + +// ABI warning +// Synchronize with target.cpp::os_list +enum Os { + OsFreestanding, + OsAnanas, + OsCloudABI, + OsDragonFly, + OsFreeBSD, + OsFuchsia, + OsIOS, + OsKFreeBSD, + OsLinux, + OsLv2, // PS3 + OsMacOSX, + OsNetBSD, + OsOpenBSD, + OsSolaris, + OsWindows, + OsHaiku, + OsMinix, + OsRTEMS, + OsNaCl, // Native Client + OsCNK, // BG/P Compute-Node Kernel + OsAIX, + OsCUDA, // NVIDIA CUDA + OsNVCL, // NVIDIA OpenCL + OsAMDHSA, // AMD HSA Runtime + OsPS4, + OsELFIAMCU, + OsTvOS, // Apple tvOS + OsWatchOS, // Apple watchOS + OsMesa3D, + OsContiki, + OsAMDPAL, + OsHermitCore, + OsHurd, + OsWASI, + OsEmscripten, + OsUefi, + OsOther, +}; + +// ABI warning +struct ZigTarget { + enum ZigLLVM_ArchType arch; + enum ZigLLVM_VendorType vendor; + + enum ZigLLVM_EnvironmentType abi; + Os os; + + bool is_native_os; + bool is_native_cpu; + + const char *llvm_cpu_name; + const char *llvm_cpu_features; + const char *cpu_builtin_str; + const char *os_builtin_str; + const char *dynamic_linker; + + const char **llvm_cpu_features_asm_ptr; + size_t llvm_cpu_features_asm_len; +}; + +// ABI warning +struct Stage2Progress; +// ABI warning +struct Stage2ProgressNode; + +enum BuildMode { + BuildModeDebug, + BuildModeFastRelease, + BuildModeSafeRelease, + BuildModeSmallRelease, +}; + + +struct ZigStage1Pkg { + const char *name_ptr; + size_t name_len; + + const char *path_ptr; + size_t path_len; + + struct ZigStage1Pkg **children_ptr; + size_t children_len; + + struct ZigStage1Pkg *parent; +}; + +// This struct is used by both main.cpp and stage1.zig. +struct ZigStage1 { + const char *root_name_ptr; + size_t root_name_len; + + const char *output_dir_ptr; + size_t output_dir_len; + + const char *builtin_zig_path_ptr; + size_t builtin_zig_path_len; + + const char *test_filter_ptr; + size_t test_filter_len; + + const char *test_name_prefix_ptr; + size_t test_name_prefix_len; + + const char *zig_lib_dir_ptr; + size_t zig_lib_dir_len; + + const char *zig_std_dir_ptr; + size_t zig_std_dir_len; + + void *userdata; + struct ZigStage1Pkg *root_pkg; + + CodeModel code_model; + TargetSubsystem subsystem; + ErrColor err_color; + + bool pic; + bool link_libc; + bool link_libcpp; + bool strip; + bool is_single_threaded; + bool dll_export_fns; + bool link_mode_dynamic; + bool valgrind_enabled; + bool function_sections; + bool enable_stack_probing; + bool enable_time_report; + bool enable_stack_report; + bool dump_analysis; + bool enable_doc_generation; + bool emit_bin; + bool emit_asm; + bool emit_llvm_ir; + bool test_is_evented; + bool verbose_tokenize; + bool verbose_ast; + bool verbose_link; + bool verbose_ir; + bool verbose_llvm_ir; + bool verbose_cimport; + bool verbose_cc; + bool verbose_llvm_cpu_features; +}; + +ZIG_EXTERN_C void zig_stage1_os_init(void); + +ZIG_EXTERN_C struct ZigStage1 *zig_stage1_create(enum BuildMode optimize_mode, + const char *main_pkg_path_ptr, size_t main_pkg_path_len, + const char *root_src_path_ptr, size_t root_src_path_len, + const char *zig_lib_dir_ptr, size_t zig_lib_dir_len, + const ZigTarget *target, bool is_test_build, Stage2ProgressNode *progress_node); + +ZIG_EXTERN_C void zig_stage1_build_object(struct ZigStage1 *); + +ZIG_EXTERN_C void zig_stage1_destroy(struct ZigStage1 *); + +#endif diff --git a/src/stage2.cpp b/src/stage2.cpp index ad6a9f9d97..f8b078c237 100644 --- a/src/stage2.cpp +++ b/src/stage2.cpp @@ -5,40 +5,12 @@ #include "util.hpp" #include "zig_llvm.h" #include "target.hpp" +#include "buffer.hpp" +#include "os.hpp" #include #include #include -Error stage2_translate_c(struct Stage2Ast **out_ast, - struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len, - const char **args_begin, const char **args_end, const char *resources_path) -{ - const char *msg = "stage0 called stage2_translate_c"; - stage2_panic(msg, strlen(msg)); -} - -void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len) { - const char *msg = "stage0 called stage2_free_clang_errors"; - stage2_panic(msg, strlen(msg)); -} - -void stage2_zen(const char **ptr, size_t *len) { - const char *msg = "stage0 called stage2_zen"; - stage2_panic(msg, strlen(msg)); -} - -int stage2_env(int argc, char** argv) { - const char *msg = "stage0 called stage2_env"; - stage2_panic(msg, strlen(msg)); -} - -int stage2_cc(int argc, char** argv, bool is_cpp) { - const char *msg = "stage0 called stage2_cc"; - stage2_panic(msg, strlen(msg)); -} - -void stage2_attach_segfault_handler(void) { } - void stage2_panic(const char *ptr, size_t len) { fwrite(ptr, 1, len, stderr); fprintf(stderr, "\n"); @@ -46,32 +18,6 @@ void stage2_panic(const char *ptr, size_t len) { abort(); } -void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file) { - const char *msg = "stage0 called stage2_render_ast"; - stage2_panic(msg, strlen(msg)); -} - -int stage2_fmt(int argc, char **argv) { - const char *msg = "stage0 called stage2_fmt"; - stage2_panic(msg, strlen(msg)); -} - -stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len) { - const char *msg = "stage0 called stage2_DepTokenizer_init"; - stage2_panic(msg, strlen(msg)); -} - -void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self) { - const char *msg = "stage0 called stage2_DepTokenizer_deinit"; - stage2_panic(msg, strlen(msg)); -} - -stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self) { - const char *msg = "stage0 called stage2_DepTokenizer_next"; - stage2_panic(msg, strlen(msg)); -} - - struct Stage2Progress { int trash; }; @@ -196,10 +142,6 @@ static void get_native_target(ZigTarget *target) { if (target->abi == ZigLLVM_UnknownEnvironment) { target->abi = target_default_abi(target->arch, target->os); } - if (target_is_glibc(target)) { - target->glibc_or_darwin_version = heap::c_allocator.create(); - target_init_default_glibc_version(target); - } } Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, @@ -217,13 +159,11 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons if (mcpu == nullptr) { target->llvm_cpu_name = ZigLLVMGetHostCPUName(); target->llvm_cpu_features = ZigLLVMGetNativeFeatures(); - target->cache_hash = "native\n\n"; } else if (strcmp(mcpu, "baseline") == 0) { target->is_native_os = false; target->is_native_cpu = false; target->llvm_cpu_name = ""; target->llvm_cpu_features = ""; - target->cache_hash = "baseline\n\n"; } else { const char *msg = "stage0 can't handle CPU/features in the target"; stage2_panic(msg, strlen(msg)); @@ -264,11 +204,8 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons const char *msg = "stage0 can't handle CPU/features in the target"; stage2_panic(msg, strlen(msg)); } - target->cache_hash = "\n\n"; } - target->cache_hash_len = strlen(target->cache_hash); - if (dynamic_linker != nullptr) { target->dynamic_linker = dynamic_linker; } @@ -276,49 +213,29 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons return ErrorNone; } -int stage2_cmd_targets(const char *zig_triple, const char *mcpu, const char *dynamic_linker) { - const char *msg = "stage0 called stage2_cmd_targets"; - stage2_panic(msg, strlen(msg)); -} - -enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, const char *libc_file) { - libc->include_dir = "/dummy/include"; - libc->include_dir_len = strlen(libc->include_dir); - libc->sys_include_dir = "/dummy/sys/include"; - libc->sys_include_dir_len = strlen(libc->sys_include_dir); - libc->crt_dir = ""; - libc->crt_dir_len = strlen(libc->crt_dir); - libc->msvc_lib_dir = ""; - libc->msvc_lib_dir_len = strlen(libc->msvc_lib_dir); - libc->kernel32_lib_dir = ""; - libc->kernel32_lib_dir_len = strlen(libc->kernel32_lib_dir); - return ErrorNone; -} +const char *stage2_fetch_file(struct ZigStage1 *stage1, const char *path_ptr, size_t path_len, + size_t *result_len) +{ + Error err; + Buf contents_buf = BUF_INIT; + Buf path_buf = BUF_INIT; -enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file) { - const char *msg = "stage0 called stage2_libc_render"; - stage2_panic(msg, strlen(msg)); + buf_init_from_mem(&path_buf, path_ptr, path_len); + if ((err = os_fetch_file_path(&path_buf, &contents_buf))) { + return nullptr; + } + *result_len = buf_len(&contents_buf); + return buf_ptr(&contents_buf); } -enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc) { - const char *msg = "stage0 called stage2_libc_find_native"; +const char *stage2_cimport(struct ZigStage1 *stage1) { + const char *msg = "stage0 called stage2_cimport"; stage2_panic(msg, strlen(msg)); } -enum Error stage2_detect_native_paths(struct Stage2NativePaths *native_paths) { - native_paths->include_dirs_ptr = nullptr; - native_paths->include_dirs_len = 0; - - native_paths->lib_dirs_ptr = nullptr; - native_paths->lib_dirs_len = 0; - - native_paths->rpaths_ptr = nullptr; - native_paths->rpaths_len = 0; - - native_paths->warnings_ptr = nullptr; - native_paths->warnings_len = 0; - - return ErrorNone; +const char *stage2_add_link_lib(struct ZigStage1 *stage1, + const char *lib_name_ptr, size_t lib_name_len, + const char *symbol_name_ptr, size_t symbol_name_len) +{ + return nullptr; } - -const bool stage2_is_zig0 = true; diff --git a/src/stage2.h b/src/stage2.h index 2e64189450..4bc92631dc 100644 --- a/src/stage2.h +++ b/src/stage2.h @@ -5,6 +5,8 @@ * See http://opensource.org/licenses/MIT */ +// This file deals with exposing stage2 Zig code to stage1 C++ code. + #ifndef ZIG_STAGE2_H #define ZIG_STAGE2_H @@ -12,7 +14,7 @@ #include #include -#include "zig_llvm.h" +#include "stage1.h" #ifdef __cplusplus #define ZIG_EXTERN_C extern "C" @@ -27,7 +29,7 @@ #endif // ABI warning: the types and declarations in this file must match both those in -// stage2.cpp and src-self-hosted/stage2.zig. +// stage2.cpp and src-self-hosted/stage1.zig. // ABI warning enum Error { @@ -124,74 +126,9 @@ struct Stage2ErrorMsg { unsigned offset; // byte offset into source }; -// ABI warning -struct Stage2Ast; - -// ABI warning -ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast, - struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len, - const char **args_begin, const char **args_end, const char *resources_path); - -// ABI warning -ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len); - -// ABI warning -ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file); - -// ABI warning -ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len); - -// ABI warning -ZIG_EXTERN_C int stage2_env(int argc, char **argv); - -// ABI warning -ZIG_EXTERN_C int stage2_cc(int argc, char **argv, bool is_cpp); - -// ABI warning -ZIG_EXTERN_C void stage2_attach_segfault_handler(void); - // ABI warning ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len); -// ABI warning -ZIG_EXTERN_C int stage2_fmt(int argc, char **argv); - -// ABI warning -struct stage2_DepTokenizer { - void *handle; -}; - -// ABI warning -struct stage2_DepNextResult { - enum TypeId { - error, - null, - target, - prereq, - }; - - TypeId type_id; - - // when ent == error --> error text - // when ent == null --> undefined - // when ent == target --> target pathname - // when ent == prereq --> prereq pathname - const char *textz; -}; - -// ABI warning -ZIG_EXTERN_C stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len); - -// ABI warning -ZIG_EXTERN_C void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self); - -// ABI warning -ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self); - -// ABI warning -struct Stage2Progress; -// ABI warning -struct Stage2ProgressNode; // ABI warning ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void); // ABI warning @@ -212,69 +149,6 @@ ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node); ZIG_EXTERN_C void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items); -// ABI warning -struct Stage2LibCInstallation { - const char *include_dir; - size_t include_dir_len; - const char *sys_include_dir; - size_t sys_include_dir_len; - const char *crt_dir; - size_t crt_dir_len; - const char *msvc_lib_dir; - size_t msvc_lib_dir_len; - const char *kernel32_lib_dir; - size_t kernel32_lib_dir_len; -}; - -// ABI warning -ZIG_EXTERN_C enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, const char *libc_file); -// ABI warning -ZIG_EXTERN_C enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file); -// ABI warning -ZIG_EXTERN_C enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc); - -// ABI warning -// Synchronize with target.cpp::os_list -enum Os { - OsFreestanding, - OsAnanas, - OsCloudABI, - OsDragonFly, - OsFreeBSD, - OsFuchsia, - OsIOS, - OsKFreeBSD, - OsLinux, - OsLv2, // PS3 - OsMacOSX, - OsNetBSD, - OsOpenBSD, - OsSolaris, - OsWindows, - OsHaiku, - OsMinix, - OsRTEMS, - OsNaCl, // Native Client - OsCNK, // BG/P Compute-Node Kernel - OsAIX, - OsCUDA, // NVIDIA CUDA - OsNVCL, // NVIDIA OpenCL - OsAMDHSA, // AMD HSA Runtime - OsPS4, - OsELFIAMCU, - OsTvOS, // Apple tvOS - OsWatchOS, // Apple watchOS - OsMesa3D, - OsContiki, - OsAMDPAL, - OsHermitCore, - OsHurd, - OsWASI, - OsEmscripten, - OsUefi, - OsOther, -}; - // ABI warning struct Stage2SemVer { uint32_t major; @@ -282,56 +156,20 @@ struct Stage2SemVer { uint32_t patch; }; -// ABI warning -struct ZigTarget { - enum ZigLLVM_ArchType arch; - enum ZigLLVM_VendorType vendor; - - enum ZigLLVM_EnvironmentType abi; - Os os; - - bool is_native_os; - bool is_native_cpu; - - // null means default. this is double-purposed to be darwin min version - struct Stage2SemVer *glibc_or_darwin_version; - - const char *llvm_cpu_name; - const char *llvm_cpu_features; - const char *cpu_builtin_str; - const char *cache_hash; - size_t cache_hash_len; - const char *os_builtin_str; - const char *dynamic_linker; - const char *standard_dynamic_linker_path; - - const char **llvm_cpu_features_asm_ptr; - size_t llvm_cpu_features_asm_len; -}; - // ABI warning ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, const char *dynamic_linker); // ABI warning -ZIG_EXTERN_C int stage2_cmd_targets(const char *zig_triple, const char *mcpu, const char *dynamic_linker); +ZIG_EXTERN_C const char *stage2_fetch_file(struct ZigStage1 *stage1, const char *path_ptr, size_t path_len, + size_t *result_len); - -// ABI warning -struct Stage2NativePaths { - const char **include_dirs_ptr; - size_t include_dirs_len; - const char **lib_dirs_ptr; - size_t lib_dirs_len; - const char **rpaths_ptr; - size_t rpaths_len; - const char **warnings_ptr; - size_t warnings_len; -}; // ABI warning -ZIG_EXTERN_C enum Error stage2_detect_native_paths(struct Stage2NativePaths *native_paths); +ZIG_EXTERN_C const char *stage2_cimport(struct ZigStage1 *stage1); // ABI warning -ZIG_EXTERN_C const bool stage2_is_zig0; +ZIG_EXTERN_C const char *stage2_add_link_lib(struct ZigStage1 *stage1, + const char *lib_name_ptr, size_t lib_name_len, + const char *symbol_name_ptr, size_t symbol_name_len); #endif diff --git a/src/target.cpp b/src/target.cpp index dff134a01d..f1cab8eded 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -10,8 +10,6 @@ #include "target.hpp" #include "util.hpp" #include "os.hpp" -#include "compiler.hpp" -#include "glibc.hpp" #include @@ -346,33 +344,6 @@ const char *target_abi_name(ZigLLVM_EnvironmentType abi) { return ZigLLVMGetEnvironmentTypeName(abi); } -Error target_parse_glibc_version(Stage2SemVer *glibc_ver, const char *text) { - glibc_ver->major = 2; - glibc_ver->minor = 0; - glibc_ver->patch = 0; - SplitIterator it = memSplit(str(text), str("GLIBC_.")); - { - Optional> opt_component = SplitIterator_next(&it); - if (!opt_component.is_some) return ErrorUnknownABI; - glibc_ver->major = strtoul(buf_ptr(buf_create_from_slice(opt_component.value)), nullptr, 10); - } - { - Optional> opt_component = SplitIterator_next(&it); - if (!opt_component.is_some) return ErrorNone; - glibc_ver->minor = strtoul(buf_ptr(buf_create_from_slice(opt_component.value)), nullptr, 10); - } - { - Optional> opt_component = SplitIterator_next(&it); - if (!opt_component.is_some) return ErrorNone; - glibc_ver->patch = strtoul(buf_ptr(buf_create_from_slice(opt_component.value)), nullptr, 10); - } - return ErrorNone; -} - -void target_init_default_glibc_version(ZigTarget *target) { - *target->glibc_or_darwin_version = {2, 17, 0}; -} - Error target_parse_arch(ZigLLVM_ArchType *out_arch, const char *arch_ptr, size_t arch_len) { *out_arch = ZigLLVM_UnknownArch; for (size_t arch_i = 0; arch_i < array_length(arch_list); arch_i += 1) { @@ -756,66 +727,6 @@ const char *target_llvm_ir_file_ext(const ZigTarget *target) { return ".ll"; } -const char *target_exe_file_ext(const ZigTarget *target) { - if (target->os == OsWindows) { - return ".exe"; - } else if (target->os == OsUefi) { - return ".efi"; - } else if (target_is_wasm(target)) { - return ".wasm"; - } else { - return ""; - } -} - -const char *target_lib_file_prefix(const ZigTarget *target) { - if ((target->os == OsWindows && !target_abi_is_gnu(target->abi)) || - target->os == OsUefi || - target_is_wasm(target)) - { - return ""; - } else { - return "lib"; - } -} - -const char *target_lib_file_ext(const ZigTarget *target, bool is_static, bool is_versioned, - size_t version_major, size_t version_minor, size_t version_patch) -{ - if (target_is_wasm(target)) { - return ".wasm"; - } - if (target->os == OsWindows || target->os == OsUefi) { - if (is_static) { - if (target->os == OsWindows && target_abi_is_gnu(target->abi)) { - return ".a"; - } else { - return ".lib"; - } - } else { - return ".dll"; - } - } else { - if (is_static) { - return ".a"; - } else if (target_os_is_darwin(target->os)) { - if (is_versioned) { - return buf_ptr(buf_sprintf(".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib", - version_major, version_minor, version_patch)); - } else { - return ".dylib"; - } - } else { - if (is_versioned) { - return buf_ptr(buf_sprintf(".so.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize, - version_major, version_minor, version_patch)); - } else { - return ".so"; - } - } - } -} - bool target_is_android(const ZigTarget *target) { return target->abi == ZigLLVM_Android; } @@ -992,40 +903,6 @@ bool target_os_requires_libc(Os os) { return (target_os_is_darwin(os) || os == OsFreeBSD || os == OsNetBSD || os == OsDragonFly); } -bool target_supports_fpic(const ZigTarget *target) { - // This is not whether the target supports Position Independent Code, but whether the -fPIC - // C compiler argument is valid. - return target->os != OsWindows; -} - -bool target_supports_clang_march_native(const ZigTarget *target) { - // Whether clang supports -march=native on this target. - // Arguably it should always work, but in reality it gives: - // error: the clang compiler does not support '-march=native' - // If we move CPU detection logic into Zig itelf, we will not need this, - // instead we will always pass target features and CPU configuration explicitly. - return target->arch != ZigLLVM_aarch64 && - target->arch != ZigLLVM_aarch64_be; -} - -bool target_supports_stack_probing(const ZigTarget *target) { - return target->os != OsWindows && target->os != OsUefi && (target->arch == ZigLLVM_x86 || target->arch == ZigLLVM_x86_64); -} - -bool target_supports_sanitize_c(const ZigTarget *target) { - return true; -} - -bool target_requires_pic(const ZigTarget *target, bool linking_libc) { - // This function returns whether non-pic code is completely invalid on the given target. - return target_is_android(target) || target->os == OsWindows || target->os == OsUefi || target_os_requires_libc(target->os) || - (linking_libc && target_is_glibc(target)); -} - -bool target_requires_pie(const ZigTarget *target) { - return target_is_android(target); -} - bool target_is_glibc(const ZigTarget *target) { return target->os == OsLinux && target_abi_is_gnu(target->abi); } @@ -1038,10 +915,6 @@ bool target_is_wasm(const ZigTarget *target) { return target->arch == ZigLLVM_wasm32 || target->arch == ZigLLVM_wasm64; } -bool target_is_single_threaded(const ZigTarget *target) { - return target_is_wasm(target); -} - ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) { if (arch == ZigLLVM_wasm32 || arch == ZigLLVM_wasm64) { return ZigLLVM_Musl; diff --git a/src/target.hpp b/src/target.hpp index 5e44301fff..c9db4754f9 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -12,22 +12,6 @@ struct Buf; -enum TargetSubsystem { - TargetSubsystemConsole, - TargetSubsystemWindows, - TargetSubsystemPosix, - TargetSubsystemNative, - TargetSubsystemEfiApplication, - TargetSubsystemEfiBootServiceDriver, - TargetSubsystemEfiRom, - TargetSubsystemEfiRuntimeDriver, - - // This means Zig should infer the subsystem. - // It's last so that the indexes of other items can line up - // with the enum in builtin.zig. - TargetSubsystemAuto -}; - enum CIntType { CIntTypeShort, CIntTypeUShort, @@ -46,9 +30,6 @@ Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arc Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); -Error target_parse_glibc_version(Stage2SemVer *out, const char *text); -void target_init_default_glibc_version(ZigTarget *target); - size_t target_arch_count(void); ZigLLVM_ArchType target_arch_enum(size_t index); const char *target_arch_name(ZigLLVM_ArchType arch); @@ -85,10 +66,6 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id); const char *target_o_file_ext(const ZigTarget *target); const char *target_asm_file_ext(const ZigTarget *target); const char *target_llvm_ir_file_ext(const ZigTarget *target); -const char *target_exe_file_ext(const ZigTarget *target); -const char *target_lib_file_prefix(const ZigTarget *target); -const char *target_lib_file_ext(const ZigTarget *target, bool is_static, bool is_versioned, - size_t version_major, size_t version_minor, size_t version_patch); bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target); ZigLLVM_OSType get_llvm_os_type(Os os_type); @@ -104,10 +81,6 @@ bool target_can_build_libc(const ZigTarget *target); const char *target_libc_generic_name(const ZigTarget *target); bool target_is_libc_lib_name(const ZigTarget *target, const char *name); bool target_is_libcpp_lib_name(const ZigTarget *target, const char *name); -bool target_supports_fpic(const ZigTarget *target); -bool target_supports_clang_march_native(const ZigTarget *target); -bool target_requires_pic(const ZigTarget *target, bool linking_libc); -bool target_requires_pie(const ZigTarget *target); bool target_abi_is_gnu(ZigLLVM_EnvironmentType abi); bool target_abi_is_musl(ZigLLVM_EnvironmentType abi); bool target_is_glibc(const ZigTarget *target); @@ -115,9 +88,6 @@ bool target_is_musl(const ZigTarget *target); bool target_is_wasm(const ZigTarget *target); bool target_is_riscv(const ZigTarget *target); bool target_is_android(const ZigTarget *target); -bool target_is_single_threaded(const ZigTarget *target); -bool target_supports_stack_probing(const ZigTarget *target); -bool target_supports_sanitize_c(const ZigTarget *target); bool target_has_debug_info(const ZigTarget *target); const char *target_arch_musl_name(ZigLLVM_ArchType arch); diff --git a/src/zig0.cpp b/src/zig0.cpp new file mode 100644 index 0000000000..ad90a17eb3 --- /dev/null +++ b/src/zig0.cpp @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2015 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +// This file is the entry point for zig0, which is *only* used to build +// stage2, the self-hosted compiler, into an object file, which is then +// linked by the same build system (cmake) that linked this binary. + +#include "stage1.h" +#include "heap.hpp" +#include "stage2.h" +#include "target.hpp" +#include "error.hpp" + +#include +#include + +static int print_error_usage(const char *arg0) { + fprintf(stderr, "See `%s --help` for detailed usage information\n", arg0); + return EXIT_FAILURE; +} + +static int print_full_usage(const char *arg0, FILE *file, int return_code) { + fprintf(file, + "Usage: %s [options] builds an object file\n" + "\n" + "Options:\n" + " --color [auto|off|on] enable or disable colored error messages\n" + " --name [name] override output name\n" + " --output-dir [dir] override output directory (defaults to cwd)\n" + " --pkg-begin [name] [path] make pkg available to import and push current pkg\n" + " --pkg-end pop current pkg\n" + " --main-pkg-path set the directory of the root package\n" + " --release-fast build with optimizations on and safety off\n" + " --release-safe build with optimizations on and safety on\n" + " --release-small build with size optimizations on and safety off\n" + " --single-threaded source may assume it is only used single-threaded\n" + " -dynamic create a shared library (.so; .dll; .dylib)\n" + " --strip exclude debug symbols\n" + " -target [name] -- see the targets command\n" + " -mcpu [cpu] specify target CPU and feature set\n" + " --verbose-tokenize enable compiler debug output for tokenization\n" + " --verbose-ast enable compiler debug output for AST parsing\n" + " --verbose-link enable compiler debug output for linking\n" + " --verbose-ir enable compiler debug output for Zig IR\n" + " --verbose-llvm-ir enable compiler debug output for LLVM IR\n" + " --verbose-cimport enable compiler debug output for C imports\n" + " --verbose-cc enable compiler debug output for C compilation\n" + " --verbose-llvm-cpu-features enable compiler debug output for LLVM CPU features\n" + "\n" + , arg0); + return return_code; +} + +static bool str_starts_with(const char *s1, const char *s2) { + size_t s2_len = strlen(s2); + if (strlen(s1) < s2_len) { + return false; + } + return memcmp(s1, s2, s2_len) == 0; +} + +int main_exit(Stage2ProgressNode *root_progress_node, int exit_code) { + if (root_progress_node != nullptr) { + stage2_progress_end(root_progress_node); + } + return exit_code; +} + +int main(int argc, char **argv) { + zig_stage1_os_init(); + + char *arg0 = argv[0]; + Error err; + + const char *in_file = nullptr; + const char *output_dir = nullptr; + bool strip = false; + const char *out_name = nullptr; + bool verbose_tokenize = false; + bool verbose_ast = false; + bool verbose_link = false; + bool verbose_ir = false; + bool verbose_llvm_ir = false; + bool verbose_cimport = false; + bool verbose_cc = false; + bool verbose_llvm_cpu_features = false; + ErrColor color = ErrColorAuto; + const char *dynamic_linker = nullptr; + bool link_libc = false; + bool link_libcpp = false; + const char *target_string = nullptr; + ZigStage1Pkg *cur_pkg = heap::c_allocator.create(); + BuildMode build_mode = BuildModeDebug; + TargetSubsystem subsystem = TargetSubsystemAuto; + const char *override_lib_dir = nullptr; + const char *main_pkg_path = nullptr; + const char *mcpu = nullptr; + + for (int i = 1; i < argc; i += 1) { + char *arg = argv[i]; + + if (arg[0] == '-') { + if (strcmp(arg, "--") == 0) { + fprintf(stderr, "Unexpected end-of-parameter mark: %s\n", arg); + } else if (strcmp(arg, "--release-fast") == 0) { + build_mode = BuildModeFastRelease; + } else if (strcmp(arg, "--release-safe") == 0) { + build_mode = BuildModeSafeRelease; + } else if (strcmp(arg, "--release-small") == 0) { + build_mode = BuildModeSmallRelease; + } else if (strcmp(arg, "--help") == 0) { + return print_full_usage(arg0, stdout, EXIT_SUCCESS); + } else if (strcmp(arg, "--strip") == 0) { + strip = true; + } else if (strcmp(arg, "--verbose-tokenize") == 0) { + verbose_tokenize = true; + } else if (strcmp(arg, "--verbose-ast") == 0) { + verbose_ast = true; + } else if (strcmp(arg, "--verbose-link") == 0) { + verbose_link = true; + } else if (strcmp(arg, "--verbose-ir") == 0) { + verbose_ir = true; + } else if (strcmp(arg, "--verbose-llvm-ir") == 0) { + verbose_llvm_ir = true; + } else if (strcmp(arg, "--verbose-cimport") == 0) { + verbose_cimport = true; + } else if (strcmp(arg, "--verbose-cc") == 0) { + verbose_cc = true; + } else if (strcmp(arg, "--verbose-llvm-cpu-features") == 0) { + verbose_llvm_cpu_features = true; + } else if (arg[1] == 'l' && arg[2] != 0) { + // alias for --library + const char *l = &arg[2]; + if (strcmp(l, "c") == 0) { + link_libc = true; + } else if (strcmp(l, "c++") == 0 || strcmp(l, "stdc++") == 0) { + link_libcpp = true; + } + } else if (strcmp(arg, "--pkg-begin") == 0) { + if (i + 2 >= argc) { + fprintf(stderr, "Expected 2 arguments after --pkg-begin\n"); + return print_error_usage(arg0); + } + ZigStage1Pkg *new_cur_pkg = heap::c_allocator.create(); + i += 1; + new_cur_pkg->name_ptr = argv[i]; + new_cur_pkg->name_len = strlen(argv[i]); + i += 1; + new_cur_pkg->path_ptr = argv[i]; + new_cur_pkg->path_len = strlen(argv[i]); + new_cur_pkg->parent = cur_pkg; + cur_pkg->children_ptr = heap::c_allocator.reallocate(cur_pkg->children_ptr, + cur_pkg->children_len, cur_pkg->children_len + 1); + cur_pkg->children_ptr[cur_pkg->children_len] = new_cur_pkg; + cur_pkg->children_len += 1; + + cur_pkg = new_cur_pkg; + } else if (strcmp(arg, "--pkg-end") == 0) { + if (cur_pkg->parent == nullptr) { + fprintf(stderr, "Encountered --pkg-end with no matching --pkg-begin\n"); + return EXIT_FAILURE; + } + cur_pkg = cur_pkg->parent; + } else if (str_starts_with(arg, "-mcpu=")) { + mcpu = arg + strlen("-mcpu="); + } else if (i + 1 >= argc) { + fprintf(stderr, "Expected another argument after %s\n", arg); + return print_error_usage(arg0); + } else { + i += 1; + if (strcmp(arg, "--output-dir") == 0) { + output_dir = argv[i]; + } else if (strcmp(arg, "--color") == 0) { + if (strcmp(argv[i], "auto") == 0) { + color = ErrColorAuto; + } else if (strcmp(argv[i], "on") == 0) { + color = ErrColorOn; + } else if (strcmp(argv[i], "off") == 0) { + color = ErrColorOff; + } else { + fprintf(stderr, "--color options are 'auto', 'on', or 'off'\n"); + return print_error_usage(arg0); + } + } else if (strcmp(arg, "--name") == 0) { + out_name = argv[i]; + } else if (strcmp(arg, "--dynamic-linker") == 0) { + dynamic_linker = argv[i]; + } else if (strcmp(arg, "--override-lib-dir") == 0) { + override_lib_dir = argv[i]; + } else if (strcmp(arg, "--main-pkg-path") == 0) { + main_pkg_path = argv[i]; + } else if (strcmp(arg, "--library") == 0 || strcmp(arg, "-l") == 0) { + if (strcmp(argv[i], "c") == 0) { + link_libc = true; + } else if (strcmp(argv[i], "c++") == 0 || strcmp(argv[i], "stdc++") == 0) { + link_libcpp = true; + } + } else if (strcmp(arg, "-target") == 0) { + target_string = argv[i]; + } else if (strcmp(arg, "--subsystem") == 0) { + if (strcmp(argv[i], "console") == 0) { + subsystem = TargetSubsystemConsole; + } else if (strcmp(argv[i], "windows") == 0) { + subsystem = TargetSubsystemWindows; + } else if (strcmp(argv[i], "posix") == 0) { + subsystem = TargetSubsystemPosix; + } else if (strcmp(argv[i], "native") == 0) { + subsystem = TargetSubsystemNative; + } else if (strcmp(argv[i], "efi_application") == 0) { + subsystem = TargetSubsystemEfiApplication; + } else if (strcmp(argv[i], "efi_boot_service_driver") == 0) { + subsystem = TargetSubsystemEfiBootServiceDriver; + } else if (strcmp(argv[i], "efi_rom") == 0) { + subsystem = TargetSubsystemEfiRom; + } else if (strcmp(argv[i], "efi_runtime_driver") == 0) { + subsystem = TargetSubsystemEfiRuntimeDriver; + } else { + fprintf(stderr, "invalid: --subsystem %s\n" + "Options are:\n" + " console\n" + " windows\n" + " posix\n" + " native\n" + " efi_application\n" + " efi_boot_service_driver\n" + " efi_rom\n" + " efi_runtime_driver\n" + , argv[i]); + return EXIT_FAILURE; + } + } else if (strcmp(arg, "-mcpu") == 0) { + mcpu = argv[i]; + } else { + fprintf(stderr, "Invalid argument: %s\n", arg); + return print_error_usage(arg0); + } + } + } else if (!in_file) { + in_file = arg; + } else { + fprintf(stderr, "Unexpected extra parameter: %s\n", arg); + return print_error_usage(arg0); + } + } + + if (cur_pkg->parent != nullptr) { + fprintf(stderr, "Unmatched --pkg-begin\n"); + return EXIT_FAILURE; + } + + Stage2Progress *progress = stage2_progress_create(); + Stage2ProgressNode *root_progress_node = stage2_progress_start_root(progress, "", 0, 0); + if (color == ErrColorOff) stage2_progress_disable_tty(progress); + + ZigTarget target; + if ((err = target_parse_triple(&target, target_string, mcpu, dynamic_linker))) { + fprintf(stderr, "invalid target: %s\n", err_str(err)); + return print_error_usage(arg0); + } + + if (in_file == nullptr) { + fprintf(stderr, "missing zig file\n"); + return print_error_usage(arg0); + } + + if (out_name == nullptr) { + fprintf(stderr, "missing --name\n"); + return print_error_usage(arg0); + } + + ZigStage1 *stage1 = zig_stage1_create(build_mode, + main_pkg_path, (main_pkg_path == nullptr) ? 0 : strlen(main_pkg_path), + in_file, strlen(in_file), + override_lib_dir, strlen(override_lib_dir), &target, false, + root_progress_node); + + stage1->root_name_ptr = out_name; + stage1->root_name_len = strlen(out_name); + stage1->strip = strip; + stage1->verbose_tokenize = verbose_tokenize; + stage1->verbose_ast = verbose_ast; + stage1->verbose_link = verbose_link; + stage1->verbose_ir = verbose_ir; + stage1->verbose_llvm_ir = verbose_llvm_ir; + stage1->verbose_cimport = verbose_cimport; + stage1->verbose_cc = verbose_cc; + stage1->verbose_llvm_cpu_features = verbose_llvm_cpu_features; + stage1->output_dir_ptr = output_dir; + stage1->output_dir_len = strlen(output_dir); + stage1->root_pkg = cur_pkg; + stage1->err_color = color; + stage1->link_libc = link_libc; + stage1->link_libcpp = link_libcpp; + stage1->subsystem = subsystem; + stage1->pic = true; + stage1->emit_bin = true; + + zig_stage1_build_object(stage1); + + zig_stage1_destroy(stage1); + + return main_exit(root_progress_node, EXIT_SUCCESS); +} -- cgit v1.2.3 From 2ef68631cb7045c277b348777b1a064845b95cd8 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 18 Sep 2020 22:48:28 -0700 Subject: stage2 now supports using stage1 as a backend for compiling zig code * 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 code --- BRANCH_TODO | 8 +- CMakeLists.txt | 1 - src-self-hosted/Compilation.zig | 247 +++++++++++++++++++++--- src-self-hosted/link.zig | 13 ++ src-self-hosted/link/Elf.zig | 15 +- src-self-hosted/main.zig | 114 +++++++---- src-self-hosted/stage1.zig | 412 +++++++++++++--------------------------- src/analyze.cpp | 2 +- src/codegen.cpp | 61 +++--- src/codegen.hpp | 3 +- src/stage1.cpp | 11 +- src/stage1.h | 25 +-- src/stage2.cpp | 241 ----------------------- src/stage2.h | 16 +- src/target.cpp | 7 +- src/target.hpp | 1 - src/zig0.cpp | 251 ++++++++++++++++++++++-- 17 files changed, 750 insertions(+), 678 deletions(-) delete mode 100644 src/stage2.cpp (limited to 'src/stage2.cpp') diff --git a/BRANCH_TODO b/BRANCH_TODO index 9455511dbf..bee98d6d2b 100644 --- a/BRANCH_TODO +++ b/BRANCH_TODO @@ -1,3 +1,6 @@ + * build & link against compiler-rt + * build & link against freestanding libc + * Cache integration for stage1 zig code compilation * `zig test` * `zig build` * `-ftime-report` @@ -14,10 +17,7 @@ - using it as a preprocessor (-E) - try building some software * support rpaths in ELF linker code - * build & link against compiler-rt - - stage1 C++ code integration * repair @cImport - * build & link against freestanding libc * add CLI support for a way to pass extra flags to c source files * capture lld stdout/stderr better * musl @@ -35,10 +35,12 @@ * implement emit-h in stage2 * implement -fno-emit-bin * audit the base cache hash + * --main-pkg-path * audit the CLI options for stage2 * `zig init-lib` * `zig init-exe` * `zig run` + * restore error messages for stage2_add_link_lib * implement serialization/deserialization of incremental compilation metadata * incremental compilation - implement detection of which source files changed diff --git a/CMakeLists.txt b/CMakeLists.txt index d55c76ee9c..1a19c275d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -258,7 +258,6 @@ find_package(Threads) # This is our shim which will be replaced by stage1.zig. set(ZIG0_SOURCES "${CMAKE_SOURCE_DIR}/src/zig0.cpp" - "${CMAKE_SOURCE_DIR}/src/stage2.cpp" ) set(ZIG_SOURCES diff --git a/src-self-hosted/Compilation.zig b/src-self-hosted/Compilation.zig index ed46508485..f08c5ef82f 100644 --- a/src-self-hosted/Compilation.zig +++ b/src-self-hosted/Compilation.zig @@ -19,6 +19,7 @@ const libunwind = @import("libunwind.zig"); const fatal = @import("main.zig").fatal; const Module = @import("Module.zig"); const Cache = @import("Cache.zig"); +const stage1 = @import("stage1.zig"); /// General-purpose allocator. Used for both temporary and long-term storage. gpa: *Allocator, @@ -26,6 +27,7 @@ gpa: *Allocator, arena_state: std.heap.ArenaAllocator.State, bin_file: *link.File, c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{}, +stage1_module: ?*stage1.Module, link_error_flags: link.File.ErrorFlags = .{}, @@ -122,6 +124,8 @@ const Job = union(enum) { /// Generate builtin.zig source code and write it into the correct place. generate_builtin_zig: void, + /// Use stage1 C++ code to compile zig code into an object file. + stage1_module: void, }; pub const CObject = struct { @@ -274,6 +278,7 @@ pub const InitOptions = struct { strip: bool = false, single_threaded: bool = false, is_native_os: bool, + time_report: bool = false, link_eh_frame_hdr: bool = false, linker_script: ?[]const u8 = null, version_script: ?[]const u8 = null, @@ -288,12 +293,20 @@ pub const InitOptions = struct { clang_passthrough_mode: bool = false, verbose_cc: bool = false, verbose_link: bool = false, + verbose_tokenize: bool = false, + verbose_ast: bool = false, + verbose_ir: bool = false, + verbose_llvm_ir: bool = false, + verbose_cimport: bool = false, + verbose_llvm_cpu_features: bool = false, is_test: bool = false, stack_size_override: ?u64 = null, self_exe_path: ?[]const u8 = null, version: ?std.builtin.Version = null, libc_installation: ?*const LibCInstallation = null, machine_code_model: std.builtin.CodeModel = .default, + /// This is for stage1 and should be deleted upon completion of self-hosting. + color: @import("main.zig").Color = .Auto, }; pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { @@ -332,11 +345,27 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { { break :blk true; } + + if (build_options.is_stage1) { + // If stage1 generates an object file, self-hosted linker is not + // yet sophisticated enough to handle that. + break :blk options.root_pkg != null; + } + break :blk false; }; // Make a decision on whether to use LLVM or our own backend. const use_llvm = if (options.use_llvm) |explicit| explicit else blk: { + // If we have no zig code to compile, no need for LLVM. + if (options.root_pkg == null) + break :blk false; + + // If we are the stage1 compiler, we depend on the stage1 c++ llvm backend + // to compile zig code. + if (build_options.is_stage1) + break :blk true; + // We would want to prefer LLVM for release builds when it is available, however // we don't have an LLVM backend yet :) // 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 { .ReleaseFast, .ReleaseSmall => false, }; + const llvm_cpu_features: ?[*:0]const u8 = if (build_options.have_llvm and use_llvm) blk: { + var buf = std.ArrayList(u8).init(arena); + for (options.target.cpu.arch.allFeaturesList()) |feature, index_usize| { + const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); + const is_enabled = options.target.cpu.features.isEnabled(index); + + if (feature.llvm_name) |llvm_name| { + const plus_or_minus = "-+"[@boolToInt(is_enabled)]; + try buf.ensureCapacity(buf.items.len + 2 + llvm_name.len); + buf.appendAssumeCapacity(plus_or_minus); + buf.appendSliceAssumeCapacity(llvm_name); + buf.appendSliceAssumeCapacity(","); + } + } + assert(mem.endsWith(u8, buf.items, ",")); + buf.items[buf.items.len - 1] = 0; + buf.shrink(buf.items.len); + break :blk buf.items[0 .. buf.items.len - 1 :0].ptr; + } else null; + + const stage1_module: ?*stage1.Module = if (build_options.is_stage1 and use_llvm) blk: { + // Here we use the legacy stage1 C++ compiler to compile Zig code. + const stage2_target = try arena.create(stage1.Stage2Target); + stage2_target.* = .{ + .arch = @enumToInt(options.target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch + .os = @enumToInt(options.target.os.tag), + .abi = @enumToInt(options.target.abi), + .is_native_os = options.is_native_os, + .is_native_cpu = false, // Only true when bootstrapping the compiler. + .llvm_cpu_name = if (options.target.cpu.model.llvm_name) |s| s.ptr else null, + .llvm_cpu_features = llvm_cpu_features.?, + }; + const progress = try arena.create(std.Progress); + const main_progress_node = try progress.start("", 100); + if (options.color == .Off) progress.terminal = null; + + const mod = module.?; + const main_zig_file = mod.root_pkg.root_src_path; + const zig_lib_dir = options.zig_lib_directory.path.?; + const builtin_sub = &[_][]const u8{"builtin.zig"}; + const builtin_zig_path = try mod.zig_cache_artifact_directory.join(arena, builtin_sub); + + const stage1_module = stage1.create( + @enumToInt(options.optimize_mode), + undefined, + 0, // TODO --main-pkg-path + main_zig_file.ptr, + main_zig_file.len, + zig_lib_dir.ptr, + zig_lib_dir.len, + stage2_target, + options.is_test, + ) orelse return error.OutOfMemory; + + const output_dir = bin_directory.path orelse "."; + + const stage1_pkg = try arena.create(stage1.Pkg); + stage1_pkg.* = .{ + .name_ptr = undefined, + .name_len = 0, + .path_ptr = undefined, + .path_len = 0, + .children_ptr = undefined, + .children_len = 0, + .parent = null, + }; + + stage1_module.* = .{ + .root_name_ptr = root_name.ptr, + .root_name_len = root_name.len, + .output_dir_ptr = output_dir.ptr, + .output_dir_len = output_dir.len, + .builtin_zig_path_ptr = builtin_zig_path.ptr, + .builtin_zig_path_len = builtin_zig_path.len, + .test_filter_ptr = "", + .test_filter_len = 0, + .test_name_prefix_ptr = "", + .test_name_prefix_len = 0, + .userdata = @ptrToInt(comp), + .root_pkg = stage1_pkg, + .code_model = @enumToInt(options.machine_code_model), + .subsystem = stage1.TargetSubsystem.Auto, + .err_color = @enumToInt(options.color), + .pic = pic, + .link_libc = options.link_libc, + .link_libcpp = options.link_libcpp, + .strip = options.strip, + .is_single_threaded = single_threaded, + .dll_export_fns = dll_export_fns, + .link_mode_dynamic = link_mode == .Dynamic, + .valgrind_enabled = valgrind, + .function_sections = options.function_sections orelse false, + .enable_stack_probing = stack_check, + .enable_time_report = options.time_report, + .enable_stack_report = false, + .dump_analysis = false, + .enable_doc_generation = false, + .emit_bin = true, + .emit_asm = false, + .emit_llvm_ir = false, + .test_is_evented = false, + .verbose_tokenize = options.verbose_tokenize, + .verbose_ast = options.verbose_ast, + .verbose_ir = options.verbose_ir, + .verbose_llvm_ir = options.verbose_llvm_ir, + .verbose_cimport = options.verbose_cimport, + .verbose_llvm_cpu_features = options.verbose_llvm_cpu_features, + .main_progress_node = main_progress_node, + }; + break :blk stage1_module; + } else null; + const bin_file = try link.File.openPath(gpa, .{ .directory = bin_directory, .sub_path = emit_bin.basename, @@ -626,6 +767,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .machine_code_model = options.machine_code_model, .dll_export_fns = dll_export_fns, .error_return_tracing = error_return_tracing, + .llvm_cpu_features = llvm_cpu_features, }); errdefer bin_file.destroy(); @@ -635,6 +777,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .zig_lib_directory = options.zig_lib_directory, .zig_cache_directory = options.zig_cache_directory, .bin_file = bin_file, + .stage1_module = stage1_module, .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa), .keep_source_files_loaded = options.keep_source_files_loaded, .use_clang = use_clang, @@ -681,6 +824,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { try comp.work_queue.writeItem(.{ .libunwind = {} }); } + if (comp.stage1_module) |module| { + try comp.work_queue.writeItem(.{ .stage1_module = {} }); + } + return comp; } @@ -689,6 +836,11 @@ pub fn destroy(self: *Compilation) void { self.bin_file.destroy(); if (optional_module) |module| module.deinit(); + if (self.stage1_module) |module| { + module.main_progress_node.?.end(); + module.destroy(); + } + const gpa = self.gpa; self.work_queue.deinit(); @@ -997,6 +1149,10 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void { fatal("unable to update builtin.zig file: {}", .{@errorName(err)}); }; }, + .stage1_module => { + // This Job is only queued up if there is a zig module. + self.stage1_module.?.build_object(); + }, }; } @@ -1365,7 +1521,7 @@ pub fn addCCArgs( try argv.append("-fPIC"); } }, - .so, .assembly, .ll, .bc, .unknown => {}, + .shared_library, .assembly, .ll, .bc, .unknown, .static_library, .object, .zig, .zir => {}, } if (out_dep_path) |p| { try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p }); @@ -1445,17 +1601,39 @@ pub const FileExt = enum { ll, bc, assembly, - so, + shared_library, + object, + static_library, + zig, + zir, unknown, pub fn clangSupportsDepFile(ext: FileExt) bool { return switch (ext) { .c, .cpp, .h => true, - .ll, .bc, .assembly, .so, .unknown => false, + + .ll, + .bc, + .assembly, + .shared_library, + .object, + .static_library, + .zig, + .zir, + .unknown, + => false, }; } }; +pub fn hasObjectExt(filename: []const u8) bool { + return mem.endsWith(u8, filename, ".o") or mem.endsWith(u8, filename, ".obj"); +} + +pub fn hasStaticLibraryExt(filename: []const u8) bool { + return mem.endsWith(u8, filename, ".a") or mem.endsWith(u8, filename, ".lib"); +} + pub fn hasCExt(filename: []const u8) bool { return mem.endsWith(u8, filename, ".c"); } @@ -1471,6 +1649,32 @@ pub fn hasAsmExt(filename: []const u8) bool { return mem.endsWith(u8, filename, ".s") or mem.endsWith(u8, filename, ".S"); } +pub fn hasSharedLibraryExt(filename: []const u8) bool { + if (mem.endsWith(u8, filename, ".so") or + mem.endsWith(u8, filename, ".dll") or + mem.endsWith(u8, filename, ".dylib")) + { + return true; + } + // Look for .so.X, .so.X.Y, .so.X.Y.Z + var it = mem.split(filename, "."); + _ = it.next().?; + var so_txt = it.next() orelse return false; + while (!mem.eql(u8, so_txt, "so")) { + so_txt = it.next() orelse return false; + } + const n1 = it.next() orelse return false; + const n2 = it.next(); + const n3 = it.next(); + + _ = std.fmt.parseInt(u32, n1, 10) catch return false; + if (n2) |x| _ = std.fmt.parseInt(u32, x, 10) catch return false; + if (n3) |x| _ = std.fmt.parseInt(u32, x, 10) catch return false; + if (it.next() != null) return false; + + return true; +} + pub fn classifyFileExt(filename: []const u8) FileExt { if (hasCExt(filename)) { return .c; @@ -1484,26 +1688,19 @@ pub fn classifyFileExt(filename: []const u8) FileExt { return .assembly; } else if (mem.endsWith(u8, filename, ".h")) { return .h; - } else if (mem.endsWith(u8, filename, ".so")) { - return .so; - } - // Look for .so.X, .so.X.Y, .so.X.Y.Z - var it = mem.split(filename, "."); - _ = it.next().?; - var so_txt = it.next() orelse return .unknown; - while (!mem.eql(u8, so_txt, "so")) { - so_txt = it.next() orelse return .unknown; + } else if (mem.endsWith(u8, filename, ".zig")) { + return .zig; + } else if (mem.endsWith(u8, filename, ".zir")) { + return .zig; + } else if (hasSharedLibraryExt(filename)) { + return .shared_library; + } else if (hasStaticLibraryExt(filename)) { + return .static_library; + } else if (hasObjectExt(filename)) { + return .object; + } else { + return .unknown; } - const n1 = it.next() orelse return .unknown; - const n2 = it.next(); - const n3 = it.next(); - - _ = std.fmt.parseInt(u32, n1, 10) catch return .unknown; - if (n2) |x| _ = std.fmt.parseInt(u32, x, 10) catch return .unknown; - if (n3) |x| _ = std.fmt.parseInt(u32, x, 10) catch return .unknown; - if (it.next() != null) return .unknown; - - return .so; } test "classifyFileExt" { @@ -1681,7 +1878,7 @@ pub fn dump_argv(argv: []const []const u8) void { } pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 { - var buffer = std.ArrayList(u8).init(comp.gpa); + var buffer = std.ArrayList(u8).init(allocator); defer buffer.deinit(); const target = comp.getTarget(); @@ -1691,9 +1888,9 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 try buffer.writer().print( \\usingnamespace @import("std").builtin; \\/// Deprecated - \\pub const arch = std.Target.current.cpu.arch; + \\pub const arch = Target.current.cpu.arch; \\/// Deprecated - \\pub const endian = std.Target.current.cpu.arch.endian(); + \\pub const endian = Target.current.cpu.arch.endian(); \\pub const output_mode = OutputMode.{}; \\pub const link_mode = LinkMode.{}; \\pub const is_test = {}; diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig index 1ad293b275..88a964f2ff 100644 --- a/src-self-hosted/link.zig +++ b/src-self-hosted/link.zig @@ -69,6 +69,7 @@ pub const Options = struct { linker_script: ?[]const u8 = null, version_script: ?[]const u8 = null, override_soname: ?[]const u8 = null, + llvm_cpu_features: ?[*:0]const u8 = null, /// Extra args passed directly to LLD. Ignored when not linking with LLD. extra_lld_args: []const []const u8 = &[0][]const u8, @@ -134,6 +135,18 @@ pub const File = struct { /// rewriting it. A malicious file is detected as incremental link failure /// and does not cause Illegal Behavior. This operation is not atomic. pub fn openPath(allocator: *Allocator, options: Options) !*File { + const use_stage1 = build_options.is_stage1 and options.use_llvm; + if (use_stage1) { + return switch (options.object_format) { + .coff, .pe => &(try Coff.createEmpty(allocator, options)).base, + .elf => &(try Elf.createEmpty(allocator, options)).base, + .macho => &(try MachO.createEmpty(allocator, options)).base, + .wasm => &(try Wasm.createEmpty(allocator, options)).base, + .c => unreachable, // Reported error earlier. + .hex => return error.HexObjectFormatUnimplemented, + .raw => return error.RawObjectFormatUnimplemented, + }; + } const use_lld = build_options.have_llvm and options.use_lld; // comptime known false when !have_llvm const sub_path = if (use_lld) blk: { if (options.module == null) { diff --git a/src-self-hosted/link/Elf.zig b/src-self-hosted/link/Elf.zig index 62a5e486d0..5257b46279 100644 --- a/src-self-hosted/link/Elf.zig +++ b/src-self-hosted/link/Elf.zig @@ -1222,13 +1222,16 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { // If there is no Zig code to compile, then we should skip flushing the output file because it // will not be part of the linker line anyway. const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: { - try self.flushModule(comp); + const use_stage1 = build_options.is_stage1 and self.base.options.use_llvm; + if (use_stage1) { + const obj_basename = try std.fmt.allocPrint(arena, "{}.o", .{self.base.options.root_name}); + const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename}); + break :blk full_obj_path; + } + try self.flushModule(comp); const obj_basename = self.base.intermediary_basename.?; - const full_obj_path = if (directory.path) |dir_path| - try std.fs.path.join(arena, &[_][]const u8{dir_path, obj_basename}) - else - obj_basename; + const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename}); break :blk full_obj_path; } else null; @@ -1504,7 +1507,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { // (the check for that needs to be earlier), but they could be full paths to .so files, in which // case we want to avoid prepending "-l". const ext = Compilation.classifyFileExt(link_lib); - const arg = if (ext == .so) link_lib else try std.fmt.allocPrint(arena, "-l{}", .{link_lib}); + const arg = if (ext == .shared_library) link_lib else try std.fmt.allocPrint(arena, "-l{}", .{link_lib}); argv.appendAssumeCapacity(arg); } diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index f18ccdd803..6aa4be7c41 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -222,21 +222,27 @@ const usage_build_generic = \\ --libc [file] Provide a file which specifies libc paths \\ \\Link Options: - \\ -l[lib], --library [lib] Link against system library + \\ -l[lib], --library [lib] Link against system library \\ -L[d], --library-directory [d] Add a directory to the library search path - \\ -T[script] Use a custom linker script - \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) - \\ --version [ver] Dynamic library semver - \\ -rdynamic Add all symbols to the dynamic symbol table - \\ -rpath [path] Add directory to the runtime library search path - \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker - \\ -dynamic Force output to be dynamically linked - \\ -static Force output to be statically linked + \\ -T[script] Use a custom linker script + \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) + \\ --version [ver] Dynamic library semver + \\ -rdynamic Add all symbols to the dynamic symbol table + \\ -rpath [path] Add directory to the runtime library search path + \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker + \\ -dynamic Force output to be dynamically linked + \\ -static Force output to be statically linked \\ \\Debug Options (Zig Compiler Development): - \\ -ftime-report Print timing diagnostics - \\ --verbose-link Display linker invocations - \\ --verbose-cc Display C compiler invocations + \\ -ftime-report Print timing diagnostics + \\ --verbose-link Display linker invocations + \\ --verbose-cc Display C compiler invocations + \\ --verbose-tokenize Enable compiler debug output for tokenization + \\ --verbose-ast Enable compiler debug output for AST parsing + \\ --verbose-ir Enable compiler debug output for Zig IR + \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR + \\ --verbose-cimport Enable compiler debug output for C imports + \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features \\ ; @@ -278,6 +284,12 @@ pub fn buildOutputType( var watch = false; var verbose_link = false; var verbose_cc = false; + var verbose_tokenize = false; + var verbose_ast = false; + var verbose_ir = false; + var verbose_llvm_ir = false; + var verbose_cimport = false; + var verbose_llvm_cpu_features = false; var time_report = false; var show_builtin = false; var emit_bin: Emit = .yes_default_path; @@ -548,6 +560,18 @@ pub fn buildOutputType( verbose_link = true; } else if (mem.eql(u8, arg, "--verbose-cc")) { verbose_cc = true; + } else if (mem.eql(u8, arg, "--verbose-tokenize")) { + verbose_tokenize = true; + } else if (mem.eql(u8, arg, "--verbose-ast")) { + verbose_ast = true; + } else if (mem.eql(u8, arg, "--verbose-ir")) { + verbose_ir = true; + } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) { + verbose_llvm_ir = true; + } else if (mem.eql(u8, arg, "--verbose-cimport")) { + verbose_cimport = true; + } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) { + verbose_llvm_cpu_features = true; } else if (mem.startsWith(u8, arg, "-T")) { linker_script = arg[2..]; } else if (mem.startsWith(u8, arg, "-L")) { @@ -563,28 +587,27 @@ pub fn buildOutputType( } else { fatal("unrecognized parameter: '{}'", .{arg}); } - } else if (mem.endsWith(u8, arg, ".o") or - mem.endsWith(u8, arg, ".obj") or - mem.endsWith(u8, arg, ".a") or - mem.endsWith(u8, arg, ".lib")) - { - try link_objects.append(arg); - } else if (Compilation.hasAsmExt(arg) or Compilation.hasCExt(arg) or Compilation.hasCppExt(arg)) { - // TODO a way to pass extra flags on the CLI - try c_source_files.append(.{ .src_path = arg }); - } else if (mem.endsWith(u8, arg, ".so") or - mem.endsWith(u8, arg, ".dylib") or - mem.endsWith(u8, arg, ".dll")) - { - fatal("linking against dynamic libraries not yet supported", .{}); - } else if (mem.endsWith(u8, arg, ".zig") or mem.endsWith(u8, arg, ".zir")) { - if (root_src_file) |other| { - fatal("found another zig file '{}' after root source file '{}'", .{ arg, other }); - } else { - root_src_file = arg; - } - } else { - fatal("unrecognized file extension of parameter '{}'", .{arg}); + } else switch (Compilation.classifyFileExt(arg)) { + .object, .static_library => { + try link_objects.append(arg); + }, + .assembly, .c, .cpp, .h, .ll, .bc => { + // TODO a way to pass extra flags on the CLI + try c_source_files.append(.{ .src_path = arg }); + }, + .shared_library => { + fatal("linking against dynamic libraries not yet supported", .{}); + }, + .zig, .zir => { + if (root_src_file) |other| { + fatal("found another zig file '{}' after root source file '{}'", .{ arg, other }); + } else { + root_src_file = arg; + } + }, + .unknown => { + fatal("unrecognized file extension of parameter '{}'", .{arg}); + }, } } } else { @@ -617,7 +640,16 @@ pub fn buildOutputType( const file_ext = Compilation.classifyFileExt(mem.spanZ(it.only_arg)); switch (file_ext) { .assembly, .c, .cpp, .ll, .bc, .h => try c_source_files.append(.{ .src_path = it.only_arg }), - .unknown, .so => try link_objects.append(it.only_arg), + .unknown, .shared_library, .object, .static_library => { + try link_objects.append(it.only_arg); + }, + .zig, .zir => { + if (root_src_file) |other| { + fatal("found another zig file '{}' after root source file '{}'", .{ it.only_arg, other }); + } else { + root_src_file = it.only_arg; + } + }, } }, .l => { @@ -1173,7 +1205,15 @@ pub fn buildOutputType( .libc_installation = if (libc_installation) |*lci| lci else null, .verbose_cc = verbose_cc, .verbose_link = verbose_link, + .verbose_tokenize = verbose_tokenize, + .verbose_ast = verbose_ast, + .verbose_ir = verbose_ir, + .verbose_llvm_ir = verbose_llvm_ir, + .verbose_cimport = verbose_cimport, + .verbose_llvm_cpu_features = verbose_llvm_cpu_features, .machine_code_model = machine_code_model, + .color = color, + .time_report = time_report, }) catch |err| { fatal("unable to create compilation: {}", .{@errorName(err)}); }; @@ -1193,6 +1233,10 @@ pub fn buildOutputType( fatal("TODO: implement `zig cc` when using it as a preprocessor", .{}); } + if (build_options.is_stage1 and comp.stage1_module != null and watch) { + std.log.warn("--watch is not recommended with the stage1 backend; it leaks memory and is not capable of incremental compilation", .{}); + } + const stdin = std.io.getStdIn().inStream(); const stderr = std.io.getStdErr().outStream(); var repl_buf: [1024]u8 = undefined; diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig index c2ce99db22..d8d32f02cd 100644 --- a/src-self-hosted/stage1.zig +++ b/src-self-hosted/stage1.zig @@ -10,6 +10,7 @@ const stage2 = @import("main.zig"); const fatal = stage2.fatal; const CrossTarget = std.zig.CrossTarget; const Target = std.Target; +const Compilation = @import("Compilation.zig"); comptime { assert(std.builtin.link_libc); @@ -23,6 +24,8 @@ pub const log_level = stage2.log_level; pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int { std.debug.maybeEnableSegfaultHandler(); + zig_stage1_os_init(); + const gpa = std.heap.c_allocator; var arena_instance = std.heap.ArenaAllocator.init(gpa); defer arena_instance.deinit(); @@ -36,6 +39,106 @@ pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int { return 0; } +/// Matches stage2.Color; +pub const ErrColor = c_int; +/// Matches std.builtin.CodeModel +pub const CodeModel = c_int; +/// Matches std.Target.Os.Tag +pub const OS = c_int; +/// Matches std.builtin.BuildMode +pub const BuildMode = c_int; + +pub const TargetSubsystem = extern enum(c_int) { + Console, + Windows, + Posix, + Native, + EfiApplication, + EfiBootServiceDriver, + EfiRom, + EfiRuntimeDriver, + Auto, +}; + +pub const Pkg = extern struct { + name_ptr: [*]const u8, + name_len: usize, + path_ptr: [*]const u8, + path_len: usize, + children_ptr: [*]*Pkg, + children_len: usize, + parent: ?*Pkg, +}; + +pub const Module = extern struct { + root_name_ptr: [*]const u8, + root_name_len: usize, + output_dir_ptr: [*]const u8, + output_dir_len: usize, + builtin_zig_path_ptr: [*]const u8, + builtin_zig_path_len: usize, + test_filter_ptr: [*]const u8, + test_filter_len: usize, + test_name_prefix_ptr: [*]const u8, + test_name_prefix_len: usize, + userdata: usize, + root_pkg: *Pkg, + main_progress_node: ?*std.Progress.Node, + code_model: CodeModel, + subsystem: TargetSubsystem, + err_color: ErrColor, + pic: bool, + link_libc: bool, + link_libcpp: bool, + strip: bool, + is_single_threaded: bool, + dll_export_fns: bool, + link_mode_dynamic: bool, + valgrind_enabled: bool, + function_sections: bool, + enable_stack_probing: bool, + enable_time_report: bool, + enable_stack_report: bool, + dump_analysis: bool, + enable_doc_generation: bool, + emit_bin: bool, + emit_asm: bool, + emit_llvm_ir: bool, + test_is_evented: bool, + verbose_tokenize: bool, + verbose_ast: bool, + verbose_ir: bool, + verbose_llvm_ir: bool, + verbose_cimport: bool, + verbose_llvm_cpu_features: bool, + + pub fn build_object(mod: *Module) void { + zig_stage1_build_object(mod); + } + + pub fn destroy(mod: *Module) void { + zig_stage1_destroy(mod); + } +}; + +extern fn zig_stage1_os_init() void; + +pub const create = zig_stage1_create; +extern fn zig_stage1_create( + optimize_mode: BuildMode, + main_pkg_path_ptr: [*]const u8, + main_pkg_path_len: usize, + root_src_path_ptr: [*]const u8, + root_src_path_len: usize, + zig_lib_dir_ptr: [*c]const u8, + zig_lib_dir_len: usize, + target: [*c]const Stage2Target, + is_test_build: bool, +) ?*Module; + +extern fn zig_stage1_build_object(*Module) void; +extern fn zig_stage1_destroy(*Module) void; + // ABI warning export fn stage2_panic(ptr: [*]const u8, len: usize) void { @panic(ptr[0..len]); @@ -199,297 +302,50 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz } // ABI warning -const Stage2Target = extern struct { +pub const Stage2Target = extern struct { arch: c_int, - vendor: c_int, - + os: OS, abi: c_int, - os: c_int, is_native_os: bool, is_native_cpu: bool, llvm_cpu_name: ?[*:0]const u8, llvm_cpu_features: ?[*:0]const u8, - cpu_builtin_str: ?[*:0]const u8, - os_builtin_str: ?[*:0]const u8, - - dynamic_linker: ?[*:0]const u8, - - llvm_cpu_features_asm_ptr: [*]const [*:0]const u8, - llvm_cpu_features_asm_len: usize, - - fn fromTarget(self: *Stage2Target, cross_target: CrossTarget) !void { - const allocator = std.heap.c_allocator; - - var dynamic_linker: ?[*:0]u8 = null; - const target = try crossTargetToTarget(cross_target, &dynamic_linker); - - const generic_arch_name = target.cpu.arch.genericName(); - var cpu_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, - \\Cpu{{ - \\ .arch = .{}, - \\ .model = &Target.{}.cpu.{}, - \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ - \\ - , .{ - @tagName(target.cpu.arch), - generic_arch_name, - target.cpu.model.name, - generic_arch_name, - generic_arch_name, - }); - defer cpu_builtin_str_buffer.deinit(); - - var llvm_features_buffer = try std.ArrayListSentineled(u8, 0).initSize(allocator, 0); - defer llvm_features_buffer.deinit(); - - // Unfortunately we have to do the work twice, because Clang does not support - // the same command line parameters for CPU features when assembling code as it does - // when compiling C code. - var asm_features_list = std.ArrayList([*:0]const u8).init(allocator); - defer asm_features_list.deinit(); - - for (target.cpu.arch.allFeaturesList()) |feature, index_usize| { - const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); - const is_enabled = target.cpu.features.isEnabled(index); - - if (feature.llvm_name) |llvm_name| { - const plus_or_minus = "-+"[@boolToInt(is_enabled)]; - try llvm_features_buffer.append(plus_or_minus); - try llvm_features_buffer.appendSlice(llvm_name); - try llvm_features_buffer.appendSlice(","); - } - - if (is_enabled) { - // TODO some kind of "zig identifier escape" function rather than - // unconditionally using @"" syntax - try cpu_builtin_str_buffer.appendSlice(" .@\""); - try cpu_builtin_str_buffer.appendSlice(feature.name); - try cpu_builtin_str_buffer.appendSlice("\",\n"); - } - } - - switch (target.cpu.arch) { - .riscv32, .riscv64 => { - if (Target.riscv.featureSetHas(target.cpu.features, .relax)) { - try asm_features_list.append("-mrelax"); - } else { - try asm_features_list.append("-mno-relax"); - } - }, - else => { - // TODO - // Argh, why doesn't the assembler accept the list of CPU features?! - // I don't see a way to do this other than hard coding everything. - }, - } - - try cpu_builtin_str_buffer.appendSlice( - \\ }), - \\}; - \\ - ); - - assert(mem.endsWith(u8, llvm_features_buffer.span(), ",")); - llvm_features_buffer.shrink(llvm_features_buffer.len() - 1); - - var os_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, - \\Os{{ - \\ .tag = .{}, - \\ .version_range = .{{ - , .{@tagName(target.os.tag)}); - defer os_builtin_str_buffer.deinit(); - - // We'll re-use the OS version range builtin string for the cache hash. - const os_builtin_str_ver_start_index = os_builtin_str_buffer.len(); - - @setEvalBranchQuota(2000); - switch (target.os.tag) { - .freestanding, - .ananas, - .cloudabi, - .dragonfly, - .fuchsia, - .ios, - .kfreebsd, - .lv2, - .solaris, - .haiku, - .minix, - .rtems, - .nacl, - .cnk, - .aix, - .cuda, - .nvcl, - .amdhsa, - .ps4, - .elfiamcu, - .tvos, - .watchos, - .mesa3d, - .contiki, - .amdpal, - .hermit, - .hurd, - .wasi, - .emscripten, - .uefi, - .other, - => try os_builtin_str_buffer.appendSlice(" .none = {} }\n"), - - .freebsd, - .macosx, - .netbsd, - .openbsd, - => try os_builtin_str_buffer.outStream().print( - \\ .semver = .{{ - \\ .min = .{{ - \\ .major = {}, - \\ .minor = {}, - \\ .patch = {}, - \\ }}, - \\ .max = .{{ - \\ .major = {}, - \\ .minor = {}, - \\ .patch = {}, - \\ }}, - \\ }}}}, - \\ - , .{ - target.os.version_range.semver.min.major, - target.os.version_range.semver.min.minor, - target.os.version_range.semver.min.patch, - - target.os.version_range.semver.max.major, - target.os.version_range.semver.max.minor, - target.os.version_range.semver.max.patch, - }), - - .linux => try os_builtin_str_buffer.outStream().print( - \\ .linux = .{{ - \\ .range = .{{ - \\ .min = .{{ - \\ .major = {}, - \\ .minor = {}, - \\ .patch = {}, - \\ }}, - \\ .max = .{{ - \\ .major = {}, - \\ .minor = {}, - \\ .patch = {}, - \\ }}, - \\ }}, - \\ .glibc = .{{ - \\ .major = {}, - \\ .minor = {}, - \\ .patch = {}, - \\ }}, - \\ }}}}, - \\ - , .{ - target.os.version_range.linux.range.min.major, - target.os.version_range.linux.range.min.minor, - target.os.version_range.linux.range.min.patch, - - target.os.version_range.linux.range.max.major, - target.os.version_range.linux.range.max.minor, - target.os.version_range.linux.range.max.patch, - - target.os.version_range.linux.glibc.major, - target.os.version_range.linux.glibc.minor, - target.os.version_range.linux.glibc.patch, - }), - - .windows => try os_builtin_str_buffer.outStream().print( - \\ .windows = .{{ - \\ .min = {s}, - \\ .max = {s}, - \\ }}}}, - \\ - , .{ - target.os.version_range.windows.min, - target.os.version_range.windows.max, - }), - } - try os_builtin_str_buffer.appendSlice("};\n"); - - const glibc_or_darwin_version = blk: { - if (target.isGnuLibC()) { - const stage1_glibc = try std.heap.c_allocator.create(Stage2SemVer); - const stage2_glibc = target.os.version_range.linux.glibc; - stage1_glibc.* = .{ - .major = stage2_glibc.major, - .minor = stage2_glibc.minor, - .patch = stage2_glibc.patch, - }; - break :blk stage1_glibc; - } else if (target.isDarwin()) { - const stage1_semver = try std.heap.c_allocator.create(Stage2SemVer); - const stage2_semver = target.os.version_range.semver.min; - stage1_semver.* = .{ - .major = stage2_semver.major, - .minor = stage2_semver.minor, - .patch = stage2_semver.patch, - }; - break :blk stage1_semver; - } else { - break :blk null; - } - }; - - const std_dl = target.standardDynamicLinkerPath(); - const std_dl_z = if (std_dl.get()) |dl| - (try mem.dupeZ(std.heap.c_allocator, u8, dl)).ptr - else - null; - - const asm_features = asm_features_list.toOwnedSlice(); - self.* = .{ - .arch = @enumToInt(target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch - .vendor = 0, - .os = @enumToInt(target.os.tag), - .abi = @enumToInt(target.abi), - .llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null, - .llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr, - .llvm_cpu_features_asm_ptr = asm_features.ptr, - .llvm_cpu_features_asm_len = asm_features.len, - .cpu_builtin_str = cpu_builtin_str_buffer.toOwnedSlice().ptr, - .os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr, - .is_native_os = cross_target.isNativeOs(), - .is_native_cpu = cross_target.isNativeCpu(), - .glibc_or_darwin_version = glibc_or_darwin_version, - .dynamic_linker = dynamic_linker, - .standard_dynamic_linker_path = std_dl_z, - }; - } }; -fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) !Target { - var info = try std.zig.system.NativeTargetInfo.detect(std.heap.c_allocator, cross_target); - if (info.cpu_detection_unimplemented) { - // TODO We want to just use detected_info.target but implementing - // CPU model & feature detection is todo so here we rely on LLVM. - const llvm = @import("llvm.zig"); - const llvm_cpu_name = llvm.GetHostCPUName(); - const llvm_cpu_features = llvm.GetNativeFeatures(); - const arch = Target.current.cpu.arch; - info.target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features); - cross_target.updateCpuFeatures(&info.target.cpu.features); - info.target.cpu.arch = cross_target.getCpuArch(); - } - if (info.dynamic_linker.get()) |dl| { - dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl); - } else { - dynamic_linker_ptr.* = null; - } - return info.target; -} - // ABI warning const Stage2SemVer = extern struct { major: u32, minor: u32, patch: u32, }; + +// ABI warning +export fn stage2_cimport(stage1: *Module) [*:0]const u8 { + @panic("TODO implement stage2_cimport"); +} + +export fn stage2_add_link_lib( + stage1: *Module, + lib_name_ptr: [*c]const u8, + lib_name_len: usize, + symbol_name_ptr: [*c]const u8, + symbol_name_len: usize, +) ?[*:0]const u8 { + return null; // no error +} + +export fn stage2_fetch_file( + stage1: *Module, + path_ptr: [*]const u8, + path_len: usize, + result_len: *usize, +) ?[*]const u8 { + const comp = @intToPtr(*Compilation, stage1.userdata); + // TODO integrate this with cache hash + const file_path = path_ptr[0..path_len]; + const contents = std.fs.cwd().readFileAlloc(comp.gpa, file_path, std.math.maxInt(u32)) catch return null; + result_len.* = contents.len; + return contents.ptr; +} diff --git a/src/analyze.cpp b/src/analyze.cpp index ea19d81995..6c6f198e7a 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -7987,7 +7987,7 @@ Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents_buf) { size_t len; const char *contents = stage2_fetch_file(&g->stage1, buf_ptr(resolved_path), buf_len(resolved_path), &len); if (contents == nullptr) - return ErrorNoMem; + return ErrorFileNotFound; buf_init_from_mem(contents_buf, contents, len); return ErrorNone; } diff --git a/src/codegen.cpp b/src/codegen.cpp index 07728ef06e..6768021410 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8809,33 +8809,18 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { static_assert(TargetSubsystemEfiBootServiceDriver == 5, ""); static_assert(TargetSubsystemEfiRom == 6, ""); static_assert(TargetSubsystemEfiRuntimeDriver == 7, ""); - { - const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little"; - buf_appendf(contents, "pub const endian = %s;\n", endian_str); - } + + buf_append_str(contents, "/// Deprecated: use `std.Target.current.cpu.arch`\n"); + buf_append_str(contents, "pub const arch = Target.current.cpu.arch;\n"); + buf_append_str(contents, "/// Deprecated: use `std.Target.current.cpu.arch.endian()`\n"); + buf_append_str(contents, "pub const endian = Target.current.cpu.arch.endian();\n"); buf_appendf(contents, "pub const output_mode = OutputMode.Obj;\n"); buf_appendf(contents, "pub const link_mode = LinkMode.Static;\n"); buf_appendf(contents, "pub const is_test = false;\n"); buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); - buf_append_str(contents, "/// Deprecated: use `std.Target.cpu.arch`\n"); - buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch); buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi); - { - buf_append_str(contents, "pub const cpu: Cpu = "); - if (g->zig_target->cpu_builtin_str != nullptr) { - buf_append_str(contents, g->zig_target->cpu_builtin_str); - } else { - buf_appendf(contents, "Target.Cpu.baseline(.%s);\n", cur_arch); - } - } - { - buf_append_str(contents, "pub const os = "); - if (g->zig_target->os_builtin_str != nullptr) { - buf_append_str(contents, g->zig_target->os_builtin_str); - } else { - buf_appendf(contents, "Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os); - } - } + buf_appendf(contents, "pub const cpu: Cpu = Target.Cpu.baseline(.%s);\n", cur_arch); + buf_appendf(contents, "pub const os = Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os); buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); 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) { if (g->std_package == nullptr) return ErrorNone; + assert(g->main_pkg); + const char *builtin_zig_basename = "builtin.zig"; Buf *contents; @@ -8879,17 +8866,22 @@ static Error define_builtin_compile_vars(CodeGen *g) { fprintf(stderr, "Unable to write file '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err)); exit(1); } + + g->compile_var_package = new_package(buf_ptr(g->output_dir), builtin_zig_basename, "builtin"); } else { + Buf *resolve_paths[] = { g->builtin_zig_path, }; + *g->builtin_zig_path = os_path_resolve(resolve_paths, 1); + contents = buf_alloc(); if ((err = os_fetch_file_path(g->builtin_zig_path, contents))) { fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err)); exit(1); } + Buf builtin_dirname = BUF_INIT; + os_path_dirname(g->builtin_zig_path, &builtin_dirname); + g->compile_var_package = new_package(buf_ptr(&builtin_dirname), builtin_zig_basename, "builtin"); } - assert(g->main_pkg); - assert(g->std_package); - g->compile_var_package = new_package(buf_ptr(g->output_dir), builtin_zig_basename, "builtin"); if (g->is_test_build) { if (g->test_runner_package == nullptr) { g->test_runner_package = create_test_runner_pkg(g); @@ -8914,6 +8906,13 @@ static void init(CodeGen *g) { if (g->module) return; + codegen_add_time_event(g, "Initialize"); + { + const char *progress_name = "Initialize"; + codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, + progress_name, strlen(progress_name), 0)); + } + g->have_err_ret_tracing = detect_err_ret_tracing(g); assert(g->root_out_name); @@ -9374,19 +9373,11 @@ void codegen_destroy(CodeGen *g) { CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, BuildMode build_mode, Buf *override_lib_dir, - bool is_test_build, Stage2ProgressNode *progress_node) + bool is_test_build) { CodeGen *g = heap::c_allocator.create(); g->emit_bin = true; g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1"); - g->main_progress_node = progress_node; - - codegen_add_time_event(g, "Initialize"); - { - const char *progress_name = "Initialize"; - codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, - progress_name, strlen(progress_name), 0)); - } g->subsystem = TargetSubsystemAuto; g->zig_target = target; @@ -9440,7 +9431,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget Buf resolved_main_pkg_path = os_path_resolve(&main_pkg_path, 1); if (!buf_starts_with_buf(&resolved_root_src_path, &resolved_main_pkg_path)) { - fprintf(stderr, "Root source path '%s' outside main package path '%s'", + fprintf(stderr, "Root source path '%s' outside main package path '%s'\n", buf_ptr(root_src_path), buf_ptr(main_pkg_path)); exit(1); } diff --git a/src/codegen.hpp b/src/codegen.hpp index 5b4317c992..33b2f74757 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -16,8 +16,7 @@ #include CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, - BuildMode build_mode, Buf *zig_lib_dir, - bool is_test_build, Stage2ProgressNode *progress_node); + BuildMode build_mode, Buf *zig_lib_dir, bool is_test_build); void codegen_build_object(CodeGen *g); void codegen_destroy(CodeGen *); diff --git a/src/stage1.cpp b/src/stage1.cpp index 36d59c0a05..b5b87c05d9 100644 --- a/src/stage1.cpp +++ b/src/stage1.cpp @@ -20,13 +20,14 @@ struct ZigStage1 *zig_stage1_create(BuildMode optimize_mode, const char *main_pkg_path_ptr, size_t main_pkg_path_len, const char *root_src_path_ptr, size_t root_src_path_len, const char *zig_lib_dir_ptr, size_t zig_lib_dir_len, - const ZigTarget *target, bool is_test_build, Stage2ProgressNode *progress_node) + const ZigTarget *target, bool is_test_build) { - Buf *main_pkg_path = buf_create_from_mem(main_pkg_path_ptr, main_pkg_path_len); + Buf *main_pkg_path = (main_pkg_path_len == 0) ? + nullptr : buf_create_from_mem(main_pkg_path_ptr, main_pkg_path_len); Buf *root_src_path = buf_create_from_mem(root_src_path_ptr, root_src_path_len); Buf *zig_lib_dir = buf_create_from_mem(zig_lib_dir_ptr, zig_lib_dir_len); CodeGen *g = codegen_create(main_pkg_path, root_src_path, target, optimize_mode, - zig_lib_dir, is_test_build, progress_node); + zig_lib_dir, is_test_build); return &g->stage1; } @@ -68,8 +69,6 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) { CodeGen *g = reinterpret_cast(stage1); g->root_out_name = buf_create_from_mem(stage1->root_name_ptr, stage1->root_name_len); - g->zig_lib_dir = buf_create_from_mem(stage1->zig_lib_dir_ptr, stage1->zig_lib_dir_len); - g->zig_std_dir = buf_create_from_mem(stage1->zig_std_dir_ptr, stage1->zig_std_dir_len); g->output_dir = buf_create_from_mem(stage1->output_dir_ptr, stage1->output_dir_len); if (stage1->builtin_zig_path_len != 0) { 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) { } } + g->main_progress_node = stage1->main_progress_node; + add_package(g, stage1->root_pkg, g->main_pkg); codegen_build_object(g); diff --git a/src/stage1.h b/src/stage1.h index 5b0c4a4df6..c0bd0f70fc 100644 --- a/src/stage1.h +++ b/src/stage1.h @@ -100,22 +100,14 @@ enum Os { // ABI warning struct ZigTarget { enum ZigLLVM_ArchType arch; - enum ZigLLVM_VendorType vendor; - + enum Os os; enum ZigLLVM_EnvironmentType abi; - Os os; bool is_native_os; bool is_native_cpu; const char *llvm_cpu_name; const char *llvm_cpu_features; - const char *cpu_builtin_str; - const char *os_builtin_str; - const char *dynamic_linker; - - const char **llvm_cpu_features_asm_ptr; - size_t llvm_cpu_features_asm_len; }; // ABI warning @@ -161,18 +153,13 @@ struct ZigStage1 { const char *test_name_prefix_ptr; size_t test_name_prefix_len; - const char *zig_lib_dir_ptr; - size_t zig_lib_dir_len; - - const char *zig_std_dir_ptr; - size_t zig_std_dir_len; - void *userdata; struct ZigStage1Pkg *root_pkg; + struct Stage2ProgressNode *main_progress_node; - CodeModel code_model; - TargetSubsystem subsystem; - ErrColor err_color; + enum CodeModel code_model; + enum TargetSubsystem subsystem; + enum ErrColor err_color; bool pic; bool link_libc; @@ -206,7 +193,7 @@ ZIG_EXTERN_C struct ZigStage1 *zig_stage1_create(enum BuildMode optimize_mode, const char *main_pkg_path_ptr, size_t main_pkg_path_len, const char *root_src_path_ptr, size_t root_src_path_len, const char *zig_lib_dir_ptr, size_t zig_lib_dir_len, - const ZigTarget *target, bool is_test_build, Stage2ProgressNode *progress_node); + const struct ZigTarget *target, bool is_test_build); ZIG_EXTERN_C void zig_stage1_build_object(struct ZigStage1 *); diff --git a/src/stage2.cpp b/src/stage2.cpp deleted file mode 100644 index f8b078c237..0000000000 --- a/src/stage2.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// This file is a shim for zig1. The real implementations of these are in -// src-self-hosted/stage1.zig - -#include "stage2.h" -#include "util.hpp" -#include "zig_llvm.h" -#include "target.hpp" -#include "buffer.hpp" -#include "os.hpp" -#include -#include -#include - -void stage2_panic(const char *ptr, size_t len) { - fwrite(ptr, 1, len, stderr); - fprintf(stderr, "\n"); - fflush(stderr); - abort(); -} - -struct Stage2Progress { - int trash; -}; - -struct Stage2ProgressNode { - int trash; -}; - -Stage2Progress *stage2_progress_create(void) { - return nullptr; -} - -void stage2_progress_destroy(Stage2Progress *progress) {} - -Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, - const char *name_ptr, size_t name_len, size_t estimated_total_items) -{ - return nullptr; -} -Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, - const char *name_ptr, size_t name_len, size_t estimated_total_items) -{ - return nullptr; -} -void stage2_progress_end(Stage2ProgressNode *node) {} -void stage2_progress_complete_one(Stage2ProgressNode *node) {} -void stage2_progress_disable_tty(Stage2Progress *progress) {} -void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){} - -static Os get_zig_os_type(ZigLLVM_OSType os_type) { - switch (os_type) { - case ZigLLVM_UnknownOS: - return OsFreestanding; - case ZigLLVM_Ananas: - return OsAnanas; - case ZigLLVM_CloudABI: - return OsCloudABI; - case ZigLLVM_DragonFly: - return OsDragonFly; - case ZigLLVM_FreeBSD: - return OsFreeBSD; - case ZigLLVM_Fuchsia: - return OsFuchsia; - case ZigLLVM_IOS: - return OsIOS; - case ZigLLVM_KFreeBSD: - return OsKFreeBSD; - case ZigLLVM_Linux: - return OsLinux; - case ZigLLVM_Lv2: - return OsLv2; - case ZigLLVM_Darwin: - case ZigLLVM_MacOSX: - return OsMacOSX; - case ZigLLVM_NetBSD: - return OsNetBSD; - case ZigLLVM_OpenBSD: - return OsOpenBSD; - case ZigLLVM_Solaris: - return OsSolaris; - case ZigLLVM_Win32: - return OsWindows; - case ZigLLVM_Haiku: - return OsHaiku; - case ZigLLVM_Minix: - return OsMinix; - case ZigLLVM_RTEMS: - return OsRTEMS; - case ZigLLVM_NaCl: - return OsNaCl; - case ZigLLVM_CNK: - return OsCNK; - case ZigLLVM_AIX: - return OsAIX; - case ZigLLVM_CUDA: - return OsCUDA; - case ZigLLVM_NVCL: - return OsNVCL; - case ZigLLVM_AMDHSA: - return OsAMDHSA; - case ZigLLVM_PS4: - return OsPS4; - case ZigLLVM_ELFIAMCU: - return OsELFIAMCU; - case ZigLLVM_TvOS: - return OsTvOS; - case ZigLLVM_WatchOS: - return OsWatchOS; - case ZigLLVM_Mesa3D: - return OsMesa3D; - case ZigLLVM_Contiki: - return OsContiki; - case ZigLLVM_AMDPAL: - return OsAMDPAL; - case ZigLLVM_HermitCore: - return OsHermitCore; - case ZigLLVM_Hurd: - return OsHurd; - case ZigLLVM_WASI: - return OsWASI; - case ZigLLVM_Emscripten: - return OsEmscripten; - } - zig_unreachable(); -} - -static void get_native_target(ZigTarget *target) { - // first zero initialize - *target = {}; - - ZigLLVM_OSType os_type; - ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os - ZigLLVMGetNativeTarget( - &target->arch, - &target->vendor, - &os_type, - &target->abi, - &oformat); - target->os = get_zig_os_type(os_type); - target->is_native_os = true; - target->is_native_cpu = true; - if (target->abi == ZigLLVM_UnknownEnvironment) { - target->abi = target_default_abi(target->arch, target->os); - } -} - -Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, - const char *dynamic_linker) -{ - Error err; - - if (zig_triple != nullptr && strcmp(zig_triple, "native") == 0) { - zig_triple = nullptr; - } - - if (zig_triple == nullptr) { - get_native_target(target); - - if (mcpu == nullptr) { - target->llvm_cpu_name = ZigLLVMGetHostCPUName(); - target->llvm_cpu_features = ZigLLVMGetNativeFeatures(); - } else if (strcmp(mcpu, "baseline") == 0) { - target->is_native_os = false; - target->is_native_cpu = false; - target->llvm_cpu_name = ""; - target->llvm_cpu_features = ""; - } else { - const char *msg = "stage0 can't handle CPU/features in the target"; - stage2_panic(msg, strlen(msg)); - } - } else { - // first initialize all to zero - *target = {}; - - SplitIterator it = memSplit(str(zig_triple), str("-")); - - Optional> opt_archsub = SplitIterator_next(&it); - Optional> opt_os = SplitIterator_next(&it); - Optional> opt_abi = SplitIterator_next(&it); - - if (!opt_archsub.is_some) - return ErrorMissingArchitecture; - - if ((err = target_parse_arch(&target->arch, (char*)opt_archsub.value.ptr, opt_archsub.value.len))) { - return err; - } - - if (!opt_os.is_some) - return ErrorMissingOperatingSystem; - - if ((err = target_parse_os(&target->os, (char*)opt_os.value.ptr, opt_os.value.len))) { - return err; - } - - if (opt_abi.is_some) { - if ((err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len))) { - return err; - } - } else { - target->abi = target_default_abi(target->arch, target->os); - } - - if (mcpu != nullptr && strcmp(mcpu, "baseline") != 0) { - const char *msg = "stage0 can't handle CPU/features in the target"; - stage2_panic(msg, strlen(msg)); - } - } - - if (dynamic_linker != nullptr) { - target->dynamic_linker = dynamic_linker; - } - - return ErrorNone; -} - -const char *stage2_fetch_file(struct ZigStage1 *stage1, const char *path_ptr, size_t path_len, - size_t *result_len) -{ - Error err; - Buf contents_buf = BUF_INIT; - Buf path_buf = BUF_INIT; - - buf_init_from_mem(&path_buf, path_ptr, path_len); - if ((err = os_fetch_file_path(&path_buf, &contents_buf))) { - return nullptr; - } - *result_len = buf_len(&contents_buf); - return buf_ptr(&contents_buf); -} - -const char *stage2_cimport(struct ZigStage1 *stage1) { - const char *msg = "stage0 called stage2_cimport"; - stage2_panic(msg, strlen(msg)); -} - -const char *stage2_add_link_lib(struct ZigStage1 *stage1, - const char *lib_name_ptr, size_t lib_name_len, - const char *symbol_name_ptr, size_t symbol_name_len) -{ - return nullptr; -} diff --git a/src/stage2.h b/src/stage2.h index 4bc92631dc..104faa6ca8 100644 --- a/src/stage2.h +++ b/src/stage2.h @@ -130,23 +130,23 @@ struct Stage2ErrorMsg { ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len); // ABI warning -ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void); +ZIG_EXTERN_C struct Stage2Progress *stage2_progress_create(void); // ABI warning -ZIG_EXTERN_C void stage2_progress_disable_tty(Stage2Progress *progress); +ZIG_EXTERN_C void stage2_progress_disable_tty(struct Stage2Progress *progress); // ABI warning -ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress); +ZIG_EXTERN_C void stage2_progress_destroy(struct Stage2Progress *progress); // ABI warning -ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, +ZIG_EXTERN_C struct Stage2ProgressNode *stage2_progress_start_root(struct Stage2Progress *progress, const char *name_ptr, size_t name_len, size_t estimated_total_items); // ABI warning -ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, +ZIG_EXTERN_C struct Stage2ProgressNode *stage2_progress_start(struct Stage2ProgressNode *node, const char *name_ptr, size_t name_len, size_t estimated_total_items); // ABI warning -ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node); +ZIG_EXTERN_C void stage2_progress_end(struct Stage2ProgressNode *node); // ABI warning -ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node); +ZIG_EXTERN_C void stage2_progress_complete_one(struct Stage2ProgressNode *node); // ABI warning -ZIG_EXTERN_C void stage2_progress_update_node(Stage2ProgressNode *node, +ZIG_EXTERN_C void stage2_progress_update_node(struct Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items); // ABI warning diff --git a/src/target.cpp b/src/target.cpp index f1cab8eded..433c988a01 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -380,10 +380,6 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si return ErrorUnknownABI; } -Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker) { - return stage2_target_parse(target, triple, mcpu, dynamic_linker); -} - const char *target_arch_name(ZigLLVM_ArchType arch) { return ZigLLVMGetArchTypeName(arch); } @@ -408,7 +404,7 @@ void target_triple_llvm(Buf *triple, const ZigTarget *target) { buf_resize(triple, 0); buf_appendf(triple, "%s-%s-%s-%s", ZigLLVMGetArchTypeName(target->arch), - ZigLLVMGetVendorTypeName(target->vendor), + ZigLLVMGetVendorTypeName(ZigLLVM_UnknownVendor), ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)), ZigLLVMGetEnvironmentTypeName(target->abi)); } @@ -1149,7 +1145,6 @@ void target_libc_enum(size_t index, ZigTarget *out_target) { out_target->arch = libcs_available[index].arch; out_target->os = libcs_available[index].os; out_target->abi = libcs_available[index].abi; - out_target->vendor = ZigLLVM_UnknownVendor; out_target->is_native_os = false; out_target->is_native_cpu = false; } diff --git a/src/target.hpp b/src/target.hpp index c9db4754f9..d34c2aeae5 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -25,7 +25,6 @@ enum CIntType { CIntTypeCount, }; -Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker); Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len); Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); diff --git a/src/zig0.cpp b/src/zig0.cpp index 62378ff68c..bd447abded 100644 --- a/src/zig0.cpp +++ b/src/zig0.cpp @@ -14,6 +14,9 @@ #include "stage2.h" #include "target.hpp" #include "error.hpp" +#include "util.hpp" +#include "buffer.hpp" +#include "os.hpp" #include #include @@ -33,7 +36,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " --output-dir [dir] override output directory (defaults to cwd)\n" " --pkg-begin [name] [path] make pkg available to import and push current pkg\n" " --pkg-end pop current pkg\n" - " --main-pkg-path set the directory of the root package\n" " --release-fast build with optimizations on and safety off\n" " --release-safe build with optimizations on and safety on\n" " --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) { return return_code; } +static Os get_zig_os_type(ZigLLVM_OSType os_type) { + switch (os_type) { + case ZigLLVM_UnknownOS: + return OsFreestanding; + case ZigLLVM_Ananas: + return OsAnanas; + case ZigLLVM_CloudABI: + return OsCloudABI; + case ZigLLVM_DragonFly: + return OsDragonFly; + case ZigLLVM_FreeBSD: + return OsFreeBSD; + case ZigLLVM_Fuchsia: + return OsFuchsia; + case ZigLLVM_IOS: + return OsIOS; + case ZigLLVM_KFreeBSD: + return OsKFreeBSD; + case ZigLLVM_Linux: + return OsLinux; + case ZigLLVM_Lv2: + return OsLv2; + case ZigLLVM_Darwin: + case ZigLLVM_MacOSX: + return OsMacOSX; + case ZigLLVM_NetBSD: + return OsNetBSD; + case ZigLLVM_OpenBSD: + return OsOpenBSD; + case ZigLLVM_Solaris: + return OsSolaris; + case ZigLLVM_Win32: + return OsWindows; + case ZigLLVM_Haiku: + return OsHaiku; + case ZigLLVM_Minix: + return OsMinix; + case ZigLLVM_RTEMS: + return OsRTEMS; + case ZigLLVM_NaCl: + return OsNaCl; + case ZigLLVM_CNK: + return OsCNK; + case ZigLLVM_AIX: + return OsAIX; + case ZigLLVM_CUDA: + return OsCUDA; + case ZigLLVM_NVCL: + return OsNVCL; + case ZigLLVM_AMDHSA: + return OsAMDHSA; + case ZigLLVM_PS4: + return OsPS4; + case ZigLLVM_ELFIAMCU: + return OsELFIAMCU; + case ZigLLVM_TvOS: + return OsTvOS; + case ZigLLVM_WatchOS: + return OsWatchOS; + case ZigLLVM_Mesa3D: + return OsMesa3D; + case ZigLLVM_Contiki: + return OsContiki; + case ZigLLVM_AMDPAL: + return OsAMDPAL; + case ZigLLVM_HermitCore: + return OsHermitCore; + case ZigLLVM_Hurd: + return OsHurd; + case ZigLLVM_WASI: + return OsWASI; + case ZigLLVM_Emscripten: + return OsEmscripten; + } + zig_unreachable(); +} + +static void get_native_target(ZigTarget *target) { + // first zero initialize + *target = {}; + + ZigLLVM_OSType os_type; + ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os + ZigLLVM_VendorType trash; + ZigLLVMGetNativeTarget( + &target->arch, + &trash, + &os_type, + &target->abi, + &oformat); + target->os = get_zig_os_type(os_type); + target->is_native_os = true; + target->is_native_cpu = true; + if (target->abi == ZigLLVM_UnknownEnvironment) { + target->abi = target_default_abi(target->arch, target->os); + } +} + +static Error target_parse_triple(struct ZigTarget *target, const char *zig_triple, const char *mcpu, + const char *dynamic_linker) +{ + Error err; + + if (zig_triple != nullptr && strcmp(zig_triple, "native") == 0) { + zig_triple = nullptr; + } + + if (zig_triple == nullptr) { + get_native_target(target); + + if (mcpu == nullptr) { + target->llvm_cpu_name = ZigLLVMGetHostCPUName(); + target->llvm_cpu_features = ZigLLVMGetNativeFeatures(); + } else if (strcmp(mcpu, "baseline") == 0) { + target->is_native_os = false; + target->is_native_cpu = false; + target->llvm_cpu_name = ""; + target->llvm_cpu_features = ""; + } else { + const char *msg = "stage0 can't handle CPU/features in the target"; + stage2_panic(msg, strlen(msg)); + } + } else { + // first initialize all to zero + *target = {}; + + SplitIterator it = memSplit(str(zig_triple), str("-")); + + Optional> opt_archsub = SplitIterator_next(&it); + Optional> opt_os = SplitIterator_next(&it); + Optional> opt_abi = SplitIterator_next(&it); + + if (!opt_archsub.is_some) + return ErrorMissingArchitecture; + + if ((err = target_parse_arch(&target->arch, (char*)opt_archsub.value.ptr, opt_archsub.value.len))) { + return err; + } + + if (!opt_os.is_some) + return ErrorMissingOperatingSystem; + + if ((err = target_parse_os(&target->os, (char*)opt_os.value.ptr, opt_os.value.len))) { + return err; + } + + if (opt_abi.is_some) { + if ((err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len))) { + return err; + } + } else { + target->abi = target_default_abi(target->arch, target->os); + } + + if (mcpu != nullptr && strcmp(mcpu, "baseline") != 0) { + const char *msg = "stage0 can't handle CPU/features in the target"; + stage2_panic(msg, strlen(msg)); + } + } + + return ErrorNone; +} + + static bool str_starts_with(const char *s1, const char *s2) { size_t s2_len = strlen(s2); if (strlen(s1) < s2_len) { @@ -90,10 +256,9 @@ int main(int argc, char **argv) { bool link_libcpp = false; const char *target_string = nullptr; ZigStage1Pkg *cur_pkg = heap::c_allocator.create(); - BuildMode build_mode = BuildModeDebug; + BuildMode optimize_mode = BuildModeDebug; TargetSubsystem subsystem = TargetSubsystemAuto; const char *override_lib_dir = nullptr; - const char *main_pkg_path = nullptr; const char *mcpu = nullptr; for (int i = 1; i < argc; i += 1) { @@ -103,11 +268,11 @@ int main(int argc, char **argv) { if (strcmp(arg, "--") == 0) { fprintf(stderr, "Unexpected end-of-parameter mark: %s\n", arg); } else if (strcmp(arg, "--release-fast") == 0) { - build_mode = BuildModeFastRelease; + optimize_mode = BuildModeFastRelease; } else if (strcmp(arg, "--release-safe") == 0) { - build_mode = BuildModeSafeRelease; + optimize_mode = BuildModeSafeRelease; } else if (strcmp(arg, "--release-small") == 0) { - build_mode = BuildModeSmallRelease; + optimize_mode = BuildModeSmallRelease; } else if (strcmp(arg, "--help") == 0) { return print_full_usage(arg0, stdout, EXIT_SUCCESS); } else if (strcmp(arg, "--strip") == 0) { @@ -183,8 +348,6 @@ int main(int argc, char **argv) { dynamic_linker = argv[i]; } else if (strcmp(arg, "--override-lib-dir") == 0) { override_lib_dir = argv[i]; - } else if (strcmp(arg, "--main-pkg-path") == 0) { - main_pkg_path = argv[i]; } else if (strcmp(arg, "--library") == 0 || strcmp(arg, "-l") == 0) { if (strcmp(argv[i], "c") == 0) { link_libc = true; @@ -264,12 +427,13 @@ int main(int argc, char **argv) { return print_error_usage(arg0); } - ZigStage1 *stage1 = zig_stage1_create(build_mode, - main_pkg_path, (main_pkg_path == nullptr) ? 0 : strlen(main_pkg_path), + ZigStage1 *stage1 = zig_stage1_create(optimize_mode, + nullptr, 0, in_file, strlen(in_file), - override_lib_dir, strlen(override_lib_dir), &target, false, - root_progress_node); + override_lib_dir, strlen(override_lib_dir), + &target, false); + stage1->main_progress_node = root_progress_node; stage1->root_name_ptr = out_name; stage1->root_name_len = strlen(out_name); stage1->strip = strip; @@ -295,3 +459,66 @@ int main(int argc, char **argv) { return main_exit(root_progress_node, EXIT_SUCCESS); } + +void stage2_panic(const char *ptr, size_t len) { + fwrite(ptr, 1, len, stderr); + fprintf(stderr, "\n"); + fflush(stderr); + abort(); +} + +struct Stage2Progress { + int trash; +}; + +struct Stage2ProgressNode { + int trash; +}; + +Stage2Progress *stage2_progress_create(void) { + return nullptr; +} + +void stage2_progress_destroy(Stage2Progress *progress) {} + +Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, + const char *name_ptr, size_t name_len, size_t estimated_total_items) +{ + return nullptr; +} +Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, + const char *name_ptr, size_t name_len, size_t estimated_total_items) +{ + return nullptr; +} +void stage2_progress_end(Stage2ProgressNode *node) {} +void stage2_progress_complete_one(Stage2ProgressNode *node) {} +void stage2_progress_disable_tty(Stage2Progress *progress) {} +void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){} + +const char *stage2_fetch_file(struct ZigStage1 *stage1, const char *path_ptr, size_t path_len, + size_t *result_len) +{ + Error err; + Buf contents_buf = BUF_INIT; + Buf path_buf = BUF_INIT; + + buf_init_from_mem(&path_buf, path_ptr, path_len); + if ((err = os_fetch_file_path(&path_buf, &contents_buf))) { + return nullptr; + } + *result_len = buf_len(&contents_buf); + return buf_ptr(&contents_buf); +} + +const char *stage2_cimport(struct ZigStage1 *stage1) { + const char *msg = "stage0 called stage2_cimport"; + stage2_panic(msg, strlen(msg)); +} + +const char *stage2_add_link_lib(struct ZigStage1 *stage1, + const char *lib_name_ptr, size_t lib_name_len, + const char *symbol_name_ptr, size_t symbol_name_len) +{ + return nullptr; +} -- cgit v1.2.3