LINUX.ORG.RU

Как грамотно слинковать приложение для распространения в бинарном виде на другие ПК?

 , , , ,


0

2

Добрый день.

Написал GUI-приложение (игру) с использованием SDL, OpenAL, ну и всяких там libpng. Задача - скомпилировать всё так, чтобы результат можно было распространять в бинарном виде на другие ПК и чтобы не было проблем с зависимостями.

Изначально планировал положить в папку все основные .so-файлы, которые выдаёт ldd mygame. Но, во-первых, я не уверен, что это правильное решение, а во-вторых, упёрся как минимум в одну дебильную проблему. Я работаю в Debian 9, в которой пакет libSDL2 имеет версию 2.0.5+dfsg1-2. При запуске на виртуальной машине с чистым Debian 8 получаю ./libSDL2-2.0.so.0: undefined symbol: wl_proxy_marshal_constructor_versioned. При этом, если пакет libSDL2 установить в Debian 8 (версия пакета 2.0.2+dfsg1-6), все работает. Что ж это, брать более старую версию?

Чистый Ubuntu 12.04 ругается на отсутствие libXss.so.1, libwayland-client.so.0 и др., которых в папке с игрой действительно нет и я не уверен, при чём тут вообще wayland.

Кстати, в папку даже положил libstdc++.so.6, иначе ругается на version CXXABI_1.3.9 not found, version GLIBCXX 3.4.21 not found и т.д., -static-libstdc++ не дает никакого эффекта.

Короче, как грамотно поступить-то? Для справки, некоторые библиотеки под LGPL, их надо линковать только динамически. Но большинство под лицензией BSD/MIT/ZLib/WTFPL.

Собирай все библиотеки статически, в качестве libc возьми musl и не будет у тебя проблем.

-static-libstdc++ не дает никакого эффекта

А у тебя, блин, собранная статически libstdc++ вообще есть? Иначе что он линковать будет-то?

их надо линковать только динамически

GTFO проприетарщик чёртов.

timdorohin ★★★ ()
Последнее исправление: timdorohin (всего исправлений: 2)
Ответ на: комментарий от timdorohin

у тебя, блин, собранная статически libstdc++ вообще есть?

Не знаю, я думал, она есть в -dev пакете.

GTFO проприетарщик чёртов.

Спокуха, позже будет выпущена свободная версия под BSD-подобной лицензией.

ALPINE ()

Golang рулит. Это его дефолтовая фича, собирать всё в монолитный автономный переносимый бинарник :)

KRoN73 ★★★★★ ()

можно собирать в докере с самой старой убунтой, которую хочешь поддерживать.

waker ★★★★★ ()

Обычно таскают с собой с LD_LIBRARY_PATH (можно сделать бинарник компилировать вендастафл с rpath=.) Статическая линковка для мудаков.

положил libstdc++.so.6

Не делай так. Или собирай с версиями, доступными в последней обновлённой LTS убанте, или забей на дурачков. Можешь минимизировать левые зависимости.

12.04

поехавший что ли

anonymous ()

Это невозможно в принципе. Не трать время, распространяй исходники.

slovazap ★★★★★ ()

Короче, как грамотно поступить-то?

Собирай пакет для каждого поддерживаемого дистра. С зависимостями от библиотек в репозитории по возможности.

Harald ★★★★★ ()

некоторые библиотеки под LGPL, их надо линковать только динамически.

Проприетарщина? И даже для проприетарщины можно найти решение, выложив объектники.

Спокуха, позже будет выпущена свободная версия под BSD-подобной лицензией.

А, т.е. сначала мы пострадаем, а потом придём к простому решению. Нормально.

hobbit ★★★★★ ()

могу собрать/портировать(сли надо) за тебя на WebAssembly и будет из браузера работать везде

missxu ()
Ответ на: комментарий от KRoN73

Golang рулит. Это его дефолтовая фича, собирать всё в монолитный автономный переносимый бинарник :)

