From: Jacek Caban Subject: [PATCH] makedep: Support using MSVC-style delayload linking. Message-Id: <6eb2d4f2-52c7-a172-3513-252dcc2b3984@codeweavers.com> Date: Thu, 1 Aug 2019 13:18:10 +0200 llvm-dlltool doesn't support support delay import lib, but we don't need them if linker itself supports delayload. lld-link supports it, so use it when possible. Signed-off-by: Jacek Caban --- With this patch, it's possible to do 64-bit build with llvm-mingw [1]. No extra config arguments are needed. 32-bit builds need a bit more fixes. Also, it won't work yet, mostly because export tables are broken. I have patches for that. [1] https://github.com/mstorsjo/llvm-mingw Makefile.in | 1 + configure.ac | 2 ++ tools/makedep.c | 21 ++++++++++++++++----- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Makefile.in b/Makefile.in index 193ecc59a4..c5d4714669 100644 --- a/Makefile.in +++ b/Makefile.in @@ -67,6 +67,7 @@ CONVERT = @CONVERT@ ICOTOOL = @ICOTOOL@ MSGFMT = @MSGFMT@ CROSSTARGET = @CROSSTARGET@ +DELAYLOADFLAG = @DELAYLOADFLAG@ SUBDIRS = @SUBDIRS@ RUNTESTFLAGS = -q -P wine MAKEDEP = $(TOOLSDIR)/tools/makedep$(TOOLSEXT) diff --git a/configure.ac b/configure.ac index 0fe26022b7..7ebc7ef159 100644 --- a/configure.ac +++ b/configure.ac @@ -1073,6 +1073,8 @@ then esac done + WINE_TRY_CFLAGS([-Wl,-Xlink=-delayload:test.dll], [AC_SUBST(DELAYLOADFLAG,["-Wl,-Xlink=-delayload:"])]) + if test "x$enable_maintainer_mode" = xyes then WINE_TRY_CROSSCFLAGS([-Werror]) diff --git a/tools/makedep.c b/tools/makedep.c index 24866b3145..523a1bf417 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -164,6 +164,7 @@ static const char *dlltool; static const char *msgfmt; static const char *ln_s; static const char *sed_cmd; +static const char *delayload_flag; struct makefile { @@ -2097,14 +2098,17 @@ static struct makefile *get_parent_makefile( struct makefile *make ) */ static int needs_cross_lib( const struct makefile *make ) { + const char *name; if (!crosstarget) return 0; - if (make->importlib) return strarray_exists( &cross_import_libs, make->importlib ); - if (make->staticlib) + if (make->importlib) name = make->importlib; + else if (make->staticlib) { - const char *name = replace_extension( make->staticlib, ".a", "" ); + name = replace_extension( make->staticlib, ".a", "" ); if (!strncmp( name, "lib", 3 )) name += 3; - return strarray_exists( &cross_import_libs, name ); } + else return 0; + if (strarray_exists( &cross_import_libs, name )) return 1; + if (delayload_flag && strarray_exists( &delay_import_libs, name )) return 1; return 0; } @@ -2114,6 +2118,7 @@ static int needs_cross_lib( const struct makefile *make ) */ static int needs_delay_lib( const struct makefile *make ) { + if (delayload_flag) return 0; if (*dll_ext && !crosstarget) return 0; if (!make->importlib) return 0; return strarray_exists( &delay_import_libs, make->importlib ); @@ -2194,7 +2199,7 @@ static struct strarray add_import_libs( const struct makefile *make, struct stra if (lib) { - if (delay) lib = replace_extension( lib, ".a", ".delay.a" ); + if (delay && !delayload_flag) lib = replace_extension( lib, ".a", ".delay.a" ); else if (make->is_cross) lib = replace_extension( lib, ".a", ".cross.a" ); lib = top_obj_dir_path( make, lib ); strarray_add( deps, lib ); @@ -3193,6 +3198,11 @@ static void output_module( struct makefile *make ) if (make->is_cross) { + if (delayload_flag) + { + for (i = 0; i < make->delayimports.count; i++) + strarray_add( &all_libs, strmake( "%s%s.dll", delayload_flag, make->delayimports.str[i] )); + } strarray_add( &make->all_targets, strmake( "%s", make->module )); add_install_rule( make, make->module, strmake( "%s", make->module ), strmake( "c$(dlldir)/%s", make->module )); @@ -4357,6 +4367,7 @@ int main( int argc, char *argv[] ) msgfmt = get_expanded_make_variable( top_makefile, "MSGFMT" ); sed_cmd = get_expanded_make_variable( top_makefile, "SED_CMD" ); ln_s = get_expanded_make_variable( top_makefile, "LN_S" ); + delayload_flag = get_expanded_make_variable( top_makefile, "DELAYLOADFLAG" ); if (root_src_dir && !strcmp( root_src_dir, "." )) root_src_dir = NULL; if (tools_dir && !strcmp( tools_dir, "." )) tools_dir = NULL;