链接到 Filament 预编译库时出现链接器错误

Linker errors when linking to Filament precompiled libraries

我正在尝试以非常基本的方式 link 到许多库(不使用任何 Makefile 或 CMakeLists.txt),使用以下 clang++ 命令:

FILAMENT_LIBS="-lassimp -lbackend -lbluegl -lbluevk -lcamutils -lfilabridge -lfilaflat -lfilagui -lfilamat -lfilamat_combined -lfilamat_lite -lfilament -lfilameshio -lgeometry -lgltfio -lgltfio_core -lgltfio_pipeline -lgltfio_resources -libl -limage -limageio -limgui -lmatdbg -lmatdbg_resources -lmath -lmeshoptimizer -lrays -lshaders -lsmol-v -lutils"
clang++-7 -L../lib/x86_64/ ${FILAMENT_LIBS} -lpthread -lc++ -ldl -lSDL2 -I./ -I../include/ -I../app/ -I${RESOURCE_DIR} -Wno-extern-c-compat -std=c++14 -pthread ../suzanne.cpp ../app/Cube.cpp ../app/FilamentApp.cpp ../app/IBL.cpp ../app/IcoSphere.cpp ../app/Image.cpp ../app/NativeWindowHelperLinux.cpp ../app/Sphere.cpp -o suzanne

然而,这给出了错误 FilamentApp.cpp:(.text+0x4d2): undefined reference to... 后面是对上述库中函数的每一个调用必须是什么。

为了提供一些背景信息,我正在尝试编译渲染引擎 Filament 提供的示例应用程序之一。当使用源代码编译时,一切正常,但是当我尝试 link 针对库的预编译版本时,出现上述错误。

此外,当我尝试 link 使用测试器 main.cpp 文件和 Filament documentation 中描述的随附 Makefile 针对相同的库时,所有 link 和编译完全没问题。

我觉得我在这里做错了一些明显的错误,特别是我正在使用的 clang 命令,但我无法在我的生活中看到它是什么。任何帮助将不胜感激!

编辑 - 前几行错误:

../lib/x86_64//libfilament.a(Engine.cpp.o): In function `filament::details::FEngine::loop()':
Engine.cpp:(.text._ZN8filament7details7FEngine4loopEv+0x22): undefined reference to `filament::backend::DefaultPlatform::create(filament::backend::Backend*)'
../lib/x86_64//libfilament.a(Engine.cpp.o): In function `filament::details::FEngine::init()':
Engine.cpp:(.text._ZN8filament7details7FEngine4initEv+0x1f): undefined reference to `filament::backend::CommandStream::CommandStream(filament::backend::Driver&, filament::backend::CircularBuffer&)'
../lib/x86_64//libfilament.a(Engine.cpp.o): In function `filament::details::FEngine::FEngine(filament::backend::Backend, filament::backend::Platform*, void*)':
Engine.cpp:(.text._ZN8filament7details7FEngineC2ENS_7backend7BackendEPNS2_8PlatformEPv+0x267): undefined reference to `filament::backend::CommandBufferQueue::CommandBufferQueue(unsigned long, unsigned long)'
Engine.cpp:(.text._ZN8filament7details7FEngineC2ENS_7backend7BackendEPNS2_8PlatformEPv+0x332): undefined reference to `filaflat::ShaderBuilder::ShaderBuilder()'
Engine.cpp:(.text._ZN8filament7details7FEngineC2ENS_7backend7BackendEPNS2_8PlatformEPv+0x342): undefined reference to `filaflat::ShaderBuilder::ShaderBuilder()'
Engine.cpp:(.text._ZN8filament7details7FEngineC2ENS_7backend7BackendEPNS2_8PlatformEPv+0x462): undefined reference to `filaflat::ShaderBuilder::~ShaderBuilder()'
Engine.cpp:(.text._ZN8filament7details7FEngineC2ENS_7backend7BackendEPNS2_8PlatformEPv+0x471): undefined reference to `filaflat::ShaderBuilder::~ShaderBuilder()'
Engine.cpp:(.text._ZN8filament7details7FEngineC2ENS_7backend7BackendEPNS2_8PlatformEPv+0x4a2): undefined reference to `filament::backend::CommandBufferQueue::~CommandBufferQueue()'
../lib/x86_64//libfilament.a(Engine.cpp.o): In function `filament::details::FEngine::~FEngine()':
Engine.cpp:(.text._ZN8filament7details7FEngineD2Ev+0x3e): undefined reference to `filament::backend::DefaultPlatform::destroy(filament::backend::DefaultPlatform**)'
Engine.cpp:(.text._ZN8filament7details7FEngineD2Ev+0x10c): undefined reference to `filaflat::ShaderBuilder::~ShaderBuilder()'
Engine.cpp:(.text._ZN8filament7details7FEngineD2Ev+0x118): undefined reference to `filaflat::ShaderBuilder::~ShaderBuilder()'
Engine.cpp:(.text._ZN8filament7details7FEngineD2Ev+0x148): undefined reference to `filament::backend::CommandBufferQueue::~CommandBufferQueue()'
../lib/x86_64//libfilament.a(Engine.cpp.o): In function `filament::details::FEngine::shutdown()':
Engine.cpp:(.text._ZN8filament7details7FEngine8shutdownEv+0x207): undefined reference to `filament::backend::CommandBufferQueue::flush()'
Engine.cpp:(.text._ZN8filament7details7FEngine8shutdownEv+0x20f): undefined reference to `filament::backend::CommandBufferQueue::requestExit()'
../lib/x86_64//libfilament.a(Engine.cpp.o): In function `filament::details::FEngine::flushCommandBuffer(filament::backend::CommandBufferQueue&)':
Engine.cpp:(.text._ZN8filament7details7FEngine18flushCommandBufferERNS_7backend18CommandBufferQueueE+0x12): undefined reference to `filament::backend::CommandBufferQueue::flush()'
../lib/x86_64//libfilament.a(Engine.cpp.o): In function `filament::details::FEngine::flush()':
Engine.cpp:(.text._ZN8filament7details7FEngine5flushEv+0x19): undefined reference to `filament::backend::CommandBufferQueue::flush()'
../lib/x86_64//libfilament.a(Engine.cpp.o): In function `filament::details::FEngine::execute()':
Engine.cpp:(.text._ZN8filament7details7FEngine7executeEv+0x1b): undefined reference to `filament::backend::CommandBufferQueue::waitForCommands() const'
Engine.cpp:(.text._ZN8filament7details7FEngine7executeEv+0x4c): undefined reference to `filament::backend::CommandStream::execute(void*)'
Engine.cpp:(.text._ZN8filament7details7FEngine7executeEv+0x57): undefined reference to `filament::backend::CommandBufferQueue::releaseBuffer(filament::backend::CommandBufferQueue::Slice const&)'
/tmp/suzanne-ef5171.o: In function `main::$_0::operator()(filament::Engine*, filament::View*, filament::Scene*) const':
suzanne.cpp:(.text+0x1dc0): undefined reference to `TEXTURES_ALBEDO_S3TC_OFFSET'
suzanne.cpp:(.text+0x1dc7): undefined reference to `TEXTURES_PACKAGE'
suzanne.cpp:(.text+0x1dce): undefined reference to `TEXTURES_ALBEDO_S3TC_SIZE'
suzanne.cpp:(.text+0x1e10): undefined reference to `TEXTURES_AO_OFFSET'
suzanne.cpp:(.text+0x1e17): undefined reference to `TEXTURES_PACKAGE'
suzanne.cpp:(.text+0x1e1d): undefined reference to `TEXTURES_AO_SIZE'
suzanne.cpp:(.text+0x1e5e): undefined reference to `TEXTURES_METALLIC_OFFSET'
suzanne.cpp:(.text+0x1e65): undefined reference to `TEXTURES_PACKAGE'
suzanne.cpp:(.text+0x1e6b): undefined reference to `TEXTURES_METALLIC_SIZE'
suzanne.cpp:(.text+0x1eac): undefined reference to `TEXTURES_ROUGHNESS_OFFSET'
suzanne.cpp:(.text+0x1eb3): undefined reference to `TEXTURES_PACKAGE'
suzanne.cpp:(.text+0x1eb9): undefined reference to `TEXTURES_ROUGHNESS_SIZE'
suzanne.cpp:(.text+0x1f85): undefined reference to `TEXTURES_NORMAL_OFFSET'
suzanne.cpp:(.text+0x1f8c): undefined reference to `TEXTURES_PACKAGE'
suzanne.cpp:(.text+0x1f93): undefined reference to `TEXTURES_NORMAL_SIZE'
suzanne.cpp:(.text+0x1fdb): undefined reference to `RESOURCES_TEXTUREDLIT_OFFSET'
suzanne.cpp:(.text+0x1fe2): undefined reference to `RESOURCES_PACKAGE'
suzanne.cpp:(.text+0x1fe9): undefined reference to `RESOURCES_TEXTUREDLIT_SIZE'
suzanne.cpp:(.text+0x21ea): undefined reference to `RESOURCES_SUZANNE_OFFSET'
suzanne.cpp:(.text+0x21f0): undefined reference to `RESOURCES_PACKAGE'
/tmp/FilamentApp-94694a.o: In function `FilamentApp::run(Config const&, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*)>, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*)>, std::__1::function<void (filament::Engine*, filament::View*)>, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*, filament::Renderer*)>, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*, filament::Renderer*)>, unsigned long, unsigned long)':
FilamentApp.cpp:(.text+0xd8e): undefined reference to `RESOURCES_DEPTHVISUALIZER_OFFSET'
FilamentApp.cpp:(.text+0xd95): undefined reference to `RESOURCES_PACKAGE'
FilamentApp.cpp:(.text+0xd9c): undefined reference to `RESOURCES_DEPTHVISUALIZER_SIZE'
FilamentApp.cpp:(.text+0xe2c): undefined reference to `RESOURCES_AIDEFAULTMAT_OFFSET'
FilamentApp.cpp:(.text+0xe33): undefined reference to `RESOURCES_PACKAGE'
FilamentApp.cpp:(.text+0xe3a): undefined reference to `RESOURCES_AIDEFAULTMAT_SIZE'
FilamentApp.cpp:(.text+0xeaf): undefined reference to `RESOURCES_TRANSPARENTCOLOR_OFFSET'
FilamentApp.cpp:(.text+0xeb6): undefined reference to `RESOURCES_PACKAGE'
FilamentApp.cpp:(.text+0xebd): undefined reference to `RESOURCES_TRANSPARENTCOLOR_SIZE'
/tmp/FilamentApp-94694a.o: In function `FilamentApp::Window::configureCamerasForWindow()':
FilamentApp.cpp:(.text+0x6902): undefined reference to `filament::Camera::setLensProjection(double, double, double, double)'
FilamentApp.cpp:(.text+0x6a34): undefined reference to `filament::Camera::lookAt(filament::math::details::TVec3<float> const&, filament::math::details::TVec3<float> const&)'
../lib/x86_64//libfilament.a(VertexBuffer.cpp.o): In function `filament::VertexBuffer::Builder::attribute(filament::VertexAttribute, unsigned char, filament::backend::ElementType, unsigned int, unsigned char)':

编辑 2 - 第二次更改后的错误列表:

/tmp/suzanne-e10eca.o: In function `main::$_0::operator()(filament::Engine*, filament::View*, filament::Scene*) const':
suzanne.cpp:(.text+0x1dc0): undefined reference to `TEXTURES_ALBEDO_S3TC_OFFSET'
suzanne.cpp:(.text+0x1dc7): undefined reference to `TEXTURES_PACKAGE'
suzanne.cpp:(.text+0x1dce): undefined reference to `TEXTURES_ALBEDO_S3TC_SIZE'
suzanne.cpp:(.text+0x1e10): undefined reference to `TEXTURES_AO_OFFSET'
suzanne.cpp:(.text+0x1e17): undefined reference to `TEXTURES_PACKAGE'
suzanne.cpp:(.text+0x1e1d): undefined reference to `TEXTURES_AO_SIZE'
suzanne.cpp:(.text+0x1e5e): undefined reference to `TEXTURES_METALLIC_OFFSET'
suzanne.cpp:(.text+0x1e65): undefined reference to `TEXTURES_PACKAGE'
suzanne.cpp:(.text+0x1e6b): undefined reference to `TEXTURES_METALLIC_SIZE'
suzanne.cpp:(.text+0x1eac): undefined reference to `TEXTURES_ROUGHNESS_OFFSET'
suzanne.cpp:(.text+0x1eb3): undefined reference to `TEXTURES_PACKAGE'
suzanne.cpp:(.text+0x1eb9): undefined reference to `TEXTURES_ROUGHNESS_SIZE'
suzanne.cpp:(.text+0x1f85): undefined reference to `TEXTURES_NORMAL_OFFSET'
suzanne.cpp:(.text+0x1f8c): undefined reference to `TEXTURES_PACKAGE'
suzanne.cpp:(.text+0x1f93): undefined reference to `TEXTURES_NORMAL_SIZE'
suzanne.cpp:(.text+0x1fdb): undefined reference to `RESOURCES_TEXTUREDLIT_OFFSET'
suzanne.cpp:(.text+0x1fe2): undefined reference to `RESOURCES_PACKAGE'
suzanne.cpp:(.text+0x1fe9): undefined reference to `RESOURCES_TEXTUREDLIT_SIZE'
suzanne.cpp:(.text+0x21ea): undefined reference to `RESOURCES_SUZANNE_OFFSET'
suzanne.cpp:(.text+0x21f0): undefined reference to `RESOURCES_PACKAGE'
/tmp/FilamentApp-0b5ad4.o: In function `FilamentApp::run(Config const&, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*)>, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*)>, std::__1::function<void (filament::Engine*, filament::View*)>, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*, filament::Renderer*)>, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*, filament::Renderer*)>, unsigned long, unsigned long)':
FilamentApp.cpp:(.text+0xd8e): undefined reference to `RESOURCES_DEPTHVISUALIZER_OFFSET'
FilamentApp.cpp:(.text+0xd95): undefined reference to `RESOURCES_PACKAGE'
FilamentApp.cpp:(.text+0xd9c): undefined reference to `RESOURCES_DEPTHVISUALIZER_SIZE'
FilamentApp.cpp:(.text+0xe2c): undefined reference to `RESOURCES_AIDEFAULTMAT_OFFSET'
FilamentApp.cpp:(.text+0xe33): undefined reference to `RESOURCES_PACKAGE'
FilamentApp.cpp:(.text+0xe3a): undefined reference to `RESOURCES_AIDEFAULTMAT_SIZE'
FilamentApp.cpp:(.text+0xeaf): undefined reference to `RESOURCES_TRANSPARENTCOLOR_OFFSET'
FilamentApp.cpp:(.text+0xeb6): undefined reference to `RESOURCES_PACKAGE'
FilamentApp.cpp:(.text+0xebd): undefined reference to `RESOURCES_TRANSPARENTCOLOR_SIZE'
/tmp/FilamentApp-0b5ad4.o: In function `FilamentApp::Window::configureCamerasForWindow()':
FilamentApp.cpp:(.text+0x6902): undefined reference to `filament::Camera::setLensProjection(double, double, double, double)'
FilamentApp.cpp:(.text+0x6a34): undefined reference to `filament::Camera::lookAt(filament::math::details::TVec3<float> const&, filament::math::details::TVec3<float> const&)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

