winewrap
Dimitrie O. Paun
dpaun at rogers.com
Thu Dec 12 12:58:03 CST 2002
ChangeLog
New wine build utility that should make it easy for Winelib
apps to link, and generate an executable.
Index: tools/Makefile.in
===================================================================
RCS file: /var/cvs/wine/tools/Makefile.in,v
retrieving revision 1.27
diff -u -r1.27 Makefile.in
--- tools/Makefile.in 6 Dec 2002 23:22:39 -0000 1.27
+++ tools/Makefile.in 12 Dec 2002 18:54:51 -0000
@@ -9,13 +9,15 @@
bin2res \
fnt2bdf \
makedep \
- mingwrap
+ mingwrap \
+ winewrap
C_SRCS = \
bin2res.c \
fnt2bdf.c \
makedep.c \
- mingwrap.c
+ mingwrap.c \
+ winewrap.c
SUBDIRS = \
widl \
@@ -49,13 +51,17 @@
mingwrap: mingwrap.o
$(CC) $(CFLAGS) -o mingwrap mingwrap.o
+winewrap: winewrap.o
+ $(CC) $(CFLAGS) -o winewrap winewrap.o
+
install::
$(MKINSTALLDIRS) $(bindir) $(mandir)/man$(prog_manext)
$(INSTALL_SCRIPT) $(SRCDIR)/winemaker $(bindir)/winemaker
$(INSTALL_PROGRAM) mingwrap $(bindir)/mingwrap
+ $(INSTALL_PROGRAM) winewrap $(bindir)/winewrap
$(INSTALL_DATA) $(SRCDIR)/winemaker.man $(mandir)/man$(prog_manext)/winemaker.$(prog_manext)
uninstall::
- $(RM) $(bindir)/winemaker $(bindir)/mingwrap $(mandir)/man$(prog_manext)/winemaker.$(prog_manext)
+ $(RM) $(bindir)/winemaker $(bindir)/mingwrap $(bindir)/winewrap $(mandir)/man$(prog_manext)/winemaker.$(prog_manext)
### Dependencies:
--- /dev/null 2002-08-30 19:31:37.000000000 -0400
+++ tools/winewrap.c 2002-12-12 13:52:49.000000000 -0500
@@ -0,0 +1,261 @@
+/*
+ * Wine wrapper: takes care of internal details for linking.
+ *
+ * Copyright 2002 Dimitrie O. Paun
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifndef WINEDLLS
+#define WINEDLLS "/usr/local/lib/wine"
+#endif
+
+static const char *app_loader_script =
+ "#!/bin/sh\n"
+ "\n"
+ "appname=\"%s\"\n"
+ "# determine the application directory\n"
+ "appdir=''\n"
+ "case \"$0\" in\n"
+ " */*)\n"
+ " # $0 contains a path, use it\n"
+ " appdir=`dirname \"$0\"`\n"
+ " ;;\n"
+ " *)\n"
+ " # no directory in $0, search in PATH\n"
+ " saved_ifs=$IFS\n"
+ " IFS=:\n"
+ " for d in $PATH\n"
+ " do\n"
+ " IFS=$saved_ifs\n"
+ " if [ -x \"$d/$appname\" ]; then appdir=\"$d\"; break; fi\n"
+ " done\n"
+ " ;;\n"
+ "esac\n"
+ "\n"
+ "# figure out the full app path\n"
+ "if [ -n \"$appdir\" ]; then\n"
+ " apppath=\"$appdir/$appname.exe.so\"\n"
+ "else\n"
+ " apppath=\"$appname.exe.so\"\n"
+ "fi\n"
+ "\n"
+ "# determine the WINELOADER\n"
+ "if ! [ -x \"$WINELOADER\" ]; then WINELOADER=\"wine\"; fi\n"
+ "\n"
+ "# and try to start the app\n"
+ "exec \"$WINELOADER\" \"$apppath\" \"$@\"\n"
+;
+
+static char *output_name;
+static char **lib_files, **obj_files;
+static int nb_lib_files, nb_obj_files;
+static int debug = 1;
+
+void error(const char *s, ...)
+{
+ va_list ap;
+
+ va_start(ap, s);
+ fprintf(stderr, "Error: ");
+ vfprintf(stderr, s, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ exit(2);
+}
+
+
+char *strmake(const char *fmt, ...)
+{
+ int n, size = 100;
+ char *p;
+ va_list ap;
+
+ if ((p = malloc (size)) == NULL) return NULL;
+
+ while (1)
+ {
+ va_start(ap, fmt);
+ n = vsnprintf (p, size, fmt, ap);
+ va_end(ap);
+ if (n > -1 && n < size) return p;
+ if (n > -1) size *= 2;
+ if ((p = realloc (p, size)) == NULL) return NULL;
+ }
+}
+
+void spawn(char *const argv[])
+{
+ int pid, status, i;
+
+ if (debug)
+ {
+ for(i = 0; argv[i]; i++) printf("%s ", argv[i]);
+ printf("\n");
+ }
+
+ if ((pid = fork()) == 0) execvp(argv[0], argv);
+ else if (wait(&status) > 0)
+ {
+ if (WEXITSTATUS(status) == 0) return;
+ else error("%s failed.", argv[0]);
+ }
+ perror("Error:");
+ exit(1);
+}
+
+int is_resource(const char* file)
+{
+ /* see tools/winebuild/res32.c: check_header for details */
+ static const char res_sig[] = { 0,0,0,0, 32,0,0,0, 0xff,0xff, 0,0, 0xff,0xff, 0,0, 0,0,0,0, 0,0, 0,0, 0,0,0,0, 0,0,0,0 };
+ char buf[sizeof(res_sig)];
+ FILE *fin;
+
+ if (!(fin = fopen(file, "r"))) error("Can not open %s", file);
+ if (fread(buf, sizeof(buf), 1, fin) != 1) error("Truncated file %s", file);
+ fclose(fin);
+
+ return !memcmp(buf, res_sig, sizeof(buf));
+}
+
+int main(int argc, char **argv)
+{
+ char *library = 0, *p;
+ int i, j, no_opt = 0, gui_mode = 0;
+ char *spec_name, *spec_c_name, *spec_o_name;
+ char **spec_args, **comp_args, **link_args;
+ FILE *file;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (!no_opt && argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'o':
+ if (argv[i][2]) output_name = strdup(argv[i]+ 2);
+ else if (i + 1 < argc) output_name = strdup(argv[++i]);
+ else error("The -o switch takes an argument.");
+ if ( !(p = strstr(output_name, ".exe")) || *(p+4) )
+ output_name = strmake("%s.exe", output_name);
+ break;
+ case 'l':
+ if (argv[i][2]) library = argv[i]+ 2;
+ else if (i + 1 < argc) library = argv[++i];
+ else error("The -l switch takes an argument\n.");
+ if (strcmp(library, "winspool") == 0) library = "winspool.drv";
+ lib_files = realloc( lib_files, (nb_lib_files+1) * sizeof(*lib_files) );
+ lib_files[nb_lib_files++] = strdup(library);
+ break;
+ case 'm':
+ if (strcmp("-mwindows", argv[i]) == 0) gui_mode = 1;
+ else error("Unknown option %s\n", argv[i]);
+ case '-':
+ if (argv[i][2]) error("No long option supported.");
+ no_opt = 1;
+ break;
+ default:
+ error("Unknown option -%c", argv[i][1]);
+ }
+ continue;
+ }
+
+ /* it's a filename, add it to its list */
+ obj_files = realloc( obj_files, (nb_obj_files+1) * sizeof(*obj_files) );
+ obj_files[nb_obj_files++] = strdup(argv[i]);
+ }
+
+ spec_name = tempnam(0, 0);
+ spec_c_name = strmake("%s.c", spec_name);
+ spec_o_name = strmake("%s.o", spec_name);
+
+ /* build winebuild's argument list */
+ spec_args = malloc( (nb_lib_files + nb_obj_files + 20) * sizeof (char *) );
+ j = 0;
+ spec_args[j++] = "winebuild";
+ spec_args[j++] = "-fPIC";
+ spec_args[j++] = "-o";
+ spec_args[j++] = strmake("%s.c", spec_name);
+ spec_args[j++] = "--exe";
+ spec_args[j++] = output_name;
+ spec_args[j++] = "-m";
+ spec_args[j++] = gui_mode ? "gui" : "cui";
+ for (i = 0; i < nb_obj_files; i++)
+ spec_args[j++] = obj_files[i];
+ spec_args[j++] = "-L" WINEDLLS;
+ for (i = 0; i < nb_lib_files; i++)
+ spec_args[j++] = strmake("-l%s", lib_files[i]);
+ spec_args[j++] = "-lmsvcrt";
+ spec_args[j] = 0;
+
+ /* build gcc's argument list */
+ comp_args = malloc (20 * sizeof (char *) );
+ j = 0;
+ comp_args[j++] = "gcc";
+ comp_args[j++] = "-fPIC";
+ comp_args[j++] = "-o";
+ comp_args[j++] = spec_o_name;
+ comp_args[j++] = "-c";
+ comp_args[j++] = spec_c_name;
+
+ /* build ld's argument list */
+ link_args = malloc( (nb_obj_files + 20) * sizeof (char *) );
+ j = 0;
+ link_args[j++] = "gcc";
+ link_args[j++] = "-shared";
+ link_args[j++] = "-Wl,-Bsymbolic";
+ link_args[j++] = "-lwine";
+ link_args[j++] = "-lm";
+ link_args[j++] = "-o";
+ link_args[j++] = strmake("%s.so", output_name);
+ link_args[j++] = spec_o_name;
+ for (i = 0; i < nb_obj_files; i++)
+ if (!is_resource(obj_files[i])) link_args[j++] = obj_files[i];
+ link_args[j] = 0;
+
+ /* run winebuild to get the .spec.c file */
+ spawn(spec_args);
+
+ /* compile the .spec.c file */
+ spawn(comp_args);
+ unlink(spec_c_name);
+
+ /* run gcc to link */
+ spawn(link_args);
+ unlink(spec_o_name);
+
+ /* create the loader script */
+ output_name[strlen(output_name) - 4] = 0; /* remove the .exe extension */
+ if ( !(file = fopen(output_name, "w")) )
+ error ("Can not create %s.", output_name);
+ fprintf(file, app_loader_script, output_name);
+ fclose(file);
+ chmod(output_name, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH);
+
+ return 0;
+}
--
Dimi.
More information about the wine-patches
mailing list