[C] statische library maken

Pagina: 1
Acties:
  • 191 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
Hoewel ik al een tijdje met c/c++ werk, blijft het linken soms een groot raadsel voor mij.

Enige tijd geleden had ik een library gestart, namelijk SDL_ffmpeg. Dit is een soort wrapper voor ffmpeg, zodat de beginnende programmeur aan de slag kan met audio/video :)

Alles goed en wel, maar nu liep ik een beetje vast tijdens het maken van een statische library voor Windows.
Ik maak gebruik van gcc/ar voor het maken van de library. Nadat ik alle sources gecompileerd had, dacht ik makkelijk een library te kunnen maken door alle benodigde object files te maken en deze dmv ar in een bestand te proppen. Het probleem is echter dat ik dan allerlei undefined references krijg. Dit terwijl ik echter zeker weet dat deze functies wél in de library zitten...

Hier loop ik dan ook een beetje vast, ik weet dat de volgorde van linken uit kan maken, maar ik zie niet hoe ik daar rekening mee kan houden in een statische library. Het idee is dus dat ik uiteindelijk één library over houd waarin zowel de functies van ffmpeg en mijn eigen wrapper functies zitten.

Wie kan mij verder helpen? alvast bedankt!

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Als je een library maakt, dan zitten daar alleen de object files in die je opgeeft voor de library, niet ook nog eens andere object files uit andere libraries waar je toevallig gebruik van maakt. Een library maken is geen linken, dependencies worden dus ook niet uitgezocht. Een library is niets meer dan een verzameling van object files en symbols.

Als een applicatie met jouw lib linkt moet hij dus ook met SDL_ffmpeg linken. Of je moet de SDL_ffmpeg library extracten en toevoegen aan je eigen library (of misschien kun je ze gewoon mergen, ben niet zo bekend met gcc wat dat betreft)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
hmm, misschien heb ik het niet goed uitgelegd.

Wat ik dus wil is dat m'n library, libSDL_ffmpeg.a, voorziet in de functies van ffmpeg.
Dus zodat ik het voorbeeldprogramma als volgt zou kunnen maken.
$ gcc example.c -lSDL -lSDL_ffmpeg -o SDL_ffmpeg_example

Momenteel lukt dit niet omdat ik allemaal undefined references krijg.

echter, volgens nm zitten de functies wel in m'n library

$ nm lib/libSDL_ffmpeg.a | grep SDL_ffmpeg
SDL_ffmpeg.o:
00000000 T _SDL_ffmpegCreateFile
00000b63 T _SDL_ffmpegDecodeThread
0000108e T _SDL_ffmpegFlush
000000fb T _SDL_ffmpegFree
000012bc T _SDL_ffmpegGetAudioFrame
00001536 T _SDL_ffmpegGetAudioSpec
000009df T _SDL_ffmpegGetAudioStream
000015e6 T _SDL_ffmpegGetDuration
00001512 T _SDL_ffmpegGetPosition
00001754 T _SDL_ffmpegGetState
000007ce T _SDL_ffmpegGetVideoFrame
0000161b T _SDL_ffmpegGetVideoSize
00000a67 T _SDL_ffmpegGetVideoStream
00000124 T _SDL_ffmpegOpen
0000171d T _SDL_ffmpegPause
00001465 T _SDL_ffmpegReleaseAudio
0000097c T _SDL_ffmpegReleaseVideo
00000f0c T _SDL_ffmpegSeek
00001062 T _SDL_ffmpegSeekRelative
00000a26 T _SDL_ffmpegSelectAudioStream
00000aae T _SDL_ffmpegSelectVideoStream
00000aef T _SDL_ffmpegStartDecoding
00000b23 T _SDL_ffmpegStopDecoding
000016b5 T _SDL_ffmpegValidAudio
000016e9 T _SDL_ffmpegValidVideo


dus...ik heb geen idee :(

[ Voor 1% gewijzigd door Arjan op 12-01-2008 12:19 . Reden: non de-mangled nm output ]

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 15-07 15:35

leuk_he

1. Controleer de kabel!

en je compileert de library met dezelfde opties als je example.c?

C/C++ conflicten?

[ Voor 13% gewijzigd door leuk_he op 12-01-2008 00:49 ]

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
leuk_he schreef op zaterdag 12 januari 2008 @ 00:48:
en je compileert de library met dezelfde opties als je example.c?

C/C++ conflicten?
jup, alles zonder opties gecompileerd.

ik ben zo handig geweest om c++ te vermelden, terwijl ik momenteel alleen nog maar met C bezig ben.
C/C++ conflicten met name mangling enzo zijn dus ook niet aan de orde..

gcc -Iinclude/ -DSDL_FFMPEG_LIBRARY -I/c/lib/SDL-1.2.12/include -I/c/src/ffmpeg/libswscale -I/c/src/ffmpeg/libavutil -I/c/src/ffmpeg/libavformat -I/c/src/ffmpeg/libavcodec -c src/SDL_ffmpeg.c -o obj/SDL_ffmpeg.o

ar -rc lib/libSDL_ffmpeg.a obj/SDL_ffmpeg.o

gcc -Iinclude/ -lmingw32 -lSDLmain -lSDL -lSDL_ffmpeg -I/c/lib/SDL-1.2.12/include -L/c/lib/SDL-1.2.12/lib -Llib src/example.c -o bin/SDL_ffmpeg_example

../Temp/ccY1aaaa.o:example.c:(.text+0x1a): undefined reference to `SDL_ffmpegGetAudioFrame'
../Temp/ccY1aaaa.o:example.c:(.text+0x4d): undefined reference to `SDL_ffmpegGetAudioFrame'
../Temp/ccY1aaaa.o:example.c:(.text+0xc3): undefined reference to `SDL_ffmpegReleaseAudio'
../Temp/ccY1aaaa.o:example.c:(.text+0x14e): undefined reference to `SDL_ffmpegOpen'
../Temp/ccY1aaaa.o:example.c:(.text+0x197): undefined reference to `SDL_ffmpegGetAudioStream'
../Temp/ccY1aaaa.o:example.c:(.text+0x236): undefined reference to `SDL_ffmpegGetVideoStream'
../Temp/ccY1aaaa.o:example.c:(.text+0x2dc): undefined reference to `SDL_ffmpegSelectVideoStream'
../Temp/ccY1aaaa.o:example.c:(.text+0x2ef): undefined reference to `SDL_ffmpegSelectAudioStream'
../Temp/ccY1aaaa.o:example.c:(.text+0x30a): undefined reference to `SDL_ffmpegGetAudioSpec'
../Temp/ccY1aaaa.o:example.c:(.text+0x326): undefined reference to `SDL_ffmpegGetVideoSize'
../Temp/ccY1aaaa.o:example.c:(.text+0x348): undefined reference to `SDL_SetVideoMode'
../Temp/ccY1aaaa.o:example.c:(.text+0x385): undefined reference to `SDL_OpenAudio'
../Temp/ccY1aaaa.o:example.c:(.text+0x3b5): undefined reference to `SDL_ffmpegStartDecoding'
../Temp/ccY1aaaa.o:example.c:(.text+0x3c1): undefined reference to `SDL_PauseAudio'
../Temp/ccY1aaaa.o:example.c:(.text+0x3dd): undefined reference to `SDL_PollEvent'
../Temp/ccY1aaaa.o:example.c:(.text+0x402): undefined reference to `SDL_PumpEvents'
../Temp/ccY1aaaa.o:example.c:(.text+0x414): undefined reference to `SDL_GetMouseState'
../Temp/ccY1aaaa.o:example.c:(.text+0x42a): undefined reference to `SDL_ffmpegGetDuration'
../Temp/ccY1aaaa.o:example.c:(.text+0x467): undefined reference to `SDL_ffmpegSeek'
../Temp/ccY1aaaa.o:example.c:(.text+0x47a): undefined reference to `SDL_ffmpegPause'
../Temp/ccY1aaaa.o:example.c:(.text+0x48a): undefined reference to `SDL_ffmpegGetVideoFrame'
../Temp/ccY1aaaa.o:example.c:(.text+0x4b8): undefined reference to `SDL_UpperBlit'
../Temp/ccY1aaaa.o:example.c:(.text+0x4ca): undefined reference to `SDL_ffmpegReleaseVideo'
../Temp/ccY1aaaa.o:example.c:(.text+0x4d5): undefined reference to `SDL_Flip'
../Temp/ccY1aaaa.o:example.c:(.text+0x4e1): undefined reference to `SDL_Delay'
../Temp/ccY1aaaa.o:example.c:(.text+0x4f1): undefined reference to `SDL_ffmpegFree'

[ Voor 91% gewijzigd door Arjan op 12-01-2008 01:22 . Reden: command line output toegevoegd ]

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15:26
Arjan schreef op zaterdag 12 januari 2008 @ 01:14:
C/C++ conflicten met name mangling enzo zijn dus ook niet aan de orde..
Waarom gebruik je bij het nm commando dan -C ( demangle ) ? Weet je zeker dat je extern C gebruikt?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
farlane schreef op zaterdag 12 januari 2008 @ 09:35:
[...]

Waarom gebruik je bij het nm commando dan -C ( demangle ) ? Weet je zeker dat je extern C gebruikt?
ja, dat sloeg inderdaad ook nergens op, ik ben bang dat het gisteren gewoon wat laat was ;)

ik heb de output veranderd naar de niet de-mangled versie :)

voor de goede orde, c++ wordt atm. nergens gebruikt, omdat c++ mijn 'native' taal is ben ik de hele tijd verwarring aan het zaaien, maar ik heb bewust gekozen deze lib in C te schrijven om maximale portabiliteit te garanderen!

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15:26
Arjan schreef op zaterdag 12 januari 2008 @ 12:19:
ja, dat sloeg inderdaad ook nergens op, ik ben bang dat het gisteren gewoon wat laat was ;)
Ah ok. :)

Als je libSDL direct linked met je voorbeeldprogramma doet ie het wel btw? Dan lijkt het me dat op een of andere manier de SDL functies niet geexporteerd worden in jouw lib.

Je kunt gcc dacht ik ook vertellen dat hij vertelt waar hij naar bepaalde functies zoekt, misschien dat je daar iets wijzer van wordt?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
dit werkt wel:
$ gcc src/example.c obj/SDL_ffmpeg.o -lmingw32 -lSDLmain -lSDL -lavformat -lavcodec -lavutil -lwsock32 -Iinclude -I/c/lib/SDL-1.2.12/include -L/c/lib/SDL-1.
2.12/lib -Llib -L /c/src/ffmpeg/libavcodec -L /c/src/ffmpeg/libavformat -L /c/src/ffmpeg/libavutil -o bin/SDL_ffmpeg_example

Ik link nu dus ook met de ffmpeg libraries en haal de SDL_ffmpeg calls uit de object file die ik ook gebruikte bij het maken van libSDL_ffmpeg.a

Overigens ben ik niet opzoek naar het meecompileren van SDL, alleen het samenvoegen van SDL_ffmpeg en de benodigde ffmpeg calls tot één (static) library.

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
Kan er zoiets bestaan als een circular dependency binnen één library?

ik kan me haast niet voorstellen dat ld niet zelf een circular dependency kan oplossen, maar na een dagje googlen kan ik geen enkele andere uitleg bedenken voor deze issues.. :/

als iemand nog iets kan verzinnen, dan hoor ik het graag!

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15:26
Volgens mij heb je geen circular dependency toch?

Dit http://tldp.org/HOWTO/Pro...WTO/static-libraries.html voorbeeld heeft het trouwens over ar -rcs. Gebruik jij die ook?

Wat is eigenlijk de reden dat je niet -static gebruikt?

