summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/patches/wrapper.c93
-rw-r--r--src/bootstrap/stage-0-busybox.TARGETS1
-rw-r--r--src/bootstrap/stage-0-gcc.TARGETS123
3 files changed, 213 insertions, 4 deletions
diff --git a/etc/patches/wrapper.c b/etc/patches/wrapper.c
new file mode 100644
index 0000000..ca4f4b1
--- /dev/null
+++ b/etc/patches/wrapper.c
@@ -0,0 +1,93 @@
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int main(int argc, char** argv) {
+#include "toolname.h"
+#include "link_args.h"
+ char *s, *path, *newpath, *prgdir, *cwd, **newargv, *tool;
+ size_t size, s_s, s_cwd, s_prgdir, s_path, s_toolname;
+ int i;
+
+ for (link_args_c =0; link_args[link_args_c] != NULL; link_args_c++) {}
+
+ if ((prgdir=strdup(argv[0])) == NULL) {
+ return 66;
+ }
+ s = strrchr(prgdir, '/');
+ if (s == NULL) {
+ prgdir = getenv("CC_REAL_DIRECTORY");
+ if (prgdir == NULL) {
+ prgdir = ".";
+ }
+ } else {
+ *s = '\0';
+ }
+
+ if (*prgdir != '/') {
+ /* called by non-absolute path, need to prefix with cwd */
+ for (size = 1024;; size *= 2) {
+ if ((cwd=(char*)malloc(size)) == NULL) {
+ return 66;
+ }
+ if (getcwd(cwd, size) != NULL) {
+ break;
+ }
+ if (errno != ERANGE) {
+ return 66;
+ }
+ }
+ s = prgdir;
+ s_s = strlen(s);
+ s_cwd = strlen(cwd);
+
+ if ((prgdir=(char*)malloc(s_cwd + 1 + s_s + 1))==NULL) {
+ return 66;
+ }
+ strcpy(prgdir, cwd);
+ strcpy(&prgdir[s_cwd], "/");
+ strcpy(&prgdir[s_cwd+1], s);
+ }
+
+ /* prgdir is now our best guess for the directory argv[0] is located in */
+ path = getenv("PATH");
+ if (path == NULL) {
+ path = prgdir;
+ } else {
+ s_path = strlen(path);
+ s_prgdir = strlen(prgdir);
+ if ((newpath=(char*)malloc(s_prgdir + 1 + s_path + 1)) == NULL) {
+ return 66;
+ }
+ strcpy(newpath, prgdir);
+ strcpy(&newpath[s_prgdir], ":");
+ strcpy(&newpath[s_prgdir+1], path);
+ path = newpath;
+ }
+ setenv("PATH", path, 1);
+
+ if ((newargv=(char**)malloc((argc + link_args_c + 1)*sizeof(char*)))==NULL) {
+ return 66;
+ }
+ for (i=0; i<argc; i++) {
+ newargv[i] = argv[i];
+ }
+ for (i=0; i < link_args_c; i++) {
+ newargv[argc+i] = link_args[i];
+ }
+ newargv[argc+link_args_c] = NULL;
+
+ s_prgdir = strlen(prgdir);
+ s_toolname = strlen(toolname);
+ if ((tool=(char*)malloc(s_prgdir+1+s_toolname+1))==NULL) {
+ return 66;
+ }
+ strcpy(tool, prgdir);
+ strcpy(&tool[s_prgdir], "/");
+ strcpy(&tool[s_prgdir+1], toolname);
+
+ execv(tool, newargv);
+
+ return 65; /* exec failed */
+}
diff --git a/src/bootstrap/stage-0-busybox.TARGETS b/src/bootstrap/stage-0-busybox.TARGETS
index 7562eca..ee2133c 100644
--- a/src/bootstrap/stage-0-busybox.TARGETS
+++ b/src/bootstrap/stage-0-busybox.TARGETS
@@ -585,6 +585,7 @@
, "cmds":
[ "export NJOBS=$(nproc --all 2>/dev/null || echo 1)"
, "export PATH=${LOCALBASE}/bin:${LOCALBASE}/gcc/bin:$PATH"
+ , "export CC_REAL_DIRECTORY=${LOCALBASE}/gcc/bin"
, "export MAKE=${LOCALBASE}/bin/make"
, "export CC=${LOCALBASE}/gcc/bin/gcc"
, "export CXX=${LOCALBASE}/gcc/bin/g++"
diff --git a/src/bootstrap/stage-0-gcc.TARGETS b/src/bootstrap/stage-0-gcc.TARGETS
index a17ad1d..278cfe9 100644
--- a/src/bootstrap/stage-0-gcc.TARGETS
+++ b/src/bootstrap/stage-0-gcc.TARGETS
@@ -46,7 +46,7 @@
, [["@", "binutils", "", "toolchain"], "binutils"]
]
}
-, "gcc-4.7.4":
+, "gcc-4.7.4 (real)":
{ "type": ["@", "rules", "CC/foreign/shell", "data"]
, "arguments_config": ["TOOLCHAIN_CONFIG"]
, "project": ["staged_sources_and_binutils"]
@@ -162,9 +162,124 @@
, "cd ${DESTDIR}/bin"
, "mv gcc gcc.real"
, "mv g++ g++.real"
- , "printf '#!/bin/sh\\nexport PATH=\"$(dirname $0):$PATH\"\\nexec gcc.real %s \"$@\"' \"${LINK_ARGS}\" >gcc"
- , "printf '#!/bin/sh\\nexport PATH=\"$(dirname $0):$PATH\"\\nexec g++.real %s \"$@\"' \"${LINK_ARGS}\" >g++"
- , "chmod +x gcc g++"
+ ]
+ , "out_dirs": ["."]
+ }
+, "link_args.h":
+ { "type": "file_gen"
+ , "arguments_config": ["TOOLCHAIN_CONFIG"]
+ , "name": "link_args.h"
+ , "data":
+ { "type": "let*"
+ , "bindings":
+ [ [ "system_lib_dir"
+ , { "type": "lookup"
+ , "key": "HOST_SYSTEM_LIB_DIR"
+ , "map":
+ { "type": "var"
+ , "name": "TOOLCHAIN_CONFIG"
+ , "default": {"type": "empty_map"}
+ }
+ }
+ ]
+ , [ "link_args"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "system_lib_dir"}
+ , "then":
+ [ { "type": "join"
+ , "$1": ["-B", {"type": "var", "name": "system_lib_dir"}]
+ }
+ , { "type": "join"
+ , "$1": ["-L", {"type": "var", "name": "system_lib_dir"}]
+ }
+ , "-Xlinker"
+ , "-rpath"
+ , "-Xlinker"
+ , {"type": "var", "name": "system_lib_dir"}
+ ]
+ }
+ ]
+ , [ "link_args_c"
+ , { "type": "json_encode"
+ , "$1":
+ {"type": "length", "$1": {"type": "var", "name": "link_args"}}
+ }
+ ]
+ , [ "args_array"
+ , { "type": "join"
+ , "separator": ", "
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ { "type": "foreach"
+ , "range": {"type": "var", "name": "link_args"}
+ , "body":
+ {"type": "json_encode", "$1": {"type": "var", "name": "_"}}
+ }
+ , ["NULL"]
+ ]
+ }
+ }
+ ]
+ ]
+ , "body":
+ { "type": "join"
+ , "$1":
+ [ "char* link_args[]"
+ , " = {"
+ , {"type": "var", "name": "args_array"}
+ , "};\n"
+ , "size_t link_args_c = (size_t) "
+ , {"type": "var", "name": "link_args_c"}
+ , ";\n"
+ ]
+ }
+ }
+ }
+, "toolname.h":
+ { "type": "file_gen"
+ , "arguments_config": ["TOOL"]
+ , "name": "toolname.h"
+ , "data":
+ { "type": "join"
+ , "$1":
+ [ "char *toolname = "
+ , { "type": "json_encode"
+ , "$1":
+ {"type": "join", "$1": [{"type": "var", "name": "TOOL"}, ".real"]}
+ }
+ , ";\n"
+ ]
+ }
+ }
+, "wrapper":
+ { "type": ["@", "rules", "CC", "binary"]
+ , "arguments_config": ["TOOL"]
+ , "pure C": [""]
+ , "name": [{"type": "var", "name": "TOOL"}]
+ , "private-hdrs": ["toolname.h", "link_args.h"]
+ , "srcs": [["@", "patches", "", "wrapper.c"]]
+ }
+, "gcc":
+ { "type": "configure"
+ , "target": "wrapper"
+ , "config": {"type": "singleton_map", "key": "TOOL", "value": "gcc"}
+ }
+, "g++":
+ { "type": "configure"
+ , "target": "wrapper"
+ , "config": {"type": "singleton_map", "key": "TOOL", "value": "g++"}
+ }
+, "wrappers":
+ {"type": "install", "files": {"wrapper/gcc": "gcc", "wrapper/g++": "g++"}}
+, "gcc-4.7.4":
+ { "type": ["@", "rules", "CC/foreign/shell", "data"]
+ , "project": ["gcc-4.7.4 (real)"]
+ , "localbase": [["@", "busybox", "", "bootstrap"], "wrappers"]
+ , "cmds":
+ [ "export PATH=$(pwd)/binutils/bin:${LOCALBASE}/bin:$PATH"
+ , "cp -r . ${DESTDIR}"
+ , "cp ${LOCALBASE}/wrapper/gcc ${LOCALBASE}/wrapper/g++ ${DESTDIR}/bin"
]
, "out_dirs": ["."]
}