fix linking glibc: caching static libs and
handle linking pthread, rt, dl, m bettermaster
parent
2caf39c961
commit
bbbcf16ef9
|
@ -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 {
|
||||||
|
|
23
src/link.cpp
23
src/link.cpp
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue