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.
This commit is contained in:
Dimitrie O. Paun 2003-01-07 19:47:19 +00:00 committed by Alexandre Julliard
parent 3800e91eb5
commit 60d1134d25
2 changed files with 125 additions and 14 deletions

View File

@ -58,10 +58,11 @@ install::
$(MKINSTALLDIRS) $(bindir) $(mandir)/man$(prog_manext) $(MKINSTALLDIRS) $(bindir) $(mandir)/man$(prog_manext)
$(INSTALL_SCRIPT) $(SRCDIR)/winemaker $(bindir)/winemaker $(INSTALL_SCRIPT) $(SRCDIR)/winemaker $(bindir)/winemaker
$(INSTALL_PROGRAM) winegcc $(bindir)/winegcc $(INSTALL_PROGRAM) winegcc $(bindir)/winegcc
cd $(bindir) && $(RM) wineg++ && $(LN_S) winegcc wineg++
$(INSTALL_PROGRAM) winewrap $(bindir)/winewrap $(INSTALL_PROGRAM) winewrap $(bindir)/winewrap
$(INSTALL_DATA) $(SRCDIR)/winemaker.man $(mandir)/man$(prog_manext)/winemaker.$(prog_manext) $(INSTALL_DATA) $(SRCDIR)/winemaker.man $(mandir)/man$(prog_manext)/winemaker.$(prog_manext)
uninstall:: 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: ### Dependencies:

View File

@ -26,10 +26,18 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> # include <unistd.h>
#endif #endif
static char **tmp_files;
static int nb_tmp_files;
static int verbose = 0;
static int keep_generated = 0;
void error(const char *s, ...) void error(const char *s, ...)
{ {
va_list ap; va_list ap;
@ -42,13 +50,114 @@ void error(const char *s, ...)
exit(2); 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) int main(int argc, char **argv)
{ {
char **gcc_argv; char **gcc_argv;
int i, j; 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; 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++ ) for ( i = 1 ; i < argc ; i++ )
{ {
if (argv[i][0] == '-') /* option */ if (argv[i][0] == '-') /* option */
@ -94,9 +203,6 @@ int main(int argc, char **argv)
use_static_linking = 1; use_static_linking = 1;
} }
break; break;
case 'x':
if (strcmp("-xc++", argv[i]) == 0) cpp = 1;
break;
case '-': case '-':
if (strcmp("-static", argv[i]+1) == 0) if (strcmp("-static", argv[i]+1) == 0)
use_static_linking = 1; use_static_linking = 1;
@ -125,16 +231,26 @@ int main(int argc, char **argv)
case 'L': case 'L':
case 'o': case 'o':
gcc_argv[i++] = argv[j]; 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; break;
case 'l': case 'l':
gcc_argv[i++] = strcmp(argv[j], "-luuid") ? argv[j] : "-lwine_uuid"; gcc_argv[i++] = strcmp(argv[j], "-luuid") ? argv[j] : "-lwine_uuid";
argv[j] = 0;
break; break;
default: default:
; /* ignore the rest */ ; /* ignore the rest */
} }
} }
else 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 (use_stdlib && use_msvcrt) gcc_argv[i++] = "-lmsvcrt";
if (gui_app) gcc_argv[i++] = "-lcomdlg32"; if (gui_app) gcc_argv[i++] = "-lcomdlg32";
@ -175,13 +291,7 @@ int main(int argc, char **argv)
gcc_argv[i] = NULL; gcc_argv[i] = NULL;
if (verbose) spawn(gcc_argv);
{
for (i = 0; gcc_argv[i]; i++) printf("%s ", gcc_argv[i]);
printf("\n");
}
execvp(gcc_argv[0], gcc_argv); return 0;
return 1;
} }