首页 > 解决方案 > 从 qmake 转换为 cmake,我如何以相同的方式找到库?

问题描述

在 qmake 我可以有这样的东西:

LIBS += -lopengl32 \
    -lglu32 

这将自动找到 OpenGL 和 GLU 并将其链接到我的应用程序。我怎样才能在cmake中做同样的事情?是不是很简单:

target_link_libraries(${TARGET_NAME} opengl32 glu32)

如果是这样,cmake 如何知道在哪里可以找到这些库?有没有办法做到这一点,find_libraries而不是打电话?以上(如果有效)会让我感到焦虑。

标签: c++qtcmakeqmake

解决方案


是的,有办法。

关于您提供的样品:

target_link_libraries(${TARGET_NAME} opengl32 glu32)

在这种情况下,当您仅列出要链接的库时,CMake 只会将它们传递给链接器,而无需任何额外工作;链接器必须找到它们。

关于包含库的 CMake 方式:

但是,CMake 可能会为您提供更多帮助。请查看以下代码片段,它代表了在 CMake 中查找库的首选方式:

#NOTE: this is a complete & working CMakeLists.txt

project(my_opengl_program)

set(TARGET_NAME ${PROJECT_NAME})
set(TARGET_SOURCES my_opengl_program.cpp my_opengl_program.h)

add_executable(${TARGET_NAME} ${TARGET_SOURCES})

find_package(OpenGL REQUIRED)
target_link_libraries(${TARGET_NAME} OpenGL::GL OpenGL::GLU)

find_library不要直接使用,而是使用find_package. 它将找到您需要的库(通过find_library内部使用)并为您设置各种有用的变量。

此外,大多数包还将定义所谓的导入库,OpenGL::GLOpenGL::GLU您的情况下,可用于链接。与CMake 目标链接的美妙之处在于,您的可执行文件将从用于链接的目标继承所有相关的编译/链接要求。当然,“导入库”也是 CMake 目标 :)

请注意,您的可执行文件没有额外的编译/链接选项、包含目录、编译定义等。一切必要的东西都继承自OpenGL::GLOpenGL::GLU

CMake 还为许多标准库提供包(向下滚动到“查找模块”)。

关于搜索库

您始终可以find_library直接使用,在这种情况下,您有责任处理库强加的所有要求。

确定搜索库的位置可能非常复杂,并且由各种CMake变量以及传递给find_library. 在最简单的情况下,当没有CMAKE_*更改相关变量时,并且使用基本语法调用 find_library 时,例如:

find_library(GL_LIB opengl32)
fund_library(GLU_LIB glu32)

搜索openGL32并将glu32由CMake 变量控制CMAKE_SYSTEM_PREFIX_PATHCMAKE_SYSTEM_LIBRARY_PATH

最后,这里是find_libraryfind_packagecmake 支持的库(向下滚动到“查找模块”)、target_link_libraries的完整文档

[更新]

find_library vs find_package

find_library有人提出了关于和之间的区别的问题find_package

简而言之,这两个命令不是“竞争”而是“互补”。可以将find_library其视为包含库的低级接口。在这种情况下,find_package将是一个更高的界面,更易于使用。另一方面,find_package需要库维护者或直接来自 CMake 的额外支持。

深入挖掘问题:

假设使用 find_library (SOME_OTHER_LIB some_other_lib_name). 如果找到了库,则该变量SOME_OTHER_LIB将包含库的路径,这足以用于链接,使用target_link_libraries.

但是要真正使用该库,源需要包含SOME_OTHER_LIB特定的头文件,即find_path(...)需要引入另一个头文件来定位头文件,然后是target_include_directories(...). 此外,库所需的编译选项也需要以某种方式提取,并使用target_compile_options(...)

当然,如果 SOME_OTHER_LIB 用于多个地方,all target_include_directories, target_compile_options, andtarget_link_libraries必须全部使用。

必须对使用的每个外部库重复相同的过程。

人们可以快速发现模式,而这正是find_package派上用场的地方。所有底层工作都对最终用户(即使用 CMake 的开发人员)隐藏,并且为她/他提供了一个干净统一的界面。缺点是find_package需要一种“驱动程序”来“驱动”包含外部库的过程。CMake 直接支持的所有库都可以在cmake-modules上找到(向下滚动到“查找模块”)。

锦上添花,几乎所有 find 模块还创建所谓的“导入库”(OpenGL::GLOpenGL::GLU您的情况下),它们是包含第 3 方库的所有要求的 cmake 目标。所有这些数据都是通过链接导入库来继承的,从而使代码更加简洁。

不幸的是,对于创建的导入库的命名没有“强制执行”(只是指南),所以唯一的解决方案是检查文档。对于OpenGL模块,可以在FindOpenGL页面上找到。


推荐阅读