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

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

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

动机:如 Where's the rxvt-native utility gone in cygwin 1.7.26 for 64bit windows? 中所述,rxvt-native 是我在 Windows 中最喜欢的终端仿真器,目前在 64 位 Cygwin 中不可用。我的希望是,就像我可以 运行 32 位 Linux 应用程序在 64 位 Linux 发行版上一样,也许我可以 运行 64 位上的 32 位 rxvt Cygwin.

我尝试将可执行文件从旧电脑的 C:\cygwin\bin 目录复制到新电脑的 C:\cygwin64\usr\local\bin 目录,但无法 运行。

当我运行这个过程时,它只是静静地什么都不做。

ldd 告诉我缺少一些依赖项:

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

我已尝试从我的 32 位系统复制 cygwin1.dll 文件,但我不确定如何使其仅供此进程使用,而不对其他进程隐藏 64 位文件。

我的下一个选择是卸载我的 64 位 cygwin 并重新开始使用 32 位变体,但我仍然希望有办法...感谢您提供的任何帮助。

不,你不能。
32 位应用程序需要 32 位 cygwin1.dll,而 64 位 cygwin 需要 64 位 cygwin1.dll.

rxvt win32 native 被默认的 cygwin 终端 mintty 取代

像任何 Nix 发行版一样,Cygwin 64 模拟器允许 运行ning 32 位 可执行文件(只要它们兼容)。您只需要拥有:

  • 安装了正确的包
  • 正确的 .dlls 在正确的位置(如您所提到的)——但是手动复制它们(尤其是在系统位置)既不可扩展,也不能 gua运行确保系统之后能正常工作

首先,您需要安装 cygwin32 包(至少):

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

code.c:

#include <stdio.h>


int main() {
    printf("\"void*\" is %d bits long.\n", sizeof(void*) * 8);
    return 0;
}

输出:

[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Whosebug/q054206577]> ~/sopr.sh
### Set shorter prompt to better fit when pasted in Whosebug (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

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

[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

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

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

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

给你。

最终 注释:

  • (64 位) ldd 这是一个 .exe(不同于 Nix,它是一个脚本),没有优雅地处理 32 位 工件的依赖关系。不幸的是,cygwin32-binutils 包没有提供不会有这个问题的 32 位 对应物,所以目前这就像尽善尽美
  • 在 运行 运行 .exe 时,您可能 运行 遇到一些问题,因为 cygwin1.dll 之间可能存在差异] 版本(rxvt-native.exe 期望的版本,以及系统中存在的版本)。如果是这样,我建议您启动 Cygwin 32 环境,获取 cygwin 包版本(我们称它为 CYGWIN_PKG_VER), 在Cygwin 64t环境下,安装cygwin32 最接近 %CYGWIN_PKG_VER%
  • 的版本


更新#0

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

启动 bash(或任何其他命令)

更新#1

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

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