From: Jacek Caban Subject: [PATCH 2/3] winebuild: Use lld-link to create importlibs on MSVC target. Message-Id: <26c25d8b-d727-dd00-296c-3554c50adb69@codeweavers.com> Date: Mon, 25 Jan 2021 15:24:38 +0100 Signed-off-by: Jacek Caban --- tools/winebuild/build.h | 1 + tools/winebuild/import.c | 31 +++++++++++++++++++++---------- tools/winebuild/spec32.c | 10 ++++++++-- tools/winebuild/utils.c | 11 +++++++++++ 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 4fb6e23700e..104c77db593 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -264,6 +264,7 @@ extern void output_rva( const char *format, ... ) __attribute__ ((__format__ (__printf__, 1, 2))); extern void spawn( struct strarray array ); extern struct strarray find_tool( const char *name, const char * const *names ); +extern struct strarray find_link_tool(void); extern struct strarray get_as_command(void); extern struct strarray get_ld_command(void); extern const char *get_nm_command(void); diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 827a875e5df..f2942c8cb4d 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -1858,39 +1858,50 @@ static void build_windows_import_lib( DLLSPEC *spec ) { struct strarray args; char *def_file; - const char *as_flags, *m_flag; + const char *as_flags, *m_flag, *link_flag; def_file = open_temp_output_file( ".def" ); output_def_file( spec, 1 ); fclose( output_file ); - args = find_tool( "dlltool", NULL ); switch (target_cpu) { case CPU_x86: - m_flag = "i386"; + link_flag = m_flag = "i386"; as_flags = "--as-flags=--32"; break; case CPU_x86_64: m_flag = "i386:x86-64"; as_flags = "--as-flags=--64"; + link_flag = "x64"; break; case CPU_ARM: - m_flag = "arm"; + link_flag = m_flag = "arm"; as_flags = NULL; break; case CPU_ARM64: - m_flag = "arm64"; + link_flag = m_flag = "arm64"; as_flags = NULL; break; default: - m_flag = NULL; + link_flag = m_flag = NULL; break; } - strarray_add( &args, "-k", strendswith( output_file_name, ".delay.a" ) ? "-y" : "-l", - output_file_name, "-d", def_file, NULL ); - if (m_flag) - strarray_add( &args, "-m", m_flag, as_flags, NULL ); + + if (target_platform == PLATFORM_MINGW) + { + args = find_tool( "dlltool", NULL ); + strarray_add( &args, "-k", strendswith( output_file_name, ".delay.a" ) ? "-y" : "-l", + output_file_name, "-d", def_file, NULL ); + if (m_flag) + strarray_add( &args, "-m", m_flag, as_flags, NULL ); + } + else + { + args = find_link_tool(); + strarray_add( &args, strmake( "-implib:%s", output_file_name ), strmake( "-def:%s", def_file ), + link_flag ? strmake( "-machine:%s", link_flag ) : NULL, NULL ); + } spawn( args ); } diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 678f104c555..3f0ce372339 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -1010,8 +1010,14 @@ void output_def_file( DLLSPEC *spec, int import_only ) if (!is_private) total++; if (import_only && odp->type == TYPE_STUB) continue; - if ((odp->flags & FLAG_FASTCALL) && is_pe()) - name = strmake( "@%s", name ); + if (is_pe()) + { + if (odp->flags & FLAG_FASTCALL) + name = strmake( "@%s", name ); + else if (target_platform == PLATFORM_WINDOWS && target_cpu == CPU_x86 && + (odp->type == TYPE_STDCALL || odp->type == TYPE_STUB)) + name = strmake( "_%s", name ); + } output( " %s", name ); diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c index 928a2460aa1..411a53c7133 100644 --- a/tools/winebuild/utils.c +++ b/tools/winebuild/utils.c @@ -387,6 +387,17 @@ struct strarray find_tool( const char *name, const char * const *names ) fatal_error( "cannot find the '%s' tool\n", name ); } +/* find a link tool in the path */ +struct strarray find_link_tool(void) +{ + struct strarray ret = empty_strarray; + const char *file; + if (!(file = find_binary( NULL, "lld-link" ))) + fatal_error( "cannot find the 'lld-link tool\n" ); + strarray_add_one( &ret, file ); + return ret; +} + struct strarray get_as_command(void) { struct strarray args;