c++ - 从 qmake 转换为 cmake,我如何以相同的方式找到库?
问题描述
在 qmake 我可以有这样的东西:
LIBS += -lopengl32 \
-lglu32
这将自动找到 OpenGL 和 GLU 并将其链接到我的应用程序。我怎样才能在cmake中做同样的事情?是不是很简单:
target_link_libraries(${TARGET_NAME} opengl32 glu32)
如果是这样,cmake 如何知道在哪里可以找到这些库?有没有办法做到这一点,find_libraries
而不是打电话?以上(如果有效)会让我感到焦虑。
解决方案
是的,有办法。
关于您提供的样品:
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::GL
在OpenGL::GLU
您的情况下,可用于链接。与CMake 目标链接的美妙之处在于,您的可执行文件将从用于链接的目标继承所有相关的编译/链接要求。当然,“导入库”也是 CMake 目标 :)
请注意,您的可执行文件没有额外的编译/链接选项、包含目录、编译定义等。一切必要的东西都继承自OpenGL::GL
和OpenGL::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_PATH
。CMAKE_SYSTEM_LIBRARY_PATH
最后,这里是find_library、find_package、 cmake 支持的库(向下滚动到“查找模块”)、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::GL
在OpenGL::GLU
您的情况下),它们是包含第 3 方库的所有要求的 cmake 目标。所有这些数据都是通过链接导入库来继承的,从而使代码更加简洁。
不幸的是,对于创建的导入库的命名没有“强制执行”(只是指南),所以唯一的解决方案是检查文档。对于OpenGL
模块,可以在FindOpenGL页面上找到。
推荐阅读
- python - 使用 numpy 进行优雅的批处理段相交计算
- javascript - 如何在 Laravel 8 中为完整的日历 JS 插件添加额外的字段值
- c - 使用 scanf 溢出,即使使用 fflush 和输入长度限制
- r - 使用 scale_x_datetime 绘制 POSIXct 时 x 轴上的日期错误
- c - 如何从 wordnet C 库中获取随机单词?
- excel - 从 3rd 方应用程序中读取列表框项目
- html - 当我们单击在 RASA(actions.py 文件)中创建的按钮时的动画
- html - Bootstrap 5/Flex:复杂的响应式菜单
- powershell - ISE 中的 Powershell Get-Childitem
- angular - 将 SSL 证书添加到本地服务器