Можете ли вы запустить 32-битное приложение Cygwin в 64-битной установке?

Можно ли запустить 32-битное приложение Cygwin в 64-битной установке?

Мотивация: как описано в Где в cygwin 1.7.26 для 64-битных окон находится собственная утилита rxvt?, 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-битного варианта, но я все еще надеюсь, что есть способ ... Спасибо за любую помощь, которую вы можете оказать.


person joanis    schedule 15.01.2019    source источник


Ответы (2)


Как и любой другой дистрибутив Lnx, эмулятор Cygwin 64 позволяет запускать 32-битные исполняемые файлы (если они совместимы). Вам нужно всего лишь иметь:

  • Установлены правильные пакеты
  • Правильные .dll в нужном месте (как вы упомянули), но их ручное копирование (особенно в системные местоположения) не масштабируется и не гарантирует, что система будет работать должным образом впоследствии.

Во-первых, вам понадобится установленный пакет cygwin32 (как минимум):

Img0

Поскольку у меня нет вашего 32-битного исполняемого файла (мне не нравилось искать загрузку, распаковку и так далее ...), я создал небольшой пример (чтобы он запустился, вы ' d также нужны инструменты 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/StackOverflow/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/StackOverflow/q054206577]> ls
code.c
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054206577]> x86_64-pc-cygwin-gcc.exe -o exe-gcc-064.exe code.c
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054206577]> i686-pc-cygwin-gcc.exe -o exe-gcc-032.exe code.c -m32
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/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/StackOverflow/q054206577]>
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/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/StackOverflow/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/StackOverflow/q054206577]> ./exe-gcc-064.exe
"void*" is 64 bits long.
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054206577]>
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/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/StackOverflow/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/StackOverflow/q054206577]> ./exe-gcc-032.exe
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054206577]>
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054206577]> echo $?
127

Как видите, я столкнулся с той же проблемой для exe-gcc-032.exe. Зависимость ??? - это 32-разрядная cygwin1.dll. Давайте исследуем проблему:

[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/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/StackOverflow/q054206577]> cygcheck -f /usr/bin/cygwin1.dll
cygwin-2.11.2-1
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/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/StackOverflow/q054206577]>
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/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/StackOverflow/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/StackOverflow/q054206577]>
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/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/StackOverflow/q054206577]> export PATH=/usr/i686-pc-cygwin/sys-root/usr/bin:${PATH}
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054206577]> ./exe-gcc-032.exe
"void*" is 32 bits long.
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/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-битном варианте system вернул 127 (точно так же, как код выхода exe-gcc-032.exe, если не указан правильный путь). Я подозреваю, что эти 2 не могут быть связаны друг с другом, и что-то происходит со средой при запуске 32-битных приложений, и, вероятно, rxvt-native пытается запустить bash < / em> (или любую другую команду) через system.

@ EDIT1:

Итак, возможно запускать 32-битное приложение из Cygwin 64 (краткая проверка, не обнаружила никаких официальных источников, заявляющих, что это Неподдерживаемая конфигурация). Но в этом конкретном случае, поскольку приложение является сложным (это терминал, необходимый для запуска нескольких других приложений), возникает проблема. Возможные пути (некоторые из них предложены другими людьми) для дальнейшего развития:

  • Пора отпускать (наверное, есть веская причина, по которой его не перенесли). Переключитесь на современную замену (Mintty)
  • Найдите неофициальную предварительно собранную 64-битную версию rxvt или попробуйте собрать ее самостоятельно (есть некоторые другие люди, которым она нравится)
  • 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
  • Продолжайте исследования в этом направлении, но, насколько я понимаю, он начинает (если еще не стал) превращаться в карту замка - это больше похоже на обходной путь (gainarie)
