From 60d1134d25bfce19c8953d8381301b1abd297a69 Mon Sep 17 00:00:00 2001 From: "Dimitrie O. Paun" Date: Tue, 7 Jan 2003 19:47:19 +0000 Subject: [PATCH] Teach winegcc to produce executables directly from a bunch of source files. Create a wineg++ akin to g++. Drop support for the abused -xc++ switched. --- tools/Makefile.in | 3 +- tools/winegcc.c | 136 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 125 insertions(+), 14 deletions(-) diff --git a/tools/Makefile.in b/tools/Makefile.in index 8e3607c85d6..3756ee132c4 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -58,10 +58,11 @@ install:: $(MKINSTALLDIRS) $(bindir) $(mandir)/man$(prog_manext) $(INSTALL_SCRIPT) $(SRCDIR)/winemaker $(bindir)/winemaker $(INSTALL_PROGRAM) winegcc $(bindir)/winegcc + cd $(bindir) && $(RM) wineg++ && $(LN_S) winegcc wineg++ $(INSTALL_PROGRAM) winewrap $(bindir)/winewrap $(INSTALL_DATA) $(SRCDIR)/winemaker.man $(mandir)/man$(prog_manext)/winemaker.$(prog_manext) uninstall:: - $(RM) $(bindir)/winemaker $(bindir)/winegcc $(bindir)/winewrap $(mandir)/man$(prog_manext)/winemaker.$(prog_manext) + $(RM) $(bindir)/winemaker $(bindir)/winegcc $(bindir)/wineg++ $(bindir)/winewrap $(mandir)/man$(prog_manext)/winemaker.$(prog_manext) ### Dependencies: diff --git a/tools/winegcc.c b/tools/winegcc.c index 3b0648fd601..769edaf4e96 100644 --- a/tools/winegcc.c +++ b/tools/winegcc.c @@ -26,10 +26,18 @@ #include #include #include +#include +#include +#include #ifdef HAVE_UNISTD_H # include #endif +static char **tmp_files; +static int nb_tmp_files; +static int verbose = 0; +static int keep_generated = 0; + void error(const char *s, ...) { va_list ap; @@ -42,13 +50,114 @@ void error(const char *s, ...) exit(2); } +char *strmake(const char *fmt, ...) +{ + int n, size = 100; + char *p; + va_list ap; + + if ((p = malloc (size)) == NULL) + error("Can not malloc %d bytes.", size); + + while (1) + { + va_start(ap, fmt); + n = vsnprintf (p, size, fmt, ap); + va_end(ap); + if (n > -1 && n < size) return p; + size *= 2; + if ((p = realloc (p, size)) == NULL) + error("Can not realloc %d bytes.", size); + } +} + +void spawn(char *const argv[]) +{ + int pid, status, wret, i; + + if (verbose) + { + for(i = 0; argv[i]; i++) printf("%s ", argv[i]); + printf("\n"); + } + + if ((pid = fork()) == 0) execvp(argv[0], argv); + else if (pid > 0) + { + while (pid != (wret = waitpid(pid, &status, 0))) + if (wret == -1 && errno != EINTR) break; + + if (pid == wret && WIFEXITED(status) && WEXITSTATUS(status) == 0) return; + error("%s failed.", argv[0]); + } + perror("Error:"); + exit(3); +} + +int strendswith(const char *str, const char *end) +{ + int l = strlen(str); + int m = strlen(end); + + return l >= m && strcmp(str + l - m, end) == 0; +} + +void clean_temp_files() +{ + int i; + + if (keep_generated) return; + + for (i = 0; i < nb_tmp_files; i++) + unlink(tmp_files[i]); +} + +char *get_temp_file(const char *suffix) +{ + char *tmp = strmake("%s%s", tempnam(0, "wgcc"), suffix); + + tmp_files = realloc( tmp_files, (nb_tmp_files+1) * sizeof(*tmp_files) ); + tmp_files[nb_tmp_files++] = tmp; + + return tmp; +} + +char *get_obj_file(char **argv, int n) +{ + char *tmpobj, **compargv; + int i, j; + + if (strendswith(argv[n], ".o")) return argv[n]; + if (strendswith(argv[n], ".a")) return argv[n]; + + tmpobj = get_temp_file(".o"); + compargv = malloc(sizeof(char*) * (n + 10)); + i = 0; + compargv[i++] = BINDIR "/winegcc"; + compargv[i++] = "-c"; + compargv[i++] = "-o"; + compargv[i++] = tmpobj; + for (j = 1; j <= n; j++) + if (argv[j]) compargv[i++] = argv[j]; + compargv[i] = 0; + + spawn(compargv); + + return tmpobj; +} + + int main(int argc, char **argv) { char **gcc_argv; int i, j; - int linking = 1, verbose = 0, cpp = 0, use_static_linking = 0; + int linking = 1, cpp = 0, use_static_linking = 0; int use_stdinc = 1, use_stdlib = 1, use_msvcrt = 0, gui_app = 0; + atexit(clean_temp_files); + + if (strendswith(argv[0], "++")) cpp = 1; + for ( i = 1 ; i < argc ; i++ ) { if (argv[i][0] == '-') /* option */ @@ -94,9 +203,6 @@ int main(int argc, char **argv) use_static_linking = 1; } break; - case 'x': - if (strcmp("-xc++", argv[i]) == 0) cpp = 1; - break; case '-': if (strcmp("-static", argv[i]+1) == 0) use_static_linking = 1; @@ -125,16 +231,26 @@ int main(int argc, char **argv) case 'L': case 'o': gcc_argv[i++] = argv[j]; + argv[j] = 0; + if (!gcc_argv[i-1][2] && j + 1 < argc) + { + gcc_argv[i++] = argv[++j]; + argv[j] = 0; + } break; case 'l': gcc_argv[i++] = strcmp(argv[j], "-luuid") ? argv[j] : "-lwine_uuid"; + argv[j] = 0; break; default: ; /* ignore the rest */ } } else - gcc_argv[i++] = argv[j]; + { + gcc_argv[i++] = get_obj_file(argv, j); + argv[j] = 0; + } } if (use_stdlib && use_msvcrt) gcc_argv[i++] = "-lmsvcrt"; if (gui_app) gcc_argv[i++] = "-lcomdlg32"; @@ -175,13 +291,7 @@ int main(int argc, char **argv) gcc_argv[i] = NULL; - if (verbose) - { - for (i = 0; gcc_argv[i]; i++) printf("%s ", gcc_argv[i]); - printf("\n"); - } + spawn(gcc_argv); - execvp(gcc_argv[0], gcc_argv); - - return 1; + return 0; }