blob: d54f1f5db650577450a5cc8b47e1475543f1abf0 [file] [log] [blame]
Peter Korsgaard85dc57f2011-04-29 13:09:26 +02001/**
2 * Buildroot wrapper for external toolchains. This simply executes the real
3 * toolchain with a number of arguments (sysroot/arch/..) hardcoded,
4 * to ensure the external toolchain uses the correct configuration.
Arnout Vandecappellebefb9a32012-07-15 01:12:05 +00005 * The hardcoded path arguments are defined relative to the actual location
6 * of the binary.
Peter Korsgaard85dc57f2011-04-29 13:09:26 +02007 *
8 * (C) 2011 Peter Korsgaard <jacmet@sunsite.dk>
Daniel Nyströme8c46b12011-06-21 21:54:27 +02009 * (C) 2011 Daniel Nyström <daniel.nystrom@timeterminal.se>
Arnout Vandecappellebefb9a32012-07-15 01:12:05 +000010 * (C) 2012 Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Spenser Gillilandaa86b522013-07-19 18:31:58 -050011 * (C) 2013 Spenser Gilliland <spenser@gillilanding.com>
Peter Korsgaard85dc57f2011-04-29 13:09:26 +020012 *
13 * This file is licensed under the terms of the GNU General Public License
14 * version 2. This program is licensed "as is" without any warranty of any
15 * kind, whether express or implied.
16 */
17
18#include <stdio.h>
19#include <string.h>
20#include <limits.h>
21#include <unistd.h>
Daniel Nyströme8c46b12011-06-21 21:54:27 +020022#include <stdlib.h>
Peter Korsgaard85dc57f2011-04-29 13:09:26 +020023
Arnout Vandecappellebefb9a32012-07-15 01:12:05 +000024static char path[PATH_MAX];
25static char sysroot[PATH_MAX];
Peter Korsgaard85dc57f2011-04-29 13:09:26 +020026
Spenser Gillilandaa86b522013-07-19 18:31:58 -050027/**
28 * GCC errors out with certain combinations of arguments (examples are
29 * -mabi-float={hard|soft} and -m{little|big}-endian), so we have to ensure
30 * that we only pass the predefined one to the real compiler if the inverse
31 * option isn't in the argument list.
32 * This specifies the worst case number of extra arguments we might pass
33 */
34#define EXCLUSIVE_ARGS 1
35
Daniel Nyströme8c46b12011-06-21 21:54:27 +020036static char *predef_args[] = {
Peter Korsgaard85dc57f2011-04-29 13:09:26 +020037 path,
Arnout Vandecappellebefb9a32012-07-15 01:12:05 +000038 "--sysroot", sysroot,
Peter Korsgaard85dc57f2011-04-29 13:09:26 +020039#ifdef BR_ARCH
40 "-march=" BR_ARCH,
41#endif /* BR_ARCH */
42#ifdef BR_TUNE
43 "-mtune=" BR_TUNE,
44#endif /* BR_TUNE */
Stany MARCEL3fb60102011-11-01 13:19:16 +010045#ifdef BR_CPU
46 "-mcpu=" BR_CPU,
47#endif
Peter Korsgaard85dc57f2011-04-29 13:09:26 +020048#ifdef BR_ABI
49 "-mabi=" BR_ABI,
50#endif
Spenser Gilliland27c93702013-07-19 18:31:57 -050051#ifdef BR_FPU
Thomas Petazzonid7745512013-07-16 10:03:12 +020052 "-mfpu=" BR_FPU,
53#endif
Peter Korsgaard85dc57f2011-04-29 13:09:26 +020054#ifdef BR_SOFTFLOAT
55 "-msoft-float",
56#endif /* BR_SOFTFLOAT */
Thomas Petazzoni85d07692013-07-16 10:03:22 +020057#ifdef BR_MODE
58 "-m" BR_MODE,
59#endif
Arnout Vandecappelle (Essensium/Mind)a22dc0f2012-03-13 23:30:00 +010060#ifdef BR_64
61 "-m64",
62#endif
Sonic Zhang57133822013-05-03 00:39:34 +000063#ifdef BR_BINFMT_FLAT
64 "-Wl,-elf2flt",
65#endif
Markos Chandrasf3a2b802013-10-14 10:52:25 +010066#ifdef BR_MIPS_TARGET_LITTLE_ENDIAN
67 "-EL",
68#endif
69#ifdef BR_MIPS_TARGET_BIG_ENDIAN
70 "-EB",
71#endif
Thomas Petazzonib95e4362011-12-31 12:09:33 +010072#ifdef BR_ADDITIONAL_CFLAGS
73 BR_ADDITIONAL_CFLAGS
74#endif
Peter Korsgaard85dc57f2011-04-29 13:09:26 +020075};
76
Peter Korsgaard85dc57f2011-04-29 13:09:26 +020077int main(int argc, char **argv)
78{
Daniel Nyströme8c46b12011-06-21 21:54:27 +020079 char **args, **cur;
Arnout Vandecappellebefb9a32012-07-15 01:12:05 +000080 char *relbasedir, *absbasedir;
81 char *progpath = argv[0];
82 char *basename;
Yann E. MORIN60cb2902013-09-21 00:00:30 +020083 char *env_debug;
84 int ret, i, count = 0, debug;
Arnout Vandecappellebefb9a32012-07-15 01:12:05 +000085
86 /* Calculate the relative paths */
87 basename = strrchr(progpath, '/');
88 if (basename) {
89 *basename = '\0';
90 basename++;
91 relbasedir = malloc(strlen(progpath) + 7);
92 if (relbasedir == NULL) {
93 perror(__FILE__ ": malloc");
94 return 2;
95 }
96 sprintf(relbasedir, "%s/../..", argv[0]);
97 absbasedir = realpath(relbasedir, NULL);
98 } else {
99 basename = progpath;
Patrick Ziegler74ae7af2013-05-28 23:41:19 +0000100 absbasedir = malloc(PATH_MAX + 1);
101 ret = readlink("/proc/self/exe", absbasedir, PATH_MAX);
102 if (ret < 0) {
103 perror(__FILE__ ": readlink");
104 return 2;
105 }
106 absbasedir[ret] = '\0';
107 for (i = ret; i > 0; i--) {
108 if (absbasedir[i] == '/') {
109 absbasedir[i] = '\0';
110 if (++count == 3)
111 break;
112 }
113 }
Arnout Vandecappellebefb9a32012-07-15 01:12:05 +0000114 }
115 if (absbasedir == NULL) {
116 perror(__FILE__ ": realpath");
117 return 2;
118 }
119
120 /* Fill in the relative paths */
121#ifdef BR_CROSS_PATH_REL
122 ret = snprintf(path, sizeof(path), "%s/" BR_CROSS_PATH_REL "/%s", absbasedir, basename);
123#else /* BR_CROSS_PATH_ABS */
124 ret = snprintf(path, sizeof(path), BR_CROSS_PATH_ABS "/%s", basename);
125#endif
126 if (ret >= sizeof(path)) {
127 perror(__FILE__ ": overflow");
128 return 3;
129 }
130 ret = snprintf(sysroot, sizeof(sysroot), "%s/" BR_SYSROOT, absbasedir);
131 if (ret >= sizeof(sysroot)) {
132 perror(__FILE__ ": overflow");
133 return 3;
134 }
Peter Korsgaard85dc57f2011-04-29 13:09:26 +0200135
Spenser Gillilandaa86b522013-07-19 18:31:58 -0500136 cur = args = malloc(sizeof(predef_args) +
137 (sizeof(char *) * (argc + EXCLUSIVE_ARGS)));
Daniel Nyströme8c46b12011-06-21 21:54:27 +0200138 if (args == NULL) {
139 perror(__FILE__ ": malloc");
140 return 2;
Peter Korsgaard85dc57f2011-04-29 13:09:26 +0200141 }
142
Daniel Nyströme8c46b12011-06-21 21:54:27 +0200143 /* start with predefined args */
144 memcpy(cur, predef_args, sizeof(predef_args));
145 cur += sizeof(predef_args) / sizeof(predef_args[0]);
146
Spenser Gillilandaa86b522013-07-19 18:31:58 -0500147#ifdef BR_FLOAT_ABI
148 /* add float abi if not overridden in args */
149 for (i = 1; i < argc; i++) {
150 if (!strncmp(argv[i], "-mfloat-abi=", strlen("-mfloat-abi=")) ||
151 !strcmp(argv[i], "-msoft-float") ||
152 !strcmp(argv[i], "-mhard-float"))
153 break;
154 }
155
156 if (i == argc)
157 *cur++ = "-mfloat-abi=" BR_FLOAT_ABI;
158#endif
159
Daniel Nyströme8c46b12011-06-21 21:54:27 +0200160 /* append forward args */
161 memcpy(cur, &argv[1], sizeof(char *) * (argc - 1));
162 cur += argc - 1;
163
164 /* finish with NULL termination */
165 *cur = NULL;
Peter Korsgaard85dc57f2011-04-29 13:09:26 +0200166
Yann E. MORIN60cb2902013-09-21 00:00:30 +0200167 /* Debug the wrapper to see actual arguments passed to
168 * the compiler:
169 * unset, empty, or 0: do not trace
170 * set to 1 : trace all arguments on a single line
171 * set to 2 : trace one argument per line
172 */
173 if ((env_debug = getenv("BR_DEBUG_WRAPPER"))) {
174 debug = atoi(env_debug);
175 if (debug > 0) {
176 fprintf(stderr, "Toolchain wrapper executing:");
177 for (i = 0; args[i]; i++)
178 fprintf(stderr, "%s'%s'",
Peter Korsgaardb9558e02013-09-23 09:45:56 +0200179 (debug == 2) ? "\n " : " ", args[i]);
Yann E. MORIN60cb2902013-09-21 00:00:30 +0200180 fprintf(stderr, "\n");
181 }
Yann E. MORINaaa06aa2013-07-18 23:54:50 +0200182 }
183
Peter Korsgaard85dc57f2011-04-29 13:09:26 +0200184 if (execv(path, args))
185 perror(path);
186
Daniel Nyströme8c46b12011-06-21 21:54:27 +0200187 free(args);
188
Peter Korsgaard85dc57f2011-04-29 13:09:26 +0200189 return 2;
190}