Commit 3be4b6434c

Andrew Kelley <superjoe30@gmail.com>
2017-02-03 18:34:20
add ability to set linker script
1 parent e00eec1
src/all_types.hpp
@@ -1223,6 +1223,7 @@ struct CodeGen {
     Buf *mmacosx_version_min;
     Buf *mios_version_min;
     bool linker_rdynamic;
+    const char *linker_script;
 
     // The function definitions this module includes. There must be a corresponding
     // fn_protos entry.
src/codegen.cpp
@@ -225,6 +225,11 @@ 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, ConstExprValue *const_val);
 static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, bool is_export);
 
src/codegen.hpp
@@ -43,6 +43,7 @@ void codegen_set_mlinker_version(CodeGen *g, Buf *darwin_linker_version);
 void codegen_set_rdynamic(CodeGen *g, bool rdynamic);
 void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min);
 void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min);
+void codegen_set_linker_script(CodeGen *g, const char *linker_script);
 
 void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
 
src/link.cpp
@@ -154,6 +154,11 @@ static void construct_linker_job_linux(LinkJob *lj) {
         find_libc_lib_path(g);
     }
 
+    if (g->linker_script) {
+        lj->args.append("-T");
+        lj->args.append(g->linker_script);
+    }
+
     lj->args.append("--gc-sections");
 
     lj->args.append("-m");
src/main.cpp
@@ -56,6 +56,7 @@ static int usage(const char *arg0) {
         "  -mios-version-min [ver]      (darwin only) set iOS deployment target\n"
         "  -framework [name]            (darwin only) link against framework\n"
         "  --check-unused               perform semantic analysis on unused declarations\n"
+        "  --linker-script [path]       use a custom linker script\n"
     , arg0);
     return EXIT_FAILURE;
 }
@@ -140,6 +141,7 @@ int main(int argc, char **argv) {
     const char *mmacosx_version_min = nullptr;
     const char *mios_version_min = nullptr;
     bool check_unused = false;
+    const char *linker_script = nullptr;
 
     for (int i = 1; i < argc; i += 1) {
         char *arg = argv[i];
@@ -231,6 +233,8 @@ int main(int argc, char **argv) {
                     mios_version_min = argv[i];
                 } else if (strcmp(arg, "-framework") == 0) {
                     frameworks.append(argv[i]);
+                } else if (strcmp(arg, "--linker-script") == 0) {
+                    linker_script = argv[i];
                 } else {
                     fprintf(stderr, "Invalid argument: %s\n", arg);
                     return usage(arg0);
@@ -343,7 +347,7 @@ int main(int argc, char **argv) {
             CodeGen *g = codegen_create(&root_source_dir, target);
             codegen_set_is_release(g, is_release_build);
             codegen_set_is_test(g, cmd == CmdTest);
-
+            codegen_set_linker_script(g, linker_script);
             codegen_set_check_unused(g, check_unused);
 
             codegen_set_clang_argv(g, clang_argv.items, clang_argv.length);