Russian Qt Forum
Ноябрь 05, 2024, 17:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Необходимо перенести свою прогу на Linux  (Прочитано 27849 раз)
Hort
Гость
« : Ноябрь 06, 2008, 13:30 »

Программирую с Qt на Windows. Все пока устраивает, но Qt - кроссплатформеная библиотека, так что возникает необходимость переносить свою прогу под Линукс.
С линуксом знаком только обзорно, так что посоветуйте самый безболезненный способ создать "сырцы" для него.
* Установил себе на виртуальной машине openSUSE 11 - с ним идет в комплекте Qt 4.4.0 - вроде должен подойти.
* Скачал qtcreator-0.9-linux-x86-setup.bin, что теперь с ним делать? openSUSE выдает диалог "открыть с помощью..." при его запуске.

И еще вопрос - можно ли сделать "сырцы" средствами одного QtCreator'а? и как именно?
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #1 : Ноябрь 06, 2008, 14:10 »

ты "сырцы" - исходники, сам уже сделал, если тебе скомпилить надо, то либо в командной строке это делай, либо в KDeveloper, а креатор это поделка, просто сговнили за пару дней/недель и все.
Записан

Юра.
ритт
Гость
« Ответ #2 : Ноябрь 06, 2008, 14:31 »

320.5К билдов за пару дней/недель? ну-ну...
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #3 : Ноябрь 06, 2008, 17:57 »

Программирую с Qt на Windows. Все пока устраивает, но Qt - кроссплатформеная библиотека, так что возникает необходимость переносить свою прогу под Линукс.
С линуксом знаком только обзорно, так что посоветуйте самый безболезненный способ создать "сырцы" для него.
* Установил себе на виртуальной машине openSUSE 11 - с ним идет в комплекте Qt 4.4.0 - вроде должен подойти.

Ну дык установи еще qt-4-4-0-devel пакеты. После их установки заходишь в каталог с исходниками, и даешь две команды

qmake super_mega_project.pro
make

И получишь бинарь.

Если что пойдет не так, устанавливай QT Open Source пакет с сайта троллей. Запиши в какой каталог он установился. Тебе нужно выяснить, в какой каталог qmake легло. И надо тогда запускать qmake с полным путем. Вот так

/usr/local/share/qt4/bin/qmake uper_mega_project.pro
make

Само собой, компилятор gcc тоже должен быть установлен.
Записан

Собираю информацию по крупицам
http://webhamster.ru
Hort
Гость
« Ответ #4 : Ноябрь 06, 2008, 18:21 »

И получишь бинарь.
мне наоборот нужен архив вида *.tar.gz чтобы другие пользователи могли его распаковать и командами
./configurate
make
make install
могли установить его на своем компе
Записан
Hort
Гость
« Ответ #5 : Ноябрь 06, 2008, 18:57 »

Установил себе Qt Creator. Там он установился с помощью какогото новомодного инсталятора. Я так понимаю он устанавливал уже скомпилированные файлы или компилировал их "на лету"? Чтобы "на лету" не похоже - слишком быстро установился даже на виртуальной машине. Теперь вопрос - как сделать такие же бинарники чтобы они запускались под любым линуксом, а не только под какимито определенными (как например *.rpm) и не зависили от версии дистрибутива, т.к. на сайте под линукс 2 инсталяхи - 32 и 64 битная - значит наверно от дистрибутива не зависит.
ЗЫ зачем мне это? чтобы пользователь просто взял инсталяху под линукс и утановил прогу, а не мучался с версиями Qt или искал установочные пакеты для своего дистрибутива
« Последнее редактирование: Ноябрь 06, 2008, 18:59 от Hort » Записан
Admin
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1988



Просмотр профиля
« Ответ #6 : Ноябрь 06, 2008, 21:31 »

для таких сборок нужно собирать Qt и все другие либы статически, и бинарь будет нехилого размера
Записан
Hort
Гость
« Ответ #7 : Ноябрь 06, 2008, 21:50 »

для таких сборок нужно собирать Qt и все другие либы статически, и бинарь будет нехилого размера
а как сделать архив tar.gz со скрипом установки своего Qt приложения? А то чтото гуглил и ничего путнего не нашел
Записан
ритт
Гость
« Ответ #8 : Ноябрь 06, 2008, 22:55 »

http://www.qt-prop.org/content/show.php/BitRock+InstallBuilder+for+Qt+Apps?content=58491
Записан
Hort
Гость
« Ответ #9 : Ноябрь 06, 2008, 23:56 »

ктонибуть может подкинуть инфу про генерацию configure скрипта для qt проектов? или как это делаете вы?
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #10 : Ноябрь 07, 2008, 03:03 »

Теперь вопрос - как сделать такие же бинарники чтобы они запускались под любым линуксом, а не только под какимито определенными (как например *.rpm) и не зависили от версии дистрибутива, т.к. на сайте под линукс 2 инсталяхи - 32 и 64 битная - значит наверно от дистрибутива не зависит.
ЗЫ зачем мне это? чтобы пользователь просто взял инсталяху под линукс и утановил прогу, а не мучался с версиями Qt или искал установочные пакеты для своего дистрибутива

То, про что ты говоришь - это мечта. О которой походу уже все линухоиды забыли. Как это тебе не покажется странным, но сделать бинарь (пускай и большой), который бы работал хотя бы на любом 32-х битном дистре линуха не получится! Говорю это из практики, какими только инструментами не пользовался (статификаторы, статическая сборка средствами компилятора, стат сборка через apbuild) - работать бинарь будет примерно в 15-20% в лучшем случае. Остальные случаи - сегфолт, или остановка программы с руганью на неправильную версию LIBC, руганью на версию X11, руганью на ненахождение графических дров, а если и "работает", то наблюдаются прочие глюки в виде отсутсвия звука или графики (если они использовались).

Посему, ныне существует такая концепция - прога должна распространяться в исходниках! Бинари засовывайте в жп. И на целевой системе прогу надо собирать из исходников. Если соберется - скорее всего работать будет. Ну или включать прогу в репозитарий, чтоб майнтейнер собрал, а пользователь тупо установил пакет.

Есть еще такой подход - называется билдферма. Разработчик вместо того чтоб разрабатывать программу, должен озаботится установкой ~50 виртуальных машин, собрать инсталляхи всех популярных в данный момент дистров (одной убунты надо сейчас где-то 6 штук - 6.04, 6.10, 7.04, 7.10, 8.04, 8.10) каждый дистр ставится в свою виртуальную машину, пишутся скрипты, чтоб сборка шла в каждой виртуалке с учетом особенностей каждого дистра. Ну и пакеты можно заодно под конкретный дистр собрать (сам себе майнтейнер). Потом на сайте вываливается список дистров, и для каждого возможность скачать архив с бинарем или пакет в нужном формате с нужными зависимостями.

Вот полюбуйся здесь http://etersoft.ru/wine/platforms, как раз версии на билдферме собирали. Так долбаться надо для того, "чтобы пользователь просто взял инсталяху под линукс и утановил прогу".
Записан

Собираю информацию по крупицам
http://webhamster.ru
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #11 : Ноябрь 07, 2008, 03:18 »

Подробнее, какие залипухи возникат при бинарной переносимости в Линухе, расписаны здесь http://autopackage.org/docs/devguide/ch07.html.

Могу даже свой недоделаный перевод выложить, чтоб прочуствовал.

(Хм, не нашел paste-сервиса в котором бы текст с переносом длинных строк размещался. Везде строки не переносятся, надо горизонтально скроллить. Кто знает paste-сервис с форматированием конечного текста с автопереносом строк, дайте ссылу плиз).


Бинарная переносимость


Содержание

- Версии функций (Symbol Versions)
- Конфликты версий функций (Symbolic collisions)
- Фальшивые зависимости (Bogus dependencies)
- Заголовочные файлы (Headers)
- Обработка исключений (Exception handling internals)
- C++


Версии функций

