Can you run a 32 bit Cygwin application in a 64 bit installation?
Asked Answered
R

2

4

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.

Republicanize answered 15/1, 2019 at 20:48 Comment(0)
I
5

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:

Img0

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:



Update #0

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)).



Update #1

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:

      • SSh: I didn't check for restrictions regarding the 2 SShDs running in parallel on the same machine, but if there aren't any, you should change the listening port from default (22) for one of them. I'd suggest to do that for the former, so that the latter is available from "outside" using default settings
  • 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)

Improbable answered 16/1, 2019 at 11:28 Comment(12)
Thanks for this very detailed answer. I had noticed Cygwin didn't honour LD_LIBRARY_PATH, thanks for pointing out it uses PATH to find DLLs instead. I guess that's consistent with Windows behaviour. I'll try this when I have a chance and report back on my results.Republicanize
You're correct, at the end it still uses Win loader. Let me kow about the results :)Improbable
Hum, I got partial success. With my PATH pointing to where 32-bit cygwin1.dll and libW11.dll are, my 32-bit rxvt runs, but it's not happy: it can't launch bash, for example. I think I'm going to give up on this idea and go for something supported instead, either drop to cygwin32, pick a terminal in Cygwin 64, or maybe even go to Putty. Thanks for your help!Republicanize
bash is a 64 bit process, but I don't see why it couldn't be launched from a 32 bit one. What do you mean by it's not working? Made me curious, I'll try launching some command from my program and see how it behaves. But anyway, this whole setup is kind of workaroundy, you could try building the rxvt for 64. So (til this point), terminal works, but it's unusable.Improbable
Sorry, I should know better than to say it's not working in such a vague way... So the rxvt window comes up, and the cursor stays at the top line with not prompt or anything getting printed. running ps, the rxvt process has no child processes. By now, though, I've successfully configured mintty to my satisfaction, so I'm going to give up on rxvt anyway.Republicanize
This answer is wrong. In order to execute a 32-bit cygwin executable you must use a 32-bit cygwin installation. The 32-bit executable requires the 32-bit cygwin1.dll, and every dll the executable calls must be the 32-bit version. There are no adaptors that allow calling back and forth between cygwin 32-bit dlls and cygwin 64-bit dlls. But, you can very easily install both the 32-bit and 64-bit cygwin environments. They cannot intercommunicate via Posix pipes or shared memory, however they do share the same Windows disk file system, and can use windows only pipes to exchange data.Rissa
@DougHenderson: I beg to differ. "In order to execute a 32-bit cygwin executable you must use a 32-bit cygwin installation": Is this a personal opinion or do you have some official sources to back it up? Then how do you explain cygwin1.dll presence in cygwin32 pkg?Improbable
I was trying to keep my comment simple. As you found out, with a lot of work you can get a simple app to work. You used a subset of a 32-bit installation and jumped through hoops to switch from the 64-bit installation to the 32-bit installation. Life is too short to fiddle around like this.Rissa
@DougHenderson: You're correct, it was a number of hours of work.But only because when I encounter smth that I don't understand why it is the way it is, I want to get to the bottom of it. Coming back to our current situation: the answer to OP's question is yes (and this is what I proved in the answer). You can run an app, but not any app. Whether there are alternatives (that are better, or easier, ...), very likely. But, by no means wold that make the answer incorrect (or wrong). Btw, I learned a lot during this investigation.Improbable
Just came back to accept this answer. You solved the problem as asked, and it's not your fault I am giving up on this route. @DougHenderson I agree these hoops are too much, and that's why I have up, but I also found it very informative to learn how one can do this. I wish it were simpler, but now I know how to do it if I need to again, and I also know there are better approaches.Republicanize
PS : my SO inbasket was not telling me about these edits and comments, so I just saw the edits now. I would have responded sooner otherwise.Republicanize
That's ok, I am in no rush :). Unfortunately, things are not always as we would like them to be.Improbable
A
1

No you can't.
The 32 bit application requires the 32bit cygwin1.dll, while the 64 bit cygwin needs the 64bit cygwin1.dll.

The rxvt win32 native was replaced by mintty that is the default cygwin terminal

Artistic answered 16/1, 2019 at 2:9 Comment(3)
The mintty terminal works, but I really don't like it. But now that you hinted at it, I tried it again and played with the customization options, and maybe I can adapt to it. Thanks for the suggestion, maybe it's time to move on from my old favourite... +1 even though "No you can't" is not quite accurate (see @CristiFati's answer),Republicanize
The OP may have success looking for a mingw32 or msys version of rxvt or urxvt. I, too, like rxvt, back in the day, but have adapted to mintty.Rissa
Two years later... I am long-since fully adapted to mintty. My current world is all utf-8, and a reliable, fully-unicode compliant, terminal has become a must. It's funny to reread my question now, prompted by a recent upvote. It makes me wonder why I resisted the switch so much.Republicanize

© 2022 - 2024 — McMap. All rights reserved.