[ Voor 13% gewijzigd door farlane op 13-01-2008 15:28 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
farlane schreef op zondag 13 januari 2008 @ 15:28:
Volgens mij heb je geen circular dependency toch?
Het lijkt erop van niet, aangezien ik nog heb geprobeerd om ld aan te sturen met de --start-group/--end-group opties. Hiermee kun je ld laten zoeken binnen een bepaalde groep archives, om zo circular references op te lossen. Dit leverde alleen maar meer undefined references op...
Dit http://tldp.org/HOWTO/Pro...WTO/static-libraries.html voorbeeld heeft het trouwens over ar -rcs. Gebruik jij die ook?
de -s optie schrijft de index in het archive, niet strikt noodzakelijk, heb de optie erbij gezet maar het maakte niks uit.
Wat is eigenlijk de reden dat je niet -static gebruikt?
-static forceert het gebruik van de statische variant van een lib boven de dynamische. Aangezien ik geen dynamische versie van SDL_ffmpeg heb lijkt me deze optie niet noodzakelijk.

Het probleem is dat ik nog geen stap dichterbij ben gekomen :'(
hier de updated output.
$ make all

gcc -Iinclude/ -I/c/lib/SDL-1.2.12/include -L/c/lib/SDL-1.2.12/lib -Llib -lmingw32 -lSDLmain -lSDL -lSDL_ffmpeg src/example.c -o bin/SDL_ffmpeg_example

[bla]/ccu2aaaa.o:example.c:(.text+0x1a): undefined reference to `SDL_ffmpegGetAudioFrame'
[bla]/ccu2aaaa.o:example.c:(.text+0x4d): undefined reference to `SDL_ffmpegGetAudioFrame'
[bla]/ccu2aaaa.o:example.c:(.text+0xc3): undefined reference to `SDL_ffmpegReleaseAudio'
[bla]/ccu2aaaa.o:example.c:(.text+0x14e): undefined reference to `SDL_ffmpegOpen'
[bla]/ccu2aaaa.o:example.c:(.text+0x197): undefined reference to `SDL_ffmpegGetAudioStream'
[bla]/ccu2aaaa.o:example.c:(.text+0x236): undefined reference to `SDL_ffmpegGetVideoStream'
[bla]/ccu2aaaa.o:example.c:(.text+0x2dc): undefined reference to `SDL_ffmpegSelectVideoStream'
[bla]/ccu2aaaa.o:example.c:(.text+0x2ef): undefined reference to `SDL_ffmpegSelectAudioStream'
[bla]/ccu2aaaa.o:example.c:(.text+0x30a): undefined reference to `SDL_ffmpegGetAudioSpec'
[bla]/ccu2aaaa.o:example.c:(.text+0x326): undefined reference to `SDL_ffmpegGetVideoSize'
[bla]/ccu2aaaa.o:example.c:(.text+0x348): undefined reference to `SDL_SetVideoMode'
[bla]/ccu2aaaa.o:example.c:(.text+0x385): undefined reference to `SDL_OpenAudio'
[bla]/ccu2aaaa.o:example.c:(.text+0x3b5): undefined reference to `SDL_ffmpegStartDecoding'
[bla]/ccu2aaaa.o:example.c:(.text+0x3c1): undefined reference to `SDL_PauseAudio'
[bla]/ccu2aaaa.o:example.c:(.text+0x3dd): undefined reference to `SDL_PollEvent'
[bla]/ccu2aaaa.o:example.c:(.text+0x402): undefined reference to `SDL_PumpEvents'
[bla]/ccu2aaaa.o:example.c:(.text+0x414): undefined reference to `SDL_GetMouseState'
[bla]/ccu2aaaa.o:example.c:(.text+0x42a): undefined reference to `SDL_ffmpegGetDuration'
[bla]/ccu2aaaa.o:example.c:(.text+0x467): undefined reference to `SDL_ffmpegSeek'
[bla]/ccu2aaaa.o:example.c:(.text+0x47a): undefined reference to `SDL_ffmpegPause'
[bla]/ccu2aaaa.o:example.c:(.text+0x48a): undefined reference to `SDL_ffmpegGetVideoFrame'
[bla]/ccu2aaaa.o:example.c:(.text+0x4b8): undefined reference to `SDL_UpperBlit'
[bla]/ccu2aaaa.o:example.c:(.text+0x4ca): undefined reference to `SDL_ffmpegReleaseVideo'
[bla]/ccu2aaaa.o:example.c:(.text+0x4d5): undefined reference to `SDL_Flip'
[bla]/ccu2aaaa.o:example.c:(.text+0x4e1): undefined reference to `SDL_Delay'
[bla]/ccu2aaaa.o:example.c:(.text+0x4f1): undefined reference to `SDL_ffmpegFree'

collect2: ld returned 1 exit status
make: *** [SDL_ffmpeg_example] Error 1

Wat ik echt niet kan verklaren, is dat ld zeurt over SDL_ffmpeg* calls, terwijl ik nu net alléén deze calls in de library heb gezet... nm is het overigens met me eens:
$ nm lib/libSDL_ffmpeg.a
SDL_ffmpeg.o:
00000000 b .bss
00000000 d .data
00000000 r .rdata
00000000 t .text
00000000 B _FFMPEG_init_was_called
         U _SDL_CreateRGBSurface
         U _SDL_CreateSemaphore
         U _SDL_CreateThread
         U _SDL_Delay
         U _SDL_FreeSurface
         U _SDL_GetTicks
         U _SDL_SemPost
         U _SDL_SemWait
         U _SDL_WaitThread
00000000 T _SDL_ffmpegCreateFile
00000b63 T _SDL_ffmpegDecodeThread
0000108e T _SDL_ffmpegFlush
000000fb T _SDL_ffmpegFree
000012bc T _SDL_ffmpegGetAudioFrame
00001536 T _SDL_ffmpegGetAudioSpec
000009df T _SDL_ffmpegGetAudioStream
000015e6 T _SDL_ffmpegGetDuration
00001512 T _SDL_ffmpegGetPosition
00001754 T _SDL_ffmpegGetState
000007ce T _SDL_ffmpegGetVideoFrame
0000161b T _SDL_ffmpegGetVideoSize
00000a67 T _SDL_ffmpegGetVideoStream
00000124 T _SDL_ffmpegOpen
0000171d T _SDL_ffmpegPause
00001465 T _SDL_ffmpegReleaseAudio
0000097c T _SDL_ffmpegReleaseVideo
00000f0c T _SDL_ffmpegSeek
00001062 T _SDL_ffmpegSeekRelative
00000a26 T _SDL_ffmpegSelectAudioStream
00000aae T _SDL_ffmpegSelectVideoStream
00000aef T _SDL_ffmpegStartDecoding
00000b23 T _SDL_ffmpegStopDecoding
000016b5 T _SDL_ffmpegValidAudio
000016e9 T _SDL_ffmpegValidVideo
         U ___divdi3
         U __imp___iob
         U _av_find_stream_info
00000ee7 t _av_free_packet
         U _av_open_input_file
000007c1 t _av_q2d
         U _av_read_frame
         U _av_register_all
         U _av_seek_frame
         U _avcodec_alloc_frame
         U _avcodec_decode_audio2
         U _avcodec_decode_video
         U _avcodec_find_decoder
         U _avcodec_flush_buffers
         U _avcodec_open
         U _avpicture_fill
         U _avpicture_get_size
         U _fprintf
         U _free
0000175f T _getAudioFrame
00001924 T _getVideoFrame
         U _malloc
         U _memcpy
         U _memmove
         U _memset
         U _sws_getContext
         U _sws_scale

De enige verklaring die ik daarvoor dus kon bedenken was de circular reference, maar zoals vermeld heb ik dit ook geprobeerd en dat liep op niets uit.
-( archives -)
--start-group archives --end-group

The archives should be a list of archive files. They may be either explicit file names, or `-l' options. The specified archives are searched repeatedly until no new undefined references are created. Normally, an archive is searched only once in the order that it is specified on the command line. If a symbol in that archive is needed to resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the linker would not be able to resolve that reference. By grouping the archives, they all be searched repeatedly until all possible references are resolved. Using this option has a significant performance cost. It is best to use it only when there are unavoidable circular references between two or more archives.
Ik kan me niet voorstellen dat een static library maken zoveel moeite moet kosten..
Ik zal dus vast wel wat over het hoofd zien, maar wat 8)7

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

Verwijderd

Een andere goede samenvatting van materie rond libraries en C is deze. Als het niet de oplossing biedt dan is het in ieder geval leerzaam :)

Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
Hooray \o/ :)

Ik ben er uit, de oplossing lag toch in de volgorde waarin de objecten in de archive gekopieerd werden..
Ik moet zeggen dat ik ld wel een beetje retarded vind dat ie een archive niet standaard als een group beschouwt, maar er zal wel een reden voor zijn.

waar ik eerst
-lavformat -lavcodec -lavutil

opgaf, heb ik nu de objecten uit deze archives in bovenstaande volgorde in m'n eigen archive geplaatst, waardoor het ineens wel werkt!

Ik snap totaal niet waarom ik bullshit meldingen als undefined reference to `SDL_ffmpegGetAudioFrame' kreeg, maar ik kan in ieder geval verder :)

vanwege dit soort gezeik ben ik een groot voorstander voor 2-pass linkers, of op z'n minst een simpele commandline optie die je linker omtovert in een 2-pass versie. Ik dacht dat de --start-group optie dit als effect had, maar bij mij gaf het iig niet het gewenste resultaat, maar misschien deed ik wat fout.

ben in ieder geval erg blij dat ik weer verder kan!

oprecht vertrouwen wordt nooit geschaad

Pagina: 1