Autor Wątek: Deployment binarki pod linuxem  (Przeczytany 4011 razy)

Offline Nargil

  • Użytkownik
    • projekty

# Styczeń 29, 2012, 19:28:05
No właśnie, jeśli udostępniam kod źródłowy, to każdy sobie skompiluje vs jego wersje bibliotek w systemie i problem znika (oprócz tego, że user musi pobrać sporo kodów źródłowych każdej używanej przeze mnie biblioteki), tudzież autorzy dystrybucji się tym zajmują by pakiet używał aktualnych bibliotek obowiązujących w distro.

Natomiast jeśli chcę wypuścić jedynie binarkę to co ?
Przykładowo ldd Debug/ProjektOgre
linux-vdso.so.1 =>  (0x00007fffcd5ff000)
libOgreMain.so.1.8.0 => /usr/lib/libOgreMain.so.1.8.0 (0x00007ff028411000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007ff0281f4000)
libOIS-1.3.0.so => /usr/lib/libOIS-1.3.0.so (0x00007ff027fd1000)
libBulletDynamics.so.2.79 => /usr/lib/libBulletDynamics.so.2.79 (0x00007ff027d73000)
libBulletCollision.so.2.79 => /usr/lib/libBulletCollision.so.2.79 (0x00007ff027a94000)
libLinearMath.so.2.79 => /usr/lib/libLinearMath.so.2.79 (0x00007ff027878000)
libBulletSoftBody.so.2.79 => /usr/lib/libBulletSoftBody.so.2.79 (0x00007ff02762e000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007ff027329000)
libm.so.6 => /lib/libm.so.6 (0x00007ff0270a9000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007ff026e93000)
libc.so.6 => /lib/libc.so.6 (0x00007ff026af3000)
libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x00007ff026855000)
libX11.so.6 => /usr/lib/libX11.so.6 (0x00007ff026519000)
libXt.so.6 => /usr/lib/libXt.so.6 (0x00007ff0262b4000)
libXaw.so.7 => /usr/lib/libXaw.so.7 (0x00007ff026043000)
libdl.so.2 => /lib/libdl.so.2 (0x00007ff025e3f000)
libboost_thread.so.1.48.0 => /usr/lib/libboost_thread.so.1.48.0 (0x00007ff025c24000)
libfreeimage.so.3 => /usr/lib/libfreeimage.so.3 (0x00007ff025690000)
libzzip-0.so.13 => /usr/lib/libzzip-0.so.13 (0x00007ff025489000)
libz.so.1 => /usr/lib/libz.so.1 (0x00007ff025270000)
/lib/ld-linux-x86-64.so.2 (0x00007ff028c1f000)
libbz2.so.1.0 => /lib/libbz2.so.1.0 (0x00007ff025060000)
libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00007ff024e45000)
libSM.so.6 => /usr/lib/libSM.so.6 (0x00007ff024c3e000)
libICE.so.6 => /usr/lib/libICE.so.6 (0x00007ff024a23000)
libXext.so.6 => /usr/lib/libXext.so.6 (0x00007ff024811000)
libXmu.so.6 => /usr/lib/libXmu.so.6 (0x00007ff0245f8000)
libXpm.so.4 => /usr/lib/libXpm.so.4 (0x00007ff0243e7000)
librt.so.1 => /lib/librt.so.1 (0x00007ff0241df000)
libXau.so.6 => /usr/lib/libXau.so.6 (0x00007ff023fdd000)
libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x00007ff023dd8000)
libuuid.so.1 => /lib/libuuid.so.1 (0x00007ff023bd3000)
Mam skopiować te wszystkie pliki do jakiegoś podkatalogu z moją binarką i stworzyć skrypt run.sh
LD_LIBRARY_PATH=./libs/ Debug/ProjektOgre $*?? Tam jest np libX***, a jak ktoś będzie miał inną, niekompatybilną wersję xorg ?

Czy ograniczyć się do tych bardziej egzotycznych bibliotek: Ogre, OIS, freeimage, bullet, boost.thread i liczyć, że resztą każdy ma w systemie ?

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Xirdus

  • Redaktor

# Styczeń 29, 2012, 23:36:03
Zrób paczki .deb i .rpm - mają one mechanizmy zależności, które mówią, jakie pakiety muszą zostać zainstalowane by twoja aplikacja działała.

Offline Nargil

  • Użytkownik
    • projekty

# Styczeń 30, 2012, 00:28:46
How ? Ja używam Archa.

To nie wymaga znajomości jakie paczki posiadają systemy (odpowiednio debian i rh) ?
Poza tym takie paczki lubią zmieniać numerki i wtedy będę się musiał bawić w maintance mojego pakietu.

Offline toxic

  • Użytkownik

  • +1
# Styczeń 30, 2012, 01:47:53
Mój przepis jest taki, żeby rozwiązać i wrzucić użytkownikowi do paczki jak najwięcej zależności, tj:
1) co się da to skompilować/zlinkować statycznie (nawet jeśli spodziewamy się, że użytkownik posiada część bibliotek u siebie, to i tak wolę mu wcisnąć większą binarkę, ale za to nie wymagającą tychże bibliotek)
2) co się nie da skompilować statycznie (albo jest nieopłacalne) - to dorzucam do paczki z grą (własne pliki .so) i dorzucam launchera, który ustawia odpowiednie LD_LIBRARY_PATH przed uruchomieniem binarki. Przykładowo w katalogu $paczka/lib32 sa pliki typu libsfml-1.6.so, libopenal1.so - coś tego typu.
3) i to chyba już... jedna rzecz która mi jeszcze przychodzi do głowy to to, żeby nie kompilować binarki na zbyt nowym :) linuksie - chodzi mi o zależność na libstdc++.so.6 - ta biblioteczka jest jakoś tam wewnętrznie wersjonowana i zdarzało mi się, że moje binarki zlinkowane (nie pamiętam czy statycznie czy dynamicznie) z libstdc++.so.6 nie odpalały się na starszych dystrybucjach, bo "RUNTIME COSTAM UNDEFINED" - jakiś tam error, że biblioteka standardowa jest w za niskiej wersji i mam spierdalać.

Gier co prawda nie sprzedałem ani jednej, ale coś takiego od biedy działało na co popularniejszych linuksach u znajomych.
Doradzałbym też obejrzenie jak paczkują swoje produkcje jakieś zespoły indie - np. możesz pobrać demo WorldOfGoo i zobaczyć jak oni się zpaczkowali, możesz spróbować podejrzeć linuksowe demo Defcon. Bliżej ogra - może Torchlight ma demo dla linuksa? I tamże podejrzeć jak to jest zrobione? Albo dowolne demo gier na linuksa. Zawartości powinny byc inspirujące ;-)

Z 'moich' projektów możesz też podejrzeć jak są paczki zrobione dla:
a) Warlocks Gauntlet -> http://musztardasarepska.pl/wgdown -> snapshot developerski (ale to jest robione na SFMLu, a nie Ogrze)
b) Shadow Clones -> http://systemszok.wikispaces.com/Pobierz (ogre, ale chyba 1.5.x, czyli stary :P)
c) Wielki Mistrz/cytadela -> http://amatorskagra.wikispaces.com/Download / https://bitbucket.org/toxic/citadel/downloads -> ogre1.6.x+bullet, czyli całkiem blisko tego co robisz

Może coś z tego skorzystasz (a może nie tędy droga - jak mówiłem, żadnej gry jak dotąd nie sprzedałem :) ).

pozdr,
tox

Offline bies

  • Użytkownik

# Styczeń 30, 2012, 02:28:59
WorldOfGoo ma tylko SDL, libogg i libvorbis ładowane przez $LD_LIBRARY_PATH. Reszta (w tym min. libstdc++.so.6) brana jest z systemu. Shank ma SDL, libfmod i libgcc/libstdc++ ładowane przez $LD_LIBRARY_PATH. Reszta (właściwie tylko glibc) z systemu. Shadowgrounds ma naprawdę dużo bibliotek załączonych (w tym i kawałki X-ów). Używane bez $LD_LIBRARY_PATH, zapewne przez -Wl,-rpath $ORIGIN. Zupełne podstawy brane są z systemu (glibc, OGL).

