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.
5 * The hardcoded path arguments are defined relative to the actual location
8 * (C) 2011 Peter Korsgaard <jacmet@sunsite.dk>
9 * (C) 2011 Daniel Nyström <daniel.nystrom@timeterminal.se>
10 * (C) 2012 Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
11 * (C) 2013 Spenser Gilliland <spenser@gillilanding.com>
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.
24 static char path
[PATH_MAX
];
25 static char sysroot
[PATH_MAX
];
28 * GCC errors out with certain combinations of arguments (examples are
29 * -mfloat-abi={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
39 #define EXCLUSIVE_ARGS 4
41 static char *predef_args
[] = {
52 #endif /* BR_SOFTFLOAT */
62 #ifdef BR_MIPS_TARGET_LITTLE_ENDIAN
65 #ifdef BR_MIPS_TARGET_BIG_ENDIAN
68 #ifdef BR_ADDITIONAL_CFLAGS
73 int main(int argc
, char **argv
)
76 char *relbasedir
, *absbasedir
;
77 char *progpath
= argv
[0];
80 int ret
, i
, count
= 0, debug
;
82 /* Calculate the relative paths */
83 basename
= strrchr(progpath
, '/');
87 relbasedir
= malloc(strlen(progpath
) + 7);
88 if (relbasedir
== NULL
) {
89 perror(__FILE__
": malloc");
92 sprintf(relbasedir
, "%s/../..", argv
[0]);
93 absbasedir
= realpath(relbasedir
, NULL
);
96 absbasedir
= malloc(PATH_MAX
+ 1);
97 ret
= readlink("/proc/self/exe", absbasedir
, PATH_MAX
);
99 perror(__FILE__
": readlink");
102 absbasedir
[ret
] = '\0';
103 for (i
= ret
; i
> 0; i
--) {
104 if (absbasedir
[i
] == '/') {
105 absbasedir
[i
] = '\0';
111 if (absbasedir
== NULL
) {
112 perror(__FILE__
": realpath");
116 /* Fill in the relative paths */
117 #ifdef BR_CROSS_PATH_REL
118 ret
= snprintf(path
, sizeof(path
), "%s/" BR_CROSS_PATH_REL
"/%s", absbasedir
, basename
);
119 #else /* BR_CROSS_PATH_ABS */
120 ret
= snprintf(path
, sizeof(path
), BR_CROSS_PATH_ABS
"/%s", basename
);
122 if (ret
>= sizeof(path
)) {
123 perror(__FILE__
": overflow");
126 ret
= snprintf(sysroot
, sizeof(sysroot
), "%s/" BR_SYSROOT
, absbasedir
);
127 if (ret
>= sizeof(sysroot
)) {
128 perror(__FILE__
": overflow");
132 cur
= args
= malloc(sizeof(predef_args
) +
133 (sizeof(char *) * (argc
+ EXCLUSIVE_ARGS
)));
135 perror(__FILE__
": malloc");
139 /* start with predefined args */
140 memcpy(cur
, predef_args
, sizeof(predef_args
));
141 cur
+= sizeof(predef_args
) / sizeof(predef_args
[0]);
144 /* add float abi if not overridden in args */
145 for (i
= 1; i
< argc
; i
++) {
146 if (!strncmp(argv
[i
], "-mfloat-abi=", strlen("-mfloat-abi=")) ||
147 !strcmp(argv
[i
], "-msoft-float") ||
148 !strcmp(argv
[i
], "-mhard-float"))
153 *cur
++ = "-mfloat-abi=" BR_FLOAT_ABI
;
156 #if defined(BR_ARCH) || \
157 defined(BR_TUNE) || \
159 /* Add our -march/cpu/tune/abi flags, but only if none are
160 * already specified on the commandline
162 for (i
= 1; i
< argc
; i
++) {
163 if (!strncmp(argv
[i
], "-march=", strlen("-march=")) ||
164 !strncmp(argv
[i
], "-mtune=", strlen("-mtune=")) ||
165 !strncmp(argv
[i
], "-mcpu=", strlen("-mcpu=" )))
170 *cur
++ = "-march=" BR_ARCH
;
173 *cur
++ = "-mtune=" BR_TUNE
;
176 *cur
++ = "-mcpu=" BR_CPU
;
179 #endif /* ARCH || TUNE || CPU */
181 /* append forward args */
182 memcpy(cur
, &argv
[1], sizeof(char *) * (argc
- 1));
185 /* finish with NULL termination */
188 /* Debug the wrapper to see actual arguments passed to
190 * unset, empty, or 0: do not trace
191 * set to 1 : trace all arguments on a single line
192 * set to 2 : trace one argument per line
194 if ((env_debug
= getenv("BR2_DEBUG_WRAPPER"))) {
195 debug
= atoi(env_debug
);
197 fprintf(stderr
, "Toolchain wrapper executing:");
198 for (i
= 0; args
[i
]; i
++)
199 fprintf(stderr
, "%s'%s'",
200 (debug
== 2) ? "\n " : " ", args
[i
]);
201 fprintf(stderr
, "\n");
205 if (execv(path
, args
))