aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-02-16 13:25:30 -0500
committerAndrew Kelley <andrew@ziglang.org>2020-02-16 13:25:30 -0500
commit4b02a39aa93b0043f05de0d90443051c019643ab (patch)
tree12632d2e43bc6e13911d8e88d1f91e84b11106f6 /src/codegen.cpp
parent5e37fc0746a75ed319fc57ae62d8cc966382c592 (diff)
downloadzig-4b02a39aa93b0043f05de0d90443051c019643ab.tar.gz
zig-4b02a39aa93b0043f05de0d90443051c019643ab.zip
self-hosted libc detection
* libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp64
1 files changed, 34 insertions, 30 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index a0bc56f093..22d76c1372 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -8982,17 +8982,20 @@ static void detect_dynamic_linker(CodeGen *g) {
#if defined(ZIG_OS_LINUX)
{
Error err;
- Buf *result = buf_alloc();
for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) {
const char *lib_name = possible_ld_names[i];
- if ((err = zig_libc_cc_print_file_name(lib_name, result, false, true))) {
+ char *result_ptr;
+ size_t result_len;
+ if ((err = stage2_libc_cc_print_file_name(&result_ptr, &result_len, lib_name, false))) {
if (err != ErrorCCompilerCannotFindFile && err != ErrorNoCCompilerInstalled) {
fprintf(stderr, "Unable to detect native dynamic linker: %s\n", err_str(err));
exit(1);
}
continue;
}
- g->dynamic_linker_path = result;
+ g->dynamic_linker_path = buf_create_from_mem(result_ptr, result_len);
+ // Skips heap::c_allocator because the memory is allocated by stage2 library.
+ free(result_ptr);
return;
}
}
@@ -9028,16 +9031,16 @@ static void detect_libc(CodeGen *g) {
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<Buf*>(g->libc_include_dir_len);
- g->libc_include_dir_list[0] = arch_include_dir;
- g->libc_include_dir_list[1] = generic_include_dir;
- g->libc_include_dir_list[2] = arch_os_include_dir;
- g->libc_include_dir_list[3] = generic_os_include_dir;
+ g->libc_include_dir_list = heap::c_allocator.allocate<const char*>(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->zig_target->is_native) {
- g->libc = heap::c_allocator.create<ZigLibCInstallation>();
+ g->libc = heap::c_allocator.create<Stage2LibCInstallation>();
// search for native_libc.txt in following dirs:
// - LOCAL_CACHE_DIR
@@ -9082,8 +9085,8 @@ static void detect_libc(CodeGen *g) {
if (libc_txt == nullptr)
libc_txt = &global_libc_txt;
- if ((err = zig_libc_parse(g->libc, libc_txt, g->zig_target, false))) {
- if ((err = zig_libc_find_native(g->libc, true))) {
+ if ((err = stage2_libc_parse(g->libc, buf_ptr(libc_txt)))) {
+ 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));
@@ -9103,7 +9106,7 @@ static void detect_libc(CodeGen *g) {
fprintf(stderr, "Unable to open %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));
exit(1);
}
- zig_libc_render(g->libc, file);
+ stage2_libc_render(g->libc, file);
if (fclose(file) != 0) {
fprintf(stderr, "Unable to save %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));
exit(1);
@@ -9113,27 +9116,28 @@ static void detect_libc(CodeGen *g) {
exit(1);
}
}
- bool want_sys_dir = !buf_eql_buf(&g->libc->include_dir, &g->libc->sys_include_dir);
+ 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<Buf*>(dir_count);
+ g->libc_include_dir_list = heap::c_allocator.allocate<const char *>(dir_count);
- g->libc_include_dir_list[g->libc_include_dir_len] = &g->libc->include_dir;
+ g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->include_dir;
g->libc_include_dir_len += 1;
if (want_sys_dir) {
- g->libc_include_dir_list[g->libc_include_dir_len] = &g->libc->sys_include_dir;
+ g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->sys_include_dir;
g->libc_include_dir_len += 1;
}
if (want_um_and_shared_dirs != 0) {
- g->libc_include_dir_list[g->libc_include_dir_len] = buf_sprintf("%s" OS_SEP ".." OS_SEP "um",
- buf_ptr(&g->libc->include_dir));
+ g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
+ "%s" OS_SEP ".." OS_SEP "um", g->libc->include_dir));
g->libc_include_dir_len += 1;
- g->libc_include_dir_list[g->libc_include_dir_len] = buf_sprintf("%s" OS_SEP ".." OS_SEP "shared",
- buf_ptr(&g->libc->include_dir));
+ g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
+ "%s" OS_SEP ".." OS_SEP "shared", g->libc->include_dir));
g->libc_include_dir_len += 1;
}
assert(g->libc_include_dir_len == dir_count);
@@ -9208,9 +9212,9 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
args.append(buf_ptr(g->zig_c_headers_dir));
for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {
- Buf *include_dir = g->libc_include_dir_list[i];
+ const char *include_dir = g->libc_include_dir_list[i];
args.append("-isystem");
- args.append(buf_ptr(include_dir));
+ args.append(include_dir);
}
if (g->zig_target->is_native) {
@@ -9666,7 +9670,7 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
cache_buf(cache_hash, compiler_id);
cache_int(cache_hash, g->err_color);
cache_buf(cache_hash, g->zig_c_headers_dir);
- cache_list_of_buf(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len);
+ 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);
cache_int(cache_hash, g->zig_target->arch);
cache_int(cache_hash, g->zig_target->sub_arch);
@@ -10482,11 +10486,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
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_buf(ch, &g->libc->include_dir);
- cache_buf(ch, &g->libc->sys_include_dir);
- cache_buf(ch, &g->libc->crt_dir);
- cache_buf(ch, &g->libc->msvc_lib_dir);
- cache_buf(ch, &g->libc->kernel32_lib_dir);
+ cache_str(ch, g->libc->include_dir);
+ cache_str(ch, g->libc->sys_include_dir);
+ cache_str(ch, g->libc->crt_dir);
+ cache_str(ch, g->libc->msvc_lib_dir);
+ cache_str(ch, g->libc->kernel32_lib_dir);
}
cache_buf_opt(ch, g->dynamic_linker_path);
cache_buf_opt(ch, g->version_script_path);
@@ -10765,7 +10769,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
}
CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,
- ZigLibCInstallation *libc, const char *name, Stage2ProgressNode *parent_progress_node)
+ 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,
@@ -10804,7 +10808,7 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o
CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
OutType out_type, BuildMode build_mode, Buf *override_lib_dir,
- ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)
+ Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)
{
CodeGen *g = heap::c_allocator.create<CodeGen>();
g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");