3 * Copyright (C) 2000 Manuel Novoa III
5 * This is a crude wrapper to use uClibc with gcc.
6 * It was originally written to work around ./configure for ext2fs-utils.
7 * It certainly can be improved, but it works for me in the normal cases.
11 * A bug was fixed in building the gcc command line when dynamic linking.
12 * The functions dlopen, etc. now work. At this time, you must make sure
13 * the correct libdl.so is included however. It is safest to, for example,
14 * add /lib/libdl.so.1 if using ld-linux.so.1 rather than adding -ldl to the
17 * Note: This is only a problem if devel and target archs are the same. To
18 * avoid the problem, you can use a customized dynamic linker.
23 * The wrapper now works with either installed and uninstalled uClibc versions.
24 * If you want to use the uninstalled header files and libs, either include
25 * the string "build" in the invocation name such as
26 * 'ln -s <ARCH>-uclibc-gcc <ARCH>-uclibc-gcc-build'
27 * or include it in the environment variable setting of UCLIBC_GCC.
28 * Note: This automatically enables the "rpath" behavior described below.
30 * The wrapper will now pass the location of the uClibc shared libs used to
31 * the linker with the "-rpath" option if the invocation name includes the
32 * string "rpath" or if the environment variable UCLIBC_GCC include it (as
33 * with "build" above). This is primarily intended to be used on devel
34 * platforms of the same arch as the target. A good place to use this feature
35 * would be in the uClibc/test directory.
37 * The wrapper now displays the command line passed to gcc when '-v' is used.
41 * "rpath" and "build" behavior are now decoupled. You can of course get
42 * the old "build" behavior by setting UCLIBC_GCC="rpath-build". Order
43 * isn't important here, as only the substrings are searched for.
45 * Added environment variable check for UCLIBC_GCC_DLOPT to let user specify
46 * an alternative dynamic linker at runtime without using command line args.
47 * Since this wouldn't commonly be used, I made it easy on myself. You have
48 * to match the option you would have passed to the gcc wrapper. As an
51 * export UCLIBC_GCC_DLOPT="-Wl,--dynamic-linker,/lib/ld-alt-linker.so.3"
53 * This is really only useful if target arch == devel arch and DEVEL_PREFIX
54 * isn't empty. It involves a recompile, but you can at least test apps
55 * on your devel system if combined with the "rpath" behavor if by using
56 * LD_LIBRARY_PATH, etc.
58 * Also added check for "-Wl,--dynamic-linker" on the command line. The
59 * use default dynamic linker or the envirnment-specified dynamic linker
60 * is disabled in that case.
62 * Added options --uclibc-use-build-dir and --uclibc-use-rpath so that those
63 * behaviors can be invoked from the command line.
70 * Check/modify gcc-specific environment variables?
78 #include "gcc-uClibc.h"
80 static char *rpath_link[] = {
81 "-Wl,-rpath-link,"UCLIBC_DEVEL_PREFIX UCLIBC_ROOT_DIR"/lib",
82 "-Wl,-rpath-link,"UCLIBC_BUILD_DIR"/lib"
85 static char *rpath[] = {
86 "-Wl,-rpath,"UCLIBC_DEVEL_PREFIX UCLIBC_ROOT_DIR"/lib",
87 "-Wl,-rpath,"UCLIBC_BUILD_DIR"/lib"
90 static char *uClibc_inc[] = {
91 "-I"UCLIBC_DEVEL_PREFIX UCLIBC_ROOT_DIR"/usr/include/",
92 "-I"UCLIBC_BUILD_DIR"/include/"
95 static char *crt0_path[] = {
96 UCLIBC_DEVEL_PREFIX UCLIBC_ROOT_DIR"/usr/lib/crt0.o",
97 UCLIBC_BUILD_DIR"/lib/crt0.o"
100 static char *lib_path[] = {
101 "-L"UCLIBC_DEVEL_PREFIX UCLIBC_ROOT_DIR"/lib",
102 "-L"UCLIBC_BUILD_DIR"/lib"
105 static char *usr_lib_path = "-L"UCLIBC_DEVEL_PREFIX UCLIBC_ROOT_DIR"/usr/lib";
107 static char static_linking[] = "-static";
108 static char nostdinc[] = "-nostdinc";
109 static char nostartfiles[] = "-nostartfiles";
110 static char nodefaultlibs[] = "-nodefaultlibs";
111 static char nostdlib[] = "-nostdlib";
113 int main(int argc, char **argv)
115 int use_build_dir = 0, linking = 1, use_static_linking = 0;
116 int use_stdinc = 1, use_start = 1, use_stdlib = 1;
117 int source_count = 0, use_rpath = 0, verbose = 0;
124 build_dlstr = "-Wl,--dynamic-linker," BUILD_DYNAMIC_LINKER;
125 dlstr = getenv("UCLIBC_GCC_DLOPT");
127 dlstr = "-Wl,--dynamic-linker," DYNAMIC_LINKER;
130 ep = getenv("UCLIBC_GCC");
135 if (strstr(ep,"build") != 0) {
139 if (strstr(ep,"rpath") != 0) {
143 for ( i = 1 ; i < argc ; i++ ) {
144 if (argv[i][0] == '-') { /* option */
145 switch (argv[i][1]) {
146 case 'c': /* compile or assemble */
147 case 'S': /* generate assembler code */
148 case 'E': /* preprocess only */
149 case 'r': /* partial-link */
150 case 'i': /* partial-link */
151 case 'M': /* map file generation */
152 if (argv[i][2] == 0) linking = 0;
154 case 'v': /* verbose */
155 if (argv[i][2] == 0) verbose = 1;
158 if (strcmp(nostdinc,argv[i]) == 0) {
160 } else if (strcmp(nostartfiles,argv[i]) == 0) {
162 } else if (strcmp(nodefaultlibs,argv[i]) == 0) {
164 } else if (strcmp(nostdlib,argv[i]) == 0) {
170 if (strcmp(static_linking,argv[i]) == 0) {
171 use_static_linking = 1;
174 case 'W': /* -static could be passed directly to ld */
175 if (strncmp("-Wl,",argv[i],4) == 0) {
176 if (strstr(argv[i],static_linking) != 0) {
177 use_static_linking = 1;
179 if (strstr(argv[i],"--dynamic-linker") != 0) {
185 if (strcmp(static_linking,argv[i]+1) == 0) {
186 use_static_linking = 1;
190 } else { /* assume it is an existing source file */
196 gcc_argv = __builtin_alloca(sizeof(char*) * (argc + 20));
198 if (!(gcc_argv = malloc(sizeof(char) * (argc + 20)))) {
204 gcc_argv[i++] = GCC_BIN;
205 for ( j = 1 ; j < argc ; j++ ) {
206 if (strcmp("--uclibc-use-build-dir",argv[j]) == 0) {
208 } else if (strcmp("--uclibc-use-rpath",argv[j]) == 0) {
211 gcc_argv[i++] = argv[j];
215 gcc_argv[i++] = nostdinc;
216 gcc_argv[i++] = uClibc_inc[use_build_dir];
217 gcc_argv[i++] = GCC_INCDIR;
219 if (linking && source_count) {
220 if (!use_static_linking) {
221 if (dlstr && use_build_dir) {
222 gcc_argv[i++] = build_dlstr;
224 gcc_argv[i++] = dlstr;
227 gcc_argv[i++] = rpath[use_build_dir];
230 gcc_argv[i++] = rpath_link[use_build_dir]; /* just to be safe */
231 gcc_argv[i++] = lib_path[use_build_dir];
232 if (!use_build_dir) {
233 gcc_argv[i++] = usr_lib_path;
236 gcc_argv[i++] = crt0_path[use_build_dir];
239 gcc_argv[i++] = nostdlib;
240 gcc_argv[i++] = "-lc";
241 gcc_argv[i++] = GCC_LIB;
244 gcc_argv[i++] = NULL;
247 printf("Invoked as %s\n", argv[0]);
248 for ( j = 0 ; gcc_argv[j] ; j++ ) {
249 printf("arg[%2i] = %s\n", j, gcc_argv[j]);
253 return execvp(GCC_BIN, gcc_argv);