2010-11-29 66 views
6

Je suis à linux. Mon fichier Makefile est ceComment lier et créer une bibliothèque de liens dynamiques correctement?

main2: main.cpp 
g++ -c $(LIBS) $(CFLAGS) -fPIC main.cpp 
g++ -shared main.o -o main.so 

Où,

SDL_CFLAGS := $(shell sdl-config --cflags) 
SDL_LDFLAGS := $(shell sdl-config --libs) 
CC = gcc 
COPTS = -g -Wall 
CFLAGS = $(SDL_CFLAGS) 
LIBS = -lstdc++ -lSDL $(SDL_LDFLAGS) -L/usr/X11R6/lib -lGL -lGLU 

qui court

g++ -c -lstdc++ -lSDL -L/usr/lib -lSDL -L/usr/X11R6/lib -lGL -lGLU -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -fPIC main.cpp 

g++ -shared main.o -o main.so 

Maintenant, cela fonctionne sans erreur. Les fichiers main.o et main.so sont produits.

Cependant, lorsque je tente de créer un lien avec main.os ctypes python

from ctypes import * import os 
libtest = cdll.LoadLibrary(os.getcwd()+ '/main.so') libtest.main_loop() 
libtest.main_loop() 

Je reçois cette erreur

>>> libtest = cdll.LoadLibrary(os.getcwd() + '/main.so') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.6/ctypes/__init__.py", line 431, in LoadLibrary 
    return self._dlltype(name) 
    File "/usr/lib/python2.6/ctypes/__init__.py", line 353, in __init__ 
    self._handle = _dlopen(self._name, mode) 
OSError: /home/atomos/DF/open_gl_client/ctypes_client/main.so: undefined symbol: glEnd 

Je ne sais pas si je suis en train de créer correctement la bibliothèque liée. Comment créer une bibliothèque liée que je peux charger? Dois-je créer un fichier .o et .os pour chaque bibliothèque que j'importe à partir de main.cpp ou est-ce que cela est pris en charge automatiquement?

Je ne comprends pas ce que fait le compilateur ou l'éditeur de liens, mais cela fonctionne pour un exemple simple sans importations, mais pour les fichiers cpp qui importent des bibliothèques opengl, il donne cette erreur.

---- ---- Mise à jour ldd contre main.so rendements

ldd main.so 
     linux-gate.so.1 => (0xb7755000) 
     libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xaf625000) 
     libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xaf5ff000) 
     libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xaf4a4000) 
     libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xaf485000) 
     /lib/ld-linux.so.2 (0xb7756000) 

---- ---- Mise à jour

J'ai couru g ++ sans -shared dans la deuxième étape de compilation et a reçu cette erreur

