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