2010-11-29 4 views
6

Я в Linux. Мой Makefile файл этоКак правильно связать и построить динамическую библиотеку ссылок?

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

Где

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 

который работает

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 

Теперь это работает без ошибок. Создаются файлы main.o и main.so.

Однако, когда я пытаюсь связать main.os с питона ctypes

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

Я получаю эту ошибку

>>> 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 

Я не уверен, если я правильно создать связанную библиотеку. Как создать связанную библиотеку, которую я могу загрузить?

Должен ли я создавать файлы .o и .os для каждой библиотеки, которую я импортирую из main.cpp, или это автоматически выполняется?

Я не понимаю, что делает компилятор или компоновщик, однако он работает для простого примера без импорта, но для файлов cpp, которые импортируют библиотеки opengl, он дает эту ошибку.

---- ---- Обновление LDD против main.so урожайности

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) 

---- ---- Обновление

Я побежал г ++ без -shared флага во втором шаг компиляции и получил эту ошибку

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

«build file» - Я думаю, вы имеете в виду * Makefile *. – 2010-11-29 01:36:07

ответ

11

Во-первых, обратите внимание, что THI s легче отлаживать, если вы не создаете общую библиотеку. Вы строите с -shared, поэтому ошибки компоновщика не выполняются, пока вы не динамически загружаете библиотеку в Python. Выключите -shared пока вы отладка, и вы увидите ошибки в командной строке при попытке ссылки:

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 

Теперь проблема заключается в том, что вы передаете аргументы компоновщика компилятора. Я вижу, что вы прекрасно разделили CFLAGS и LIBS в Makefile. Хорошо. Но вы передаете как $(LIBS), так и $(CFLAGS) на первой линии, чтобы построить main.o. LIBS будет проигнорирован в этой строке, поскольку они являются флагами ссылок.

Во второй строке, где вы фактически создаете окончательный исполняемый файл, вы не проходите $(LIBS), поэтому программа не связана с libGL или другими библиотеками.

Поэтому просто исправить Makefile таким образом:

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

Edit: Я так понял, что в GCC, вы должны always put the libraries after the object files, поэтому я изменил последнюю строку Makefile соответственно.

+0

Устранена проблема. Спасибо. – HaltingState 2010-11-29 01:55:37

+5

Замечательно. Можете ли вы отметить флажок «принятый ответ», чтобы отметить это как решение? Благодарю. – mgiuca 2010-11-29 02:22:31

1

Простой:

Вы передавая ссылку флаги объекта шаг компиляции.

Вот что вам нужно:

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 

Кроме того, вы, вероятно, не хотят создавать так файл, а нормальный исполняемый файл.

Смежные вопросы