Можете ли вы запустить 32-битное приложение Cygwin в 64-битной установке?
Можно ли запустить 32-разрядное приложение Cygwin в 64-разрядной установке?
Мотивация: Как обсуждалось в разделе "Где в 64-битных окнах отсутствует утилита rxvt-native в cygwin 1.7.26?, rxvt-native
Мой любимый эмулятор терминала в Windows, в настоящее время недоступен в 64 Cygwin. Я надеюсь, что точно так же, как я могу запускать 32-битные приложения Linux в 64-битных дистрибутивах Linux, возможно, я мог бы запустить 32-битную версию rxvt на 64-битной 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)
Я пытался скопировать cygwin1.dll
файл из моей 32-битной системы, но я не уверен, как сделать его доступным только для этого процесса, не скрывая 64-битную систему от других процессов.
Мой следующий вариант - удалить мой 64-битный Cygwin и начать заново с 32-битного варианта, но я все еще надеюсь, что есть способ... Спасибо за любую помощь, которую вы можете предоставить.
2 ответа
Как и любой дистрибутив Lnx, эмулятор Cygwin 64 позволяет запускать 32-битные исполняемые файлы (если они совместимы). Вам нужно только иметь:
- Нужные пакеты установлены
- Нужные DLL-файлы находятся в нужном месте (как вы упомянули), но их копирование вручную (особенно в системных папках) не масштабируется и не гарантирует, что система впоследствии будет работать должным образом.
Во-первых, вам нужно установить пакет 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/Stackru/q054206577]> uname -a CYGWIN_NT-10.0 cfati-5510-0 2.11.2(0.329/5/3) 2018-11-08 14:34 x86_64 Cygwin [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> ls code.c [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> x86_64-pc-cygwin-gcc.exe -o exe-gcc-064.exe code.c [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> i686-pc-cygwin-gcc.exe -o exe-gcc-032.exe code.c -m32 [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> 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 [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> file exe-gcc-064.exe exe-gcc-064.exe: PE32+ executable (console) x86-64, for MS Windows [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> 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) [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> ./exe-gcc-064.exe "void*" is 64 bits long. [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> file exe-gcc-032.exe exe-gcc-032.exe: PE32 executable (console) Intel 80386, for MS Windows [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> 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) [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> ./exe-gcc-032.exe [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> echo $? 127
Как видите, я столкнулся с точно такой же проблемой для exe-gcc-032.exe. ??? Зависимость является 32-битной cygwin1.dll. Давайте рассмотрим проблему:
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> find /usr -name cygwin1.dll /usr/i686-pc-cygwin/sys-root/usr/bin/cygwin1.dll /usr/bin/cygwin1.dll [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> cygcheck -f /usr/bin/cygwin1.dll cygwin-2.11.2-1 [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> file /usr/bin/cygwin1.dll /usr/bin/cygwin1.dll: PE32+ executable (DLL) (console) x86-64, for MS Windows [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> cygcheck -f /usr/i686-pc-cygwin/sys-root/usr/bin/cygwin1.dll cygwin32-2.10.0-1 [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> 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 [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> 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/Delphi/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:/cygdrive/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 Engine 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/Install/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} (в начале):
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> export PATH=/usr/i686-pc-cygwin/sys-root/usr/bin:${PATH} [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> ./exe-gcc-032.exe "void*" is 32 bits long. [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/Stackru/q054206577]> ./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}
@ EDIT0:
я добавил system("echo ${PATH}");
(и неявно #include <stdlib.h>
) в моей тестовой программе и в 32-битном варианте система вернула 127 (точно так же, как код выхода exe-gcc-032.exe, когда не указан правильный путь). Я подозреваю, что 2 не может быть не связанным, и что-то происходит со средой при запуске 32-битных приложений, и, вероятно, rxvt-native пытается запустить bash (или любую другую команду) через систему.
@ EDIT1:
Таким образом, можно запустить 32-битное приложение из Cygwin 64 (краткая проверка не выявила никаких официальных источников, утверждающих, что это неподдерживаемая конфигурация). Но в данном конкретном случае, поскольку приложение является сложным (это терминал, необходимый для запуска нескольких других приложений), возникает проблема. Возможные пути (некоторые предложенные другими людьми) пойти дальше:
- Время отпустить (вероятно, есть веская причина, почему он не был портирован). Переключиться на современную замену (Mintty)
- Ищите неофициальную предварительно собранную 64-битную версию rxvt или попробуйте собрать ее самостоятельно (есть другие люди, которым она нравится)
- На вашем компьютере установлены обе среды (Cygwin 32 и Cygwin 64)
- Используйте свой любимый терминал (из Cygwin 32). Это будет ваша "основная" среда
- Администрирование Cygwin 64 "удаленно", например, через:
- ssh: я не проверял ограничения, связанные с двумя sshd, работающими параллельно на одной и той же машине, но если их нет, вам следует изменить порт прослушивания по умолчанию (22) для одного из них. Я бы предложил сделать это для первого, чтобы последний был доступен снаружи, используя настройки по умолчанию
- Продолжайте исследования в этом направлении, но, как я вижу, он начинает (если он еще не стал) стать картой замка - это больше похоже на обходной путь (получай)
Нет, ты не можешь.
Для 32-битного приложения требуется 32-битный cygwin1.dll, а для 64-битного cygwin - 64-битный cygwin1.dll.
Rxvt win32 native был заменен на mintty, который является терминалом cygwin по умолчанию