This patch obsoletes: "winegcc: behave like g++ when invoked as wineg++" which was broken anyway. With this patch, one can almost run: CC=winegcc configure succesfully. The remaining problem is that configure is trying to be smart, and gets confused by our *.exe.so files, and thinks it needs to append .exe.so to all executables. Darn... ChangeLog 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. Index: tools/Makefile.in =================================================================== RCS file: /var/cvs/wine/tools/Makefile.in,v retrieving revision 1.30 diff -u -r1.30 Makefile.in --- tools/Makefile.in 19 Dec 2002 23:41:30 -0000 1.30 +++ tools/Makefile.in 6 Jan 2003 19:53:45 -0000 @@ -58,10 +58,11 @@ $(MKINSTALLDIRS) $(bindir) $(mandir)/man$(prog_manext) $(INSTALL_SCRIPT) $(SRCDIR)/winemaker $(bindir)/winemaker $(INSTALL_PROGRAM) winegcc $(bindir)/winegcc + $(RM) $(bindir)/wineg++ && $(LN_S) $(bindir)/winegcc $(bindir)/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: Index: tools/winegcc.c =================================================================== RCS file: /var/cvs/wine/tools/winegcc.c,v retrieving revision 1.7 diff -u -r1.7 winegcc.c --- tools/winegcc.c 5 Jan 2003 20:28:54 -0000 1.7 +++ tools/winegcc.c 7 Jan 2003 04:13:22 -0000 @@ -26,10 +26,18 @@ #include <stdlib.h> #include <stdarg.h> #include <string.h> +#include <errno.h> +#include <sys/wait.h> +#include <sys/stat.h> #ifdef HAVE_UNISTD_H # include <unistd.h> #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 @@ 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 @@ 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 @@ 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 +292,7 @@ gcc_argv[i] = NULL; - if (verbose) - { - for (i = 0; gcc_argv[i]; i++) printf("%s ", gcc_argv[i]); - printf("\n"); - } - - execvp(gcc_argv[0], gcc_argv); + spawn(gcc_argv); - return 1; + return 0; } -- Dimi.