person CristiFati    schedule 16.01.2019
comment
Спасибо за очень подробный ответ. Я заметил, что Cygwin не соблюдает LD_LIBRARY_PATH, спасибо за указание, что вместо этого он использует PATH для поиска DLL. Думаю, это согласуется с поведением Windows. Я попробую это, когда у меня будет возможность, и доложу о своих результатах. - person joanis; 16.01.2019
comment
Вы правы, в конце концов он по-прежнему использует загрузчик Win. Дайте поболтать о результатах :) - person CristiFati; 16.01.2019
comment
Хм, у меня частичный успех. Когда мой PATH указывает на то, где находятся 32-битные cygwin1.dll и libW11.dll, мой 32-битный rxvt работает, но он не рад: например, он не может запустить bash. Я думаю, что откажусь от этой идеи и выберу что-то поддерживаемое, либо перейду на cygwin32, выбрав терминал в Cygwin 64, либо, может быть, даже перейду на Putty. Спасибо за вашу помощь! - person joanis; 16.01.2019
comment
bash - это 64-битный процесс, но я не понимаю, почему его нельзя запустить из 32-битного. Что вы имеете в виду, говоря, что это не работает? Меня заинтересовало, попробую запустить какую-нибудь команду из своей программы и посмотрю, как она себя ведет. Но в любом случае, вся эта настройка - своего рода обходной путь, вы можете попробовать собрать rxvt для 64. Итак (до этого момента) терминал работает, но его нельзя использовать. - person CristiFati; 16.01.2019
comment
Извините, я должен знать лучше, чем говорить, что он не работает таким расплывчатым образом ... Итак, появляется окно rxvt, и курсор остается в верхней строке без приглашения или чего-либо, что печатается. запущен ps, процесс rxvt не имеет дочерних процессов. Однако к настоящему времени я успешно настроил mintty, так что я все равно откажусь от rxvt. - person joanis; 16.01.2019
comment
Это неверный ответ. Чтобы запустить 32-битный исполняемый файл cygwin, вы должны использовать 32-битную установку cygwin. 32-битный исполняемый файл требует 32-битного cygwin1.dll, и каждая DLL, вызываемая исполняемым файлом, должна быть 32-битной версией. Не существует адаптеров, которые позволяли бы переключаться между 32-разрядными библиотеками cygwin и 64-разрядными библиотеками cygwin. Но вы можете очень легко установить как 32-битную, так и 64-битную среду cygwin. Они не могут взаимодействовать через каналы Posix или разделяемую память, однако они используют одну и ту же дисковую файловую систему Windows и могут использовать только каналы Windows для обмена данными. - person Doug Henderson; 17.01.2019
comment
@DougHenderson: Я не согласен. Чтобы запустить 32-битный исполняемый файл cygwin, вы должны использовать 32-битную установку cygwin: это личное мнение или у вас есть официальные источники для его резервного копирования? Тогда как вы объясните наличие cygwin1.dll в пакете cygwin32? - person CristiFati; 17.01.2019
comment
Я старался, чтобы мой комментарий был простым. Как вы выяснили, потрудившись, вы можете получить простое приложение для работы. Вы использовали подмножество 32-разрядной установки и перепрыгнули через обручи, чтобы переключиться с 64-разрядной установки на 32-разрядную. Жизнь слишком коротка, чтобы так возиться. - person Doug Henderson; 17.01.2019
comment
@DougHenderson: Вы правы, это было несколько часов работы, но только потому, что, когда я сталкиваюсь с чем-то, что я не понимаю, почему это так, я хочу разобраться в этом. Возвращаясь к нашей текущей ситуации: ответ на вопрос OP - да (и это то, что я доказал в ответе). Вы можете запустить приложение, но не любое приложение. Есть ли альтернативы (лучше или проще ...), очень вероятно. Но ни в коем случае не делайте ответ неверным (или неправильным). Кстати, я многому научился в ходе этого расследования. - person CristiFati; 17.01.2019
comment
Просто вернулся, чтобы принять этот ответ. Вы решили проблему, как и просили, и я не виноват, что отказываюсь от этого пути. @DougHenderson Я согласен, что этих обручей слишком много, и поэтому я встал, но я также нашел очень информативным узнать, как это можно сделать. Хотелось бы, чтобы это было проще, но теперь я знаю, как это сделать, если понадобится снова, и я также знаю, что есть подходы получше. - person joanis; 19.01.2019
comment
PS: моя корзина SO не рассказывала мне об этих правках и комментариях, поэтому я просто видел правки сейчас. В противном случае я бы ответил раньше. - person joanis; 19.01.2019
comment
Ничего страшного, я никуда не тороплюсь :). К сожалению, не всегда все обстоит так, как нам хотелось бы. - person CristiFati; 19.01.2019

Нет, вы не можете.
32-битное приложение требует 32-битного cygwin1.dll, а 64-битное cygwin требует 64-битного cygwin1.dll.

Встроенный rxvt win32 был заменен на mintty, который является терминалом cygwin по умолчанию.

person matzeri    schedule 16.01.2019
comment
Терминал mintty работает, но мне он очень не нравится. Но теперь, когда вы намекнули на это, я попробовал еще раз и поигрался с параметрами настройки, и, возможно, я смогу адаптироваться к этому. Спасибо за предложение, возможно, пришло время отказаться от моего старого любимого ... +1, хотя Нет, вы не можете, не совсем точно (см. Ответ @CristiFati), - person joanis; 16.01.2019
comment
OP может успешно найти версию rxvt или urxvt для mingw32 или msys. Мне тоже нравится rxvt, когда-то, но адаптировался к mintty. - person Doug Henderson; 17.01.2019