Commit bbbcf16ef9

Andrew Kelley <andrew@ziglang.org>
2019-03-07 21:50:49
fix linking glibc: caching static libs and
handle linking pthread, rt, dl, m better
1 parent 2caf39c
Changed files (2)
src/codegen.cpp
@@ -8283,7 +8283,7 @@ static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix) {
 }
 
 // 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;
 
     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);
     }
 
-    if (g->enable_cache) {
-        cache_buf(&g->cache_hash, &digest);
-    }
-
     g->link_objects.append(o_final_path);
     g->caches_to_release.append(cache_hash);
-
-    return is_cache_miss;
 }
 
 // returns true if we had any cache misses
-static bool gen_c_objects(CodeGen *g) {
+static void gen_c_objects(CodeGen *g) {
     Error err;
-    bool any_cache_misses = false;
 
     if (g->c_source_files.length == 0)
-        return any_cache_misses;
+        return;
 
     Buf *self_exe_path = buf_alloc();
     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) {
         CFile *c_file = g->c_source_files.at(c_file_i);
-        bool is_cache_miss = gen_c_object(g, self_exe_path, c_file);
-        any_cache_misses = any_cache_misses || is_cache_miss;
+        gen_c_object(g, self_exe_path, c_file);
     }
-    return any_cache_misses;
 }
 
 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()
 // 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;
 
     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->rpath_list.items, g->rpath_list.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_int(ch, g->emit_file_type);
     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->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->is_single_threaded);
     cache_bool(ch, g->linker_rdynamic);
     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_minor);
     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->clang_argv, g->clang_argv_len);
     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);
 
-    *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);
     if ((err = cache_hit(ch, digest)))
@@ -9199,12 +9193,11 @@ void codegen_build_and_link(CodeGen *g) {
 
     Buf *artifact_dir = buf_alloc();
     Buf digest = BUF_INIT;
-    bool any_c_objects_generated;
     if (g->enable_cache) {
         Buf *manifest_dir = buf_alloc();
         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) {
                 // message already printed
             } 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);
     } else {
         // 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);
         resolve_out_paths(g);
     } else {
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_build_and_link(child_gen);
             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) {
             CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
             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) {
         LinkLib *link_lib = g->link_libs_list.at(i);
         if (buf_eql_str(link_lib->name, "c")) {
+            // libc is linked specially
             continue;
         }
         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")) {
-                lj->args.append(get_libc_crt_file(g, "libm.so.6")); // this is our dummy so file
                 continue;
             } 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;
             } 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;
             } 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;
             }
         }
@@ -857,7 +844,11 @@ static void construct_linker_job_elf(LinkJob *lj) {
             lj->args.append("--no-as-needed");
         } else if (target_is_glibc(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"));
         } else {
             zig_unreachable();