cmake - 从 `pkg-config` 使用 `cmake` 的正确方法是什么?

标签 cmake pkg-config

在网上查了一下,看到很多这样的代码:

include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)

target_include_directories(app SYSTEM PUBLIC ${SDL2_INCLUDE_DIRS})
target_link_libraries(app ${SDL2_LIBRARIES})
然而,这似乎是错误的做法,因为它只使用包含目录和库,但忽略了 pkg-config 可能返回的定义、库路径和其他标志。 .
这样做的正确方法是什么,并确保 pkg-config 返回的所有编译和链接标志被编译的 app 使用?是否有一个命令可以完成此操作,例如 target_use(app SDL2) ?
引用:
  • include()
  • FindPkgConfig
  • 最佳答案

    首先,调用:

    include(FindPkgConfig)
    

    应替换为:
    find_package(PkgConfig)
    
    find_package() call 更灵活,允许使用 REQUIRED 等选项, 自动执行必须手动执行的操作 include() .

    其次,手动调用pkg-config应尽可能避免。 CMake 带有一组丰富的包定义,可在 Linux 中的 /usr/share/cmake-3.0/Modules/Find*cmake 下找到。 .这些为用户提供了比直接调用 pkg_search_module() 更多的选项和选择。 .

    至于提到的假设target_use()命令,CMake 已经以 PUBLIC|PRIVATE|INTERFACE 的方式内置了该命令。像 target_include_directories(mytarget PUBLIC ...) 这样的电话将导致在每个使用 mytarget 的目标中自动使用包含目录,例如target_link_libraries(myapp mytarget) .然而,这种机制似乎只适用于在 CMakeLists.txt 中创建的库。文件并且不适用于通过 pkg_search_module() 获得的库.来电add_library(bar SHARED IMPORTED)可能用于那个,但我还没有研究过。

    至于主要问题,这在大多数情况下都有效:
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(SDL2 REQUIRED sdl2)
    ...
    target_link_libraries(testapp ${SDL2_LIBRARIES})
    target_include_directories(testapp PUBLIC ${SDL2_INCLUDE_DIRS})
    target_compile_options(testapp PUBLIC ${SDL2_CFLAGS_OTHER})
    
    SDL2_CFLAGS_OTHER包含成功编译所需的定义和其他标志。旗帜SDL2_LIBRARY_DIRSSDL2_LDFLAGS_OTHER然而仍然被忽略,不知道这会成为一个问题的频率。

    更多文档在这里 http://www.cmake.org/cmake/help/v3.0/module/FindPkgConfig.html

    关于cmake - 从 `pkg-config` 使用 `cmake` 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65767540/

    相关文章:

    c++ - 为 C++ 程序编写 makefile

    c++ - CMake 添加(测试)可执行文件

    linux - 哪些库应该作为依赖项进入 pkg-config 文件?

    c++ - 如何将库的 .pc 文件添加到特定目录?

    c++ - 构建 VTK 'INSTALL' 项目时出现 CMake 错误

    windows - Cmake 命令行窗口太长

    c++ - 调试嵌入式目标时使用了错误的 python 解释器

    c++ - 编译基本的 openCV 程序时出错

    CMake 错误与 gtkmm

    shared-libraries - 在 pkg-config 中使用 Requires 与 Requires.private 时,链接过程有何不同?