[PATCH v2 2/2] tools: compiled-in paths should not be used when cross-compiling

Kevin Puetz PuetzKevinA at JohnDeere.com
Thu Feb 3 08:27:25 CST 2022


When cross-compiling wine (or winelib applications), one configures
and builds wine __tooldeps__ in one prefix,
then builds the target separately (using --with-wine-tools)

Any paths compiled into wine's tool binaries via FOODIR or BIN_TO_FOODIR
would thus refer to that --with-wine-tools build, not to the target.
Previously BIN_TO_LIBDIR was exempted from being prefixed by $SYSROOT,
but really it should just not be used at all when cross-compiling.

Add --wine-libdir and --wine-includedir options so these paths can be
explicitly specified if they are not a standard location inside $SYSROOT.
This should match the --includedir or --libdir options to configure,
and will entirely override any built-in guessing.

Signed-off-by: Kevin Puetz <PuetzKevinA at JohnDeere.com>
--

Previously it was possible to compile with a cross-winelib
only if wine was installed inside of $SYSROOT, in one of the 3 subfolders
that the get_lib_dir would try ($PREFIX, /usr, or /usr/local).
And even then, build configuration's files (variables from init_argv0_dir)
would be first in the ist and preferred if they existed.

This worked for most libraries becuase .h and .def files aren't
architecture-specific, so the build/host confusion caused little harm.
And prior to wine 6.22 few libraries used static importlib.a files,
Even for those that did the linker would *probably* reject and skip
over wrong-architecture .a files, though more subtle problems could
manifest if e.g. both --host and --build were some flavor of linux-x86,
but perhaps using different gcc versions or options.

Allowing --wine-{include,lib}dir to be specified explicitly clears up
all this ambiguity and guessing; a cross-compiler can just say where
the host wine binaries are and be sure winegcc won't find something else.
---
 tools/widl/widl.c            | 13 ++++++++++---
 tools/widl/widl.man.in       |  5 +++++
 tools/winegcc/winegcc.c      | 28 ++++++++++++++++++++--------
 tools/winegcc/winegcc.man.in | 10 ++++++++++
 tools/wrc/wrc.c              | 13 ++++++++++---
 tools/wrc/wrc.man.in         |  6 ++++++
 6 files changed, 61 insertions(+), 14 deletions(-)

diff --git a/tools/widl/widl.c b/tools/widl/widl.c
index 8150d6158e4..8456c2d974f 100644
--- a/tools/widl/widl.c
+++ b/tools/widl/widl.c
@@ -71,6 +71,7 @@ static const char usage[] =
 "   -r                 Generate registration script\n"
 "   -robust            Ignored, present for midl compatibility\n"
 "   --sysroot=DIR      Prefix include paths with DIR\n"
+"   --wine-includedir= Prefix of installed wine headers (DIR/wine/*)\n"
 "   -s                 Generate server stub\n"
 "   -t                 Generate typelib\n"
 "   -u                 Generate interface identifiers file\n"
@@ -142,6 +143,7 @@ static const char *dlldir;
 static struct strarray dlldirs;
 static char *output_name;
 static const char *sysroot = "";
+static const char *wine_includedir = NULL;
 
 int line_number = 1;
 
