diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 9467325826f..c1c2fa525a5 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -190,6 +190,7 @@ extern const char *get_asm_short_keyword(void); extern void add_import_dll( const char *name, const char *filename ); extern void add_delayed_import( const char *name ); extern void add_ignore_symbol( const char *name ); +extern void add_extra_ld_symbol( const char *name ); extern void read_undef_symbols( char **argv ); extern int resolve_imports( DLLSPEC *spec ); extern int output_imports( FILE *outfile, DLLSPEC *spec, int *nb_delayed ); diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index e265d5c5197..f08551b9607 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -60,6 +60,7 @@ struct name_table static struct name_table undef_symbols; /* list of undefined symbols */ static struct name_table ignore_symbols; /* list of symbols to ignore */ +static struct name_table extra_ld_symbols; /* list of extra symbols that ld should resolve */ static struct name_table delayed_imports; /* list of delayed import dlls */ static char *ld_tmp_file; /* ld temp file name */ @@ -438,6 +439,12 @@ void add_ignore_symbol( const char *name ) else add_name( &ignore_symbols, name ); } +/* add a symbol to the list of extra symbols that ld must resolve */ +void add_extra_ld_symbol( const char *name ) +{ + add_name( &extra_ld_symbols, name ); +} + /* add a function to the list of imports from a given dll */ static void add_import_func( struct import *imp, ORDDEF *func ) { @@ -546,8 +553,8 @@ static int check_unused( const struct import* imp, const DLLSPEC *spec ) /* returns the name of the combined file */ static const char *ldcombine_files( char **argv ) { - int i, len = 0; - char *cmd; + unsigned int i, len = 0; + char *cmd, *p; int fd, err; if (output_file_name && output_file_name[0]) @@ -563,10 +570,14 @@ static const char *ldcombine_files( char **argv ) atexit( remove_ld_tmp_file ); if (!ld_command) ld_command = xstrdup("ld"); + for (i = 0; i < extra_ld_symbols.count; i++) len += strlen(extra_ld_symbols.names[i]) + 5; for (i = 0; argv[i]; i++) len += strlen(argv[i]) + 1; - cmd = xmalloc( len + strlen(ld_tmp_file) + 8 + strlen(ld_command) ); - sprintf( cmd, "%s -r -o %s", ld_command, ld_tmp_file ); - for (i = 0; argv[i]; i++) sprintf( cmd + strlen(cmd), " %s", argv[i] ); + cmd = p = xmalloc( len + strlen(ld_tmp_file) + 8 + strlen(ld_command) ); + p += sprintf( cmd, "%s -r -o %s", ld_command, ld_tmp_file ); + for (i = 0; i < extra_ld_symbols.count; i++) + p += sprintf( p, " -u %s", asm_name(extra_ld_symbols.names[i]) ); + for (i = 0; argv[i]; i++) + p += sprintf( p, " %s", argv[i] ); err = system( cmd ); if (err) fatal_error( "%s -r failed with status %d\n", ld_command, err ); free( cmd ); diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index bb8b9947cf3..60242150bdd 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -234,31 +234,32 @@ static void exit_on_signal( int sig ) static const char usage_str[] = "Usage: winebuild [OPTIONS] [FILES]\n\n" "Options:\n" -" -C --source-dir=DIR Look for source files in DIR\n" -" -d --delay-lib=LIB Import the specified library in delayed mode\n" -" -D SYM Ignored for C flags compatibility\n" -" -E --export=FILE Export the symbols defined in the .spec or .def file\n" -" -e --entry=FUNC Set the DLL entry point function (default: DllMain)\n" -" -f FLAGS Compiler flags (only -fPIC is supported)\n" -" -F --filename=DLLFILE Set the DLL filename (default: from input file name)\n" -" -h --help Display this help message\n" -" -H --heap=SIZE Set the heap size for a Win16 dll\n" -" -i --ignore=SYM[,SYM] Ignore specified symbols when resolving imports\n" -" -I DIR Ignored for C flags compatibility\n" -" -k --kill-at Kill stdcall decorations in generated .def files\n" -" -K FLAGS Compiler flags (only -KPIC is supported)\n" +" -C, --source-dir=DIR Look for source files in DIR\n" +" -d, --delay-lib=LIB Import the specified library in delayed mode\n" +" -D SYM Ignored for C flags compatibility\n" +" -E, --export=FILE Export the symbols defined in the .spec or .def file\n" +" -e, --entry=FUNC Set the DLL entry point function (default: DllMain)\n" +" -f FLAGS Compiler flags (only -fPIC is supported)\n" +" -F, --filename=DLLFILE Set the DLL filename (default: from input file name)\n" +" -h, --help Display this help message\n" +" -H, --heap=SIZE Set the heap size for a Win16 dll\n" +" -i, --ignore=SYM[,SYM] Ignore specified symbols when resolving imports\n" +" -I DIR Ignored for C flags compatibility\n" +" -k, --kill-at Kill stdcall decorations in generated .def files\n" +" -K, FLAGS Compiler flags (only -KPIC is supported)\n" " --ld-cmd=LD Command to use for linking (default: ld)\n" -" -l --library=LIB Import the specified library\n" -" -L --library-path=DIR Look for imports libraries in DIR\n" -" -M --main-module=MODULE Set the name of the main module for a Win16 dll\n" +" -l, --library=LIB Import the specified library\n" +" -L, --library-path=DIR Look for imports libraries in DIR\n" +" -M, --main-module=MODULE Set the name of the main module for a Win16 dll\n" " --nm-cmd=NM Command to use to get undefined symbols (default: nm)\n" -" -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" +" -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" " --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" " --version Print the version and exit\n" -" -w --warnings Turn on warnings\n" +" -w, --warnings Turn on warnings\n" "\nMode options:\n" " --dll Build a .c file from a .spec or .def file\n" " --def Build a .def file from a .spec file\n" @@ -283,7 +284,7 @@ enum long_options_values 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: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:w"; static const struct option long_options[] = { @@ -314,6 +315,7 @@ static const struct option long_options[] = { "dll-name", 1, 0, 'N' }, { "output", 1, 0, 'o' }, { "res", 1, 0, 'r' }, + { "undefined", 1, 0, 'u' }, { "warnings", 0, 0, 'w' }, { NULL, 0, 0, 0 } }; @@ -421,6 +423,9 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec ) res_files = xrealloc( res_files, (nb_res_files+1) * sizeof(*res_files) ); res_files[nb_res_files++] = xstrdup( optarg ); break; + case 'u': + add_extra_ld_symbol( optarg ); + break; case 'w': display_warnings = 1; break; diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in index b76a19ec925..2509878dc42 100644 --- a/tools/winebuild/winebuild.man.in +++ b/tools/winebuild/winebuild.man.in @@ -196,6 +196,11 @@ Specify the target CPU and platform on which the generated code will be built. The target specification is in the standard autoconf format as returned by config.sub. .TP +.BI \-u,\ --undefined= symbol +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 \--version Display the program version and exit. .TP