如何在 VSCode 中使用 CMake 包含并链接 .dylib 文件?

问题描述 投票:0回答:1

我刚刚开始学习如何使用 CMake,我正在尝试将

glfw
文件包含到我的项目中。我真的试图推迟在 StackOverflow 上提问,但到目前为止,我已经花了 2 天时间阅读一个又一个教程,但毫无效果,所以我真的很感谢任何指导/帮助来为我指明正确的方向。

我的项目结构如下:

main.cpp
CMakeLists.txt
build
dependencies
    - glfw 
        - lib
            - libglfw.3.dylib
        - include
            - glfw3.h
            - glfw3native.h

我从 https://www.glfw.org/download.html 下载了适用于 MacOS 的预构建二进制文件,并将头文件和

.dylib
文件移动到我的项目目录中。

我的

CMakeLists.txt
文件当前如下所示:

cmake_minimum_required(VERSION 3.27)

project(demo)

add_executable(demo main.cpp)

include_directories(${CMAKE_SOURCE_DIR}/dependencies/glfw/include)
link_directories(${CMAKE_SOURCE_DIR}/dependencies/glfw/lib)

if (APPLE) 
    target_link_libraries(demo PRIVATE
    "-framework OpenGL"
)
endif()

add_library(glfw SHARED IMPORTED)
target_sources(glfw INTERFACE ${CMAKE_SOURCE_DIR}/dependencies/glfw/lib/libglfw.3.dylib)
target_link_libraries(demo INTERFACE glfw)

# set_target_properties(glfw PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/dependencies/glfw/lib/libglfw.3.dylib)

在 VSCode 上运行

CMake: Build
报告 glfw 存在未定义的符号。我知道这意味着我没有正确链接库,但我不知道哪里出了问题。

我对CMake的概念理解是:

  • include_directories
    告诉 CMake 在哪里查找头文件,因此我可以使用
    #include
    预处理器指令。这在
    main.cpp
    中运行得很好,我可以
    #include <glfw3.h>
    ,甚至可以看到函数和类型的 IntelliSense 提示。
  • link_directories
    告诉 CMake 在哪里寻找库。它实际上并不进行链接,只进行搜索。
  • add_library(<name> <type> IMPORTED)
    “引用位于项目外部的库文件”[源]。它创建了名为
    <name>
    的目标,使其在我的 CMake 项目中可用。 (在这种情况下,从技术上讲,该库不在项目目录“外部”,但我认为这并不重要,因为我只需提供二进制文件的完整路径。)
  • target_sources
    指定使用哪些文件来构建目标,也称为源文件。我不确定是否需要“构建”目标,因为它已经是预编译的二进制文件,所以我认为我在这里做错了什么。我还尝试使用
    set_target_properties
    函数(已注释掉),但它也不起作用(仍然出现未定义符号错误)。
  • 最后,我使用
    glfw
    target_link_libraries
    目标链接到我的主项目的目标。在我看来,这告诉链接器链接
    glfw
    目标。由于我指定了 (1) 在哪里搜索文件,以及 (2) 要搜索什么文件,所以它应该可以工作。

之前,我在项目中使用

vcpkg
并在本地安装了glfw文件。我用过

set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake)

set(CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/vcpkg/packages/glfw3_arm64-osx/share/glfw3 ${CMAKE_PREFIX_PATH})

find_package(glfw3 CONFIG REQUIRED)
target_link_libraries(demo PRIVATE glfw)
target_include_directories(demo PRIVATE ${CMAKE_SOURCE_DIR}/vcpkg/packages/glfw3_arm64-osx/include/GLFW)

这实际上工作得很好,但我不喜欢链接静态

libglfw3.a
文件。我不想静态链接该文件,因为我知道它会影响可执行文件的整体文件大小。我想学习如何在运行时正确链接动态文件。

我真的很想学习如何很好地使用 CMake,并且不想被其明显的复杂性所打败,据我所知,它有自己的社区,里面有一些讨厌它的人。任何帮助我指明正确方向/说明“正确”做事方式(如果有的话)的帮助将不胜感激。我真的希望有一个关于如何使用 CMake 的清晰、明确的事实来源。如果有人可以提供最新的教程,那也是一件幸事。谢谢。

c++ cmake linker dylib
1个回答
0
投票

没关系,我自己想出来了。我正确链接了库,但没有设置运行时路径 (CMAKE_BUILD_RPATH) 变量。编译器需要设置 RPATH,以便在运行时能够正确找到

.dylib
文件。添加一行就解决了。

set(CMAKE_BUILD_RPATH ${CMAKE_SOURCE_DIR}/dependencies/glfw/lib/libglfw.3.dylib)

现在我明白需要 RPATH 来查找

.dll
文件及其等效项,我意识到这是一个相当微不足道的问题。

但我只是希望无论是谁投了反对票,至少能告诉我我哪里出错了/我如何能更好地提出我的问题,而不是仅仅投反对票,除了向我表明我问了一个“愚蠢”的问题之外,不提供任何帮助。

这就是我尽可能多地在 StackOverflow 上提问的原因之一,以免我的问题被贴上“坏”问题的标签,尽管我尽了最大努力遵循提问指南。

© www.soinside.com 2019 - 2024. All rights reserved.