A wine installation should not be divided across multiple prefixes, and one shouldn't mix components from multiple installations. winegcc should therefore select a single viable get_inc_dir (as was with get_lib_dir) and add (only) its ${includedir}/wine/msvcrt and ${includedir}/wine/windows, not offer gcc multiple (potentially nonexistent or unrelated) paths to search for wine headers
Signed-off-by: Kevin Puetz PuetzKevinA@JohnDeere.com --
e.g. for a wine built with --prefix /opt/wine-6 it's potentially the case that /usr/include/wine/* may also exist (perhaps from a distro package), but we don't really want winegcc adding both -I/opt/wine-6/include/windows -I/usr/include/wine/windows
get_inc_dir is identical in all winegcc/widl/wrc tools, and thus seems like a good candidate to move into tools.h. However, its interactions with init_argv0_dir (includedir global variable, INCLUDDIR macro, etc) made that not really work out. --- tools/widl/widl.c | 39 ++++++++++++++++++++++------------ tools/winegcc/winegcc.c | 47 ++++++++++++++++++++++++----------------- tools/wrc/wrc.c | 39 ++++++++++++++++++++++------------ 3 files changed, 80 insertions(+), 45 deletions(-)
diff --git a/tools/widl/widl.c b/tools/widl/widl.c index 7b2276b0a41..9e3b4a026f3 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -256,6 +256,29 @@ static void add_widl_version_define(void) wpp_add_cmdline_define(version_str); }
+static const char *get_inc_dir(const char *sysroot) +{ + const char *stdincpath[] = { 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; + + if (!stdincpath[i]) continue; + path = strmake( "%s%s/%s",root, stdincpath[i], "wine"); + if (!stat(path,&statbuf) && S_ISDIR(statbuf.st_mode)) + { + return strmake( "%s%s",root,stdincpath[i]); + } + } + + return strmake( "%s%s", root, INCLUDEDIR ); +} + /* clean things up when aborting on a signal */ static void exit_on_signal( int sig ) { @@ -733,19 +756,9 @@ int main(int argc,char *argv[])
if (stdinc) { - static const char *incl_dirs[] = { INCLUDEDIR, "/usr/include", "/usr/local/include" }; - - if (includedir) - { - wpp_add_include_path( strmake( "%s/wine/msvcrt", includedir )); - wpp_add_include_path( strmake( "%s/wine/windows", includedir )); - } - for (i = 0; i < ARRAY_SIZE(incl_dirs); i++) - { - if (i && !strcmp( incl_dirs[i], incl_dirs[0] )) continue; - wpp_add_include_path( strmake( "%s%s/wine/msvcrt", sysroot, incl_dirs[i] )); - wpp_add_include_path( strmake( "%s%s/wine/windows", sysroot, incl_dirs[i] )); - } + const char *inc_dir = get_inc_dir(sysroot); + wpp_add_include_path( strmake( "%s/wine/msvcrt", inc_dir)); + wpp_add_include_path( strmake( "%s/wine/windows", inc_dir)); }
if (pointer_size) diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index bcec3916843..a5303b2794e 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -648,6 +648,29 @@ static char *get_lib_dir( struct options *opts ) return strmake( "%s%s", root, LIBDIR ); }
+static const char *get_inc_dir(const char *sysroot) +{ + const char *stdincpath[] = { 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; + + if (!stdincpath[i]) continue; + path = strmake( "%s%s/%s",root, stdincpath[i], "wine"); + if (!stat(path,&statbuf) && S_ISDIR(statbuf.st_mode)) + { + return strmake( "%s%s",root,stdincpath[i]); + } + } + + return strmake( "%s%s", root, INCLUDEDIR ); +} + static void init_argv0_dir( const char *argv0 ) { #ifndef _WIN32 @@ -814,32 +837,18 @@ no_compat_defines: /* standard includes come last in the include search path */ if (!opts->wine_objdir && !opts->nostdinc) { - const char *incl_dirs[] = { INCLUDEDIR, "/usr/include", "/usr/local/include" }; - const char *root = opts->isysroot ? opts->isysroot : opts->sysroot ? opts->sysroot : ""; + const char *inc_sysroot = opts->isysroot ? opts->isysroot : opts->sysroot; + const char *inc_dir = get_inc_dir(inc_sysroot); const char *isystem = gcc_defs ? "-isystem" : "-I"; const char *idirafter = gcc_defs ? "-idirafter" : "-I";
if (opts->use_msvcrt) { - if (includedir) strarray_add( &comp_args, strmake( "%s%s/wine/msvcrt", isystem, includedir )); - for (j = 0; j < ARRAY_SIZE(incl_dirs); j++) - { - if (j && !strcmp( incl_dirs[0], incl_dirs[j] )) continue; - strarray_add(&comp_args, strmake( "%s%s%s/wine/msvcrt", isystem, root, incl_dirs[j] )); - } + strarray_add(&comp_args, strmake( "%s%s/wine/msvcrt", isystem, inc_dir )); strarray_add(&comp_args, "-D__MSVCRT__"); } - if (includedir) - { - strarray_add( &comp_args, strmake( "%s%s/wine/windows", isystem, includedir )); - strarray_add( &comp_args, strmake( "%s%s", idirafter, includedir )); - } - for (j = 0; j < ARRAY_SIZE(incl_dirs); j++) - { - if (j && !strcmp( incl_dirs[0], incl_dirs[j] )) continue; - strarray_add(&comp_args, strmake( "%s%s%s/wine/windows", isystem, root, incl_dirs[j] )); - strarray_add(&comp_args, strmake( "%s%s%s", idirafter, root, incl_dirs[j] )); - } + strarray_add(&comp_args, strmake( "%s%s/wine/windows", isystem, inc_dir )); + strarray_add(&comp_args, strmake( "%s%s", idirafter, inc_dir)); } else if (opts->wine_objdir) strarray_add(&comp_args, strmake("-I%s/include", opts->wine_objdir) ); diff --git a/tools/wrc/wrc.c b/tools/wrc/wrc.c index c80827127fe..1b7c771dcf3 100644 --- a/tools/wrc/wrc.c +++ b/tools/wrc/wrc.c @@ -225,6 +225,29 @@ static void set_version_defines(void) free( version ); }
+static const char *get_inc_dir(const char *sysroot) +{ + const char *stdincpath[] = { 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; + + if (!stdincpath[i]) continue; + path = strmake( "%s%s/%s",root, stdincpath[i], "wine"); + if (!stat(path,&statbuf) && S_ISDIR(statbuf.st_mode)) + { + return strmake( "%s%s",root,stdincpath[i]); + } + } + + return strmake( "%s%s", root, INCLUDEDIR ); +} + /* clean things up when aborting on a signal */ static void exit_on_signal( int sig ) { @@ -453,19 +476,9 @@ int main(int argc,char *argv[]) /* If we do need to search standard includes, add them to the path */ if (stdinc) { - static const char *incl_dirs[] = { INCLUDEDIR, "/usr/include", "/usr/local/include" }; - - if (includedir) - { - wpp_add_include_path( strmake( "%s/wine/msvcrt", includedir )); - wpp_add_include_path( strmake( "%s/wine/windows", includedir )); - } - for (i = 0; i < ARRAY_SIZE(incl_dirs); i++) - { - if (i && !strcmp( incl_dirs[i], incl_dirs[0] )) continue; - wpp_add_include_path( strmake( "%s%s/wine/msvcrt", sysroot, incl_dirs[i] )); - wpp_add_include_path( strmake( "%s%s/wine/windows", sysroot, incl_dirs[i] )); - } + const char *inc_dir = get_inc_dir(sysroot); + wpp_add_include_path( strmake( "%s/wine/msvcrt", inc_dir)); + wpp_add_include_path( strmake( "%s/wine/windows", inc_dir)); }
/* Kill io buffering when some kind of debuglevel is enabled */
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@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 because .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 | 14 ++++++++++---- tools/widl/widl.man.in | 5 +++++ tools/winegcc/winegcc.c | 28 ++++++++++++++++++++-------- tools/winegcc/winegcc.man.in | 10 ++++++++++ tools/wrc/wrc.c | 14 ++++++++++---- tools/wrc/wrc.man.in | 6 ++++++ 6 files changed, 61 insertions(+), 16 deletions(-)
diff --git a/tools/widl/widl.c b/tools/widl/widl.c index 9e3b4a026f3..b34b1f8cad9 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,15 +260,14 @@ 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_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;
@@ -568,6 +571,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 +762,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_includedir(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 a5303b2794e..983fe96c5ba 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -185,6 +185,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; @@ -551,9 +553,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; @@ -570,7 +572,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; @@ -648,15 +649,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;
@@ -838,7 +838,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";
@@ -1174,7 +1174,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 ); @@ -1665,6 +1665,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); @@ -1954,6 +1956,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 1b7c771dcf3..c9ce35abe58 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,15 +229,14 @@ static void set_version_defines(void) free( version ); }
-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;
@@ -371,6 +374,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 +482,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_includedir(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
Hi Kevin,
On 2/21/22 03:12, Kevin Puetz wrote:
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@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 because .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.
Sine wine-6.9, we install libraries into target-specific subdirectories of lib dir. This means that get_lib_dir() should already skip lib lib directories that are not compatible with specified target.
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.
While we may end up needing something like this anyway (for more complicated cases), I think that ideally we would make the experience seamless by not requiring those options. One way to achieve that, would be to make more use of target-specific subdirectories. It should be possible to not use sysroot for importlibs and includes at all. I can imagine installing importlibs into the non-sysrooted wine tools installation, making this single installation capable of handling multiple targets. This matches a common practice for cross compilation sysroots: for example, I have aarch64 sysroot in /usr/aarch64-unknown-linux-gnu/, but GCC uses /usr/lib/gcc/aarch64-unknown-linux-gnu/ for libraries (and includes) bundled with the compiler. Once something like that is setup, it should work just fine now (well, I didn't try, so there may be some bugs, but it shouldn't be too hard to get working). This patch would prevent such setup from using BIN_TO_FOODIR in such case. Would better support for such configuration be good for your use case? Maybe we should look at making such thing easy to setup.
Also, as I mentioned above, lib dir should already be able to skip target incompatible lib dir, but we don't have similar tool for include dirs and I can see a point in making that more reliable. The problem with current architecture is that libdir and includedir may be very different and there is no good way to translate one path to the other. The solution that compilers use (both GCC and Clang) is to ship internal headers inside libdir. While that may seem less intuitive, it makes sense for such cases. From compiler's perspective, places like /usr/include are mostly for 3rd party libraries to expose their interfaces, while internal compiler headers are an implementation detail of the compiler itself (and are potentially tied to its compiler version/config). Those considerations are similar to Wine headers and winegcc. If we followed that pattern, we could just just use strmake( "%s/include", get_lib_dir()) for include dir and headers would just match libraries version with no extra work needed. Anyway, this part likely not needed for your case and I can't be sure if it's a good idea without trying, but that's what I came out with when I was thinking about more reliable way to locate includes.
Thanks,
Jacek
It seems more helpful to suggest using the new --wine-{lib,include}dir options that to just return a prefix that was already checked and did not exist or contain the right files.
Signed-off-by: Kevin Puetz PuetzKevinA@JohnDeere.com --
Adding this error() revealed a latent bug in makedep: output_source_idl already used widl --nostdinc (relative paths are sufficient, since all the files are in src/include anyway).
But the calls to widl --dlldata-only and the TESTDLL/TESTRES wrc calls did not, so they would use include paths from outside the source tree. --- tools/makedep.c | 6 +++--- tools/widl/widl.c | 2 +- tools/winegcc/winegcc.c | 5 +++-- tools/wrc/wrc.c | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/tools/makedep.c b/tools/makedep.c index 25277efd7bb..c043e229d05 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -2969,7 +2969,7 @@ static void output_source_spec( struct makefile *make, struct incl_file *source, output_filename( obj_dir_path( make, dll_name )); output_filename( tools_path( make, "wrc" )); output( "\n" ); - output( "\t%secho "%s.dll TESTDLL \"%s\"" | %s -u -o $@\n", cmd_prefix( "WRC" ), obj, output_file, + output( "\t%secho "%s.dll TESTDLL \"%s\"" | %s -u -o $@ --nostdinc\n", cmd_prefix( "WRC" ), obj, output_file, tools_path( make, "wrc" ));
output( "%s:", output_file); @@ -3482,7 +3482,7 @@ static void output_test_module( struct makefile *make ) output( "\n" );
output( "programs/winetest/%s: %s%s\n", testres, obj_dir_path( make, stripped ), ext ); - output( "\t%secho "%s TESTRES \"%s%s\"" | %s -u -o $@\n", cmd_prefix( "WRC" ), + output( "\t%secho "%s TESTRES \"%s%s\"" | %s -u -o $@ --nostdinc\n", cmd_prefix( "WRC" ), testmodule, obj_dir_path( make, stripped ), ext, tools_path( make, "wrc" ));
output_filenames_obj_dir( make, make->ok_files ); @@ -3715,7 +3715,7 @@ static void output_sources( struct makefile *make ) { output( "%s: %s %s\n", obj_dir_path( make, "dlldata.c" ), tools_path( make, "widl" ), src_dir_path( make, "Makefile.in" )); - output( "\t%s%s --dlldata-only -o $@", cmd_prefix( "WIDL" ), tools_path( make, "widl" )); + output( "\t%s%s --dlldata-only -o $@ --nostdinc", cmd_prefix( "WIDL" ), tools_path( make, "widl" )); output_filenames( make->dlldata_files ); output( "\n" ); } diff --git a/tools/widl/widl.c b/tools/widl/widl.c index b34b1f8cad9..41c238a3ed6 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -279,7 +279,7 @@ static const char *guess_includedir(const char *sysroot) } }
- return strmake( "%s%s", root, INCLUDEDIR ); + error("could not find include/wine: add --wine-includedir\n"); }
/* clean things up when aborting on a signal */ diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 983fe96c5ba..650c5adeb06 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -646,7 +646,8 @@ static const char *guess_libdir( struct options *opts ) buffer[strlen(buffer) - strlen(winecrt0)] = 0; return buffer; } - return strmake( "%s%s", root, LIBDIR ); + + error("could not find libwinecrt0.a: add --wine-libdir\n"); }
static const char *guess_includedir(const char *sysroot) @@ -668,7 +669,7 @@ static const char *guess_includedir(const char *sysroot) } }
- return strmake( "%s%s", root, INCLUDEDIR ); + error("could not find include/wine: add --wine-includedir\n"); }
static void init_argv0_dir( const char *argv0 ) diff --git a/tools/wrc/wrc.c b/tools/wrc/wrc.c index c9ce35abe58..a55375bc5f6 100644 --- a/tools/wrc/wrc.c +++ b/tools/wrc/wrc.c @@ -248,7 +248,7 @@ static const char *guess_includedir(const char *sysroot) } }
- return strmake( "%s%s", root, INCLUDEDIR ); + error("could not find include/wine: add --wine-includedir\n"); }
/* clean things up when aborting on a signal */