Alexandre Julliard : widl: Search for imported typelibs in the library search path.

Alexandre Julliard julliard at winehq.org
Fri Nov 12 16:16:04 CST 2021


Module: wine
Branch: master
Commit: c94f44f9b4559351c0ca86d344fe37aabc15200c
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c94f44f9b4559351c0ca86d344fe37aabc15200c

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Nov 12 12:40:56 2021 +0100

widl: Search for imported typelibs in the library search path.

Add a -L option to specify that path.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 tools/makedep.c        |  1 +
 tools/widl/Makefile.in |  4 +++-
 tools/widl/typelib.c   | 14 -----------
 tools/widl/widl.c      | 64 +++++++++++++++++++++++++++++++++++++++++++++++++-
 tools/widl/widl.h      |  1 +
 tools/widl/widl.man.in |  3 +++
 6 files changed, 71 insertions(+), 16 deletions(-)

diff --git a/tools/makedep.c b/tools/makedep.c
index 2a52ecd09c0..f9fbf7f8d8e 100644
--- a/tools/makedep.c
+++ b/tools/makedep.c
@@ -2787,6 +2787,7 @@ static void output_source_idl( struct makefile *make, struct incl_file *source,
     output( "\t%s%s -o $@", cmd_prefix( "WIDL" ), tools_path( make, "widl" ) );
     output_filenames( target_flags );
     output_filename( "--nostdinc" );
+    output_filename( "-Ldlls/\\*" );
     output_filenames( defines );
     output_filenames( get_expanded_make_var_array( make, "EXTRAIDLFLAGS" ));
     output_filenames( get_expanded_file_local_var( make, obj, "EXTRAIDLFLAGS" ));
diff --git a/tools/widl/Makefile.in b/tools/widl/Makefile.in
index 7eb74b813a4..32d27060c22 100644
--- a/tools/widl/Makefile.in
+++ b/tools/widl/Makefile.in
@@ -29,6 +29,8 @@ MANPAGES = widl.man.in
 
 widl_EXTRADEFS = \
 	-DINCLUDEDIR="\"${includedir}\"" \
-	-DBIN_TO_INCLUDEDIR=\"`${MAKEDEP} -R ${bindir} ${includedir}`\"
+	-DDLLDIR="\"${dlldir}\"" \
+	-DBIN_TO_INCLUDEDIR=\"`${MAKEDEP} -R ${bindir} ${includedir}`\" \
+	-DBIN_TO_DLLDIR=\"`${MAKEDEP} -R ${bindir} ${dlldir}`\"
 
 INSTALL_DEV = $(PROGRAMS)
diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
index d0fbdcab690..d47e937d70c 100644
--- a/tools/widl/typelib.c
+++ b/tools/widl/typelib.c
@@ -349,20 +349,6 @@ static void read_pe_importlib(importlib_t *importlib, void *data, unsigned int s
     read_msft_importlib( importlib, ptr, resdata->Size );
 }
 
-static int open_typelib(const char *name)
-{
-    char *file_name;
-    int fd;
-
-    file_name = wpp_find_include(name, NULL);
-    if(!file_name)
-        return open(name, O_RDONLY | O_BINARY );
-
-    fd = open(file_name, O_RDONLY | O_BINARY );
-    free(file_name);
-    return fd;
-}
-
 static void read_importlib(importlib_t *importlib)
 {
     int fd, size;
diff --git a/tools/widl/widl.c b/tools/widl/widl.c
index 325a55fff8d..2319a495f6a 100644
--- a/tools/widl/widl.c
+++ b/tools/widl/widl.c
@@ -55,6 +55,7 @@ static const char usage[] =
 "   -h                 Generate headers\n"
 "   -H file            Name of header file (default is infile.h)\n"
 "   -I directory       Add directory to the include search path (multiple -I allowed)\n"
+"   -L directory       Add directory to the library search path (multiple -L allowed)\n"
 "   --local-stubs=file Write empty stubs for call_as/local methods to file\n"
 "   -m32, -m64         Set the target architecture (Win32 or Win64)\n"
 "   -N                 Do not preprocess input\n"
@@ -151,6 +152,8 @@ char *temp_name;
 const char *prefix_client = "";
 const char *prefix_server = "";
 static const char *includedir;
+static const char *dlldir;
+static struct strarray dlldirs;
 static char *output_name;
 static const char *sysroot = "";
 
@@ -185,7 +188,7 @@ enum {
 };
 
 static const char short_options[] =
-    "b:cC:d:D:EhH:I:m:No:O:pP:rsS:tT:uU:VW";
+    "b:cC:d:D:EhH:I:L:m:No:O:pP:rsS:tT:uU:VW";
 static const struct long_option long_options[] = {
     { "acf", 1, ACF_OPTION },
     { "app_config", 0, APP_CONFIG_OPTION },
@@ -578,6 +581,7 @@ static void init_argv0_dir( const char *argv0 )
 #endif
     if (!dir) return;
     includedir = strmake( "%s/%s", get_dirname( dir ), BIN_TO_INCLUDEDIR );
+    dlldir = strmake( "%s/%s", get_dirname( dir ), BIN_TO_DLLDIR );
 #endif
 }
 
@@ -680,6 +684,9 @@ static void option_callback( int optc, char *optarg )
     case 'I':
       wpp_add_include_path(optarg);
       break;
+    case 'L':
+      strarray_add( &dlldirs, optarg );
+      break;
     case 'm':
       if (!strcmp( optarg, "32" )) pointer_size = 4;
       else if (!strcmp( optarg, "64" )) pointer_size = 8;
@@ -742,6 +749,61 @@ static void option_callback( int optc, char *optarg )
     }
 }
 
+static const char *get_pe_dir(void)
+{
+    switch (target_cpu)
+    {
+    case CPU_x86:    return "/i386-windows";
+    case CPU_x86_64: return "/x86_64-windows";
+    case CPU_ARM:    return "/arm-windows";
+    case CPU_ARM64:  return "/aarch64-windows";
+    default:         return "";
+    }
+}
+
+int open_typelib( const char *name )
+{
+    static const char *default_dirs[] = { DLLDIR, "/usr/lib/wine", "/usr/local/lib/wine" };
+    const char *pe_dir = get_pe_dir();
+    int fd;
+    unsigned int i;
+
+#define TRYOPEN(str) do { \
+        char *file = str; \
+        if ((fd = open( file, O_RDONLY | O_BINARY )) != -1) return fd; \
+        free( file ); } while(0)
+
+    for (i = 0; i < dlldirs.count; i++)
+    {
+        if (strendswith( dlldirs.str[i], "/*" ))  /* special case for wine build tree */
+        {
+            int namelen = strlen( name );
+            if (strendswith( name, ".dll" )) namelen -= 4;
+            TRYOPEN( strmake( "%.*s/%.*s/%s", (int)strlen(dlldirs.str[i]) - 2, dlldirs.str[i],
+                              namelen, name, name ));
+            TRYOPEN( strmake( "%.*s/%.*s/%s.fake", (int)strlen(dlldirs.str[i]) - 2, dlldirs.str[i],
+                              namelen, name, name ));
+        }
+        else
+        {
+            TRYOPEN( strmake( "%s%s/%s", dlldirs.str[i], pe_dir, name ));
+            TRYOPEN( strmake( "%s/%s", dlldirs.str[i], name ));
+        }
+    }
+
+    if (stdinc)
+    {
+        if (dlldir) TRYOPEN( strmake( "%s%s/%s", dlldir, pe_dir, name ));
+        for (i = 0; i < ARRAY_SIZE(default_dirs); i++)
+        {
+            if (i && !strcmp( default_dirs[i], default_dirs[0] )) continue;
+            TRYOPEN( strmake( "%s%s/%s", default_dirs[i], pe_dir, name ));
+        }
+    }
+    error( "cannot find %s\n", name );
+#undef TRYOPEN
+}
+
 int main(int argc,char *argv[])
 {
   int i;
diff --git a/tools/widl/widl.h b/tools/widl/widl.h
index 6dc19b3dafa..38ffc477115 100644
--- a/tools/widl/widl.h
+++ b/tools/widl/widl.h
@@ -89,6 +89,7 @@ enum stub_mode
     MODE_Oif  /* new-style fully interpreted stubs */
 };
 extern enum stub_mode get_stub_mode(void);
+extern int open_typelib( const char *name );
 
 extern void write_header(const statement_list_t *stmts);
 extern void write_id_data(const statement_list_t *stmts);
diff --git a/tools/widl/widl.man.in b/tools/widl/widl.man.in
index 234f512f962..858b04a38e8 100644
--- a/tools/widl/widl.man.in
+++ b/tools/widl/widl.man.in
@@ -58,6 +58,9 @@ Use old naming conventions.
 Generate a type library. The default output filename is
 \fIinfile\fB.tlb\fR.  If the output file name ends in \fB.res\fR, a
 binary resource file containing the type library is generated instead.
+.IP "\fB-L \fIpath\fR"
+Add a directory to the library search path for imported typelibs. The
+option can be specified multiple times.
 .PP
 .B UUID file options:
 .IP "\fB-u\fR"




More information about the wine-cvs mailing list