[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