который не работает нигде кроме твоей ОС, держи в курсе

missxu ()
Ответ на: комментарий от missxu

который не работает нигде кроме твоей ОС, держи в курсе

Где не работает бинарник ipfs или syncthing?

KRoN73 ★★★★★ ()
Ответ на: комментарий от gasinvein

Собирай в flatpak, публикуйся на Flathub.

Даже не думай об этом! В топку этот плоскопак!

Причина проста. Время жизни стандартных runtime неизвестно. 6, 12 или более месяцев? Автор ничего не гарантирует.

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

Надо взглянуть на опыт gog, steam. Либо носить все нужные библиотеки с собой или выбрать нужную версию дистрибутива и раз в 2 года (Debian, Ubuntu) адаптировать игру под них.

anonymous ()

Почитай эти два моих сообщения:

Интервью с креативным директором Gaijin Entertainment (комментарий)
Интервью с креативным директором Gaijin Entertainment (комментарий)

Пример игры, собранной по советам по ссылке: https://yadi.sk/d/VU8tPelkZrBd7 Я упоминал sh-файл, запускающий игру - я взял его из World of Goo, он также встречается без изменений в десятках других игр: Cogs, And Yet It Moves, VVVVVV, Super Meat Boy. В интернете есть инди-игра Me and My Shadow, там другой sh-файл, учитывающий также ARM-арзитектуру

ZenitharChampion ★★★★★ ()
Последнее исправление: ZenitharChampion (всего исправлений: 3)

Вот инструкция для тех, кто хочет скомпилировать новый GCC в старом дистрибутиве.

Лёгкий уровень: Ubuntu 16.04 (ядро 4.4)
Средний уровень: Debian 6 (ядро 2.6.32)
Сложный уровень: CentOS 4 (ядро 2.6.9)

Компилировать будем в /home/username/gcc-8. make install выполняем без sudo, потому что устанавливаем в директорию пользователя. Количество потоков сборки -jN для Intel CPU равно кол-ву реальных ядер (например -j4), для AMD FX - кол-ву ядер минус одно, например -j7.

Компилируем GMP

mkdir /home/username/builddir
cd /home/username/builddir
wget https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2
tar xf gmp-6.1.2.tar.bz2
cd gmp-6.1.2
CPPFLAGS=-fexceptions ./configure --enable-cxx --prefix=/home/username/gcc-8
make -j4
make install

Компилируем MPFR

cd /home/username/builddir
wget https://www.mpfr.org/mpfr-current/mpfr-4.0.1.tar.bz2
tar xf mpfr-4.0.1.tar.bz2
cd mpfr-4.0.1
./configure --prefix=/home/username/gcc-8 --with-gmp=/home/username/gcc-8
make -j4
make install

Компилируем MPC

cd /home/username/builddir
wget https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz
tar xf mpc-1.1.0.tar.gz
cd mpc-1.1.0
./configure --prefix=/home/username/gcc-8 --with-gmp=/home/username/gcc-8 --with-mpfr=/home/username/gcc-8
make -j4
make install

Компилируем ISL

cd /home/username/builddir
wget http://isl.gforge.inria.fr/isl-0.20.tar.bz2
tar xf isl-0.20.tar.bz2
cd isl-0.20
./configure --prefix=/home/username/gcc-8 --with-gmp=/home/username/gcc-8 --with-mpfr=/home/username/gcc-8 --with-mpc=/home/username/gcc-8
make -j4
make install

Компилируем GCC

cd /home/username/builddir
wget http://mirror.linux-ia64.org/gnu/gcc/releases/gcc-8.2.0/gcc-8.2.0.tar.gz
tar xf gcc-8.2.0.tar.gz
cd gcc-8.2.0
mkdir objdir
cd objdir
export LD_LIBRARY_PATH=/home/username/gcc-8/lib:$LD_LIBRARY_PATH
../configure --prefix=/home/username/gcc-8 --enable-languages=c,c++ --with-gmp=/home/username/gcc-8 --with-mpfr=/home/username/gcc-8 --with-mpc=/home/username/gcc-8 --with-isl=/home/username/gcc-8
make -j4
make install