Оказывается, довольно трудно делать бинарники, которые будут надежно работать на разных дистрибутивов, и даже в версиях одного и того же дистрибутива. Однако, для того чтобы ваш пакет был готов для корректной работы на всех дистрибутивах Linux, это проблема должна быть решена в первую очередь. Игнорировать эту проблему нельзя.

Первой проблемой является номер версии glibc. Glibc - это специальная библиотека, включенная в GNU C. Все программы используют ее либо прямо, либо косвенно, поскольку программный интерфейс ядра предоставляет функции для различных служб - для файловой системы, DNS поиска, арифметических функций и т. д. Эта библиотека, кроме того, занимается реализацией механизма shared library. Обычно, когда какая-либо библиотека теряет бинарную совместимость, майнтейнер (человек, ответственный за сборку), увеличивает главный (major) номер библиотеки, просто переименовав so-файл библиотеки (изменяется нужная цифра в имени so-файла). Это стандартное решение. И при таком решении, в системе может присутствовать одновременно несколько вариантов одной и той же библиотеки. Однако, для glibc такое решение применить невозможно, по многим причинам, не будем вдаваться в подробности почему. Вместо этого, используется переименование каждой отдельной функции, чтобы была возможность хранить разные версии одной и той же функции внутри glibc библиотеки. ELF-интерпретатор, при обработке библиотеки glibc, делает прозрачным доступ к нужной функции.

Чтобы увидеть такие функции, наберите команду

Код:
# nm --dynamic /lib/libc.so.6 | grep chown
000b0ec0 T chown
000f7030 T chown
000b0f20 W fchown
000b0fe0 T fchownat
000b0f80 W lchown

Видно, что есть две реализации функции chown.

Когда программа компилируется, она связывается с последними версиями функций. Если при запуске программы, функция нужной версий не присутствует в системе, процесс будет прерван и программа не запустится. Эта проблема, и производные от нее, присутствуют в UNIX-подобных системах в течение очень долгого времени. Так как пользователи не имеют возможности просто обновлять glibc, приложение должно быть скомпилировано с достаточно старым набором версий функций – версий, присутствующих в большем количестве дистрибутивов, в которых планируется запускать бинарник. К счастью, есть по крайней мере частичное решение этой проблемы в виде apbuild. Это решение подменяет для gcc контроль версий функций, используемых в программе. Если любая версия функции в системе окажется слишком новой для собираемой программы, сборка будет прекращена. Автоматически будет выбрана старая версия функции, и бинарник будет переносимым (по крайней мере, для glibc) так, что сможет работать с glibc 2.2 – т.е. даже на дистрибутивах, старее Debian Stable или RH 7.2!

(Бредовый абзац. Совершенно непонятно что такое apbuild и что делает эта программа).


Конфликты версий функций

Еще одна проблема – это конфликт функций. Семантика ELF, к сожалению, основывается на устаревшей концепции статической компоновки.  Когда программа выполняется, строится дерево зависимостей в бинарнике путем обхода функций через библиотеку /lib/ld-linux.so (которая является динамический компоновщик ELF).  Если, согласно зависимостям, программа foo, зависит от libbar.so, которая, в свою очередь использует libpng.so, то foo, libbar.so и libpng.so будут отмаппены в память. Семантически, все символы из этих объектов сбрасываются в одну большую кучу, и это является сутью проблемы. Когда происходит увеличение версии функции, ELF интерпретатор glibc будет всегда выбирать первую функцию которую найдет, независимо от того, что объект уже подвергался процессу компоновки ранее.

(Теперь я еще больше запутался, как происходит интерпретация ELF файлов)

Для примера, давайте возьмем наш бинарник foo, и свяжем его с двумя библиотеками libA и libB.  LibA в свою очередь будет связана с libA1, а libB связана с libB1. LibA1 и libB1 – это разные бинарники, и предположим, что в каждом есть своя реализация функции с именем someFunction(). То есть, имеем две абсолютно разные функции, которые имеют одно и то же имя. Казалось бы, что libA будет использовать функцию someFunction() из  libA1, а  libB будет вызывать функцию из  libB1, что достаточно интуитивно (и  именно так и происходит в Windows). Но в линукс такое поведение компоновщика не реализовано. Функция someFunction() будет вызываться из  libA1 только потому что будет найдена первой. И это, как правило, приводит к почти мгновенному сегфолту при старте программы.

