Статическая сборка Qt 4.8.1 на Ubuntu 12.04

Я пытаюсь создать почти статическое приложение из-за проблем с переносимостью. Я надеюсь, что смогу запустить исполняемый файл на нескольких 64-битных дистрибутивах Linux. Мне удалось статически связать Qt и построить со статически связанными libstdc++ и libgcc.

Однако у меня есть некоторые проблемы с сторонней библиотекой. Я собрал Qt с -qt-zlib, но мое конечное приложение по-прежнему динамически связано с системной zlib. В частности, я настроил с:

./configure -static -nomake demos -nomake examples -nomake tools -release -no-webkit -qt-zlib -no-gif -qt-libtiff -qt-libpng -qt-libmng -qt-libjpe

Я удалил все ссылки на zlib в приложении, предполагая, что приложение сможет ссылаться на статически созданную zlib Qt. Мне почти кажется, что Qt игнорирует флаг -qt-zlib и использует системную библиотеку, которую затем использует и мое приложение.

Кроме того, мне пришлось установить пакет libfontconfig-dev, чтобы шрифт после сборки из исходников не был ужасным, но теперь Qt также динамически связывается с ним. Как видите, есть статическая библиотека для libfontconfig, которую я пытался связать, но поскольку Qt уже слинкован с libfontconfig, компоновщик ее игнорирует. Есть ли способ во время сборки Qt указать не динамически связываться со сторонними библиотеками?

Я не хочу, чтобы какие-либо зависимости Qt были статически связаны, если это возможно. Прямо сейчас я считаю, что приложение будет работать по крайней мере на Ubuntu 12.04, но другие дистрибутивы вполне могут размещать некоторые библиотеки в других местах.

Фрагмент из моего файла .pro:

QT += core \
      gui \
      opengl
QMAKE_CXXFLAGS += -fpermissive
QMAKE_LFLAGS += -static-libgcc -static-libstdc++
CONFIG += static
TEMPLATE = app
LIBS += /usr/local/lib/libboost_thread.a \
        /usr/local/lib/libboost_program_options.a \
        /usr/lib/x86_64-linux-gnu/libfontconfig.a \
        /usr/lib/x86_64-linux-gnu/libGLU.a

Вывод из лдд:

linux-vdso.so.1 =>  (0x00007fff992b4000)
libSM.so.6 => /usr/lib/x86_64-linux-gnu/libSM.so.6 (0x00007f195ccbc000)
libICE.so.6 => /usr/lib/x86_64-linux-gnu/libICE.so.6 (0x00007f195caa2000)
**libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f195c86b000)**
libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f195c5cf000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f195c3be000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f195c089000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f195be85000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f195bc7d000)
**libGL.so.1 => /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1 (0x00007f195ba1c000)**
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f195b7ff000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f195b505000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f195b147000)
/lib64/ld-linux-x86-64.so.2 (0x00007f195ced9000)
libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007f195af42000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f195ad18000)
**libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f195ab00000)**
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f195a8e2000)
libglapi.so.0 => /usr/lib/x86_64-linux-gnu/libglapi.so.0 (0x00007f195a6bd000)
libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f195a4b9000)
libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f195a2b3000)
libX11-xcb.so.1 => /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1 (0x00007f195a0b1000)
libxcb-glx.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-glx.so.0 (0x00007f1959e99000)
libXxf86vm.so.1 => /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007f1959c94000)
libdrm.so.2 => /usr/lib/x86_64-linux-gnu/libdrm.so.2 (0x00007f1959a89000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f1959885000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f195967f000)

Обновление:

С тех пор я отказался от этой задачи, поскольку она не кажется выполнимой. Поскольку разработчик решил, что можно выпустить исходный код, я просто перенесу его со стандартными ./configure, make и make install.

Даже если бы я смог слинковать эти библиотеки статически, версия libc отличалась бы даже от Ubuntu 11. Насколько я знаю, libc нельзя слинковать статически. Похоже, лучший вариант — собрать пакет с автоматическими инструментами GNU, но даже это — болезненная задача.

Любые подсказки или советы о том, как использовать инструменты GNU для создания сценария ./configure для проекта Qt?


person Michael Boselowitz    schedule 21.05.2012    source источник


Ответы (2)


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

Лучшим решением для переносимости на платформах Linux является выпуск исходного кода и использование Autotools GNU для создания сценария ./configure. Однако эту задачу нелегко выполнить с проектами Qt.

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

Если вы не хотите выпускать исходный код, создайте полустатически (с Qt и, возможно, несколькими другими библиотеками) связанный исполняемый файл и установщик, который проверяет, что библиотеки находятся в правильных местах, и устанавливает их при необходимости.

person Michael Boselowitz    schedule 13.06.2012

Если я угадаю..

Некоторое время назад я сделал статически связанное приложение в какой-то ОС на базе Linux, и мне пришлось включить ВСЕ статические библиотеки, которые я хочу использовать, и сторонние тоже. Но с модулями Qt было непонятное поведение.. например для меня: qico модуль, который я хотел, будет включаться статически только с такими конструкциями:

в .pro файле:

QTPLUGIN += qico
DEFINES += STATIC

в main.cpp:

#ifdef STATIC
#include <QtPlugin>
Q_IMPORT_PLUGIN(qico)
#endif

Возможно, это поможет.

person Gerix    schedule 23.05.2012