Использовать так:

export CC=/home/username/gcc-8/bin/gcc
export CXX=/home/username/gcc-8/bin/g++

При распространении бинарника, скомпилированного этим компилятором, может понадобиться положить в архив с программой - libgcc.so.1 и libstdc++.so.6 из нового компилятора.

ZenitharChampion ★★★★★ ()
Последнее исправление: ZenitharChampion (всего исправлений: 5)

некоторые библиотеки под LGPL, их надо линковать только динамически

Нет.

xaizek ★★★★★ ()
Ответ на: комментарий от ZenitharChampion

Зачем так сложно? Зависимости можно просто закинуть в верхнеуровневую директорию к gcc, он сам их соберёт

Gvidon ★★★★ ()
Ответ на: комментарий от ZenitharChampion

Я сейчас практикую сложный уровень, считая что Linux 2.6.9 и Glibc 2.3 хватит всем. Во всяком случае, в 3D-играх, тогда как всякий софт для вычислений может захотеть более новый Glibc

Посмотри какой замечательный бинарник PCXS2 я сделал! Сборочное окружение: CentOS 5, ядро 2.6.18, GCC 4.8. Все зависимости = «с собой», это wxWidgets, libSDL, libGLEW, libCg, libSoundTouch, PortAudio. Если libSDL 1.2 и PortAudio не менялись уже лет 10, то libGLEW, например, регулярно обновляет свою версию. Вследствие чего, бинарник PCSX2 с сайта работает в одной конкретной версии убунты - ни версией ниже, ни версией выше. А мой работает везде

Я вносил изменения в исходный код, как правило это был даунгрейд минимально необходимой версии GTK2 с 2.24 до 2.10. Я просто смотрел историю коммитов, находил места, на которых останавливалась компиляция, и возвращал «осовремененный» код на старый. Также мне пришлось обновить linux-headers с 2.6.18 до 2.6.24 из Fedora 8, чтобы скомпилировалась поддержка геймпадов в плагине LilyPad. И задевайнить пару переменных для них же. Кстати, я не уверен что геймпады действительно работают после моих правок

Ещё мне понадобилось заменить системные файлы в /usr/include/GL на более новые версии, скачав их с сайта https://khronos.org/. Таким образом, плагин GSdx скомпилировался с поддержкой OpenGL 3, тогда как CentOS 5 вышел задолго до него. Мне вот интересно, а можно ли скомпилировать libSDL 2 с поддержкой Xinput 2 таким образом, не обновляя системный libXi до версии 1.3 или выше? Просто вместе с libXi мне также пришлось обновлять xcb, а это слишком низкоуровнево

ZenitharChampion ★★★★★ ()
Последнее исправление: ZenitharChampion (всего исправлений: 1)
Ответ на: комментарий от commagray

Лучше быть анонимусом, чем понифилом😉

anonymous ()
Ответ на: комментарий от ZenitharChampion

https://gcc.gnu.org/install/prerequisites.html

If a GMP source distribution is found in a subdirectory of your GCC sources named gmp, it will be built together with GCC
If an MPFR source distribution is found in a subdirectory of your GCC sources named mpfr, it will be built together with GCC

И так далее

А ещё вместе с gcc идёт скриптик contrib/download_prerequisites, который их ещё и скачает сам автоматически.

Gvidon ★★★★ ()
Последнее исправление: Gvidon (всего исправлений: 1)
Ответ на: комментарий от Landgraf

Snap де-факто ubuntu-only. Я бы не стал его советовать, по меньшей мере, до тех пор, пока не будет полноценной официальной поддержки в других дистрибутивах (а её, полагаю, не будет никогда).

