Is it possible to run a 32-bit Cygwin application in a 64-bit installation?
Motivation: As discussed in Where's the rxvt-native utility gone in cygwin 1.7.26 for 64bit windows?, rxvt-native
, my favourite terminal emulator in Windows, is not currently available in 64 Cygwin. My hope is that just like I can run 32-bit Linux applications on 64-bit Linux distros, maybe I could run the 32-bit rxvt on 64-bit Cygwin.
I have tried copying the executable from my old PC's C:\cygwin\bin
directory to my new PC's C:\cygwin64\usr\local\bin
directory but it is not able to run it.
When I run the process, it just silently does nothing.
ldd
tells me some dependencies are missing:
$ ldd /usr/local/bin/rxvt-native.exe
ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x7ffcb79b0000)
??? => ??? (0x77a10000)
wow64.dll => /cygdrive/c/Windows/System32/wow64.dll (0x62c20000)
wow64win.dll => /cygdrive/c/Windows/System32/wow64win.dll (0x62c80000)
I have tried copying the cygwin1.dll
file from my 32-bit system but I'm not sure how to make it available only to this process without hiding the 64-bit one from other processes.
My next option is to uninstall my 64-bit cygwin and start again with the 32-bit variant, but I'm still hoping there's a way... Thanks for any help you can provide.
Like any Nix distribution, the Cygwin64 emulator allows running 32bit (pc032) executables (as long as they are compatible). You only need to have:
The right packages installed
The right .dlls in the right place (as you mentioned) - but manually copying them (especially in system locations) is neither scalable, nor does it guarantee that the system will properly work afterwards
First, you'd need the Cygwin32 package (at least) installed:
Since I don't have your pc032 executable (I didn't fell like searching downloading, unpacking, and so on ...), I created a small example (to make it run, you'd need the GCC toolchains as well - which I have for other purposes, but anyway this is not related to the question) that reproduces the behavior.
code00.c:
#include <stdio.h>
int main()
{
printf("\"void*\" is %d bits long.\n", sizeof(void*) * 8);
return 0;
}
Output:
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054206577]> ~/sopr.sh ### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ### [064bit prompt]> uname -a CYGWIN_NT-10.0 cfati-5510-0 2.11.2(0.329/5/3) 2018-11-08 14:34 x86_64 Cygwin [064bit prompt]> ls code00.c [064bit prompt]> x86_64-pc-cygwin-gcc.exe -o exe-gcc-064.exe code00.c [064bit prompt]> i686-pc-cygwin-gcc.exe -o exe-gcc-032.exe code00.c -m32 [064bit prompt]> ls -al total 433 drwxrwx---+ 1 Administrators None 0 Jan 16 12:45 . drwxrwx---+ 1 Administrators None 0 Jan 16 10:33 .. -rwxrwx---+ 1 Administrators None 142 Jan 16 10:39 code00.c -rwxrwxr-x+ 1 cfati None 151062 Jan 16 12:45 exe-gcc-032.exe -rwxrwxr-x+ 1 cfati None 157755 Jan 16 12:45 exe-gcc-064.exe [064bit prompt]> [064bit prompt]> file exe-gcc-064.exe exe-gcc-064.exe: PE32+ executable (console) x86-64, for MS Windows [064bit prompt]> ldd exe-gcc-064.exe ntdll.dll => /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffcaf990000) KERNEL32.DLL => /cygdrive/c/WINDOWS/System32/KERNEL32.DLL (0x7ffcaf300000) KERNELBASE.dll => /cygdrive/c/WINDOWS/System32/KERNELBASE.dll (0x7ffcabe60000) cygwin1.dll => /usr/bin/cygwin1.dll (0x180040000) [064bit prompt]> ./exe-gcc-064.exe "void*" is 64 bits long. [064bit prompt]> [064bit prompt]> file exe-gcc-032.exe exe-gcc-032.exe: PE32 executable (console) Intel 80386, for MS Windows [064bit prompt]> ldd exe-gcc-032.exe ntdll.dll => /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffcaf990000) ??? => ??? (0x77150000) wow64.dll => /cygdrive/c/WINDOWS/System32/wow64.dll (0x7ffcaf800000) wow64win.dll => /cygdrive/c/WINDOWS/System32/wow64win.dll (0x7ffcad570000) [064bit prompt]> ./exe-gcc-032.exe [064bit prompt]> [064bit prompt]> echo $? 127
As you can see, I ran into the exact same problem for exe-gcc-032.exe. The ??? dependency is the (pc032) cygwin1.dll. Let's explore the problem:
[064bit prompt]> find /usr -name cygwin1.dll /usr/i686-pc-cygwin/sys-root/usr/bin/cygwin1.dll /usr/bin/cygwin1.dll [064bit prompt]> cygcheck -f /usr/bin/cygwin1.dll cygwin-2.11.2-1 [064bit prompt]> file /usr/bin/cygwin1.dll /usr/bin/cygwin1.dll: PE32+ executable (DLL) (console) x86-64, for MS Windows [064bit prompt]> [064bit prompt]> cygcheck -f /usr/i686-pc-cygwin/sys-root/usr/bin/cygwin1.dll cygwin32-2.10.0-1 [064bit prompt]> file /usr/i686-pc-cygwin/sys-root/usr/bin/cygwin1.dll /usr/i686-pc-cygwin/sys-root/usr/bin/cygwin1.dll: PE32 executable (DLL) (console) Intel 80386 (stripped to external PDB), for MS Windows [064bit prompt]> [064bit prompt]> echo ${PATH} /usr/local/bin:/usr/bin:/cygdrive/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/WINDOWS/System32/>WindowsPowerShell/v1.0:/cygdrive/c/Install/x64/NVidia/GPU Computing Toolkit/CUDA/AllVers/bin:/cygdrive/c/Install/x64/NVidia/GPU Computing Toolkit/CUDA/AllVers/libnvvp:/cygdrive/c/Install/x86/Borland/Del>phi/7/>Bin:/cygdrive/c/Install/x86/Borland/Delphi/7/Projects/Bpl:/cygdrive/c/ProgramData/Oracle/Java/javapath:/cygdrive/c/Program Files (x86)/Intel/iCLS Client:/cygdrive/c/Program Files/Intel/iCLS Client:/cygd>rive/c/>Program Files (x86)/Intel/Intel(R) Management Engine Components/DAL:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/DAL:/cygdrive/c/Program Files (x86)/Intel/Intel(R) Management En>gine >Components/IPT:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/IPT:/cygdrive/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/cygdrive/c/WINDOWS/System32/OpenSSH:/cygdrive/c/>Insta>ll/>x86/IVI Foundation/VISA/AllVers/WinNT/Bin:/cygdrive/c/Program Files/IVI Foundation/VISA/Win64/Bin:/cygdrive/c/Install/x86/IVI Foundation/VISA/AllVers/WinNT/Bin:/cygdrive/e/Work/Dev/Utils/cfati-5510-0/>windows:/cygdrive/c/Install/x64/NVidia/GPU Computing Toolkit/cuDNN/AllVers/bin:/cygdrive/c/Users/cfati/AppData/Local/Microsoft/WindowsApps:/cygdrive/c/Install/Qt/Qt/5.9.1/msvc2015/bin
So, the pc032 .dll exists (installed by the above package), but it can't be found, as its dir is not in PATH (env var - due to its content length, this isn't immediately visible).
Note that Cygwin doesn't honor LD_LIBRARY_PATH in this scenario.
The obvious step is to let the system know about this .dll, by adding its dir in PATH (at the beginning):
[064bit prompt]> export PATH=/usr/i686-pc-cygwin/sys-root/usr/bin:${PATH} [064bit prompt]> ./exe-gcc-032.exe "void*" is 32 bits long. [064bit prompt]> ./exe-gcc-064.exe "void*" is 64 bits long.
There you go.
Final notes:
(64bit (pc064)) LDD ([Cygwin]: ldd) which is an .exe (unlike on Nix, where it's a script), doesn't gracefully handle dependencies for pc032 artifacts. Unfortunately, cygwin32-binutils package doesn't provide a pc032 counterpart that wouldn't have this problem, so at the current moment this is as good as it gets
You might run into some issues when running your .exe, because of possible differences between cygwin1.dll versions (the one that rxvt-native.exe expects, and the one present on the system). If so, I'd suggest that you start your Cygwin32 environment, get the Cygwin package version (let's call it CYGWIN_PKG_VER), and on the Cygwin64t environment, install the Cygwin32 version that is closest to %CYGWIN_PKG_VER%
Might also going through:
[SO]: Flask app no longer working from cygwin when set to developer mode (@CristiFati's answer)
[SO]: How can I compile a hybrid (asm, C) source code into a 32bit program? (@CristiFati's answer)
I added system("echo ${PATH}");
(and implicitly #include <stdlib.h>
) in my test program, and on the pc032 variant, System returned 127 (just like exe-gcc-032.exe's exit code when not having the proper path). I suspect the 2 can't be unrelated, and something happens with the environment, when launching pc032 applications, and probably rxvt-native.exe tries to launch Bash (or any other command) via System ([Man7]: SYSTEM(3)).
So, it is possible to run a pc032 application from Cygwin64 (a brief check, didn't reveal any official sources stating that it's an Unsupported Configuration). But in this particular case, since the app is complex (it's a terminal, required to run multiple other applications), there is a problem. Possible ways (some suggested by other people) to go further:
Time to let go (probably there is a good reason why it wasn't ported). Switch to a modern replacement (MinTTY)
Search for an unofficial prebuilt pc064 version of RXVT, or try building it yourself (there are some other people who like it)
Have both environments (Cygwin32 and Cygwin64) installed on your PC
Use your favorite terminal (from Cygwin32). This will be your "main" environment
Administrate Cygwin64 "remotely", e.g. via:
Continue research on this direction, but as I see things, it's starting (if it hasn't already) to become a card castle - this seems more like a (lame) workaround (RO: gainarie)