ошибки компилятора — Компиляция проекта C ++ с библиотеками

Мои друзья разработали игру C ++ в Visual Studio для Windows, и я хотел бы скомпилировать ее на своем компьютере с Linux x64. Я не очень знаком с C ++, но я пытаюсь g ++ в командной строке. Однако я получаю только кучу неопределенные ссылки ошибки.

Основная структура файла:

Libraries/SFML-2.0/lib
Libraries/SFML-2.0/include
Libraries/SFML_Linux64/lib
Libraries/SFML_Linux64/include
Libraries/Box2D/lib
Libraries/Box2D/include
Libraries/Box2DLinux/lib
Libraries/Box2DLinux/include
Game
Game/lib
Game/includes
Game/... (other subdirectories)

Я попробовал следующую команду:

g++ -Wall Multiplaya/app.cpp -I Libraries/SFML_Linux64/include/ -I Libraries/Box2DLinux/include/ -L Libraries/SFML_Linux64/lib/ -L Libraries/Box2DLinux/lib/

Это тот тип ошибок, которые я получаю (некоторые строки обрезаны и заменены на ...):

/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: I funktionen "_start":
(.text+0x20): undefined reference to `main'
/tmp/ccFXe37c.o: I funktionen "mp::createNetworkThread(void*)":
app.cpp:(.text+0x10): undefined reference to `worldDataMutex'
app.cpp:(.text+0x15): undefined reference to `sf::Mutex::lock()'
...
/tmp/ccFXe37c.o: I funktionen "mp::App::exec()":
app.cpp:(.text+0x148): undefined reference to `mp::ResourceHandler::instance()'
app.cpp:(.text+0x15a): undefined reference to `mp::ResourceHandler::loadTexture(std::string)'
app.cpp:(.text+0x3d7): undefined reference to `mp::Window::Window(mp::WorldData*)'
app.cpp:(.text+0x406): undefined reference to `mp::Controller::Controller(mp::World*, mp::Window*)'
...
app.cpp:(.text+0x471): undefined reference to `sf::Mutex::unlock()'
app.cpp:(.text+0x4bb): undefined reference to `sf::Thread::launch()'
app.cpp:(.text+0x4d7): undefined reference to `sf::Clock::Clock()'
app.cpp:(.text+0x4e6): undefined reference to `sf::Clock::getElapsedTime() const'
...
collect2: fel: ld returnerade avslutningsstatus 1

(Я надеюсь, что вы можете просмотреть шведский выше.)

0

Решение

Очень любезно с вашей стороны указывать пути к компоновщику. Тем не менее, линкеры — неблагодарные неряхи и обычно не ищите какие-либо библиотечные файлы самостоятельно когда они видят неопределенную ссылку на функцию.

Подобно, undefined reference to `sf::Mutex::lock() — Бьюсь об заклад, есть libsfml-system.so.2.0 или что-то в Libraries/SFML_Linux64/lib/ каталог, с определением для sf::Mutex::lock(), Но компоновщик не волнует. Ты должен сказать -lsfml-system в конце вашего вызова компиляции.

Это сделает g++ понять, чтобы искать функции не только в libstdc++ библиотека, но и в libsfml-system файл. И если g++ случайно найти такой файл по умолчанию или дополнительный (указывается с -L flag) библиотечные каталоги, он будет использоваться для разрешения ссылок на вызовы функций.

Но вы должны явно указать ему, какие библиотечные файлы вы хотите добавить, указав только каталоги с библиотеками мало что делает. Итак, попробуйте использовать

g++ -Wall Multiplaya/app.cpp -I Libraries/SFML_Linux64/include/ -I Libraries/Box2DLinux/include/ -L Libraries/SFML_Linux64/lib/ -L Libraries/Box2DLinux/lib/ -lsfml-system

Программы на C ++ состоят из двух этапов: первый этап — это компиляция, а второй — создание ссылок.

Во время компиляции вы превращаете ваши исходные файлы в объектные файлы — вещи, которые содержат скомпилированный машинный код. Теперь есть хитрость, которую вы должны понять. Скажи если есть a.cpp с

// a.cpp
int f(int x);

int main() {
return f(42);
}

Вы можете скомпилировать это с g++ -c a.cpp и он получит вам объектный файл a.o (с скомпилированным кодом), без каких-либо ошибок компиляции. Но ждать! Там нет фактического определения того, что f() в a.cpp!

И теперь, когда вы переходите ко второму шагу, ссылки и вызывает g++ -o test a.o, он будет жаловаться, что есть неопределенная ссылка на f(), Итак, давайте сделаем b.cpp с этим текстом:

// b.cpp
int f(int x) {
return 2 * x - 3;
}

скомпилируйте это с g++ -c b.cpp а затем выполнить связывание как g++ -o test a.o b.o — и вау, теперь ссылки без ошибок!

Что случилось? Хорошо, когда компилятор видит вызов функции, он помещает в объектный файл не фактический call инструкция, но заполнитель, который говорит: «вызовите функцию с таким-то именем и такими-то параметрами». И тогда компоновщик берет кучу объектных файлов и сшивает их вместе. Когда он видит такую ​​табличку, он ищет упомянутую функцию в объектных файлах, которые ей дали, и выполняет фактический вызов ей вместо заполнителя.

Итак, сборка программы на C ++ выглядит примерно так:

  1. Для каждого x.cpp файл у вас есть, позвоните g++ -c x.cpp <bunch of flags> -I<include directories>
  2. Тогда позвони g++ -o resultprogram a.o b.o c.o d.o ... <bunch of flags> -L<library directories> -l<additional libraries>

-l flag сообщает компоновщику, что если он видит вызов функции, и нигде в указанных объектных файлах (a.o, b.o и т. д.) такая функция не определена, то он должен искать в этой библиотеке. Обратите внимание, что компоновщик не будет смотреть ни в каких объектных файлах и / или библиотеках, кроме тех, которые вы указали (хорошо, он также будет выглядеть в стандартной библиотеке C ++ libstdc++, но это все).

Тем не менее, этот процесс довольно скучно делать вручную, если у вас есть 10 или более файлов. Вот почему люди используют «файлы проекта» и «системы сборки». Когда Visual Studio строит проект, он выполняет все те шаги, которые я упомянул: он компилирует каждый файл в проекте, а затем связывает результат вместе. В Linux у вас нет Visual Studio, но у вас есть make полезность. Я полагаю, что есть несколько утилит для преобразования VS-проектов в make-файлы.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector