2012-05-06 3 views
2

Я пытаюсь создать простой загрузчик obj с opengl в C++. Компиляция все с одной командой работает отлично,проблемы при связывании объектов с g ++

g++ -o main main.cpp timer.cpp screen.cpp obj_loader.cpp `sdl-config --cflags --libs` `pkg-config --cflags --libs glu` 

возвращается без ошибок.

компиляции объектов индивидуально работает тоже хорошо,

g++ main.cpp -o main.o -c -Wall `sdl-config --cflags --libs` `pkg-config glu --cflags --libs` 
g++ obj_loader.cpp -o obj_loader.o -c -Wall `sdl-config --cflags --libs` `pkg-config glu --cflags --libs` 
g++ timer.cpp -o timer.o -c -Wall `sdl-config --cflags --libs` `pkg-config glu --cflags --libs` 
g++ screen.cpp -o screen.o -c -Wall `sdl-config --cflags --libs` `pkg-config glu --cflags --libs` 

также не возвращает никаких ошибок.

Однако при выполнении окончательного

g++ main.o obj_loader.o timer.o screen.o -o main 

Я получаю кучу неопределенных ссылочных ошибок:

main.o: In function `draw()': 
main.cpp:(.text+0x1d): undefined reference to `glColor3f' 
main.cpp:(.text+0x27): undefined reference to `glBegin' 
main.cpp:(.text+0x36): undefined reference to `glVertex2i' 
main.cpp:(.text+0x45): undefined reference to `glVertex2i' 
main.cpp:(.text+0x54): undefined reference to `glVertex2i' 
main.cpp:(.text+0x63): undefined reference to `glVertex2i' 
main.cpp:(.text+0x68): undefined reference to `glEnd' 
main.o: In function `main': 
main.cpp:(.text+0xf8): undefined reference to `SDL_PollEvent' 
main.cpp:(.text+0x10b): undefined reference to `glClear' 
main.cpp:(.text+0x115): undefined reference to `SDL_GL_SwapBuffers' 
main.cpp:(.text+0x11a): undefined reference to `glFinish' 
main.cpp:(.text+0x14e): undefined reference to `SDL_Delay' 
timer.o: In function `Timer::start()': 
timer.cpp:(.text+0x4d): undefined reference to `SDL_GetTicks' 
timer.o: In function `Timer::pause()': 
timer.cpp:(.text+0xa6): undefined reference to `SDL_GetTicks' 
timer.o: In function `Timer::unpause()': 
timer.cpp:(.text+0xe5): undefined reference to `SDL_GetTicks' 
timer.o: In function `Timer::tick()': 
timer.cpp:(.text+0x136): undefined reference to `SDL_GetTicks' 
timer.o: In function `Timer::get_ticks()': 
timer.cpp:(.text+0x172): undefined reference to `SDL_GetTicks' 
screen.o: In function `init()': 
screen.cpp:(.text+0xa): undefined reference to `SDL_Init' 
screen.cpp:(.text+0x31): undefined reference to `SDL_SetVideoMode' 
screen.cpp:(.text+0x64): undefined reference to `SDL_WM_SetCaption' 
screen.o: In function `init_GL()': 
screen.cpp:(.text+0x80): undefined reference to `glClearColor' 
screen.cpp:(.text+0x8a): undefined reference to `glMatrixMode' 
screen.cpp:(.text+0x8f): undefined reference to `glLoadIdentity' 
screen.cpp:(.text+0xc0): undefined reference to `glOrtho' 
screen.cpp:(.text+0xca): undefined reference to `glMatrixMode' 
screen.cpp:(.text+0xcf): undefined reference to `glLoadIdentity' 
screen.cpp:(.text+0xd4): undefined reference to `glGetError' 
screen.o: In function `clean_up()': 
screen.cpp:(.text+0xf4): undefined reference to `SDL_Quit' 
collect2: ld returned 1 exit status 

Мои включены библиотеки являются:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 

#include "SDL/SDL.h" 
#include "SDL/SDL_opengl.h" 

#include "GL/gl.h" 
#include "GL/glu.h" 

и мой Makefile:

