Een static MySQL libary gebruiken in plaats van dynamic

Pagina: 1
Acties:

  • pierre-oord
  • Registratie: April 2002
  • Laatst online: 15-01 10:55
Ik probeer een programma te schrijven wat gecompileerd en wel overal als package moet kunnen werken op x86 linux systemen.

Ik kan eventueel de huidige compileer scripts online zetten. Deze scripts (gewoon met die standaard ./configure en makefiles) zorgen ervoor dat van libmysqlclient.so.15 gebruik wordt gemaakt. Het programma functioneert hiermee juist, maar op een ander systeem gaat dat niet omdat dat bestand ontbreekt. In de binary vind ik verwijzingen naar libmysqlclient.so.15. Als ik mijn versie naar ander systeem move, dan blijft het programma hangen (ik heb nog geen lange debug kunnen doen maar 'tis ook logisch aangezien deze .so files zelf ook nog op andere libaries rusten)

Oplossing lijkt simpel: Static compileren. Dit heeft alleen wat meer voeten in de aarde dan dat het lijkt. De makefile scripts zijn via een soort project-systeem voor het grootste deel gemaakt (dat heeft een duitse vriend gedaan). We komen er alleen niet uit hoe we dit statisch moeten compileren. Alle opties al meegegeven, ik heb de makefile bewerkt, ik heb de output die het programma uiteindelijk compileerd (gcc blablabla) al aangepast met allerlei opties gevonden op internet, maar het blijft niet lukken.

Ook heb ik powerdns, die statisch te compileren valt (er zijn packages voor namelijk zoals .deb's) gedownload en met de optie voor statische binaries gecompileerd. Dit werkt prima. Alleen wil het overnemen van commando's uit de makefiles nog niet lukken.

Waar ik wel uit ben is dat gebruik moet worden gemaakt van libmysqlclient.a, omdat dit de statische versie is van libmysqlclient.so (die zelf weer op andere bronnen rust). Na wat doe wil het geheel soms compileren, maar dan komt de fout:
*** glibc detected *** double free or corruption (!prev): 0x081fafa0 ***

Heeft iemand voor mij enige informatie over het maken van het programma met een vaste libmysqlclient? Op google is helaas zeer weinig te vinden over mysql en op statisch compileren op zichzelf. Misschien is er ergens een prachtige makefile generator? Het programma is zeer klein en berust kwa libaries eigenlijk alleen op standaard libaries van C en dit mysql libary.

Mijn dank is groot voor een oplossing!


edit:
Iedereen vraagt mij steeds"Waarom" ik dit wil. Even korte uitleg:
- Ik wil het programma binary werkend kunnen hebben op machines. Zo kan iedereen het downloaden en zonder moeite installeren, zonder extra's nodig te hebben.

Ik heb net nog iets geprobeerd: De libmysqlclient.a file dynamic compileren. Ik dacht, dan heb ik alleen die .a nodig en niet de dependencies van libmysqlclient zelf. Het programma draait zelfs! Maar wel alleen op mijn machine. Zodra ik het kopieer, draait het programma (ik zie berichten) totdat de eerste connectie naar mysql database wordt opgezet. Dan krijg ik gelijk weer zo'n glibc fout. Ik heb toen van het systeem alle libmysqlclient.a files gerenamed, en mijn versie erop gezet, zonder succes.
Wat mij ook opviel is dat als ik de binary file doorzoek (met texteditor) dan kan ik altijd libmysqlclient.so.15 terugvinden, maar in het geval dat ik tegen de .a compileer, kan ik nergens meer iets over een .a file terugvinden.

Nou hele lap tekst zo nu maar wie weet is het behulpzaam. Ik denk dat de handigste oplossing gewoon static compileren is. Het moet kunnen, maar hóe!

[ Voor 27% gewijzigd door pierre-oord op 19-12-2005 00:09 ]

Ondernemer in tech (oud LOQED.com, nu UpToMore.com)


  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

Je zult de libmysqlclient ook static moeten compilen voordat je hem in een programma kunt gebruiken die daar naar linkt. libmysqlclient is namelijk zelf ook afhankelijk van een aantal andere libraries.
Als je een static libmysqlclient gebruikt zal het volgens mij direct moeten werken.

Nu met Land Rover Series 3 en Defender 90


  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Um.

Als je compiled hoor je geen verwijzingen te hebben naar specifieke libraries. De Linker gebruikt dan de op het systeem aanwezige libs. Als jij dus op de een of andere manier specifieke libs aan weet te spreken bij het compilen die er niet zijn dan doe je iets fout.

Gebruik je wellicht dlopen()? Da's niet de bedoeling namelijk.

Overigens is dit meer NOS dan PW volgens mij.

[ Voor 8% gewijzigd door CyBeR op 19-12-2005 08:43 ]

All my posts are provided as-is. They come with NO WARRANTY at all.


  • pierre-oord
  • Registratie: April 2002
  • Laatst online: 15-01 10:55
CyBeR schreef op maandag 19 december 2005 @ 08:38:
Um.

Als je compiled hoor je geen verwijzingen te hebben naar specifieke libraries. De Linker gebruikt dan de op het systeem aanwezige libs. Als jij dus op de een of andere manier specifieke libs aan weet te spreken bij het compilen die er niet zijn dan doe je iets fout.

Gebruik je wellicht dlopen()? Da's niet de bedoeling namelijk.

Overigens is dit meer NOS dan PW volgens mij.
Nee geen dlopen, het gaat puur om het compileerproces met ./configure, make. libmysqlclient.a is de static versie voor zover ik weet, als ik die nu gebruik (met zo'n linker programma ofzo en dan compileren met gcc?) dan wil die wel op mijn machine werken, maar krijg ik weer zo'n glibc fout op een andere machine zodra het een "mysql" functie van mijn programma gaat aanspreken. Als ik die .a file met -static options laat compileren, wil het programma op mijn systeem helemaal niet meer starten.

Maar misschien inderdaad een move naar NOS, zou een mod dat dan willen doen?

Ondernemer in tech (oud LOQED.com, nu UpToMore.com)


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 12:47
Een static library (.a) is in principe een archive (vandaar de a ;)) van object-files. Alleen de code van mysqlclient zit dus in de library. Die library zelf is waarschijnlijk wel weer afhankelijk van andere libraries, zoals in ieder geval de standard C library (libc) waar alle standardfuncties (als malloc() en socket() en weet ik het) in zitten. In het geval van mysqlclient zijn er verder, denk ik, geen dependencies, maar dat weet ik niet zeker.

Zoals je al gemerkt had zijn verschillende versies van libraries helaas niet helemaal binary compatible. Als je dus statisch linkt met libmysqlclient, maar nog steeds dynamisch linkt met libc, dan is de kans groot dat op een systeem met een incompatible libc je programma niet werkt. Wat dat betreft is de situatie eigenlijk hetzelfde als die waarin je het .so-bestand gekopieerd had.

Er zijn een aantal manieren om dit scenario op te lossen:
[list=1]
• De applicatie op elk systeem opnieuw van source compileren; je hebt daar al een geschikte build environment voor als ik het goed begrijp, en de source compatibility is meestal een stuk groter dan de binary compatibility.
• Zorgen dat alle systemen binary compatible zijn; beide systemen up-to-date brengen dus.
• De hele applicatie statisch compileren (inclusief libc) zodat je alleen afhankelijk bent van een compatible kernel.
De eerste optie is in principe het beste en geeft de beste portabiliteit, maar dat betekent dat je op elk systeem opnieuw moet compileren. De tweede optie wordt gebruikt voor binary packages - je kunt alleen een binary package installeren als de juiste versies van de benodigde libraries geïnstalleerd zijn.

De derde optie wordt vaak gebruikt door bedrijven die closed-source software leveren voor Linux. Het voordeel is dat een enkele executable op een heleboel verschillende systemen kan draaien, maar het nadeel is natuurlijk dat je de gebruikte libraries nooit los kunt upgraden en dat je binaries erg groot worden.
CyBeR schreef op maandag 19 december 2005 @ 08:38:
Als je compiled hoor je geen verwijzingen te hebben naar specifieke libraries. De Linker gebruikt dan de op het systeem aanwezige libs. Als jij dus op de een of andere manier specifieke libs aan weet te spreken bij het compilen die er niet zijn dan doe je iets fout.
Ik weet niet wat je bedoelt met 'specifieke libraries', maar het is dus wél de bedoeling dat je een verwijzing hebt naar 'libmysqlclient.so.15', juist om te voorkomen dat de dynamische linker je executable met een incompatible library linkt. Dat versienummer ('15') wordt alleen opgehoogd als een library z'n API zo wijzigt dat 'ie incompatible is met oudere versies.

edit:
Trouwens, die foutmelding (*** glibc detected *** double free or corruption (!prev): 0x081fafa0 ***) zou ook gewoon door een bug in je applicatie kunnen komen. Heb je al eens een stacktrace bekeken?

[ Voor 21% gewijzigd door Soultaker op 19-12-2005 20:53 ]


  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Soultaker schreef op maandag 19 december 2005 @ 20:49:
Ik weet niet wat je bedoelt met 'specifieke libraries', maar het is dus wél de bedoeling dat je een verwijzing hebt naar 'libmysqlclient.so.15', juist om te voorkomen dat de dynamische linker je executable met een incompatible library linkt. Dat versienummer ('15') wordt alleen opgehoogd als een library z'n API zo wijzigt dat 'ie incompatible is met oudere versies.
Nee, oh? :P Ik had 't niet over binaries van systeem naar syteem, maar bij het compilen.

All my posts are provided as-is. They come with NO WARRANTY at all.


  • pierre-oord
  • Registratie: April 2002
  • Laatst online: 15-01 10:55
@soultaker:

Bedankt voor je duidelijke uitleg. Ik laat nog even zien wat ik nu voor compileer script hebt gemaakt (eerst doe ik gweoon ./configure en daarna doe ik wat het "make" commando voor output geeft aanpassen in een eigen script, het programma is niet zo groot. Ik ben bang dat het met die libc te maken heeft, ik probeer het op een totaal ander systeem uit namelijk (ander OS, slackware geloof ik ipv debian).

Dit is de output van compileren:
code:
1
2
3
4
5
6
7
8
9
XXXXXXXXXX@pierre-srv:~/pierretest/src$ sh zogaathet
gcc -g -O2 --all-static -I/usr/include/mysql -o programma2 programma2.o sockets.o scheduler.o md5.o  /usr/local/mysql/lib/libmysqlclient.a -lz -lcrypt -lnsl -lm -lc -ldl
mkdir: cannot create directory `.libs': Bestand bestaat
/usr/local/mysql/lib/libmysqlclient.a(mf_pack.o): In function `expand_tilde':mf_pack.c:(.text+0x7a6): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/local/mysql/lib/libmysqlclient.a(libmysql.o): In function `read_user_name':libmysql.c:(.text+0x9d3): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/local/mysql/lib/libmysqlclient.a(mf_pack.o): In function `expand_tilde':mf_pack.c:(.text+0x7af): warning: Using 'endpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
programma2.o: In function `check_license':/home/christian/pierretest/src/programma2.c:96: warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/local/mysql/lib/libmysqlclient.a(my_gethostbyname.o): In function `my_gethostbyname_r':my_gethostbyname.c:(.text+0x24): warning: Using 'gethostbyname_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/local/mysql/lib/libmysqlclient.a(libmysql.o): In function `mysql_server_init':libmysql.c:(.text+0x5d): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking


Dit is het compileerscript:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if gcc -DHAVE_CONFIG_H -I. -I. -I..     -g -O2 -L/usr/local/mysql/lib -I/usr/include/mysql -MT programma2.o -MD -MP -MF ".deps/programma2.Tpo" -c -o programma2.o programma2.c; \
then mv -f ".deps/programma2.Tpo" ".deps/programma2.Po"; else rm -f ".deps/programma2.Tpo"; exit 1; fi

if gcc -DHAVE_CONFIG_H -I. -I. -I..     -g -O2 -L/usr/local/mysql/lib -I/usr/include/mysql -MT sockets.o -MD -MP -MF ".deps/sockets.Tpo" -c -o sockets.o sockets.c; \
then mv -f ".deps/sockets.Tpo" ".deps/sockets.Po"; else rm -f ".deps/sockets.Tpo"; exit 1; fi

if gcc -DHAVE_CONFIG_H -I. -I. -I..     -g -O2 -L/usr/local/mysql/lib -I/usr/include/mysql -MT scheduler.o -MD -MP -MF ".deps/scheduler.Tpo" -c -o scheduler.o scheduler.c; \
then mv -f ".deps/scheduler.Tpo" ".deps/scheduler.Po"; else rm -f ".deps/scheduler.Tpo"; exit 1; fi

if gcc -DHAVE_CONFIG_H -I. -I. -I..     -g -O2 -L/usr/local/mysql/lib -I/usr/include/mysql -MT md5.o -MD -MP -MF ".deps/md5.Tpo" -c -o md5.o md5.c; \
then mv -f ".deps/md5.Tpo" ".deps/md5.Po"; else rm -f ".deps/md5.Tpo"; exit 1; fi

#/bin/sh ../libtool --tag=CC --mode=link gcc  -g -O2 -L/usr/local/mysql/lib  --all-static -lmysqlclient -lz -lcrypt -lnsl -lm -lc -ldl -I/usr/include/mysql -o programma2   programma2.o sockets.o scheduler.o md5.o

/bin/sh ../libtool --tag=CC --mode=link gcc  -g -O2 --all-static /usr/local/mysql/lib/libmysqlclient.a  -lz -lcrypt -lnsl -lm -lc -ldl -I/usr/include/mysql -o programma2   programma2.o sockets.o scheduler.o md5.o


mkdir .libs

gcc -g -O2 -I/usr/include/mysql -o programma2 programma2.o sockets.o scheduler.o md5.o -static -L/usr/local/mysql/lib /usr/local/mysql/lib/libmysqlclient.a -lz


Ik denk dus dat het aan libc ligt, ik kwam op google alleen tegen dat alleen versie 2 static compileren ondersteund? Klopt dat? Lijkt me wat vreemd.

Over die bug:
De applicatie werkt non-static dus gewoon prima! Ik zie het programma wel de eerst print's op het scherm weergeven, maar zodra het bericht moet komen "geconnect anar mysql database" krijg ik die fout. Ik denk dus dat er iets niet goed gaat met mysql-includen of misschien met libc zelf. Anders zou het dynamic toch ook niet moeten werken?

Bij jouw punt 3 over upgraden libaries: dat kan dus alleen als het versienummer wordt gelijkgehouden begrijp ik? Dus als Debina bijvoorbeeld een eigen versie released van een binary als die fouten bevat. Opzich wel mooi (wel weer kans dat het breekt).

Kun je mij misschien wat meer vertellen over libc en dat statisch erin doen?
Overigens, op mijn debian machine staat een 4.0 versie van GCC (gcc version 4.0.3 20051201 (prerelease) (Debian 4.0.2-5)) om te compileren. Ik kan even niet vinden hoe ik aan de libc versie kan komen.

Bedankt voor al jullie info iig!

edit:
GLIBC versie debian systeem: pierre-srv:/home/christian/pierretest/src# /lib/libc.so.6
GNU C Library stable release version 2.3.5

GLIBC versie test systeem (glibc is hetzelfde als libc geloof ik toch.. misschien staat het voor GNU?): GNU C Library stable release version 2.3.4

Ik loop dus 1 versie vergeleken met het testsysteem.
Maar even nog voor de duidelijkheid: Ik heb nu met deze configuratie ook op mijn systeem de "*** glibc detected *** double free or corruption (!prev): 0x081c3000 ***" kort na het starten van het programma. Ik krijg het soms ook met die .a versie wel goed gecompileerd, maar dan krijg ik deze fout alsnog op het testsysteem. Hoe ik het nou goed kreeg gecompileerd ben ik even vergeten misschien kan iemand mij helpen met dat buildscript? (Overigens leunt dat volgens mij nog op andere makefiels, ik doe eerst een ./configure (waar amper opties in zitten) en dan make, om te zien welke commando's make uitvoert, en dan zet ik die in mijn bash script...

[ Voor 21% gewijzigd door pierre-oord op 19-12-2005 21:23 ]

Ondernemer in tech (oud LOQED.com, nu UpToMore.com)


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 22-01 23:51

NMe

Quia Ego Sic Dico.

PW>>NOS :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • pierre-oord
  • Registratie: April 2002
  • Laatst online: 15-01 10:55
Probleem opgelost!
Ik heb even wat directe informatie aan Soultaker gevraagd, waar ik heb erg dankbaar voor ben.
Het komt op het volgende neer:
- Mijn script klopt
- Ik moet inderdaad de .a file gebruiken.
- Static zorgt dat gcc zoekt naar static files om erbij te stoppen ipv dynamic.

Ik heb met ldd gecontroleerd wat er static en niet static was. Mysql ging standaard door gebruik van de .a static. Alleen als ik de libc dingen door de -static optie erin deed, ging het fout.

Wat blijkt is dat het gewoon een functie van het programma is. Waarom het alleen bij static compileren gebeurde, weet ik niet. Ik moet de exacte oorzaak nog vinden, maar voor nu, heb ik even de functie uitgezet, en dat werkt goed!
Als ik de exacte bug in het programma heb gevonden zal ik dat nog even posten.

Ondernemer in tech (oud LOQED.com, nu UpToMore.com)


  • _JGC_
  • Registratie: Juli 2000
  • Laatst online: 12:58
Ik denk dat je dit probleem te pakken hebt:
http://sources.redhat.com...pha/2003-06/msg00055.html

Er hoeft maar iets te veranderen tussen de glibc waar je statisch mee compileert en de glibc waar de boel onder draait en je hebt al crashes en corruption te pakken.

  • igmar
  • Registratie: April 2000
  • Laatst online: 31-01 23:50

igmar

ISO20022

pierre-oord schreef op maandag 19 december 2005 @ 21:13:
code:
1
/usr/local/mysql/lib/libmysqlclient.a(libmysql.o): In function `read_user_name':libmysql.c:(.text+0x9d3): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
En als je libmysqlclient_r gebruikt ? Je moet dan je applicatie linken met -pthread als optie, maar voor de werking zou dat niet uit mogen maken.
Pagina: 1