g++ main.o -o main.so 
main.o: In function `Texture_map_list::add_texture(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)': 
main.cpp:(.text+0xf0fe): undefined reference to `glGenTextures' 
main.cpp:(.text+0xf2ba): undefined reference to `glBindTexture' 
main.cpp:(.text+0xf2d7): undefined reference to `glTexParameterf' 
main.cpp:(.text+0xf2f4): undefined reference to `glTexParameterf' 
main.cpp:(.text+0xf310): undefined reference to `glTexParameteri' 
main.cpp:(.text+0xf32c): undefined reference to `glTexParameteri' 
main.cpp:(.text+0xf365): undefined reference to `gluBuild2DMipmaps' 
main.o: In function `init()': 
main.cpp:(.text+0xf457): undefined reference to `SDL_Init' 
main.cpp:(.text+0xf46d): undefined reference to `SDL_WM_SetCaption' 
main.cpp:(.text+0xf472): undefined reference to `SDL_GetVideoInfo' 
main.cpp:(.text+0xf480): undefined reference to `SDL_GetError' 
main.cpp:(.text+0xf497): undefined reference to `SDL_Quit' 
main.cpp:(.text+0xf4e2): undefined reference to `SDL_GL_SetAttribute' 
main.cpp:(.text+0xf505): undefined reference to `SDL_SetVideoMode' 
main.cpp:(.text+0xf513): undefined reference to `SDL_GetError' 
main.cpp:(.text+0xf52a): undefined reference to `SDL_Quit' 
main.cpp:(.text+0xf559): undefined reference to `glClearColor' 
main.cpp:(.text+0xf565): undefined reference to `glEnable' 
main.cpp:(.text+0xf571): undefined reference to `glMatrixMode' 
main.cpp:(.text+0xf576): undefined reference to `glLoadIdentity' 
main.cpp:(.text+0xf5a2): undefined reference to `gluPerspective' 
main.o: In function `process_keypresses()': 
main.cpp:(.text+0x10678): undefined reference to `SDL_PollEvent' 
main.cpp:(.text+0x109a1): undefined reference to `SDL_PollEvent' 
main.o: In function `main_loop': 
main.cpp:(.text+0x10d76): undefined reference to `SDL_GetKeyState' 
main.cpp:(.text+0x10d9f): undefined reference to `SDL_Quit' 
main.o: In function `render()': 
main.cpp:(.text+0x10e00): undefined reference to `SDL_GetMouseState' 
main.cpp:(.text+0x10e90): undefined reference to `SDL_GetMouseState' 
main.cpp:(.text+0x10f94): undefined reference to `glClear' 
main.cpp:(.text+0x10fa0): undefined reference to `glMatrixMode' 
main.cpp:(.text+0x10fa5): undefined reference to `glLoadIdentity' 
main.cpp:(.text+0x11081): undefined reference to `gluLookAt' 
main.cpp:(.text+0x11120): undefined reference to `glTranslatef' 
main.cpp:(.text+0x1114d): undefined reference to `glRotatef' 
main.cpp:(.text+0x1117a): undefined reference to `glRotatef' 
main.cpp:(.text+0x1119e): undefined reference to `SDL_GL_SwapBuffers' 
main.o: In function `draw_plane(float, float, float)': 
main.cpp:(.text+0x111d8): undefined reference to `glColor3f' 
main.cpp:(.text+0x111e4): undefined reference to `glBegin' 
main.cpp:(.text+0x1120b): undefined reference to `glVertex3f' 

....

+0

"fichier de construction" - Je pense que vous voulez dire * Makefile *. –

Répondre

11

d'abord, notez que thi s est plus facile à déboguer si vous ne construisez pas une bibliothèque partagée. Vous construisez avec -shared afin que les erreurs de l'éditeur de liens ne se produisent pas jusqu'à ce que vous chargiez dynamiquement la bibliothèque en Python. Éteignez -shared pendant que vous le débogage, et vous verrez les erreurs sur la ligne de commande lorsque vous essayez de lien:

g++ main.o -o main 
main.o: In function `main': 
main.cpp:(.text+0x1d): undefined reference to `glBegin' 
main.cpp:(.text+0x22): undefined reference to `glEnd' 
collect2: ld returned 1 exit status 

Maintenant, le problème est que vous passez des arguments de l'éditeur de liens au compilateur. Je vois que vous avez bien séparé CFLAGS et LIBS dans le Makefile. Bien. Mais vous passez à la fois $(LIBS) et $(CFLAGS) sur la première ligne, pour construire main.o. Le LIBS sera ignoré sur cette ligne, car ce sont des indicateurs de lien. Sur la deuxième ligne, où vous créez réellement l'exécutable final, vous ne transmettez pas $(LIBS), donc le programme n'est pas lié à libGL ou à d'autres bibliothèques.

Par conséquent, il suffit de fixer votre makefile ainsi:

main2: main.cpp 
    g++ -c $(CFLAGS) -fPIC main.cpp 
    g++ -shared main.o $(LIBS) -o main.so 

Modifier: J'ai réalisé depuis que GCC, vous devez always put the libraries after the object files, donc je l'ai changé la dernière ligne du makefile en conséquence.

+0

Cela a résolu le problème. Je vous remercie. – HaltingState

+5

Super pour entendre. Pouvez-vous cocher la case à cocher «réponse acceptée» pour indiquer que cela est résolu? Merci. – mgiuca

+0

J'ai appuyé sur la case de réponse acceptée et j'ai été mise à jour. Désolé, j'ai oublié de faire ça. – HaltingState

1

Simple:

Vous passez les indicateurs de lien à l'étape de compilation d'objets.

Voici ce dont vous avez besoin:

g++ -c -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT main.cpp 
g++ -lstdc++ -lSDL -L/usr/lib -lSDL -L/usr/X11R6/lib -lGL -lGLU -fPIC main.o -o main 

Plus vous ne voulez probablement pas de créer un fichier de sorte, mais un exécutable normal.

+0

Eh bien, il veut créer un fichier, puisqu'il l'importe en Python. – mgiuca