CC=g++ 
SDL_FLAGS=`sdl-config --cflags --libs` 
GL_FLAGS=`pkg-config glu --cflags --libs` 

CFLAGS=-c -Wall 

FLAGS=$(CFLAGS) $(SDL_FLAGS) $(GL_FLAGS) 
LDFLAGS= 

SOURCES=main.cpp obj_loader.cpp timer.cpp screen.cpp 
OBJECTS=$(SOURCES:.cpp=.o) 
EXECUTABLE=main 

all: $(SOURCES) $(EXECUTABLE) 

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(OBJECTS) -o [email protected] $(LDFLAGS) 

.cpp.o: 
    $(CC) $< -o [email protected] $(FLAGS) 

clean: 
    rm -f *o main 
+0

Ну, в командной строке вы приводите пример, тот, который не работает ... не показывает вам связывание необходимых библиотек, в то время как тот, который работает, делает. У вашего Makefile, похоже, есть точно такая же проблема. Я не ожидал, что это сработает. –

ответ

2

Да, все эти предметы возвращаются --libs? Вам нужны те, чтобы правильно связать окончательный исполняемый файл.

0

Я не вижу никаких -llibraryname, чтобы сказать g ++ ссылку на opengl. Я бы ожидал увидеть это на строке g ++, которая сама построит основную строку (т. Е. Линию, которая заканчивается на «main»). Насколько я знаю, файлы .o сами по себе не содержат информации о том, где найти библиотеки для решения своих ссылок. Эта информация должна быть передана в виде -l переключателей в командной строке.

1

sdl-config и pkg-config принять два флага: --cflags и --libs. Первый из этих флагов необходим, когда вы компилируете исходные файлы в объектные файлы. Второй из этих флагов необходим, когда вы связываетесь. Когда вы скомпилировали все с помощью одной команды, обе фазы обрабатывались одной командой, поэтому было естественно, что вы должны одновременно передавать --cflags и --libs в sdl-config и pkg-config. Теперь, когда вы отделили эти этапы, вам необходимо передать правильный вариант sdl-config и pkg-config в нужное время.

g++ main.cpp -o main.o -c -Wall `sdl-config --cflags` `pkg-config glu --cflags` 
g++ obj_loader.cpp -o obj_loader.o -c -Wall `sdl-config --cflags` `pkg-config glu --cflags` 
g++ timer.cpp -o timer.o -c -Wall `sdl-config --cflags` `pkg-config glu --cflags` 
g++ screen.cpp -o screen.o -c -Wall `sdl-config --cflags` `pkg-config glu --cflags` 

g++ main.o obj_loader.o timer.o screen.o -o main `sdl-config --libs` `pkg-config glu --libs` 

В вашем сборочном файле, это означает, что настройка переменных следующим образом: (Я также сделал несколько других незначительных исправлений в свой Makefile)

CC=g++ 
LD=g++ 

CFLAGS=-c -Wall $(shell sdl-config --cflags) $(shell pkg-config glu --cflags) 
LDFLAGS=$(shell sdl-config --libs) $(shell pkg-config glu --libs) 

SOURCES=main.cpp obj_loader.cpp timer.cpp screen.cpp 
OBJECTS=$(SOURCES:.cpp=.o) 
EXECUTABLE=main 

all: $(EXECUTABLE) 

$(EXECUTABLE): $(OBJECTS) 
    $(LD) $(LDFLAGS) $(OBJECTS) -o [email protected] 

.cpp.o: 
    $(CC) $(CFLAGS) $< -o [email protected] 

clean: 
    rm -f *.o main 

Там много больше критики о вашем Makefile - - вы, вероятно, могли бы устранить большую часть строк действий здесь, потому что GNU Make имеет встроенные импликации. Вероятно, вам необходимо добавить правила, определяющие зависимости файлов .o - каждый файл .cpp, вероятно, содержит файлы .h, и необходимо знать, как перекомпилировать файлы .cpp при изменении файлов .h.

+0

И makefile может использовать 'CFLAGS: = $ (shell sdl-config --cflags) и т. Д., Чтобы избежать повторного запуска команд оболочки backtick для каждого .o, который компилируется. –

+0

@JonathanWakely: сделано. –