gpt4 book ai didi

c++ - 使用库编译 C++ 项目

转载 作者:行者123 更新时间:2023-11-28 03:18:58 25 4
gpt4 key购买 nike

我的 friend 在 Windows 上的 Visual Studio 中开发了一个 C++ 游戏,我想在我的 Linux x64 机器上编译它。我对 C++ 不太熟悉,但我正在命令行上尝试 g++。但是我只得到一堆 undefined reference 错误。

基本的文件结构是:

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

(希望大家能看懂上面的瑞典语。)

最佳答案

您非常有礼貌地提供了链接器的库路径。然而,链接器是忘恩负义的懒汉,当它们看到对函数的 undefined reference 时,通常不会自行查找任何库文件

喜欢,undefined reference to `sf::Mutex::lock() — 我敢打赌有 libsfml-system.so.2.0Libraries/SFML_Linux64/lib/ 中的任何内容目录,定义为 sf::Mutex::lock() .但链接器并不关心。你必须说-lsfml-system在编译调用结束时。

这将使 g++了解不仅在 libstdc++ 中寻找功能图书馆,也在libsfml-system文件。如果g++碰巧在默认或附加(由 -L 标志指定)库目录中找到这样的文件,他将使用它来解析对函数调用的引用。

但是您必须明确地告诉它您要放入哪些库文件,仅指定包含库的目录 作用不大。所以,尝试使用

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

How to build C++ programs

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 ,它会提示有 undefined reference 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标志告诉链接器,如果他看到对函数的调用,并且在指定的目标文件(a.o、b.o 等)中的任何地方都没有定义这样的函数,那么它应该在这个库中查找。请注意,链接器不会查找您指定的目标文件和/或库(好吧,它还会查找标准 C++ 库 libstdc++,但仅此而已)。

但是,如果您有 10 个或更多文件,手动完成此过程会很无聊。这就是人们使用“项目文件”和“构建系统”的原因。当 Visual Studio 构建项目时,它会执行我提到的所有这些步骤:它编译项目中的每个文件,然后将结果链接在一起。在 Linux 上,你没有 Visual Studio,但你有 make公用事业。我相信有一些实用程序可以将 VS 项目转换为 makefile。

关于c++ - 使用库编译 C++ 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16016739/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com