From 2fda3d6a179c0f2c74cc5d7530eccba260f87697 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 30 Dec 2009 11:51:19 +0100 Subject: [PATCH] winebuild: Add support for building Windows import libraries. --- tools/winebuild/build.h | 1 + tools/winebuild/import.c | 49 ++++++++++++++++++++++++++++++++++++++++ tools/winebuild/main.c | 12 ++++++++++ tools/winebuild/winebuild.man.in | 4 ++++ 4 files changed, 66 insertions(+) diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 7dca2d81b96..0543eb1d3af 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -251,6 +251,7 @@ extern void output_get_pc_thunk(void); extern void output_module( DLLSPEC *spec ); extern void output_stubs( DLLSPEC *spec ); extern void output_imports( DLLSPEC *spec ); +extern void output_import_lib( DLLSPEC *spec, char **argv ); extern void output_exports( DLLSPEC *spec ); extern int load_res32_file( const char *name, DLLSPEC *spec ); extern void output_resources( DLLSPEC *spec ); diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 0caaffde6be..648d29f71be 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -1304,3 +1304,52 @@ void output_imports( DLLSPEC *spec ) if (nb_imports || ext_link_imports.count || has_stubs(spec) || has_relays(spec)) output_get_pc_thunk(); } + +/* output an import library for a Win32 module and additional object files */ +void output_import_lib( DLLSPEC *spec, char **argv ) +{ + char *dlltool, *def_file; + char *cmd; + int err; + + if (target_platform != PLATFORM_WINDOWS) + fatal_error( "Unix-style import libraries not supported yet\n" ); + + def_file = get_temp_file_name( output_file_name, ".def" ); + fclose( output_file ); + if (!(output_file = fopen( def_file, "w" ))) + fatal_error( "Unable to create output file '%s'\n", def_file ); + BuildDef32File( spec ); + fclose( output_file ); + output_file = NULL; + + dlltool = find_tool( "dlltool", NULL ); + cmd = xmalloc( strlen(dlltool) + strlen(output_file_name) + strlen(def_file) + 12 ); + sprintf( cmd, "%s -k -l %s -d %s", dlltool, output_file_name, def_file ); + if (verbose) fprintf( stderr, "%s\n", cmd ); + err = system( cmd ); + if (err) fatal_error( "%s failed with status %d\n", dlltool, err ); + free( cmd ); + free( dlltool ); + + if (argv[0]) + { + char *ar = find_tool( "ar", NULL ); + int i, len; + + for (i = len = 0; argv[i]; i++) len += strlen(argv[i]) + 1; + cmd = xmalloc( strlen(ar) + strlen(output_file_name) + len + 5 ); + sprintf( cmd, "%s rs %s", ar, output_file_name ); + for (i = 0; argv[i]; i++) + { + strcat( cmd, " " ); + strcat( cmd, argv[i] ); + } + if (verbose) fprintf( stderr, "%s\n", cmd ); + err = system( cmd ); + if (err) fatal_error( "%s failed with status %d\n", dlltool, err ); + free( cmd ); + free( ar ); + } + output_file_name = NULL; +} diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index e81f88fd9b1..138ec68c39a 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -100,6 +100,7 @@ enum exec_mode_values MODE_DLL, MODE_EXE, MODE_DEF, + MODE_IMPLIB, MODE_RELAY16, MODE_RELAY32, MODE_RESOURCES @@ -268,6 +269,7 @@ static const char usage_str[] = " --dll Build a .c file from a .spec or .def file\n" " --def Build a .def file from a .spec file\n" " --exe Build a .c file for an executable\n" +" --implib Build an import library\n" " --relay16 Build the 16-bit relay assembly routines\n" " --relay32 Build the 32-bit relay assembly routines\n" " --resources Build a .o file for the resource files\n\n" @@ -278,6 +280,7 @@ enum long_options_values LONG_OPT_DLL = 1, LONG_OPT_DEF, LONG_OPT_EXE, + LONG_OPT_IMPLIB, LONG_OPT_ASCMD, LONG_OPT_EXTERNAL_SYMS, LONG_OPT_FAKE_MODULE, @@ -300,6 +303,7 @@ static const struct option long_options[] = { "dll", 0, 0, LONG_OPT_DLL }, { "def", 0, 0, LONG_OPT_DEF }, { "exe", 0, 0, LONG_OPT_EXE }, + { "implib", 0, 0, LONG_OPT_IMPLIB }, { "as-cmd", 1, 0, LONG_OPT_ASCMD }, { "external-symbols", 0, 0, LONG_OPT_EXTERNAL_SYMS }, { "fake-module", 0, 0, LONG_OPT_FAKE_MODULE }, @@ -475,6 +479,9 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec ) set_exec_mode( MODE_EXE ); if (!spec->subsystem) spec->subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI; break; + case LONG_OPT_IMPLIB: + set_exec_mode( MODE_IMPLIB ); + break; case LONG_OPT_ASCMD: as_command = xstrdup( optarg ); break; @@ -662,6 +669,11 @@ int main(int argc, char **argv) if (!parse_input_file( spec )) break; BuildDef32File( spec ); break; + case MODE_IMPLIB: + if (!spec_file_name) fatal_error( "missing .spec file\n" ); + if (!parse_input_file( spec )) break; + output_import_lib( spec, argv ); + break; case MODE_RELAY16: if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] ); BuildRelays16(); diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in index d41fae7a8c9..e0dd72b14ed 100644 --- a/tools/winebuild/winebuild.man.in +++ b/tools/winebuild/winebuild.man.in @@ -46,6 +46,10 @@ executable, and all the other object files must be listed as Build a .def file from a spec file. The .spec file is specified via the -E option. This is used when building dlls with a PE (Win32) compiler. .TP +.BI \--implib +Build a PE import library from a spec file. The .spec file is +specified via the -E option. +.TP .B \--relay16 Generate the assembly code for the 16-bit relay routines. This is for Wine internal usage only, you should never need to use this option. -- 2.11.4.GIT