Так почему эти конфликты версий приводят к проблемам портирования бинарников? Ну хотя бы из-за того, что когда две библиотеки объявляют функции с одинаковыми именами, это происходит достаточно редко, а вот когда в системе присутствуют две версии одной и той же библиотеки, то это довольно распространенное явление. К примеру, libpng  имеет две основных широко используемых версии -  libpng.so.2 и libpng.so.3, и они совместимы. При поставке программы в виде исходников компиляция произойдет с последней версией, но будет несовместимость в случае поставки бинарника. Если скомпилировать бинарник в дистрибутиве с  libpng.so.3, то программа будет слинкована с  libpng.so.3. Если пользователь захочет запустить эту программу в старом дистрибутиве, в котором есть только  libpng.so.2, то ему вначале нужно будет установить новую версию данной библиотеки, чтобы программа заработала. Мы можем сказать – что ж тут такого страшного? А неприятность в том, что программа (к примеру, игра) слинкована не только с libpng.so.3, но и с libSDL.

А теперь предположим, что  libSDL связана с библиотекой libSDL_image, которая в данном дистрибутиве была собрана с зависимостью от libpng.so.2. И теперь, когда программа будет загружена, две разных версии  библиотеки libpng (с одной стороны libpng.so.2, с другой стороны libpng.so.3) будут одновременно динамически подлинкованы, и это приведет к остановке программы. Это нехорошо.

Напомним, что мы имеем две версии исходников, которые не имеют ABI совместимости. В принципе, пользователь может решить проблему путем перекомпиляции программы, в момент которой произойдет линковка с libpng.so.2. На один раз этого будет достаточно. Но пересобирать программы из исходников не каждому по силам.

Как результат, при запуске, бинарники получаются связанными с библиотеками таким механизмом, в котором совершенно неизвестно, какие версии библиотек были использованы при компиляции бинарника. В принципе, запуск бинарника на другом дистрибутиве может произойти нормально, но никаких гарантий нет.

К счастью, существует решение этой проблемы в виде подключения к ELF-бинарнику надстройки в виде  исправлящих (fixup) правил, как это было реализовано в операционной системе Sun Solaris. Прямые и групповые применения правил исправления позволяют ограничить видимость функций, что предотвращает проблему конфликта версий. К сожалению, такого механизма нет в glibc. Есть добровольцы? Проблема настолько большая и глубокая, что разработчики системы autopackage планируют временно прекратить разработку autoackage-инструментария, и потратить несколько месяцев на работу по изменению glibc.


Фальшивые зависимости

Опять же, рассмотрим зависимость функций при  линковке. Типично, неприятность происходит при использовании конфигурирующих foo-скриптов, или конфигурирующих pkg-скриптов, которые находятся в  установочных пакетах, которые используются для распространения программ. Это удобные способы,  используемые для настройки системы сборки. К сожалению, есть побочный эффект – такие программы генерируют команды сборки, подобные следующей

Код:
-L/opt/foolib/lib -lfoo -lxml2 -lglib-2.0

Первые две опции понять достаточно просто (-L/opt/foolib/lib показывает путь, где могут находиться библиотеки программы foo, а -lfoo говорит линковщику что нужно собирать бинарник, используя библиотеку libfoo.so, которая скорее всего и лежит в каталоге /opt/foolib/lib). А что можно сказать о последних двух опциях? Они указаны из-за того, что библиотека libfoo содержит внутри себя вызовы функций из libxml2 и glib2. К сожалению, оказывается, что некоторые старые версии динамического линковщика (LD) пытаются полностью «покрыть» весь набор функций, используемых в зависимых библиотеках (т. е. чтобы был доступ к каждой функции библиотеки, даже если библиотека только находится в зависимостях, но ни одна функция этой библиотеки не используется). И так происходит для каждой библиотеки, и подобная обработка идет до конца цепочки зависимостей библиотек.

