Now that we have to be able to run the assembler from winebuild, added
an option to generate a .spec.o file in a single step. Added --save-temps and --verbose options for easier debugging.
This commit is contained in:
parent
7d7da60db4
commit
5173234ea8
|
@ -177,6 +177,7 @@ extern void close_input_file( FILE *file );
|
|||
extern void dump_bytes( FILE *outfile, const unsigned char *data, int len,
|
||||
const char *label, int constant );
|
||||
extern int remove_stdcall_decoration( char *name );
|
||||
extern void assemble_file( const char *src_file, const char *obj_file );
|
||||
extern DLLSPEC *alloc_dll_spec(void);
|
||||
extern void free_dll_spec( DLLSPEC *spec );
|
||||
extern int has_stubs( const DLLSPEC *spec );
|
||||
|
@ -233,6 +234,8 @@ extern int nb_lib_paths;
|
|||
extern int nb_errors;
|
||||
extern int display_warnings;
|
||||
extern int kill_at;
|
||||
extern int verbose;
|
||||
extern int save_temps;
|
||||
|
||||
extern char *input_file_name;
|
||||
extern char *spec_file_name;
|
||||
|
|
|
@ -505,12 +505,9 @@ static void check_undefined_exports( DLLSPEC *spec )
|
|||
/* create a .o file that references all the undefined symbols we want to resolve */
|
||||
static char *create_undef_symbols_file( DLLSPEC *spec )
|
||||
{
|
||||
char *cmd, *as_file, *obj_file;
|
||||
char *as_file, *obj_file;
|
||||
unsigned int i;
|
||||
FILE *f;
|
||||
int err;
|
||||
|
||||
if (!as_command) as_command = xstrdup("as");
|
||||
|
||||
as_file = get_temp_file_name( output_file_name, ".s" );
|
||||
if (!(f = fopen( as_file, "w" ))) fatal_error( "Cannot create %s\n", as_file );
|
||||
|
@ -528,11 +525,7 @@ static char *create_undef_symbols_file( DLLSPEC *spec )
|
|||
fclose( f );
|
||||
|
||||
obj_file = get_temp_file_name( output_file_name, ".o" );
|
||||
cmd = xmalloc( strlen(as_command) + strlen(obj_file) + strlen(as_file) + 6 );
|
||||
sprintf( cmd, "%s -o %s %s", as_command, obj_file, as_file );
|
||||
err = system( cmd );
|
||||
if (err) fatal_error( "%s failed with status %d\n", as_command, err );
|
||||
free( cmd );
|
||||
assemble_file( as_file, obj_file );
|
||||
return obj_file;
|
||||
}
|
||||
|
||||
|
@ -553,6 +546,7 @@ static const char *ldcombine_files( DLLSPEC *spec, char **argv )
|
|||
p += sprintf( cmd, "%s -r -o %s %s", ld_command, ld_tmp_file, undef_file );
|
||||
for (i = 0; argv[i]; i++)
|
||||
p += sprintf( p, " %s", argv[i] );
|
||||
if (verbose) fprintf( stderr, "%s\n", cmd );
|
||||
err = system( cmd );
|
||||
if (err) fatal_error( "%s -r failed with status %d\n", ld_command, err );
|
||||
free( cmd );
|
||||
|
|
|
@ -46,6 +46,8 @@ int nb_lib_paths = 0;
|
|||
int nb_errors = 0;
|
||||
int display_warnings = 0;
|
||||
int kill_at = 0;
|
||||
int verbose = 0;
|
||||
int save_temps = 0;
|
||||
|
||||
#ifdef __i386__
|
||||
enum target_cpu target_cpu = CPU_x86;
|
||||
|
@ -77,6 +79,7 @@ char **lib_path = NULL;
|
|||
char *input_file_name = NULL;
|
||||
char *spec_file_name = NULL;
|
||||
const char *output_file_name = NULL;
|
||||
static const char *output_file_source_name;
|
||||
|
||||
char *as_command = NULL;
|
||||
char *ld_command = NULL;
|
||||
|
@ -266,9 +269,11 @@ static const char usage_str[] =
|
|||
" -N, --dll-name=DLLNAME Set the DLL name (default: from input file name)\n"
|
||||
" -o, --output=NAME Set the output file name (default: stdout)\n"
|
||||
" -r, --res=RSRC.RES Load resources from RSRC.RES\n"
|
||||
" --save-temps Do not delete the generated intermediate files\n"
|
||||
" --subsystem=SUBSYS Set the subsystem (one of native, windows, console)\n"
|
||||
" --target=TARGET Specify target CPU and platform for cross-compiling\n"
|
||||
" -u, --undefined=SYMBOL Add an undefined reference to SYMBOL when linking\n"
|
||||
" -v, --verbose Display the programs invoked\n"
|
||||
" --version Print the version and exit\n"
|
||||
" -w, --warnings Turn on warnings\n"
|
||||
"\nMode options:\n"
|
||||
|
@ -291,12 +296,13 @@ enum long_options_values
|
|||
LONG_OPT_NMCMD,
|
||||
LONG_OPT_RELAY16,
|
||||
LONG_OPT_RELAY32,
|
||||
LONG_OPT_SAVE_TEMPS,
|
||||
LONG_OPT_SUBSYSTEM,
|
||||
LONG_OPT_TARGET,
|
||||
LONG_OPT_VERSION
|
||||
};
|
||||
|
||||
static const char short_options[] = "C:D:E:F:H:I:K:L:M:N:d:e:f:hi:kl:m:o:r:u:w";
|
||||
static const char short_options[] = "C:D:E:F:H:I:K:L:M:N:d:e:f:hi:kl:m:o:r:u:vw";
|
||||
|
||||
static const struct option long_options[] =
|
||||
{
|
||||
|
@ -309,6 +315,7 @@ static const struct option long_options[] =
|
|||
{ "nm-cmd", 1, 0, LONG_OPT_NMCMD },
|
||||
{ "relay16", 0, 0, LONG_OPT_RELAY16 },
|
||||
{ "relay32", 0, 0, LONG_OPT_RELAY32 },
|
||||
{ "save-temps",0, 0, LONG_OPT_SAVE_TEMPS },
|
||||
{ "subsystem",1, 0, LONG_OPT_SUBSYSTEM },
|
||||
{ "target", 1, 0, LONG_OPT_TARGET },
|
||||
{ "version", 0, 0, LONG_OPT_VERSION },
|
||||
|
@ -329,6 +336,7 @@ static const struct option long_options[] =
|
|||
{ "output", 1, 0, 'o' },
|
||||
{ "res", 1, 0, 'r' },
|
||||
{ "undefined", 1, 0, 'u' },
|
||||
{ "verbose", 0, 0, 'v' },
|
||||
{ "warnings", 0, 0, 'w' },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
@ -424,12 +432,25 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )
|
|||
add_import_dll( optarg, NULL );
|
||||
break;
|
||||
case 'o':
|
||||
if (unlink( optarg ) == -1 && errno != ENOENT)
|
||||
fatal_error( "Unable to create output file '%s'\n", optarg );
|
||||
if (!(output_file = fopen( optarg, "w" )))
|
||||
fatal_error( "Unable to create output file '%s'\n", optarg );
|
||||
output_file_name = xstrdup(optarg);
|
||||
atexit( cleanup ); /* make sure we remove the output file on exit */
|
||||
{
|
||||
char *ext = strrchr( optarg, '.' );
|
||||
|
||||
if (unlink( optarg ) == -1 && errno != ENOENT)
|
||||
fatal_error( "Unable to create output file '%s'\n", optarg );
|
||||
if (ext && !strcmp( ext, ".o" ))
|
||||
{
|
||||
output_file_source_name = get_temp_file_name( optarg, ".s" );
|
||||
if (!(output_file = fopen( output_file_source_name, "w" )))
|
||||
fatal_error( "Unable to create output file '%s'\n", optarg );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(output_file = fopen( optarg, "w" )))
|
||||
fatal_error( "Unable to create output file '%s'\n", optarg );
|
||||
}
|
||||
output_file_name = xstrdup(optarg);
|
||||
atexit( cleanup ); /* make sure we remove the output file on exit */
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
res_files = xrealloc( res_files, (nb_res_files+1) * sizeof(*res_files) );
|
||||
|
@ -438,6 +459,9 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )
|
|||
case 'u':
|
||||
add_extra_ld_symbol( optarg );
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'w':
|
||||
display_warnings = 1;
|
||||
break;
|
||||
|
@ -469,6 +493,9 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )
|
|||
case LONG_OPT_RELAY32:
|
||||
set_exec_mode( MODE_RELAY32 );
|
||||
break;
|
||||
case LONG_OPT_SAVE_TEMPS:
|
||||
save_temps = 1;
|
||||
break;
|
||||
case LONG_OPT_SUBSYSTEM:
|
||||
set_subsystem( optarg, spec );
|
||||
break;
|
||||
|
@ -624,6 +651,7 @@ int main(int argc, char **argv)
|
|||
if (output_file_name)
|
||||
{
|
||||
fclose( output_file );
|
||||
if (output_file_source_name) assemble_file( output_file_source_name, output_file_name );
|
||||
output_file_name = NULL;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -166,22 +166,27 @@ void warning( const char *msg, ... )
|
|||
char *get_temp_file_name( const char *prefix, const char *suffix )
|
||||
{
|
||||
char *name;
|
||||
const char *ext;
|
||||
int fd;
|
||||
|
||||
assert( nb_tmp_files < MAX_TMP_FILES );
|
||||
if (!nb_tmp_files) atexit( cleanup_tmp_files );
|
||||
if (!nb_tmp_files && !save_temps) atexit( cleanup_tmp_files );
|
||||
|
||||
if (!prefix || !prefix[0]) prefix = "winebuild.tmp";
|
||||
if (!prefix || !prefix[0]) prefix = "winebuild";
|
||||
if (!suffix) suffix = "";
|
||||
name = xmalloc( strlen(prefix) + strlen(suffix) + sizeof("/tmp/.XXXXXX") );
|
||||
sprintf( name, "%s.XXXXXX%s", prefix, suffix );
|
||||
if (!(ext = strchr( prefix, '.' ))) ext = prefix + strlen(prefix);
|
||||
name = xmalloc( sizeof("/tmp/") + (ext - prefix) + sizeof(".XXXXXX") + strlen(suffix) );
|
||||
strcpy( name, "/tmp/" );
|
||||
memcpy( name + 5, prefix, ext - prefix );
|
||||
strcpy( name + 5 + (ext - prefix), ".XXXXXX" );
|
||||
strcat( name, suffix );
|
||||
|
||||
/* first try without the /tmp/ prefix */
|
||||
if ((fd = mkstemps( name + 5, strlen(suffix) )) != -1)
|
||||
name += 5;
|
||||
else if ((fd = mkstemps( name, strlen(suffix) )) == -1)
|
||||
fatal_error( "could not generate a temp file\n" );
|
||||
|
||||
if ((fd = mkstemps( name, strlen(suffix) ) == -1))
|
||||
{
|
||||
sprintf( name, "/tmp/%s.XXXXXX%s", prefix, suffix );
|
||||
if ((fd = mkstemps( name, strlen(suffix) ) == -1))
|
||||
fatal_error( "could not generate a temp file\n" );
|
||||
}
|
||||
close( fd );
|
||||
tmp_files[nb_tmp_files++] = name;
|
||||
return name;
|
||||
|
@ -275,6 +280,26 @@ int remove_stdcall_decoration( char *name )
|
|||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* assemble_file
|
||||
*
|
||||
* Run a file through the assembler.
|
||||
*/
|
||||
void assemble_file( const char *src_file, const char *obj_file )
|
||||
{
|
||||
char *cmd;
|
||||
int err;
|
||||
|
||||
if (!as_command) as_command = xstrdup("as");
|
||||
cmd = xmalloc( strlen(as_command) + strlen(obj_file) + strlen(src_file) + 6 );
|
||||
sprintf( cmd, "%s -o %s %s", as_command, obj_file, src_file );
|
||||
if (verbose) fprintf( stderr, "%s\n", cmd );
|
||||
err = system( cmd );
|
||||
if (err) fatal_error( "%s failed with status %d\n", as_command, err );
|
||||
free( cmd );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* alloc_dll_spec
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.\" -*- nroff -*-
|
||||
.TH WINEBUILD 1 "March 2003" "@PACKAGE_STRING@" "Wine dll builder"
|
||||
.TH WINEBUILD 1 "September 2005" "@PACKAGE_STRING@" "Wine dll builder"
|
||||
.SH NAME
|
||||
winebuild \- Wine dll builder
|
||||
.SH SYNOPSIS
|
||||
|
@ -20,11 +20,11 @@ You have to specify exactly one of the following options, depending on
|
|||
what you want winebuild to generate.
|
||||
.TP
|
||||
.BI \--dll
|
||||
Build a C file from a .spec file (see \fBSPEC FILE SYNTAX\fR for
|
||||
details), or from a standard Windows .def file. The .spec/.def file
|
||||
is specified via the -E option. The resulting C file must be compiled
|
||||
and linked to the other object files to build a working Wine dll.
|
||||
In this mode, the
|
||||
Build an assembly file from a .spec file (see \fBSPEC FILE SYNTAX\fR
|
||||
for details), or from a standard Windows .def file. The
|
||||
.spec/.def file is specified via the -E option. The resulting file
|
||||
must be assembled and linked to the other object files to build a
|
||||
working Wine dll. In this mode, the
|
||||
.I input files
|
||||
should be the list of all object files that will be linked into the
|
||||
final dll, to allow
|
||||
|
@ -33,13 +33,13 @@ to get the list of all undefined symbols that need to be imported from
|
|||
other dlls.
|
||||
.TP
|
||||
.BI \--exe
|
||||
Build a C file for an executable. This is basically the same as
|
||||
Build an assembly file for an executable. This is basically the same as
|
||||
the --dll mode except that it doesn't require a .spec/.def file as input,
|
||||
since an executable need not export functions. Some executables however
|
||||
do export functions, and for those a .spec/.def file can be specified via
|
||||
the -E option. The executable is named from the .spec/.def file name if
|
||||
present, or explicitly through the -F option. The resulting C file must be
|
||||
compiled and linked to the other object files to build a working Wine
|
||||
present, or explicitly through the -F option. The resulting file must be
|
||||
assembled and linked to the other object files to build a working Wine
|
||||
executable, and all the other object files must be listed as
|
||||
.I input files.
|
||||
.TP
|
||||
|
@ -160,11 +160,14 @@ Specify the command to use to get the list of undefined symbols; the
|
|||
default is \fBnm\fR.
|
||||
.TP
|
||||
.BI \-o,\ --output= file
|
||||
Set the name of the output file (default is standard output).
|
||||
Set the name of the output file (default is standard output). If the
|
||||
output file name end in \fB.o\fR, the text output is sent to a
|
||||
temporary file that is then assembled to produce the specified .o
|
||||
file.
|
||||
.TP
|
||||
.BI \-r,\ --res= rsrc.res
|
||||
Load resources from the specified binary resource file. The
|
||||
\fIrsrc.res\fR can be produced from a source resource file with
|
||||
\fIrsrc.res\fR file can be produced from a source resource file with
|
||||
.BR wrc(1)
|
||||
(or with a Windows resource compiler).
|
||||
.br
|
||||
|
@ -175,6 +178,9 @@ and will automatically be handled correctly (though the
|
|||
.B \-r
|
||||
option will also work for Win32 files).
|
||||
.TP
|
||||
.B --save-temps
|
||||
Do not delete the various temporary files that \fBwinebuild\fR generates.
|
||||
.TP
|
||||
.BI --subsystem= subsystem[:major[.minor]]
|
||||
Set the subsystem of the executable, which can be one of the following:
|
||||
.br
|
||||
|
@ -205,6 +211,10 @@ Add \fIsymbol\fR to the list of undefined symbols when invoking the
|
|||
linker. This makes it possible to force a specific module of a static
|
||||
library to be included when resolving imports.
|
||||
.TP
|
||||
.B \-v, --verbose
|
||||
Display the various subcommands being invoked by
|
||||
.B winebuild.
|
||||
.TP
|
||||
.B \--version
|
||||
Display the program version and exit.
|
||||
.TP
|
||||
|
|
Loading…
Reference in New Issue