@@ -167,6 +169,7 @@ enum {
     RT_OPTION,
     ROBUST_OPTION,
     SYSROOT_OPTION,
+    WINE_INCLUDEDIR,
     WIN32_OPTION,
     WIN64_OPTION,
     WIN32_ALIGN_OPTION,
@@ -191,6 +194,7 @@ static const struct long_option long_options[] = {
     { "prefix-server", 1, PREFIX_SERVER_OPTION },
     { "robust", 0, ROBUST_OPTION },
     { "sysroot", 1, SYSROOT_OPTION },
+    { "wine-includedir", 1, WINE_INCLUDEDIR },
     { "target", 0, 'b' },
     { "winrt", 0, RT_OPTION },
     { "win32", 0, WIN32_OPTION },
@@ -256,9 +260,9 @@ static void add_widl_version_define(void)
     wpp_add_cmdline_define(version_str);
 }
 
-static const char *get_inc_dir(const char *sysroot)
+static const char *guess_inc_dir(const char *sysroot)
 {
-    const char *stdincpath[] = { includedir, INCLUDEDIR, "/usr/include", "/usr/local/include" };
+    const char *stdincpath[] = { sysroot ? NULL : includedir, INCLUDEDIR, "/usr/include", "/usr/local/include" };
     const char *root = sysroot ? sysroot : "";
     unsigned int i;
 
@@ -568,6 +572,9 @@ static void option_callback( int optc, char *optarg )
     case SYSROOT_OPTION:
       sysroot = xstrdup(optarg);
       break;
+    case WINE_INCLUDEDIR:
+      wine_includedir = xstrdup(optarg);
+      break;
     case WIN32_OPTION:
       pointer_size = 4;
       break;
@@ -756,7 +763,7 @@ int main(int argc,char *argv[])
 
   if (stdinc)
   {
-      const char *inc_dir = get_inc_dir(sysroot);
+      const char *inc_dir = wine_includedir ? wine_includedir : guess_inc_dir(sysroot);
       wpp_add_include_path( strmake( "%s/wine/msvcrt", inc_dir));
       wpp_add_include_path( strmake( "%s/wine/windows", inc_dir));
   }
diff --git a/tools/widl/widl.man.in b/tools/widl/widl.man.in
index 858b04a38e8..bf226ccb587 100644
--- a/tools/widl/widl.man.in
+++ b/tools/widl/widl.man.in
@@ -43,6 +43,11 @@ specification is in the standard autoconf format as returned by
 Force the target architecture to 32-bit or 64-bit.
 .IP \fB\-\-sysroot=\fIdir\fR
 Prefix the standard include paths with \fIdir\fR.
+.IP "\fB--wine-includedir=\fIdir\fR"
+Specify the Wine include directory. This is mainly used when
+cross-compiling, as a separately-built widl (--with-wine-tools)
+won't know the path for target headers unless it's a standard prefix
+(\fI$SYSROOT/usr/include\fR or \fI$SYSROOT/usr/local/include\fR)
 .IP \fB\-\-nostdinc\fR
 Do not search standard include paths like /usr/include and
 /usr/local/include.
diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c
index 6e701a5c08b..0aafca1271a 100644
--- a/tools/winegcc/winegcc.c
+++ b/tools/winegcc/winegcc.c
@@ -184,6 +184,8 @@ struct options
     int strip;
     int pic;
     const char* wine_objdir;
+    const char* wine_libdir;
+    const char* wine_includedir;
     const char* winebuild;
     const char* output_name;
     const char* image_base;
@@ -550,9 +552,9 @@ static const char *get_multiarch_dir( struct target target )
    return NULL;
 }
 
-static char *get_lib_dir( struct options *opts )
+static const char *guess_libdir( struct options *opts )
 {
-    const char *stdlibpath[] = { libdir, LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" };
+    const char *stdlibpath[] = { (opts->sysroot ? NULL : libdir), LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" };
     const char *bit_suffix, *other_bit_suffix, *build_multiarch, *target_multiarch, *winecrt0;
     const char *root = opts->sysroot ? opts->sysroot : "";
     unsigned int i;
@@ -569,7 +571,6 @@ static char *get_lib_dir( struct options *opts )
 
     for (i = 0; i < ARRAY_SIZE(stdlibpath); i++)
     {
-        const char *root = (i && opts->sysroot) ? opts->sysroot : "";
         char *p, *buffer;
 
         if (!stdlibpath[i]) continue;
@@ -647,15 +648,14 @@ static char *get_lib_dir( struct options *opts )
     return strmake( "%s%s", root, LIBDIR );
 }
 
-static const char *get_inc_dir(const char *sysroot)
+static const char *guess_includedir(const char *sysroot)
 {
-    const char *stdincpath[] = { includedir, INCLUDEDIR, "/usr/include", "/usr/local/include" };
+    const char *stdincpath[] = { sysroot ? NULL : includedir, INCLUDEDIR, "/usr/include", "/usr/local/include" };
     const char *root = sysroot ? sysroot : "";
     unsigned int i;
 
     for (i = 0; i < ARRAY_SIZE(stdincpath); i++)
     {
-        const char *root = (sysroot && i) ? sysroot : "";
         char *path;
         struct stat statbuf;
 
@@ -837,7 +837,7 @@ no_compat_defines:
     if (!opts->wine_objdir && !opts->nostdinc)
     {
         const char *inc_sysroot = opts->isysroot ? opts->isysroot : opts->sysroot;
-        const char *inc_dir = get_inc_dir(inc_sysroot);
+        const char *inc_dir = opts->wine_includedir ? opts->wine_includedir : guess_includedir(inc_sysroot);
         const char *isystem = gcc_defs ? "-isystem" : "-I";
         const char *idirafter = gcc_defs ? "-idirafter" : "-I";
 
@@ -1151,7 +1151,7 @@ static void build(struct options* opts)
     /* prepare the linking path */
     if (!opts->wine_objdir)
     {
-        char *lib_dir = get_lib_dir( opts );
+        const char *lib_dir = opts->wine_libdir ? opts->wine_libdir : guess_libdir( opts );
         strarray_addall( &lib_dirs, opts->lib_dirs );
         strarray_add( &lib_dirs, strmake( "%s/wine%s", lib_dir, get_arch_dir( opts->target )));
         strarray_add( &lib_dirs, lib_dir );
@@ -1637,6 +1637,8 @@ int main(int argc, char **argv)
 		    next_is_arg = (strcmp("--param", opts.args.str[i]) == 0 ||
                                    strcmp("--sysroot", opts.args.str[i]) == 0 ||
                                    strcmp("--target", opts.args.str[i]) == 0 ||
+                                   strcmp("--wine-includedir", opts.args.str[i]) == 0 ||
+                                   strcmp("--wine-libdir", opts.args.str[i]) == 0 ||
                                    strcmp("--wine-objdir", opts.args.str[i]) == 0 ||
                                    strcmp("--winebuild", opts.args.str[i]) == 0 ||
                                    strcmp("--lib-suffix", opts.args.str[i]) == 0);
@@ -1925,6 +1927,16 @@ int main(int argc, char **argv)
                         parse_target_option( &opts, option_arg );
                         raw_compiler_arg = raw_linker_arg = 0;
                     }
+                    else if (is_option( &opts, i, "--wine-includedir", &option_arg ))
+                    {
+                        opts.wine_includedir = option_arg;
+                        raw_compiler_arg = raw_linker_arg = 0;
+                    }
+                    else if (is_option( &opts, i, "--wine-libdir", &option_arg ))
+                    {
+                        opts.wine_libdir = option_arg;
+                        raw_compiler_arg = raw_linker_arg = 0;
+                    }
                     else if (is_option( &opts, i, "--wine-objdir", &option_arg ))
                     {
                         opts.wine_objdir = option_arg;
diff --git a/tools/winegcc/winegcc.man.in b/tools/winegcc/winegcc.man.in
index 87c1496fd18..0fd4a34435c 100644
--- a/tools/winegcc/winegcc.man.in
+++ b/tools/winegcc/winegcc.man.in
@@ -29,6 +29,16 @@ compiler.
 .IP "\fB-b,--target \fItarget\fR"
 Specify the target architecture triplet for cross-compiling. winegcc
 will then invoke \fItarget\fR-gcc instead of gcc.
+.IP "\fB--wine-includedir \fIdir\fR"
+Specify the Wine include directory. This is mainly used when
+cross-compiling, as a separately-built winegcc (--with-wine-tools)
+won't know the path for target headers unless it's a standard prefix
+(\fI$SYSROOT/usr/include\fR or \fI$SYSROOT/usr/local/include\fR)
+.IP "\fB--wine-libdir \fIdir\fR"
+Specify the Wine library directory. This is mainly used when
+cross-compiling, as the --with-wine-tools winegcc won't know
+where to find the target's libs unless they are in a standard prefix
+(\fI$SYSROOT/usr/lib\fR, \fI$SYSROOT/usr/local/lib\fR, or \fI$SYSROOT/lib\fR)
 .IP "\fB--wine-objdir \fIdir\fR"
 Specify the Wine object directory. This is used when building Wine
 itself, to use the includes and libraries from inside the build tree.
diff --git a/tools/wrc/wrc.c b/tools/wrc/wrc.c
index 3b38629c71b..e0634703c70 100644
--- a/tools/wrc/wrc.c
+++ b/tools/wrc/wrc.c
@@ -64,6 +64,7 @@ static const char usage[] =
 	"   --preprocessor             Specifies the preprocessor to use, including arguments\n"
 	"   -r                         Ignored for compatibility with rc\n"
 	"   --sysroot=DIR              Prefix include paths with DIR\n"
+	"   --wine-includedir=DIR      Prefix of installed wine headers (DIR/wine/*)\n"
 	"   -U, --undefine id          Undefine preprocessor identifier id\n"
 	"   --use-temp-file            Ignored for compatibility with windres\n"
 	"   -v, --verbose              Enable verbose mode\n"
@@ -144,6 +145,7 @@ static int po_mode;
 static const char *po_dir;
 static const char *sysroot = "";
 static const char *includedir;
+static const char *wine_includedir = NULL;
 const char *nlsdirs[3] = { NULL, NLSDIR, NULL };
 
 int line_number = 1;		/* The current line */
@@ -164,6 +166,7 @@ enum long_options_values
     LONG_OPT_PO_DIR,
     LONG_OPT_PREPROCESSOR,
     LONG_OPT_SYSROOT,
+    LONG_OPT_WINE_INCLUDEDIR,
     LONG_OPT_VERSION,
     LONG_OPT_DEBUG,
     LONG_OPT_PEDANTIC,
@@ -189,6 +192,7 @@ static const struct long_option long_options[] = {
 	{ "po-dir", 1, LONG_OPT_PO_DIR },
 	{ "preprocessor", 1, LONG_OPT_PREPROCESSOR },
 	{ "sysroot", 1, LONG_OPT_SYSROOT },
+	{ "wine-includedir", 1, LONG_OPT_WINE_INCLUDEDIR },
 	{ "target", 1, 'F' },
 	{ "utf8", 0, 'u' },
 	{ "undefine", 1, 'U' },
@@ -225,9 +229,9 @@ static void set_version_defines(void)
     free( version );
 }
 
-static const char *get_inc_dir(const char *sysroot)
+static const char *guess_inc_dir(const char *sysroot)
 {
-    const char *stdincpath[] = { includedir, INCLUDEDIR, "/usr/include", "/usr/local/include" };
+    const char *stdincpath[] = { sysroot ? NULL : includedir, INCLUDEDIR, "/usr/include", "/usr/local/include" };
     const char *root = sysroot ? sysroot : "";
     unsigned int i;
 
@@ -371,6 +375,9 @@ static void option_callback( int optc, char *optarg )
     case LONG_OPT_SYSROOT:
         sysroot = xstrdup( optarg );
         break;
+    case LONG_OPT_WINE_INCLUDEDIR:
+        wine_includedir = xstrdup( optarg );
+        break;
     case LONG_OPT_VERSION:
         printf(version_string);
         exit(0);
@@ -476,7 +483,7 @@ int main(int argc,char *argv[])
 	/* If we do need to search standard includes, add them to the path */
 	if (stdinc)
 	{
-            const char *inc_dir = get_inc_dir(sysroot);
+            const char *inc_dir = wine_includedir ? wine_includedir : guess_inc_dir(sysroot);
             wpp_add_include_path( strmake( "%s/wine/msvcrt", inc_dir));
             wpp_add_include_path( strmake( "%s/wine/windows", inc_dir));
 	}
diff --git a/tools/wrc/wrc.man.in b/tools/wrc/wrc.man.in
index 807c66ad006..a913ad928ce 100644
--- a/tools/wrc/wrc.man.in
+++ b/tools/wrc/wrc.man.in
@@ -116,6 +116,12 @@ To disable preprocessing, use \fB--preprocessor=cat\fR.
 .I \fB\-\-sysroot=\fIdir\fR
 Prefix the standard include paths with \fIdir\fR.
 .TP
+.I \fB\-\-wine-includedir=\fIdir\fR
+Specify the Wine include directory. This is mainly used when
+cross-compiling, as a separately-built wrc (--with-wine-tools)
+won't know the path for target headers unless it's a standard prefix
+(\fI$SYSROOT/usr/include\fR or \fI$SYSROOT/usr/local/include\fR)
+.TP
 .I \fB\-\-utf8\fR, \fB\-u\fR
 Set the default codepage of the input file to UTF-8.
 .TP
-- 
2.34.1




More information about the wine-devel mailing list