windowscygwin32bit-64bitrxvt

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


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.


Solution

  • Like any Nix distribution, the Cygwin64 emulator allows running 32bit (pc032) executables (as long as they are compatible). You only need to have:

    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:

    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: