winegcc: produce executables, new wineg++

Dimitrie O. Paun dpaun at rogers.com
Tue Jan 7 00:31:45 CST 2003


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.




More information about the wine-patches mailing list