Как сделать так, чтобы опция "mkbundle --deps" работала с моно 3.2.3

Я пытаюсь связать приложение с моно 3.2.3 в отдельный исполняемый файл. Для этого я следую этому руководству. После объявления переменных:

mono_version="3.2.3"
export MONO=/cygdrive/c/progra~2/Mono-$mono_version
machineconfig=$PROGRAMFILES\\Mono-$mono_version\\etc\\mono\\4.5\\machine.config
export PATH=$PATH:$MONO/bin
export PKG_CONFIG_PATH=$MONO/lib/pkgconfig
export CC="i686-pc-mingw32-gcc -U _WIN32"

Команда mkbundle --deps не может локализовать ссылочные сборки:

Unhandled Exception:
System.IO.FileNotFoundException: Could not load file or assembly 'gtk-sharp' or 
one of its dependencies. The system cannot find the file specified.
File name: 'gtk-sharp'

выполняя точно такую ​​же операцию с моно 2.10.9:

mono_version="2.10.9"
export MONO=/cygdrive/c/progra~2/Mono-$mono_version
machineconfig=$PROGRAMFILES\\Mono-$mono_version\\etc\\mono\\4.0\\machine.config
export PATH=$PATH:$MONO/bin
export PKG_CONFIG_PATH=$MONO/lib/pkgconfig
export CC="i686-pc-mingw32-gcc -U _WIN32"

mkbundle --deps --machine-config "$machineconfig" -c UI.exe

дает положительный результат:

OS is: Windows
WARNING:
  Check that the machine.config file you are bundling
  doesn't contain sensitive information specific to this machine.
Sources: 3 Auto-dependencies: True
   embedding: C:\users\piotr\desktop\authoringtool\UI\bin\debug\UI.exe
 config from: C:\users\piotr\desktop\authoringtool\UI\bin\debug\UI.exe.config
   embedding: C:\PROGRA~2\MONO-2~1.9\lib\mono\gac\gtk-sharp\2.12.0.0__35e10195dab3c99f\gtk-sharp.dll
   embedding: C:\PROGRA~2\MONO-2~1.9\lib\mono\gac\glib-sharp\2.12.0.0__35e10195dab3c99f\glib-sharp.dll
   .
   .
   .
   embedding: C:\PROGRA~2\MONO-2~1.9\lib\mono\4.0\Mono.Posix.dll
Machine config from: C:\Program Files (x86)\Mono-2.10.9\etc\mono\4.0\machine.config
Compiling:
as -o temp.o temp.s

Кто-нибудь знает причину такого поведения? Я использую 64-битную версию Windows 7 и Cygwin, которую я нашел на официальном сайте. Код был скомпилирован и протестирован на Xamarin Studio 4.2 и Visual Studio 2010.

1 ответ

Howto для mkbundle на Cygwin + Mingw

Протестировано с моно 4.0.3
В mono 4.0.3 mkbundle работает, но может быть сложно заставить его работать.
Сначала проверьте ваши настройки:

  • Установите Mono/GTK# по пути, который не содержит пробелов (то есть, не Program Files)
  • Установите рабочую цепочку компиляции MinGw/Cygwin (как для компиляции моно в Windows).
  • Определите обязательные переменные среды для mkbundle:
    • Расположение компилятора mingw должно быть в Windows PATH (используется cmd)
    • pkg-config также должен быть в Windows PATH
  • Используйте следующий скрипт cygwin (его можно адаптировать для запуска на cmd)
# M_PREFIX refers to Mono installation
# For more information, search for prefix installation in Mono documentation
M_PREFIX='/cygdrive/c/Mono'

export DYLD_FALLBACK_LIBRARY_PATH=${M_PREFIX}/lib:${DYLD_FALLBACK_LIBRARY_PATH}
export LD_LIBRARY_PATH=${M_PREFIX}/lib:${M_PREFIX}/lib/mono/4.5:${LD_LIBRARY_PATH}
export C_INCLUDE_PATH=${M_PREFIX}/include:${C_INCLUDE_PATH}
export ACLOCAL_PATH=${M_PREFIX}/share/aclocal:${ACLOCAL_PATH}
export PKG_CONFIG_PATH=${M_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}
# Here we added the system32 to make cmd available to mkbundle
# /usr/bin is the default location for mingw
export PATH=${M_PREFIX}/bin:/cygdrive/c/Windows/system32:/usr/bin:${PATH}

export CC="i686-pc-mingw32-gcc -U _WIN32"

Тогда вы можете запустить:

mkbundle --deps --keeptemp my.exe my.dll -o bundled.exe

Примечания: - Копировать mono-2.0.dll в каталоге приложения, как это должно быть распространено вдоль прилагаемого exe

cp ${M_PREFIX}/bin/mono-2.0.dll .

  • если -z zlib1.dll должен быть скопирован. (обратите внимание, что вызов gcc также изменяется). Вам может понадобиться больше dll в зависимости от того, как вы используете возможности фреймворка (не исчерпывающий список: libglib *.dll, libgmodule *.dll, libgthread *.dll, iconv.dll, intl.dll)
  • -c используется для создания только заглушки.
  • Вы должны указать все EXE и DLL, которые необходимы для комплекта.
  • --keeptemp сохранит temp.c и temp.s, которые могут пригодиться, если mkbundle потерпит неудачу при вызове gcc.
  • Если вы хотите вызвать gcc вручную (и это может понадобиться):
i686-pc-mingw32-gcc -U _WIN32 -g -o output.exe -Wall temp.c $(pkg-config --cflags --libs mono-2)  temp.o

Для консольных приложений

Чтобы заставить консольное приложение работать, вы должны удалить -mwindows из команды gcc. Для этого вы должны вызвать pkg-config --cflags --libs mono-2 и удалите -mwindows,

Вы должны получить что-то подобное потом:


    i686-pc-mingw32-gcc  -g -o output.exe -Wall temp.c -mms-bitfields -IC:/Mono/include/mono-2.0 -mms-bitfields  -LC:/Mono/lib -lmono-2.0 -lws2_32 -lpsapi -lole32 -lwinmm -loleaut32 -l advapi32 -lversion temp.s

Любой может улучшить mkbundle

mkbundle - это консольное приложение с открытым исходным кодом на C# ( на mono github), поэтому его можно легко модифицировать и перекомпилировать в зависимости от ваших потребностей. Чтение кода также может помочь понять, как он работает.
Использование cmd в качестве различных команд, используемых mkbundle, жестко запрограммировано, поэтому было бы полезно некоторое улучшение параметризации.

Другие вопросы по тегам