Commit e482eebf authored by Alexandre Julliard's avatar Alexandre Julliard

Split the build program in several files.

Renamed it 'winebuild' to avoid possible conflicts. Cleaned up command-line parsing. Make it understand -fPIC instead of -pic. Merged call16.s and call32.s generated files.
parent 22752323
......@@ -54,7 +54,7 @@ LINT = @LINT@
LINTFLAGS = @LINTFLAGS@
ALLLINTFLAGS = $(LINTFLAGS) $(DEFS) $(OPTIONS) $(DIVINCL)
WINAPI_CHECK = $(TOPSRCDIR)/tools/winapi_check/winapi_check
BUILD = $(TOPOBJDIR)/tools/build
BUILD = $(TOPOBJDIR)/tools/winebuild/winebuild
MAKEDEP = $(TOPOBJDIR)/tools/makedep
WRC = $(TOPOBJDIR)/tools/wrc/wrc
WRCFLAGS = -c -s -p $*
......@@ -183,10 +183,10 @@ DLLS = \
$(WRC) $(WRCFLAGS) $(WRCEXTRA) -bnh $<
.spec.spec.c:
$(BUILD) @BUILDFLAGS@ -o $@ -spec $<
$(BUILD) @DLLFLAGS@ -o $@ -spec $<
.c.glue.c:
$(BUILD) @BUILDFLAGS@ -o $@ -glue $<
$(BUILD) @DLLFLAGS@ -o $@ -glue $<
.c.ln:
$(LINT) -c $(ALLLINTFLAGS) $< || ( $(RM) $@ && exit 1 )
......@@ -212,10 +212,10 @@ $(WMC) check_wmc:
$(MAKEDEP) check_makedep:
cd $(TOPOBJDIR)/tools && $(MAKE) makedep
# Rule to rebuild the 'build' program
# Rule to rebuild the 'winebuild' program
$(BUILD) checkbuild:
cd $(TOPOBJDIR)/tools && $(MAKE) build
$(BUILD) check_winebuild:
cd $(TOPOBJDIR)/tools/winebuild && $(MAKE) winebuild
# Rule for main module
......
......@@ -493,10 +493,8 @@ then
fi
DLLFLAGS=""
BUILDFLAGS=""
if test "$LIBEXT" = "so"; then
BUILDFLAGS="-pic"
DLLFLAGS="-fPIC"
DLL_LINK="-L\$(DLLDIR) \$(IMPORTS:%=-l%) -L\$(TOPOBJDIR) -lwine"
else
......@@ -527,7 +525,6 @@ else
fi
AC_SUBST(DLL_LINK)
AC_SUBST(BUILDFLAGS)
AC_SUBST(DLLFLAGS)
AC_SUBST(LDSHARED)
AC_SUBST(LIBEXT)
......@@ -1083,6 +1080,7 @@ scheduler/Makefile
server/Makefile
tools/Makefile
tools/cvdump/Makefile
tools/winebuild/Makefile
tools/wrc/Makefile
tools/wmc/Makefile
tsx11/Makefile
......
Makefile
call16.s
asmrelay.s
thunk.glue.c
......@@ -13,7 +13,7 @@ C_SRCS = \
thunk.c
GEN_ASM_SRCS = \
call16.s
asmrelay.s
GLUE = thunk.c
......@@ -21,7 +21,7 @@ all: $(MODULE).o
@MAKE_RULES@
call16.s: $(BUILD)
$(BUILD) @BUILDFLAGS@ -o $@ -call16
asmrelay.s: $(BUILD)
$(BUILD) @DLLFLAGS@ -o $@ -relay
### Dependencies:
......@@ -12,14 +12,8 @@ C_SRCS = \
utthunk.c \
wowthunk.c
GEN_ASM_SRCS = \
call32.s
all: $(MODULE).o
@MAKE_RULES@
call32.s: $(BUILD)
$(BUILD) @BUILDFLAGS@ -o $@ -call32
### Dependencies:
Makefile
bin2res
build
fnt2bdf
makedep
......@@ -4,17 +4,19 @@ TOPOBJDIR = ..
SRCDIR = @srcdir@
VPATH = @srcdir@
PROGRAMS = build makedep fnt2bdf bin2res
PROGRAMS = makedep fnt2bdf bin2res
MODULE = none
C_SRCS = build.c makedep.c fnt2bdf.c bin2res.c
C_SRCS = makedep.c fnt2bdf.c bin2res.c
SUBDIRS = \
cvdump \
winebuild \
wmc \
wrc
INSTALLSUBDIRS = \
winebuild \
wmc \
wrc
......@@ -24,13 +26,10 @@ EXTRASUBDIRS = \
winapi_check/win32 \
wineconf.libs
all: $(PROGRAMS) wmc wrc
all: $(PROGRAMS) winebuild wmc wrc
@MAKE_RULES@
build: build.o
$(CC) $(CFLAGS) -o build build.o
makedep: makedep.o
$(CC) $(CFLAGS) -o makedep makedep.o
......@@ -42,10 +41,9 @@ bin2res: bin2res.o
install:: $(PROGRAMS) $(INSTALLSUBDIRS:%=%/__install__)
[ -d $(bindir) ] || $(MKDIR) $(bindir)
$(INSTALL_PROGRAM) build $(bindir)/winebuild
$(INSTALL_PROGRAM) fnt2bdf $(bindir)/fnt2bdf
uninstall:: $(PROGRAMS) $(INSTALLSUBDIRS:%=%/__uninstall__)
$(RM) $(bindir)/winebuild $(bindir)/fnt2bdf
$(RM) $(bindir)/fnt2bdf
### Dependencies:
This source diff could not be displayed because it is too large. You can view the blob instead.
DEFS = -D__WINE__
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
PROGRAMS = winebuild
MODULE = none
C_SRCS = \
main.c \
parser.c \
relay.c \
spec16.c \
spec32.c \
utils.c
all: $(PROGRAMS)
@MAKE_RULES@
winebuild: $(OBJS)
$(CC) $(CFLAGS) -o winebuild $(OBJS)
install:: $(PROGRAMS)
[ -d $(bindir) ] || $(MKDIR) $(bindir)
$(INSTALL_PROGRAM) winebuild $(bindir)/winebuild
uninstall::
$(RM) $(bindir)/winebuild
### Dependencies:
......@@ -4,10 +4,11 @@
name NAME
type win16|win32
[file WINFILENAME]
[base ORDINAL]
[mode dll|cuiexe|guiexe]
[heap SIZE]
[init FUNCTION]
[import DLL]
[rsrc PREFIX]
ORDINAL VARTYPE EXPORTNAME (DATA [DATA [DATA [...]]])
......@@ -31,7 +32,8 @@ General:
declarations are optional, but the default handler will print an error
message.
"base" gives the offset of the first ordinal; default is 0.
"mode" specifies whether it is the spec file for a dll or the main exe.
This is only valid for Win32 spec files.
"heap" is the size of the module local heap (only valid for Win16
modules); default is no local heap.
......@@ -47,6 +49,8 @@ is loaded. This is only valid for Win32 modules.
modules at the present). The import declaration can be present several
times.
"rsrc" specifies the prefix for the resource directory name.
Lines whose first character is a '#' will be ignored as comments.
......
/*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Martin von Loewis
* Copyright 1995, 1996, 1997 Alexandre Julliard
* Copyright 1997 Eric Youngdale
* Copyright 1999 Ulrich Weigand
*/
#ifndef __WINE_BUILD_H
#define __WINE_BUILD_H
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef NEED_UNDERSCORE_PREFIX
# define PREFIX "_"
#else
# define PREFIX
#endif
#ifdef HAVE_ASM_STRING
# define STRING ".string"
#else
# define STRING ".ascii"
#endif
#if defined(__GNUC__) && !defined(__svr4__)
# define USE_STABS
#else
# undef USE_STABS
#endif
typedef enum
{
TYPE_BYTE, /* byte variable (Win16) */
TYPE_WORD, /* word variable (Win16) */
TYPE_LONG, /* long variable (Win16) */
TYPE_PASCAL_16, /* pascal function with 16-bit return (Win16) */
TYPE_PASCAL, /* pascal function with 32-bit return (Win16) */
TYPE_ABS, /* absolute value (Win16) */
TYPE_REGISTER, /* register function */
TYPE_INTERRUPT, /* interrupt handler function (Win16) */
TYPE_STUB, /* unimplemented stub */
TYPE_STDCALL, /* stdcall function (Win32) */
TYPE_CDECL, /* cdecl function (Win32) */
TYPE_VARARGS, /* varargs function (Win32) */
TYPE_EXTERN, /* external symbol (Win32) */
TYPE_FORWARD, /* forwarded function (Win32) */
TYPE_NBTYPES
} ORD_TYPE;
typedef enum
{
SPEC_INVALID,
SPEC_WIN16,
SPEC_WIN32
} SPEC_TYPE;
typedef enum
{
SPEC_MODE_DLL,
SPEC_MODE_GUIEXE,
SPEC_MODE_CUIEXE
} SPEC_MODE;
typedef struct
{
int n_values;
int *values;
} ORD_VARIABLE;
typedef struct
{
int n_args;
char arg_types[32];
char link_name[80];
} ORD_FUNCTION;
typedef struct
{
int value;
} ORD_ABS;
typedef struct
{
char link_name[80];
} ORD_EXTERN;
typedef struct
{
char link_name[80];
} ORD_FORWARD;
typedef struct
{
ORD_TYPE type;
int ordinal;
int offset;
int lineno;
char name[80];
union
{
ORD_VARIABLE var;
ORD_FUNCTION func;
ORD_ABS abs;
ORD_EXTERN ext;
ORD_FORWARD fwd;
} u;
} ORDDEF;
/* Offset of a structure field relative to the start of the struct */
#define STRUCTOFFSET(type,field) ((int)&((type *)0)->field)
/* Offset of register relative to the start of the CONTEXT struct */
#define CONTEXTOFFSET(reg) STRUCTOFFSET(CONTEXT86,reg)
/* Offset of register relative to the start of the STACK16FRAME struct */
#define STACK16OFFSET(reg) STRUCTOFFSET(STACK16FRAME,reg)
/* Offset of register relative to the start of the STACK32FRAME struct */
#define STACK32OFFSET(reg) STRUCTOFFSET(STACK32FRAME,reg)
/* Offset of the stack pointer relative to %fs:(0) */
#define STACKOFFSET (STRUCTOFFSET(TEB,cur_stack))
#define MAX_ORDINALS 2048
#define MAX_IMPORTS 16
/* global functions */
extern void *xmalloc (size_t size);
extern void *xrealloc (void *ptr, size_t size);
extern char *xstrdup( const char *str );
extern char *strupper(char *s);
extern void fatal_error( const char *msg, ... );
extern void dump_bytes( FILE *outfile, const unsigned char *data, int len, const char *label );
extern void BuildGlue( FILE *outfile, FILE *infile );
extern void BuildRelays( FILE *outfile );
extern void BuildSpec16File( FILE *outfile );
extern void BuildSpec32File( FILE *outfile );
extern SPEC_TYPE ParseTopLevel( FILE *file );
/* global variables */
extern int current_line;
extern int nb_entry_points;
extern int nb_names;
extern int nb_imports;
extern int Base;
extern int Limit;
extern int DLLHeapSize;
extern int UsePIC;
extern int debugging;
extern unsigned short code_selector;
extern unsigned short data_selector;
extern char DLLName[80];
extern char DLLFileName[80];
extern char DLLInitFunc[80];
extern char rsrc_name[80];
extern char *DLLImports[MAX_IMPORTS];
extern const char *input_file_name;
extern const char *output_file_name;
extern ORDDEF EntryPoints[MAX_ORDINALS];
extern ORDDEF *Ordinals[MAX_ORDINALS];
extern ORDDEF *Names[MAX_ORDINALS];
extern SPEC_MODE SpecMode;
#endif /* __WINE_BUILD_H */
/*
* Main function
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Martin von Loewis
* Copyright 1995, 1996, 1997 Alexandre Julliard
* Copyright 1997 Eric Youngdale
* Copyright 1999 Ulrich Weigand
*/
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include "winnt.h"
#include "build.h"
#ifdef __i386__
extern WORD __get_cs(void);
extern WORD __get_ds(void);
__ASM_GLOBAL_FUNC( __get_cs, "movw %cs,%ax\n\tret" );
__ASM_GLOBAL_FUNC( __get_ds, "movw %ds,%ax\n\tret" );
#else
static inline WORD __get_cs(void) { return 0; }
static inline WORD __get_ds(void) { return 0; }
#endif
ORDDEF EntryPoints[MAX_ORDINALS];
ORDDEF *Ordinals[MAX_ORDINALS];
ORDDEF *Names[MAX_ORDINALS];
SPEC_MODE SpecMode = SPEC_MODE_DLL;
int Base = MAX_ORDINALS;
int Limit = 0;
int DLLHeapSize = 0;
int UsePIC = 0;
int nb_entry_points = 0;
int nb_names = 0;
int nb_imports = 0;
int debugging = 1;
char DLLName[80];
char DLLFileName[80];
char DLLInitFunc[80];
char *DLLImports[MAX_IMPORTS];
char rsrc_name[80];
const char *input_file_name;
const char *output_file_name;
unsigned short code_selector;
unsigned short data_selector;
static FILE *input_file;
static FILE *output_file;
/* execution mode */
static enum { MODE_NONE, MODE_SPEC, MODE_GLUE, MODE_RELAY } exec_mode = MODE_NONE;
/* open the input file */
static void open_input( const char *name )
{
input_file_name = name;
if (!(input_file = fopen( name, "r" )))
{
fprintf( stderr, "Cannot open input file '%s'\n", name );
exit(1);
}
}
/* cleanup on program exit */
static void cleanup(void)
{
if (output_file_name) unlink( output_file_name );
}
/*******************************************************************
* command-line option handling
*/
struct option
{
const char *name;
int has_arg;
void (*func)();
const char *usage;
};
static void do_pic(void);
static void do_output( const char *arg );
static void do_usage(void);
static void do_spec( const char *arg );
static void do_glue( const char *arg );
static void do_relay(void);
static const struct option option_table[] =
{
{ "-fPIC", 0, do_pic, "-fPIC Generate PIC code" },
{ "-h", 0, do_usage, "-h Display this help message" },
{ "-o", 1, do_output, "-o name Set the output file name (default: stdout)" },
{ "-spec", 1, do_spec, "-spec file.spec Build a .c file from a spec file" },
{ "-glue", 1, do_glue, "-glue file.c Build the 16-bit glue for a .c file" },
{ "-relay", 0, do_relay, "-relay Build the relay assembly routines" },
{ NULL }
};
static void do_pic(void)
{
UsePIC = 1;
}
static void do_output( const char *arg )
{
if (!(output_file = fopen( arg, "w" )))
{
fprintf( stderr, "Unable to create output file '%s'\n", arg );
exit(1);
}
output_file_name = arg;
atexit( cleanup ); /* make sure we remove the output file on exit */
}
static void do_usage(void)
{
const struct option *opt;
fprintf( stderr, "Usage: winebuild [options]\n\n" );
fprintf( stderr, "Options:\n" );
for (opt = option_table; opt->name; opt++) fprintf( stderr, " %s\n", opt->usage );
fprintf( stderr, "\nExactly one of -spec, -glue or -relay must be specified.\n\n" );
exit(1);
}
static void do_spec( const char *arg )
{
if (exec_mode != MODE_NONE || !arg[0]) do_usage();
exec_mode = MODE_SPEC;
open_input( arg );
}
static void do_glue( const char *arg )
{
if (exec_mode != MODE_NONE || !arg[0]) do_usage();
exec_mode = MODE_GLUE;
open_input( arg );
}
static void do_relay(void)
{
if (exec_mode != MODE_NONE) do_usage();
exec_mode = MODE_RELAY;
}
/* parse options from the argv array and remove all the recognized ones */
static void parse_options( char *argv[] )
{
const struct option *opt;
int i;
for (i = 1; argv[i]; i++)
{
for (opt = option_table; opt->name; opt++)
if (!strcmp( argv[i], opt->name )) break;
if (!opt->name)
{
fprintf( stderr, "Unrecognized option '%s'\n", argv[i] );
do_usage();
}
if (opt->has_arg && argv[i+1]) opt->func( argv[++i] );
else opt->func( "" );
}
}
/*******************************************************************
* main
*/
int main(int argc, char **argv)
{
output_file = stdout;
parse_options( argv );
/* Retrieve the selector values; this assumes that we are building
* the asm files on the platform that will also run them. Probably
* a safe assumption to make.
*/
code_selector = __get_cs();
data_selector = __get_ds();
switch(exec_mode)
{
case MODE_SPEC:
switch (ParseTopLevel( input_file ))
{
case SPEC_WIN16:
BuildSpec16File( output_file );
break;
case SPEC_WIN32:
BuildSpec32File( output_file );
break;
default: assert(0);
}
break;
case MODE_GLUE:
BuildGlue( output_file, input_file );
break;
case MODE_RELAY:
BuildRelays( output_file );
break;
default:
do_usage();
break;
}
fclose( output_file );
output_file_name = NULL;
return 0;
}
/* small utility functions for winebuild */
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "build.h"
void *xmalloc (size_t size)
{
void *res;
res = malloc (size ? size : 1);
if (res == NULL)
{
fprintf (stderr, "Virtual memory exhausted.\n");
exit (1);
}
return res;
}
void *xrealloc (void *ptr, size_t size)
{
void *res = realloc (ptr, size);
if (res == NULL)
{
fprintf (stderr, "Virtual memory exhausted.\n");
exit (1);
}
return res;
}
char *xstrdup( const char *str )
{
char *res = strdup( str );
if (!res)
{
fprintf (stderr, "Virtual memory exhausted.\n");
exit (1);
}
return res;
}
char *strupper(char *s)
{
char *p;
for (p = s; *p; p++) *p = toupper(*p);
return s;
}
void fatal_error( const char *msg, ... )
{
va_list valist;
va_start( valist, msg );
if (input_file_name && current_line)
fprintf( stderr, "%s:%d: ", input_file_name, current_line );
vfprintf( stderr, msg, valist );
va_end( valist );
exit(1);
}
/* dump a byte stream into the assembly code */
void dump_bytes( FILE *outfile, const unsigned char *data, int len, const char *label )
{
int i;
fprintf( outfile, "\nstatic unsigned char %s[] = \n{", label );
for (i = 0; i < len; i++)
{
if (!(i & 0x0f)) fprintf( outfile, "\n " );
fprintf( outfile, "%d", *data++ );
if (i < len - 1) fprintf( outfile, ", " );
}
fprintf( outfile, "\n};\n" );
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment