Premake 中的传递库依赖?

Transitive library dependency in Premake?

我在使用 gmake 和 premake5(在 Linux,elementaryOS 上)将库正确地link到我的项目时遇到了问题。我正在使用 premake 生成 makefile。我的工作区中有 3 个项目:glfw(我想要 linked 的库)、Celer(我想开始使用的库,它应该使用 glfw linked)和 Sandbox (我的测试应用程序)。 Sandbox 和 Celer 之间的 linking 工作没有任何问题,但是当我尝试 link Celer 和 glfw 时,会出现未定义的引用,我就是不明白为什么。

==== Building glfw (debug) ====
==== Building Celer (debug) ====
==== Building Sandbox (debug) ====
Linking Sandbox
../../bin/linux-Debug-x86_64/Celer/libCeler.a(Window.o): In function `Celer::Window::Window()':
/home/daniel/Documents/Development/C++/celer-engine/src/celer/Graphics/Window.cpp:6: undefined reference to `glfwInit'
/home/daniel/Documents/Development/C++/celer-engine/src/celer/Graphics/Window.cpp:11: undefined reference to `glfwDefaultWindowHints'
/home/daniel/Documents/Development/C++/celer-engine/src/celer/Graphics/Window.cpp:12: undefined reference to `glfwCreateWindow'
/home/daniel/Documents/Development/C++/celer-engine/src/celer/Graphics/Window.cpp:19: undefined reference to `glfwSwapInterval'
../../bin/linux-Debug-x86_64/Celer/libCeler.a(Window.o): In function `Celer::Window::update()':
/home/daniel/Documents/Development/C++/celer-engine/src/celer/Graphics/Window.cpp:29: undefined reference to `glfwSwapBuffers'
collect2: error: ld returned 1 exit status
Makefile:78: recipe for target '../../bin/linux-Debug-x86_64/Sandbox/Sandbox' failed
make[1]: *** [../../bin/linux-Debug-x86_64/Sandbox/Sandbox] Error 1
Makefile:45: recipe for target 'Sandbox' failed
make: *** [Sandbox] Error 2

我知道可能有成千上万的问题与 linking 相关,但我现在已经花了很多时间研究,但我仍然无法解决问题。

我已经建立了一个 GitHub 存储库,其中包含所有预制作文件和制作文件:GitHub repository

这就是 make 执行的内容:

echo "==== Building glfw (debug) ===="
make --no-print-directory -C lib/glfw -f Makefile config=debug
:
echo "==== Building Celer (debug) ===="
make --no-print-directory -C src/celer -f Makefile config=debug
:
echo "==== Building Sandbox (debug) ===="
make --no-print-directory -C test/sandbox -f Makefile config=debug
echo Linking Sandbox
g++ -o "../../bin/linux-Debug-x86_64/Sandbox/Sandbox"  ../../build/linux-Debug-x86_64/Sandbox/Sandbox.o   -L/usr/lib64 -m64 ../../bin/linux-Debug-x86_64/Celer/libCeler.a
:

啊,我没看出来你在用静态库。正如所说,静态库不包含它们的依赖项,您需要自己携带这些依赖项。因此,您需要将 Sandbox 项目从...

links { "Celer" }

更像是...

links { 
   "glfw",
   "Xrandr",
   "Xi",
   "GLU",
   "GL",
   "X11",
   "dl",
   "pthread",
   "stdc++fs",
   "Celer"
} 

我能够使用 CMake 构建项目。首先,我将当前工作目录更改为 lib/glfw/build。我用

清理目录
rm -rf *

并使用

配置和构建项目
cmake -DGLFW_BUILD_DOCS=false -DGLFW_BUILD_EXAMPLES=false -DGLFW_BUILD_TESTS=false -DGLFW_INSTALL=false ..
cmake --build .

然后我创建了一个 CMakeLists.txt 包含

cmake_minimum_required(VERSION 3.0)

project(Celer)

add_library(Celer src/celer/Graphics/Window.cpp src/celer/Debug/Logger.cpp)
target_include_directories(Celer PRIVATE lib/glfw/include)

add_executable(Sandbox test/sandbox/Sandbox.cpp)
target_include_directories(Sandbox PRIVATE src/celer)
target_link_directories(Sandbox PRIVATE lib/glfw/build/src/)
target_link_libraries(Sandbox PRIVATE Celer glfw3 dl X11 pthread)

在项目的根目录中。我将 cwd 更改为 build,清理它并使用

构建项目
cmake ..
cmake --build .

它按预期工作。有必要对所有给定的库进行 link 沙盒测试,否则无法构建。

您可以使用

将 glfw 的构建添加到您的项目中
cmake_minimum_required(VERSION 3.0)

project(Celer)

set(GLFW_BUILD_EXAMPLES false)
set(GLFW_BUILD_TESTS false)
set(GLFW_BUILD_DOC false)
set(GLFW_INSTALL false)
add_subdirectory(lib/glfw)

add_library(Celer src/celer/Graphics/Window.cpp src/celer/Debug/Logger.cpp)
target_include_directories(Celer PRIVATE lib/glfw/include)

add_executable(Sandbox test/sandbox/Sandbox.cpp)
target_include_directories(Sandbox PRIVATE src/celer)
target_link_directories(Sandbox PRIVATE lib/glfw/build/src/)
target_link_libraries(Sandbox PRIVATE Celer glfw3 dl X11 pthread)

您的构建配置中的问题可能是您尝试 link Celer 针对所有依赖项,但无法 linked 静态库。您必须 link 针对依赖项进行沙箱处理或使用动态库。