fix linking glibc: caching static libs and

handle linking pthread, rt, dl, m better
master
Andrew Kelley 2019-03-07 15:50:49 -05:00
parent 2caf39c961
commit bbbcf16ef9
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
2 changed files with 22 additions and 38 deletions

View File

@ -8283,7 +8283,7 @@ static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix) {
} }
// returns true if it was a cache miss // returns true if it was a cache miss
static bool gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
Error err; Error err;
Buf *artifact_dir; Buf *artifact_dir;
@ -8501,23 +8501,16 @@ static bool gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
os_path_join(artifact_dir, final_o_basename, o_final_path); os_path_join(artifact_dir, final_o_basename, o_final_path);
} }
if (g->enable_cache) {
cache_buf(&g->cache_hash, &digest);
}
g->link_objects.append(o_final_path); g->link_objects.append(o_final_path);
g->caches_to_release.append(cache_hash); g->caches_to_release.append(cache_hash);
return is_cache_miss;
} }
// returns true if we had any cache misses // returns true if we had any cache misses
static bool gen_c_objects(CodeGen *g) { static void gen_c_objects(CodeGen *g) {
Error err; Error err;
bool any_cache_misses = false;
if (g->c_source_files.length == 0) if (g->c_source_files.length == 0)
return any_cache_misses; return;
Buf *self_exe_path = buf_alloc(); Buf *self_exe_path = buf_alloc();
if ((err = os_self_exe_path(self_exe_path))) { if ((err = os_self_exe_path(self_exe_path))) {
@ -8529,10 +8522,8 @@ static bool gen_c_objects(CodeGen *g) {
for (size_t c_file_i = 0; c_file_i < g->c_source_files.length; c_file_i += 1) { 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); CFile *c_file = g->c_source_files.at(c_file_i);
bool is_cache_miss = gen_c_object(g, self_exe_path, c_file); gen_c_object(g, self_exe_path, c_file);
any_cache_misses = any_cache_misses || is_cache_miss;
} }
return any_cache_misses;
} }
void codegen_add_object(CodeGen *g, Buf *object_path) { void codegen_add_object(CodeGen *g, Buf *object_path) {
@ -9030,7 +9021,7 @@ static void add_cache_pkg(CodeGen *g, CacheHash *ch, ZigPackage *pkg) {
// Called before init() // Called before init()
// is_cache_hit takes into account gen_c_objects // is_cache_hit takes into account gen_c_objects
static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest, bool *c_objects_generated) { static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
Error err; Error err;
Buf *compiler_id; Buf *compiler_id;
@ -9052,7 +9043,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest, bool *c_obj
cache_list_of_buf(ch, g->darwin_frameworks.items, g->darwin_frameworks.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->rpath_list.items, g->rpath_list.length);
cache_list_of_buf(ch, g->forbidden_libs.items, g->forbidden_libs.length); cache_list_of_buf(ch, g->forbidden_libs.items, g->forbidden_libs.length);
cache_list_of_file(ch, g->link_objects.items, g->link_objects.length);
cache_list_of_file(ch, g->assembly_files.items, g->assembly_files.length); cache_list_of_file(ch, g->assembly_files.items, g->assembly_files.length);
cache_int(ch, g->emit_file_type); cache_int(ch, g->emit_file_type);
cache_int(ch, g->build_mode); cache_int(ch, g->build_mode);
@ -9067,6 +9057,10 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest, bool *c_obj
cache_bool(ch, g->is_static); cache_bool(ch, g->is_static);
cache_bool(ch, g->strip_debug_symbols); cache_bool(ch, g->strip_debug_symbols);
cache_bool(ch, g->is_test_build); 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->is_single_threaded); cache_bool(ch, g->is_single_threaded);
cache_bool(ch, g->linker_rdynamic); cache_bool(ch, g->linker_rdynamic);
cache_bool(ch, g->each_lib_rpath); cache_bool(ch, g->each_lib_rpath);
@ -9078,8 +9072,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest, bool *c_obj
cache_usize(ch, g->version_major); cache_usize(ch, g->version_major);
cache_usize(ch, g->version_minor); cache_usize(ch, g->version_minor);
cache_usize(ch, g->version_patch); cache_usize(ch, g->version_patch);
cache_buf_opt(ch, g->test_filter);
cache_buf_opt(ch, g->test_name_prefix);
cache_list_of_str(ch, g->llvm_argv, g->llvm_argv_len); 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->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->lib_dirs.items, g->lib_dirs.length);
@ -9092,7 +9084,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest, bool *c_obj
} }
cache_buf_opt(ch, g->dynamic_linker_path); cache_buf_opt(ch, g->dynamic_linker_path);
*c_objects_generated = gen_c_objects(g); // 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); buf_resize(digest, 0);
if ((err = cache_hit(ch, digest))) if ((err = cache_hit(ch, digest)))
@ -9199,12 +9193,11 @@ void codegen_build_and_link(CodeGen *g) {
Buf *artifact_dir = buf_alloc(); Buf *artifact_dir = buf_alloc();
Buf digest = BUF_INIT; Buf digest = BUF_INIT;
bool any_c_objects_generated;
if (g->enable_cache) { if (g->enable_cache) {
Buf *manifest_dir = buf_alloc(); Buf *manifest_dir = buf_alloc();
os_path_join(g->cache_dir, buf_create_from_str("h"), manifest_dir); os_path_join(g->cache_dir, buf_create_from_str("h"), manifest_dir);
if ((err = check_cache(g, manifest_dir, &digest, &any_c_objects_generated))) { if ((err = check_cache(g, manifest_dir, &digest))) {
if (err == ErrorCacheUnavailable) { if (err == ErrorCacheUnavailable) {
// message already printed // message already printed
} else if (err == ErrorNotDir) { } else if (err == ErrorNotDir) {
@ -9219,10 +9212,10 @@ void codegen_build_and_link(CodeGen *g) {
os_path_join(g->cache_dir, buf_create_from_str("artifact"), artifact_dir); os_path_join(g->cache_dir, buf_create_from_str("artifact"), artifact_dir);
} else { } else {
// There is a call to this in check_cache // There is a call to this in check_cache
any_c_objects_generated = gen_c_objects(g); gen_c_objects(g);
} }
if (g->enable_cache && buf_len(&digest) != 0 && !any_c_objects_generated) { if (g->enable_cache && buf_len(&digest) != 0) {
os_path_join(artifact_dir, &digest, &g->artifact_dir); os_path_join(artifact_dir, &digest, &g->artifact_dir);
resolve_out_paths(g); resolve_out_paths(g);
} else { } else {

View File

@ -462,16 +462,6 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
codegen_add_object(child_gen, buf_create_from_str(init_o)); codegen_add_object(child_gen, buf_create_from_str(init_o));
codegen_build_and_link(child_gen); codegen_build_and_link(child_gen);
return buf_ptr(&child_gen->output_file_path); return buf_ptr(&child_gen->output_file_path);
} else if (strcmp(file, "libc.so.6") == 0) {
return build_dummy_so(parent, "c", 6);
} else if (strcmp(file, "libm.so.6") == 0) {
return build_dummy_so(parent, "m", 6);
} else if (strcmp(file, "libpthread.so.0") == 0) {
return build_dummy_so(parent, "pthread", 0);
} else if (strcmp(file, "librt.so.1") == 0) {
return build_dummy_so(parent, "rt", 1);
} else if (strcmp(file, "libdl.so.2") == 0) {
return build_dummy_so(parent, "dl", 2);
} else if (strcmp(file, "libc_nonshared.a") == 0) { } else if (strcmp(file, "libc_nonshared.a") == 0) {
CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr); CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
codegen_set_out_name(child_gen, buf_create_from_str("c_nonshared")); codegen_set_out_name(child_gen, buf_create_from_str("c_nonshared"));
@ -805,21 +795,18 @@ static void construct_linker_job_elf(LinkJob *lj) {
for (size_t i = 0; i < g->link_libs_list.length; i += 1) { for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
LinkLib *link_lib = g->link_libs_list.at(i); LinkLib *link_lib = g->link_libs_list.at(i);
if (buf_eql_str(link_lib->name, "c")) { if (buf_eql_str(link_lib->name, "c")) {
// libc is linked specially
continue; continue;
} }
if (g->libc == nullptr && target_is_glibc(g)) { if (g->libc == nullptr && target_is_glibc(g)) {
// glibc // these libraries are always linked below when targeting glibc
if (buf_eql_str(link_lib->name, "m")) { if (buf_eql_str(link_lib->name, "m")) {
lj->args.append(get_libc_crt_file(g, "libm.so.6")); // this is our dummy so file
continue; continue;
} else if (buf_eql_str(link_lib->name, "pthread")) { } else if (buf_eql_str(link_lib->name, "pthread")) {
lj->args.append(get_libc_crt_file(g, "libpthread.so.0")); // this is our dummy so file
continue; continue;
} else if (buf_eql_str(link_lib->name, "dl")) { } else if (buf_eql_str(link_lib->name, "dl")) {
lj->args.append(get_libc_crt_file(g, "libdl.so.2")); // this is our dummy so file
continue; continue;
} else if (buf_eql_str(link_lib->name, "rt")) { } else if (buf_eql_str(link_lib->name, "rt")) {
lj->args.append(get_libc_crt_file(g, "librt.so.1")); // this is our dummy so file
continue; continue;
} }
} }
@ -857,7 +844,11 @@ static void construct_linker_job_elf(LinkJob *lj) {
lj->args.append("--no-as-needed"); lj->args.append("--no-as-needed");
} else if (target_is_glibc(g)) { } else if (target_is_glibc(g)) {
lj->args.append(build_libunwind(g)); lj->args.append(build_libunwind(g));
lj->args.append(get_libc_crt_file(g, "libc.so.6")); // this is our dummy so file lj->args.append(build_dummy_so(g, "c", 6));
lj->args.append(build_dummy_so(g, "m", 6));
lj->args.append(build_dummy_so(g, "pthread", 0));
lj->args.append(build_dummy_so(g, "dl", 2));
lj->args.append(build_dummy_so(g, "rt", 1));
lj->args.append(get_libc_crt_file(g, "libc_nonshared.a")); lj->args.append(get_libc_crt_file(g, "libc_nonshared.a"));
} else { } else {
zig_unreachable(); zig_unreachable();