Это большая проблема. Даже если ваша программа не использует функции из библиотек glib или libxml, ваша программа все равно будет требовать данные для подключения каждой библиотеки, расположенной в дереве (цепочке) зависимостей. Если совместимая версия libfoo присутствует в системе пользователя, но она слинкована с какой-нибудь другой библиотекой «не той» версии, ваш бинарник работать не будет, так как получается фальшивая зависимость (зависимость от неиспользуемой библиотеки).

Этот вопрос решен в последней версии программы apbuild, которая может просканировать бинарный файл программы, найти фальшивые зависимости, и исключить их. Это делается с помощью опции -l.

Кроме того, данная проблема решена в binutils в версиях старше 2.15.90.0.2, и решается с помощью указания линковщику ld опции –as-needed. Начиная с версии 1.9 программа apbuild будет иметь подобную функцию (пока не реализованную), которая обеспечит высокую производительность и более аккуратное преобразование бинарника. А так же мы рекомендуем пользоваться системными утилитами toolchain.


Заголовочные файлы

Некоторые библиотеки, такие как GTK+ и glibc, часто требуют использования заголовков конкретных  версий. Другими словами, даже если требуются функции «начиная с версии 2.4», в случае если они уже были скомпилированы с другими GTK+ 2.4 заголовками, существует риск, что бинарник будет требовать зависимость от GTK+ 2.4.

Единственное правильное решение этой проблемы заключается в том, чтобы взять копии старых заголовков  нужной версии, и положить их в директорию программы apbuild, таким образом при сборке будут первыми найдены и использованы именно эти заголовки, а не заголовки, присутствующие в данный момент в системе.

В частности, это решение влияет на макрос g_return_if_fail, используемый в glibc, на обработку ctype в функциях glibc, на макрос GDK_THREADS_ENTER/EXIT, используемый в GDK, и на pthread_cleanup_push/pop.

...

Дальше не перевел еще.
Записан

Собираю информацию по крупицам
http://webhamster.ru
ритт
Гость
« Ответ #12 : Ноябрь 07, 2008, 03:33 »

> с руганью на неправильную версию LIBC, руганью на версию X11
все видели инсталлятор нвидиавских дров? сколько бинарей предлагается для скачивания? а ведь он ещё и модуль ядра собирает!
открой для себя posix; если возможно, собирай приложение под древними линухами (libc2.2, gcc2.9/3.4, ...) - большинство проблем с либси из-за использования функций, отсутствующих в старых версиях...

> руганью на ненахождение графических дров
о дровах конечное приложение вообще знать не должно. если графических дров нет, то и нехрен запускать гуёвое приложение под консолью )

альтернативно можно выставить минимальные требования к дистру и в почитайке указать, что прога не рссчитана на запуск под седьмым редхатом Улыбающийся
а если программа востребована и есть сорцы, заинтересованные всегда сами смогут состряпать пакет под желаемый дистр. если проект открытый (и, опять же, востребованный), советую выложить его на qt-apps.org/kde-apps.org - там довольно отзывчивое сообщество...
я лично наблюдал стремительный взлёт проекта smplayer (и даже сам внёс небольшую лепту) - если бы не помощь сообщества, smplayer до сих пор был бы домашним фронтэндом для небольшого круга посвящённых...
Записан
ритт
Гость
« Ответ #13 : Ноябрь 07, 2008, 03:37 »

xintrea, неплохой перевод Улыбающийся
но в статье некоторые проблемы преувеличены...про гтк не могу уверенно сказать (боюсь, данная проблема имеет место быть), но на счёт фиктивных зависимостей (например) - это уже давно не проблема...а то после такой статьи прям действительно можно испугаться линухов в целом Улыбающийся

всё приходит с опытом - экспериментируйте Улыбающийся
Записан
vaprele07
Гость
« Ответ #14 : Ноябрь 07, 2008, 04:06 »

все видели инсталлятор нвидиавских дров?
вообще-то это скрипт Смеющийся
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.062 секунд. Запросов: 22.