Moim zdaniem należy zainstalować sobie trzy najpopularniejsze (Ubuntu, Fedora i coś jeszcze) distro na wirtualkach w aktualnych wersjach i dorzucić do archiwum tyle bibliotek aby działało na każdej z nich. Zrobić skrypt lub ustawić RPATH w binarce. Statyczne linkowanie bym sobie odpuścił (kwestie licencji, upgrade'ów i ogólnej upierdliwości). Podobnie robienie rpm/deb jeśli nie ma się zbyt dużo wolnego czasu.
« Ostatnia zmiana: Styczeń 30, 2012, 02:30:45 wysłana przez bies »

Offline Anton Chigurh

  • Użytkownik

# Styczeń 30, 2012, 14:22:06
Również nie polecałbym linkowania statycznego, chyba, że dołączasz wszystkie źródła.
Natomiast ogólnie w linuksach z systemami repozytoriów, czyli albo prawie wszystkich albo wszystkich, wystarczy moim zdaniem podać listę zależności, bo użytkownik sam je sobie bez trudu dociągnie, a już ostatecznym rozwiązaniem jest moim zdaniem podać komendy dla poszczególnych systemów pakietowych typu:

Debian/Ubuntu/... : apt-get install ...
Red Hat/Fedora/... : yum install ...
itd.

Wydaje mi się, że użytkownik linuksa powinien umieć włączyć emulator terminala i skopiować i wkleić komendę.

Z resztą po co binarki, kiedy są cmake itp. ? ;-)

Offline Nargil

  • Użytkownik
    • projekty

# Styczeń 30, 2012, 15:33:02
...
No ale zależności zależnościami. U mnie w Archu to wygląda tak, że robią aktualizację systemu, aktualizuje mi się boost, lub wxGTK i już pliki .so mają inny numerek. Nadal mam te pakiety, ale moja aplikacja została skompilowana przeciw wersjom poprzednim i nie może ich znaleźć - odmawia włączenia się, trzeba ponownie zlinkować.
« Ostatnia zmiana: Styczeń 30, 2012, 15:34:37 wysłana przez Nargil »

Offline Anton Chigurh

  • Użytkownik

# Styczeń 30, 2012, 22:09:25
A czy nie jest tak, że w usr/lib masz po 2-3 symlinki do danej biblioteki z odrzuconymi kolejnymi numerkami wersji? Coś jak:

plik foo.so.1.2.3
link foo.so.1
link foo.so

Od kilku lat używam linuksa i zawsze wystarczały mi biblioteki z repozytorium. Inna sprawa, że przeważnie korzystam z wolnego oprogramowania, które kompiluję więc z binarkami mam mniejsze doświadczenie. W windowsie jak coś próbowałem z binarkami czarować to rzeczywiście zaczynało się piekło: tu static, tam dynamic, tu single, tam multithreaded, i jeszcze debug/release.

W takim razie cofam to o repozytoriach :) Z binarkami jest po prostu kicha.

Offline Nargil

  • Użytkownik
    • projekty

# Styczeń 30, 2012, 22:36:37
libboost_thread.a
libboost_thread.so
libboost_thread.so.1.48.0
.so jest symlinkiem na so.1.48.0

ldd na moim projekcie wskazuje, że binarka bezpośrednio szuka so.1.48.0.
Zmuszanie kogoś, by do /usr/lib wrzucał sobie inną wersję biblioteki, niż aktualna odpada. Nikt nie chce śmiecić systemu.

Offline agent_J

  • Użytkownik

# Styczeń 31, 2012, 00:08:21
Zrób DEB i RPM jako paczki standardowe, a całą resztę olej. Albo jak Skype: ubuntu, debian, openSUSE, fedora, dynamic i static.


Offline rastabaddon

  • Użytkownik

# Maj 25, 2013, 22:22:31
ja robie lanczera

int start::execute(std::string baseDir,std::string programName,std::string image,char *const argv[], char *const envp[])
{
std::string program;
std::string bits = "64";
std::string ext = "";

#ifdef _WIN32
baseDir += "bin/windows";
ext = ".exe";
bits = "32";
#else
baseDir += "bin/linux";
bits = "64";
#endif

baseDir += "/";
baseDir += bits;
baseDir += "/";

chdir(baseDir.c_str());

baseDir = getcwd (NULL,0);

program = baseDir;

#ifndef _WIN32
program += "/";
#else
program += "\\";
#endif

program += programName;
program += bits;
program += ext;

#ifndef _WIN32
setenv("LD_LIBRARY_PATH", baseDir.c_str(),0);
#endif

printf("Base dir: %s\n\r",baseDir.c_str());
printf("Starting: %s\n\r",program.c_str());


int ret = system(program.c_str());

printf("Return: %i\n\r",ret);

return ret;
}


i wrzucam niezbedne biblioteki