编辑 3

上述错误中引用的变量存储在文件中 ./generated/resources/resources.h./generated/resources/textures.h, 关于 clang++ 执行目录。这些文件包含的头文件如下所示:

#include "generated/resources/resources.h"
#include "generated/resources/textures.h"

并且我在 clang 命令中包含了 -I./,所以 clang 应该能够看到这些文件吗?

这里是textures.h:

#ifndef TEXTURES_H_
#define TEXTURES_H_

#include <stdint.h>

extern "C" {
    extern const uint8_t TEXTURES_PACKAGE[];
    extern int TEXTURES_ALBEDO_S3TC_OFFSET;
    extern int TEXTURES_ALBEDO_S3TC_SIZE;
    extern int TEXTURES_ROUGHNESS_OFFSET;
    extern int TEXTURES_ROUGHNESS_SIZE;
    extern int TEXTURES_METALLIC_OFFSET;
    extern int TEXTURES_METALLIC_SIZE;
    extern int TEXTURES_AO_OFFSET;
    extern int TEXTURES_AO_SIZE;
    extern int TEXTURES_NORMAL_OFFSET;
    extern int TEXTURES_NORMAL_SIZE;
}
#define TEXTURES_ALBEDO_S3TC_DATA (TEXTURES_PACKAGE + TEXTURES_ALBEDO_S3TC_OFFSET)
#define TEXTURES_ROUGHNESS_DATA (TEXTURES_PACKAGE + TEXTURES_ROUGHNESS_OFFSET)
#define TEXTURES_METALLIC_DATA (TEXTURES_PACKAGE + TEXTURES_METALLIC_OFFSET)
#define TEXTURES_AO_DATA (TEXTURES_PACKAGE + TEXTURES_AO_OFFSET)
#define TEXTURES_NORMAL_DATA (TEXTURES_PACKAGE + TEXTURES_NORMAL_OFFSET)

#endif

编辑 4:

查找资源库后的错误列表:

/tmp/FilamentApp-11fd11.o: In function `FilamentApp::Window::configureCamerasForWindow()':
FilamentApp.cpp:(.text+0x6902): undefined reference to `filament::Camera::setLensProjection(double, double, double, double)'
FilamentApp.cpp:(.text+0x6a34): undefined reference to `filament::Camera::lookAt(filament::math::details::TVec3<float> const&, filament::math::details::TVec3<float> const&)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

编辑 5:

还有一些错误...

../lib/x86_64//libfilament.a(Engine.cpp.o): In function `filament::details::FEngine::loop()':
/home/joel/Documents/KiwiTest/filament-source/out/cmake-debug/../../filament/src/Engine.cpp:448: undefined reference to `filament::matdbg::DebugServer::DebugServer(filament::backend::Backend, int)'
/home/joel/Documents/KiwiTest/filament-source/out/cmake-debug/../../filament/src/Engine.cpp:453: undefined reference to `filament::matdbg::DebugServer::~DebugServer()'
../lib/x86_64//libfilament.a(Material.cpp.o): In function `filament::Material::Builder::build(filament::Engine&)':
/home/joel/Documents/KiwiTest/filament-source/out/cmake-debug/../../filament/src/Material.cpp:110: undefined reference to `filament::matdbg::DebugServer::addMaterial(utils::CString const&, void const*, unsigned long, void*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

编译时将所有库放在最后一行:

clang++-7 -stdlib=libc++ -L../lib/x86_64/ -I./ -I../include/ -I../app/ -I${RESOURCE_DIR} -Wno-extern-c-compat -std=c++14 ../suzanne.cpp ../app/Cube.cpp ../app/FilamentApp.cpp ../app/IBL.cpp ../app/IcoSphere.cpp ../app/Image.cpp ../app/NativeWindowHelperLinux.cpp ../app/Sphere.cpp -o suzanne ${FILAMENT_LIBS} -lSDL2 -ldl -pthread

此外,仅使用 -pthread(删除 -lpthread)。两者都不需要。

您可能还想删除 -lc++ 并将其替换为 -stdlib=libc++(不需要在行尾)。

链接你的程序时发生的事情是,当链接器遇到一个以前没有遇到过的符号(函数)时,它把它放在一个未解析符号列表中。对于此后检查的每个库,都会检查未解析的符号。如果遇到已检查的库中存在的符号,链接将失败。

灯丝库的顺序也很重要,所以请尝试:

FILAMENT_LIBS=-lfilament -lbackend -lbluegl -lbluevk -lfilabridge -lfilaflat -lutils -lgeometry -lsmol-v -libl

如文档中所述。请注意,我从 FILAMENT_LIBS 中删除了非灯丝库。将这些库放在一个单独的变量中,并在编译时将其放在 FILAMENT_LIBS 变量之前。

如果SDL2使用filament,你应该把-lSDL2放在灯丝库之前,否则,就把它留在原处。

如果仍然失败,作为最后的手段,您可以将灯丝库包装在一个库组中,以使其解决内部灯丝依赖关系:

-Wl,--start-group $(FILAMENT_LIBS) -Wl,--end-group

但这不是您想要的,因为它很慢,但是,这是一个选项。

一个更绝望的选择是将 all 库包装在 -Wl,--start-group ... -Wl,--end-group 对中,以验证它是否编译并且您拥有所需的所有库和目标文件。