gasinvein ★★★ ()

Интересная тема.

Тут много интересных подходов, но не нашел ответ на поставленный вопрос.

Вкратце если свести вопрос к:

Есть какая-то простая программа которую можно собрать, как сделать так чтобы все библиотеки были слинкованы статически?

Я всегда считал, что это просто какая-то опция gcc, нет?

P.S. я точно видел статически слинкованные бинарики - значит можно.

P.P.S подходы с переносами библиотек с собой, скриптами запуска и подгрузки этих библиотек - интересные подходы, но проще статически слинкованный бинарь, и обновлять его, в скорости сети и месте ни у кого проблем нет.

Как сделать?

VoDD87 ()
Ответ на: комментарий от VoDD87

Как сделать?

Для начала прочитать man ld.

ld -Bstatic -lfoo -lbar -Bdynamic -lbaz прилинкует libfoo и libbar статически, а libbaz динамически.

anonymous ()
Ответ на: комментарий от anonymous

Чуть не забыл - возможно тебе придётся самому собирать SDL с опцией --enable-loadso, потому что если дистрибутивная версия SDL собрана с --disable-loadso (а скорее всего так и есть), тебе придётся статически линковать иксовые либы, пыщпыщаудио и туеву хучу всего прочего. А так зависимости будут грузиться через dlopen. Из этого кстати следует, что glibc обязательно должна быть слинкована динамически.

anonymous ()
Ответ на: комментарий от Napilnik

Собирай и тестируй на более старом дистре чтобы не нацеплять новых зависимостей.

Нативный hmm3 давно запускали?

madcore ★★★★★ ()
Ответ на: комментарий от anonymous

--enable-loadso

Что-то я фигни написал. Нужные опции это --enable-BLAHBLAH-shared, перечень смотри в ./configure --help.

anonymous ()
Ответ на: комментарий от madcore

Нативный hmm3 давно запускали?

Вообще не в курсе что он есть, больше в различные KB играл. А вообще, он и не должен работать в линуксах - цэпэпэ, с его впылесосиванием уникальных системных фич, придумали не для написания чего-то бесплатного/свободного. То, что на линуксах такое пытаются писать, есть лишь стимулируемый проприетарщиками бэтатестинг.

Napilnik ★★★★★ ()

некоторые библиотеки под LGPL

Таки выкинуть эту бяку и линковать статически.

beastie ★★★★★ ()
Ответ на: комментарий от Einstok_Fair

Подойдет. Так же, если тебе можно или нужно встраивать какой-то скриптовый язык в приложение то стоит обратить внимание на Tk (tcl) и IUP(Lua) - менее популярные, но тоже +- неплохие тулкиты.

timdorohin ★★★ ()
Ответ на: комментарий от Einstok_Fair

На нём слишком удобно писать, это проблема для многих.

anonymous ()
Ответ на: комментарий от Einstok_Fair

Назови мне тулкит для интерфейса на питоне?Я же говорил о двух тулкитах которые тянут за собой скриптовые языки.

Нет смысла брать питон если Tk уже тащит за собой tcl, или IUP тащит Lua

Вот с WxWidgets выбор скриптового языка на тебе, да.

timdorohin ★★★ ()
Последнее исправление: timdorohin (всего исправлений: 1)
Ответ на: комментарий от Einstok_Fair

Это немного не то, это не кнопочки со списочками а диаграммы, графики и представления данных - это тулкит для визуализации, а не для GUI

timdorohin ★★★ ()
Ответ на: комментарий от anonymous

Мнээээ... я имел в виду что некоторые тулкиты используют скриптовые ЯВУ для своей работы (сами при этом могут быть написаны на C/C++)

Даже с Qt можно работать не написав ни строчки кода на c++ - qml и javascript позволяют делать много что.

Суть в том, что беря Tk тебе проще притащить в проект tcl нежели чужеродный ему puthon/lua и аналогично.

timdorohin ★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.