If e.g. the 64bit libdir was set to /foo/lib/x86_64-linux-gnu/bar, winegcc will now look for the 32bit libdir at /foo/lib/i386-linux-gnu/bar.
Signed-off-by: Andre Heider a.heider@gmail.com --- Tested on non-standard prefixes like /opt/foo as well as more exotic variations like Debian's wine-development package, which uses /usr/lib/x86_64-linux-gnu/wine-development and /usr/lib/i386-linux-gnu/wine-development
tools/winegcc/winegcc.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 6b3b4b6aab..d463d7a4bf 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -444,6 +444,21 @@ static int check_platform( struct options *opts, const char *file ) return ret; }
+static const char *get_multiarch_dir( enum target_cpu cpu ) +{ + switch(cpu) + { + case CPU_x86: return "/i386-linux-gnu"; + case CPU_x86_64: return "/x86_64-linux-gnu"; + case CPU_ARM: return "/arm-linux-gnueabi"; + case CPU_ARM64: return "/aarch64-linux-gnu"; + case CPU_POWERPC: return "/powerpc-linux-gnu"; + default: + assert(0); + return NULL; + } +} + static char *get_lib_dir( struct options *opts ) { static const char *stdlibpath[] = { LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" }; @@ -471,19 +486,24 @@ static char *get_lib_dir( struct options *opts ) strcpy( p, bit_suffix ); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found; - switch(opts->target_cpu) - { - case CPU_x86: strcpy( p, "/i386-linux-gnu" ); break; - case CPU_x86_64: strcpy( p, "/x86_64-linux-gnu" ); break; - case CPU_ARM: strcpy( p, "/arm-linux-gnueabi" ); break; - case CPU_ARM64: strcpy( p, "/aarch64-linux-gnu" ); break; - case CPU_POWERPC: strcpy( p, "/powerpc-linux-gnu" ); break; - default: - assert(0); - } + strcpy( p, get_multiarch_dir( opts->target_cpu )); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found;
+ /* try s/$build_cpu/$target_cpu/ on multiarch */ + if (build_cpu != opts->target_cpu && (p = strstr( stdlibpath[i], get_multiarch_dir( build_cpu ) ))) + { + char *suffix = p + strlen( get_multiarch_dir( build_cpu ) ); + strcpy( buffer, stdlibpath[i] ); + p = buffer + (p - stdlibpath[i]); + strcpy( p, get_multiarch_dir( opts->target_cpu ) ); + p += strlen( get_multiarch_dir( opts->target_cpu ) ); + strcpy( p, suffix ); + while (p > buffer && p[-1] == '/') p--; + strcat( p, libwine ); + if (check_platform( opts, buffer )) goto found; + } + strcpy( buffer, stdlibpath[i] ); p = buffer + strlen(buffer); while (p > buffer && p[-1] == '/') p--;
Hi Andre,
On 11/20/18 1:10 PM, Andre Heider wrote:
If e.g. the 64bit libdir was set to /foo/lib/x86_64-linux-gnu/bar, winegcc will now look for the 32bit libdir at /foo/lib/i386-linux-gnu/bar.
Signed-off-by: Andre Heider a.heider@gmail.com
Tested on non-standard prefixes like /opt/foo as well as more exotic variations like Debian's wine-development package, which uses /usr/lib/x86_64-linux-gnu/wine-development and /usr/lib/i386-linux-gnu/wine-development
tools/winegcc/winegcc.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 6b3b4b6aab..d463d7a4bf 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -444,6 +444,21 @@ static int check_platform( struct options *opts, const char *file ) return ret; }
+static const char *get_multiarch_dir( enum target_cpu cpu ) +{
- switch(cpu)
- {
- case CPU_x86: return "/i386-linux-gnu";
- case CPU_x86_64: return "/x86_64-linux-gnu";
- case CPU_ARM: return "/arm-linux-gnueabi";
- case CPU_ARM64: return "/aarch64-linux-gnu";
- case CPU_POWERPC: return "/powerpc-linux-gnu";
- default:
assert(0);
return NULL;
- }
+}
- static char *get_lib_dir( struct options *opts ) { static const char *stdlibpath[] = { LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" };
@@ -471,19 +486,24 @@ static char *get_lib_dir( struct options *opts ) strcpy( p, bit_suffix ); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found;
switch(opts->target_cpu)
{
case CPU_x86: strcpy( p, "/i386-linux-gnu" ); break;
case CPU_x86_64: strcpy( p, "/x86_64-linux-gnu" ); break;
case CPU_ARM: strcpy( p, "/arm-linux-gnueabi" ); break;
case CPU_ARM64: strcpy( p, "/aarch64-linux-gnu" ); break;
case CPU_POWERPC: strcpy( p, "/powerpc-linux-gnu" ); break;
default:
assert(0);
}
strcpy( p, get_multiarch_dir( opts->target_cpu )); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found;
/* try s/$build_cpu/$target_cpu/ on multiarch */
if (build_cpu != opts->target_cpu && (p = strstr( stdlibpath[i], get_multiarch_dir( build_cpu ) )))
{
char *suffix = p + strlen( get_multiarch_dir( build_cpu ) );
strcpy( buffer, stdlibpath[i] );
p = buffer + (p - stdlibpath[i]);
strcpy( p, get_multiarch_dir( opts->target_cpu ) );
p += strlen( get_multiarch_dir( opts->target_cpu ) );
strcpy( p, suffix );
while (p > buffer && p[-1] == '/') p--;
strcat( p, libwine );
if (check_platform( opts, buffer )) goto found;
}
It seems to me that extending the existing loop that tries to replace lib* path components would be better (it's the loop just a few lines bellow the code that you modify).
Thanks,
Jacek
Hi,
On 20/11/2018 13:53, Jacek Caban wrote:
Hi Andre,
On 11/20/18 1:10 PM, Andre Heider wrote:
If e.g. the 64bit libdir was set to /foo/lib/x86_64-linux-gnu/bar, winegcc will now look for the 32bit libdir at /foo/lib/i386-linux-gnu/bar.
Signed-off-by: Andre Heider a.heider@gmail.com
Tested on non-standard prefixes like /opt/foo as well as more exotic variations like Debian's wine-development package, which uses /usr/lib/x86_64-linux-gnu/wine-development and /usr/lib/i386-linux-gnu/wine-development
tools/winegcc/winegcc.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 6b3b4b6aab..d463d7a4bf 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -444,6 +444,21 @@ static int check_platform( struct options *opts, const char *file ) return ret; } +static const char *get_multiarch_dir( enum target_cpu cpu ) +{ + switch(cpu) + { + case CPU_x86: return "/i386-linux-gnu"; + case CPU_x86_64: return "/x86_64-linux-gnu"; + case CPU_ARM: return "/arm-linux-gnueabi"; + case CPU_ARM64: return "/aarch64-linux-gnu"; + case CPU_POWERPC: return "/powerpc-linux-gnu"; + default: + assert(0); + return NULL; + } +}
static char *get_lib_dir( struct options *opts ) { static const char *stdlibpath[] = { LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" }; @@ -471,19 +486,24 @@ static char *get_lib_dir( struct options *opts ) strcpy( p, bit_suffix ); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found; - switch(opts->target_cpu) - { - case CPU_x86: strcpy( p, "/i386-linux-gnu" ); break; - case CPU_x86_64: strcpy( p, "/x86_64-linux-gnu" ); break; - case CPU_ARM: strcpy( p, "/arm-linux-gnueabi" ); break; - case CPU_ARM64: strcpy( p, "/aarch64-linux-gnu" ); break; - case CPU_POWERPC: strcpy( p, "/powerpc-linux-gnu" ); break; - default: - assert(0); - } + strcpy( p, get_multiarch_dir( opts->target_cpu )); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found; + /* try s/$build_cpu/$target_cpu/ on multiarch */ + if (build_cpu != opts->target_cpu && (p = strstr( stdlibpath[i], get_multiarch_dir( build_cpu ) ))) + { + char *suffix = p + strlen( get_multiarch_dir( build_cpu ) ); + strcpy( buffer, stdlibpath[i] ); + p = buffer + (p - stdlibpath[i]); + strcpy( p, get_multiarch_dir( opts->target_cpu ) ); + p += strlen( get_multiarch_dir( opts->target_cpu ) ); + strcpy( p, suffix ); + while (p > buffer && p[-1] == '/') p--; + strcat( p, libwine ); + if (check_platform( opts, buffer )) goto found; + }
It seems to me that extending the existing loop that tries to replace lib* path components would be better (it's the loop just a few lines bellow the code that you modify).
Sure, I can do that, but doesn't that go against the idea of multiarch?
If your distro uses /lib/$triple it shouldn't use /lib[32|64]/$triple - at least I've never seen such a setup.
Or would that solve the issue on a setup I didn't yet encounter?
Regards, Andre
On 11/20/18 2:24 PM, Andre Heider wrote:
Hi,
On 20/11/2018 13:53, Jacek Caban wrote:
Hi Andre,
On 11/20/18 1:10 PM, Andre Heider wrote:
If e.g. the 64bit libdir was set to /foo/lib/x86_64-linux-gnu/bar, winegcc will now look for the 32bit libdir at /foo/lib/i386-linux-gnu/bar.
Signed-off-by: Andre Heider a.heider@gmail.com
Tested on non-standard prefixes like /opt/foo as well as more exotic variations like Debian's wine-development package, which uses /usr/lib/x86_64-linux-gnu/wine-development and /usr/lib/i386-linux-gnu/wine-development
tools/winegcc/winegcc.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 6b3b4b6aab..d463d7a4bf 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -444,6 +444,21 @@ static int check_platform( struct options *opts, const char *file ) return ret; } +static const char *get_multiarch_dir( enum target_cpu cpu ) +{ + switch(cpu) + { + case CPU_x86: return "/i386-linux-gnu"; + case CPU_x86_64: return "/x86_64-linux-gnu"; + case CPU_ARM: return "/arm-linux-gnueabi"; + case CPU_ARM64: return "/aarch64-linux-gnu"; + case CPU_POWERPC: return "/powerpc-linux-gnu"; + default: + assert(0); + return NULL; + } +}
static char *get_lib_dir( struct options *opts ) { static const char *stdlibpath[] = { LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" }; @@ -471,19 +486,24 @@ static char *get_lib_dir( struct options *opts ) strcpy( p, bit_suffix ); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found; - switch(opts->target_cpu) - { - case CPU_x86: strcpy( p, "/i386-linux-gnu" ); break; - case CPU_x86_64: strcpy( p, "/x86_64-linux-gnu" ); break; - case CPU_ARM: strcpy( p, "/arm-linux-gnueabi" ); break; - case CPU_ARM64: strcpy( p, "/aarch64-linux-gnu" ); break; - case CPU_POWERPC: strcpy( p, "/powerpc-linux-gnu" ); break; - default: - assert(0); - } + strcpy( p, get_multiarch_dir( opts->target_cpu )); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found; + /* try s/$build_cpu/$target_cpu/ on multiarch */ + if (build_cpu != opts->target_cpu && (p = strstr( stdlibpath[i], get_multiarch_dir( build_cpu ) ))) + { + char *suffix = p + strlen( get_multiarch_dir( build_cpu ) ); + strcpy( buffer, stdlibpath[i] ); + p = buffer + (p - stdlibpath[i]); + strcpy( p, get_multiarch_dir( opts->target_cpu ) ); + p += strlen( get_multiarch_dir( opts->target_cpu ) ); + strcpy( p, suffix ); + while (p > buffer && p[-1] == '/') p--; + strcat( p, libwine ); + if (check_platform( opts, buffer )) goto found; + }
It seems to me that extending the existing loop that tries to replace lib* path components would be better (it's the loop just a few lines bellow the code that you modify).
Sure, I can do that, but doesn't that go against the idea of multiarch?
If your distro uses /lib/$triple it shouldn't use /lib[32|64]/$triple
- at least I've never seen such a setup.
Or would that solve the issue on a setup I didn't yet encounter?
We would try to change that in this case only if $triple heuristic doesn't work. Instead of using strstr, there is a loop that tries to replace one component at the time. So if you build with -m32 on 64-bit host on a distro that uses an exotic /usr/lib/$triple/lib64/subdir libdir, we'd do following in the loop:
- skip subdir
- try to replace lib64 with lib32 or lib, if that fails
- try to replace $triple with 32-bit triple, if that fails
- try to replace lib with lib32, if that fails
- skip usr
- if we got here, we didn't find valid 32-bit libdir
Does that make sense?
Jacek
On 20/11/2018 14:38, Jacek Caban wrote:
On 11/20/18 2:24 PM, Andre Heider wrote:
Hi,
On 20/11/2018 13:53, Jacek Caban wrote:
Hi Andre,
On 11/20/18 1:10 PM, Andre Heider wrote:
If e.g. the 64bit libdir was set to /foo/lib/x86_64-linux-gnu/bar, winegcc will now look for the 32bit libdir at /foo/lib/i386-linux-gnu/bar.
Signed-off-by: Andre Heider a.heider@gmail.com
Tested on non-standard prefixes like /opt/foo as well as more exotic variations like Debian's wine-development package, which uses /usr/lib/x86_64-linux-gnu/wine-development and /usr/lib/i386-linux-gnu/wine-development
tools/winegcc/winegcc.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 6b3b4b6aab..d463d7a4bf 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -444,6 +444,21 @@ static int check_platform( struct options *opts, const char *file ) return ret; } +static const char *get_multiarch_dir( enum target_cpu cpu ) +{ + switch(cpu) + { + case CPU_x86: return "/i386-linux-gnu"; + case CPU_x86_64: return "/x86_64-linux-gnu"; + case CPU_ARM: return "/arm-linux-gnueabi"; + case CPU_ARM64: return "/aarch64-linux-gnu"; + case CPU_POWERPC: return "/powerpc-linux-gnu"; + default: + assert(0); + return NULL; + } +}
static char *get_lib_dir( struct options *opts ) { static const char *stdlibpath[] = { LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" }; @@ -471,19 +486,24 @@ static char *get_lib_dir( struct options *opts ) strcpy( p, bit_suffix ); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found; - switch(opts->target_cpu) - { - case CPU_x86: strcpy( p, "/i386-linux-gnu" ); break; - case CPU_x86_64: strcpy( p, "/x86_64-linux-gnu" ); break; - case CPU_ARM: strcpy( p, "/arm-linux-gnueabi" ); break; - case CPU_ARM64: strcpy( p, "/aarch64-linux-gnu" ); break; - case CPU_POWERPC: strcpy( p, "/powerpc-linux-gnu" ); break; - default: - assert(0); - } + strcpy( p, get_multiarch_dir( opts->target_cpu )); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found; + /* try s/$build_cpu/$target_cpu/ on multiarch */ + if (build_cpu != opts->target_cpu && (p = strstr( stdlibpath[i], get_multiarch_dir( build_cpu ) ))) + { + char *suffix = p + strlen( get_multiarch_dir( build_cpu ) ); + strcpy( buffer, stdlibpath[i] ); + p = buffer + (p - stdlibpath[i]); + strcpy( p, get_multiarch_dir( opts->target_cpu ) ); + p += strlen( get_multiarch_dir( opts->target_cpu ) ); + strcpy( p, suffix ); + while (p > buffer && p[-1] == '/') p--; + strcat( p, libwine ); + if (check_platform( opts, buffer )) goto found; + }
It seems to me that extending the existing loop that tries to replace lib* path components would be better (it's the loop just a few lines bellow the code that you modify).
Sure, I can do that, but doesn't that go against the idea of multiarch?
If your distro uses /lib/$triple it shouldn't use /lib[32|64]/$triple
- at least I've never seen such a setup.
Or would that solve the issue on a setup I didn't yet encounter?
We would try to change that in this case only if $triple heuristic doesn't work. Instead of using strstr, there is a loop that tries to replace one component at the time. So if you build with -m32 on 64-bit host on a distro that uses an exotic /usr/lib/$triple/lib64/subdir libdir, we'd do following in the loop:
skip subdir
try to replace lib64 with lib32 or lib, if that fails
try to replace $triple with 32-bit triple, if that fails
try to replace lib with lib32, if that fails
skip usr
if we got here, we didn't find valid 32-bit libdir
Does that make sense?
Oh, okay. Yeah, it does. I thought you meant all permutations. I tried to avoid that memmove() block down there, but I'll give it a spin ;)
Thanks, Andre
If e.g. the 64bit libdir was set to /foo/lib/x86_64-linux-gnu/bar, winegcc will now look for the 32bit libdir at /foo/lib/i386-linux-gnu/bar.
Signed-off-by: Andre Heider a.heider@gmail.com --- Tested on non-standard prefixes like /opt/foo as well as more exotic variations like Debian's wine-development package, which uses /usr/lib/x86_64-linux-gnu/wine-development and /usr/lib/i386-linux-gnu/wine-development
tools/winegcc/winegcc.c | 46 +++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 11 deletions(-)
diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 6b3b4b6aab..3f9dca68fc 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -444,15 +444,35 @@ static int check_platform( struct options *opts, const char *file ) return ret; }
+static const char *get_multiarch_dir( enum target_cpu cpu ) +{ + switch(cpu) + { + case CPU_x86: return "/i386-linux-gnu"; + case CPU_x86_64: return "/x86_64-linux-gnu"; + case CPU_ARM: return "/arm-linux-gnueabi"; + case CPU_ARM64: return "/aarch64-linux-gnu"; + case CPU_POWERPC: return "/powerpc-linux-gnu"; + default: + assert(0); + return NULL; + } +} + static char *get_lib_dir( struct options *opts ) { static const char *stdlibpath[] = { LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" }; static const char libwine[] = "/libwine.so"; - const char *bit_suffix, *other_bit_suffix; + const char *bit_suffix, *other_bit_suffix, *build_multiarch, *target_multiarch; unsigned int i; + size_t build_len, target_len;
bit_suffix = opts->target_cpu == CPU_x86_64 || opts->target_cpu == CPU_ARM64 ? "64" : "32"; other_bit_suffix = opts->target_cpu == CPU_x86_64 || opts->target_cpu == CPU_ARM64 ? "32" : "64"; + build_multiarch = get_multiarch_dir( build_cpu ); + target_multiarch = get_multiarch_dir( opts->target_cpu ); + build_len = strlen( build_multiarch ); + target_len = strlen( target_multiarch );
for (i = 0; i < sizeof(stdlibpath)/sizeof(stdlibpath[0]); i++) { @@ -471,16 +491,7 @@ static char *get_lib_dir( struct options *opts ) strcpy( p, bit_suffix ); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found; - switch(opts->target_cpu) - { - case CPU_x86: strcpy( p, "/i386-linux-gnu" ); break; - case CPU_x86_64: strcpy( p, "/x86_64-linux-gnu" ); break; - case CPU_ARM: strcpy( p, "/arm-linux-gnueabi" ); break; - case CPU_ARM64: strcpy( p, "/aarch64-linux-gnu" ); break; - case CPU_POWERPC: strcpy( p, "/powerpc-linux-gnu" ); break; - default: - assert(0); - } + strcpy( p, target_multiarch ); strcat( p, libwine ); if (check_platform( opts, buffer )) goto found;
@@ -495,6 +506,19 @@ static char *get_lib_dir( struct options *opts ) p--; while (p > buffer && *p != '/') p--; if (*p != '/') break; + + /* try s/$build_cpu/$target_cpu/ on multiarch */ + if (build_cpu != opts->target_cpu && !memcmp( p, build_multiarch, build_len ) && p[build_len] == '/') + { + memmove( p + target_len + 1, p + build_len + 1, strlen( p + build_len ) + 1 ); + memcpy( p, target_multiarch, target_len ); + p[target_len] = '/'; + if (check_platform( opts, buffer )) goto found; + memmove( p + build_len + 1, p + target_len + 1, strlen( p + target_len ) + 1 ); + memcpy( p, build_multiarch, build_len ); + p[build_len] = '/'; + } + if (memcmp( p + 1, "lib", 3 )) continue; if (p[4] == '/') {