您可以在 64 位安装中运行 32 位 Cygwin 应用程序吗? [英] Can you run a 32 bit Cygwin application in a 64 bit installation?

查看:20
本文介绍了您可以在 64 位安装中运行 32 位 Cygwin 应用程序吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在 64 位安装中运行 32 位 Cygwin 应用程序?

动机:如

因为我没有你的 32 位 可执行文件(我不喜欢搜索下载、解包等等......),我创建了一个小例子(让它运行,您还需要 gcc 工具链 - 我将其用于其他目的,但无论如何这与重现行为的问题无关.

code.c:

#include int main() {printf(""void*" is %d bits long.
", sizeof(void*) * 8);返回0;}

输出:

<块引用>

[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054206577]>〜/sopr.sh### 设置更短的提示以更好地适合粘贴到 StackOverflow(或其他)页面中###【064位提示】>uname -aCYGWIN_NT-10.0 cfati-5510-0 2.11.2(0.329/5/3) 2018-11-08 14:34 x86_64 Cygwin【064位提示】>ls代码.c【064位提示】>x86_64-pc-cygwin-gcc.exe -o exe-gcc-064.exe code.c【064位提示】>i686-pc-cygwin-gcc.exe -o exe-gcc-032.exe code.c -m32【064位提示】>ls -al共计 433drwxrwx---+ 1 管理员 无 0 Jan 16 12:45 .drwxrwx---+ 1 管理员 无 0 Jan 16 10:33 ..-rwxrwx---+ 1 管理员 无 118 Jan 16 10:39 code.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【064位提示】>【064位提示】>文件 exe-gcc-064.exeexe-gcc-064.exe:PE32+ 可执行文件(控制台)x86-64,适用于 MS Windows【064位提示】>ldd exe-gcc-064.exentdll.dll =>/cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffcaf990000)内核32.DLL =>/cygdrive/c/WINDOWS/System32/KERNEL32.DLL (0x7ffcaf300000)内核数据库.dll =>/cygdrive/c/WINDOWS/System32/KERNELBASE.dll (0x7ffcabe60000)cygwin1.dll =>/usr/bin/cygwin1.dll (0x180040000)【064位提示】>./exe-gcc-064.exe空*"是 64 位长.【064位提示】>【064位提示】>文件 exe-gcc-032.exeexe-gcc-032.exe:PE32 可执行文件(控制台)Intel 80386,用于 MS Windows【064位提示】>ldd exe-gcc-032.exentdll.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)【064位提示】>./exe-gcc-032.exe【064位提示】>【064位提示】>回声 $?127

如您所见,我遇到了 exe-gcc-032.exe 完全相同的问题.??? 依赖项是 32 位 cygwin1.dll.让我们来探讨一下这个问题:

<块引用>

[064bit prompt]>找到/usr -name cygwin1.dll/usr/i686-pc-cygwin/sys-root/usr/bin/cygwin1.dll/usr/bin/cygwin1.dll【064位提示】>cygcheck -f/usr/bin/cygwin1.dllcygwin-2.11.2-1【064位提示】>文件/usr/bin/cygwin1.dll/usr/bin/cygwin1.dll:PE32+ 可执行文件 (DLL)(控制台)x86-64,适用于 MS Windows【064位提示】>【064位提示】>cygcheck -f/usr/i686-pc-cygwin/sys-root/usr/bin/cygwin1.dllcygwin32-2.10.0-1【064位提示】>文件/usr/i686-pc-cygwin/sys-root/usr/bin/cygwin1.dll/usr/i686-pc-cygwin/sys-root/usr/bin/cygwin1.dll:PE32 可执行文件 (DLL)(控制台)Intel 80386(剥离到外部 PDB),用于 MS Windows【064位提示】>【064位提示】>回声 ${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计算工具包/CUDA/AllVers/bin:/cygdrive/c/Install/x64/NVidia/GPU计算工具包/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文件 (x86)/NVIDIA Corporation/PhysX/通用:/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 计算工具包/cuDNN/AllVers/bin:/cygdrive/c/Users/cfati/AppData/Local/Microsoft/WindowsApps:/cygdrive/c/Install/Qt/Qt/5.9.1/msvc2015/bin

因此,32 位 .dll 存在(由上述包安装),但是找不到,因为它的目录不在 中${PATH}(由于内容长度,这不是立即可见的).请注意,在这种情况下,Cygwin 不支持 LD_LIBRARY_PATH.

显而易见的步骤是让系统知道这个 .dll,方法是在 PATH(开头)中添加它的目录:

<块引用>

[064bit prompt]>导出路径=/usr/i686-pc-cygwin/sys-root/usr/bin:${PATH}【064位提示】>./exe-gcc-032.exe空*"是 32 位长.【064位提示】>./exe-gcc-064.exe空*"是 64 位长.

你去吧.

最后的注释:

  • (64 位) ldd 这是一个 .exe(与 Nix 不同,它是一个脚本),不能优雅地处理 32 位 人工制品的依赖项.不幸的是,cygwin32-binutils 包没有提供一个 32 位 对应的,不会有这个问题,所以目前这已经足够了莉>
  • 您在运行 .exe 时可能会遇到一些问题,因为 cygwin1.dll 版本之间可能存在差异(rxvt-native.exe 期望,以及系统上存在的那个).如果是这样,我建议您启动 Cygwin 32 环境,获取 cygwin 软件包版本(我们称之为 CYGWIN_PKG_VER),并在 Cygwin 64t 环境中,安装最接近 %CYGWIN_PKG_VER%
  • cygwin32 版本


更新#0

我在我的测试程序中添加了 system("echo ${PATH}");(并且隐式地添加了 #include ),并且在 32 位 变体上,system 返回 127(就像 exe-gcc-032.exe 没有正确路径时的退出代码).我怀疑这 2 个不可能无关,并且在启动 32 位 应用程序时,环境会发生一些事情,并且可能 rxvt-native 尝试启动 bash(或任何其他命令)通过 system.



更新#1

因此,可以从 Cygwin 64 运行 32 位 应用程序(简要检查,没有透露任何官方来源声明这是一个不支持的配置).但在这种特殊情况下,由于应用程序很复杂(它是一个终端,需要运行多个其他应用程序),因此存在问题.可能的方法(其他人建议的一些)更进一步:

  • 是时候放手了(可能没有移植它是有充分理由的).切换到现代替代品 (Mintty)
  • 搜索 rxvt 的非官方预构建 64 位 版本,或尝试自己构建它(还有一些其他人喜欢它)
  • 在您的 PC 上安装两种环境(Cygwin 32Cygwin 64)
    • 使用您最喜欢的终端(来自 Cygwin 32).这将是你的主要"环境
    • 远程"管理 Cygwin 64,例如通过:
      • ssh:我没有检查关于在同一台机器上并行运行的 2 个 sshd 的限制,但如果没有没有,您应该更改其中之一的默认侦听端口 (22).我建议对前者这样做,以便后者可以从外部"获得.使用默认设置
  • 继续研究这个方向,但在我看来,它开始(如果还没有)变成一个卡片城堡 - 这似乎更像是一种解决方法 (gainarie)

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:cygwinin directory to my new PC's C:cygwin64usrlocalin 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 Cygwin 64 emulator allows running 32 bit executables (as long as they are compatible). You only need to either 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 32 bit 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.

code.c:

#include <stdio.h>


int main() {
    printf(""void*" is %d bits long.
", 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
code.c
[064bit prompt]> x86_64-pc-cygwin-gcc.exe -o exe-gcc-064.exe code.c
[064bit prompt]> i686-pc-cygwin-gcc.exe -o exe-gcc-032.exe code.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    118 Jan 16 10:39 code.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 32 bit 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 32 bit .dll exists (installed by the above package), but it can't be found, as its dir is not in ${PATH} (due to the content length this isn't immediately visible). Note that Cygwin doesn't honour 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:

  • (64 bit) ldd which is an .exe (unlike on Nix, where it's a script), doesn't gracefully handle dependencies for 32 bit artefacts. Unfortunately, cygwin32-binutils package doesn't provide a 32 bit 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 Cygwin 32 environment, get the cygwin package version (let's call it CYGWIN_PKG_VER), and on the Cygwin 64t environment, install the cygwin32 version that is closest to %CYGWIN_PKG_VER%


Update #0

I added system("echo ${PATH}"); (and implicitly #include <stdlib.h>) in my test program, and on the 32 bit 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 32 bit applications, and probably rxvt-native tries to launch bash (or any other command) via system.



Update #1

So, it is possible to run a 32 bit application from Cygwin 64 (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 64 bit version of rxvt, or try building it yourself (there are some other people who like it)
  • Have both environments (Cygwin 32 and Cygwin 64) installed on your PC
    • Use your favorite terminal (from Cygwin 32). This will be your "main" environment
    • Administrate Cygwin 64 "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 workaround (gainarie)

这篇关于您可以在 64 位安装中运行 32 位 Cygwin 应用程序吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