C++ 从qmake转换到cmake,如何以相同的方式查找库?

C++ 从qmake转换到cmake,如何以相同的方式查找库?,c++,qt,cmake,qmake,C++,Qt,Cmake,Qmake,在qmake中,我可以有如下内容: LIBS += -lopengl32 \ -lglu32 这将自动查找OpenGL和GLU并将其链接到我的应用程序。我如何在cmake中实现同样的功能?它是否简单到: target_link_libraries(${TARGET_NAME} opengl32 glu32) 如果是,cmake如何知道在哪里可以找到这些库?有没有一种方法可以替代使用find\u libraries调用来实现这一点?以上这些(如果有效的话)会让我焦虑。是的,有一种方法

在qmake中,我可以有如下内容:

LIBS += -lopengl32 \
    -lglu32 
这将自动查找OpenGL和GLU并将其链接到我的应用程序。我如何在cmake中实现同样的功能?它是否简单到:

target_link_libraries(${TARGET_NAME} opengl32 glu32)
如果是,cmake如何知道在哪里可以找到这些库?有没有一种方法可以替代使用
find\u libraries
调用来实现这一点?以上这些(如果有效的话)会让我焦虑。

是的,有一种方法

关于您提供的样本: 在这种情况下,当您只列出要链接的库时,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_库
,而是使用
find_包
。它将找到您需要的库(通过内部使用
find_library
),并为您设置各种有用的变量

此外,大多数软件包还将定义所谓的导入库,
OpenGL::GL
OpenGL::GLU
,在您的情况下,这些库可用于链接。针对CMake目标进行链接的好处在于,您的可执行文件将从用于链接的目标继承所有相关的编译/链接需求。当然,“导入库”也是CMake的目标:)

请注意,没有其他编译/链接选项,包括目录、编译定义等。。。用于您的可执行文件。所有必要的东西都继承自
OpenGL::GL
OpenGL::GLU

CMake还为提供包(向下滚动到“查找模块”)

关于搜索图书馆 您始终可以直接使用
find_library
,在这种情况下,您有责任处理库强加的所有需求

确定要搜索库的位置可能相当复杂,并且受各种
CMake
变量以及传递给
find\u库的参数驱动。在最简单的情况下,当没有相关的
CMAKE.*
变量更改,并且使用基本语法调用find_库时,例如:

find_library(GL_LIB opengl32)
fund_library(GLU_LIB glu32)
搜索
openGL32
glu32
将由
CMAKE\u SYSTEM\u PREFIX\u PATH
CMAKE\u SYSTEM\u LIBRARY\u PATH
CMAKE变量控制

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

[更新] 查找库与查找包 有人提出了关于
find_library
find_package
之间的区别的问题

简而言之,这两个命令并不“竞争”,而是相互“补充”。人们可能认为
find_library
是包含库的低级接口。在这种情况下,
find_package
将是一个更高的接口,更易于使用。另一方面,
find_-package
需要库维护人员或CMake直接提供额外的支持

进一步挖掘问题:

假设某个库是使用
查找库(一些其他库一些其他库名称)
。如果找到库,变量
SOME\u OTHER\u lib
将包含指向库的路径,该路径足以使用
target\u link\u libraries
进行链接

但要真正使用库,源代码需要包含
一些其他库
特定的头,即需要引入另一个
查找路径(…)
来定位头,然后是
目标包含目录(…)
。此外,还需要以某种方式提取库所需的编译选项,并使用
target\u compile\u options(…)

当然,如果在多个地方使用了SOME_OTHER_库,则所有
target_包含目录
target_编译选项
,以及
target_链接库
,必须全部使用

对于使用的每个外国图书馆,必须重复相同的过程

人们可以快速发现模式,这正是
find_package
变得方便的地方。所有这些低级工作都对最终用户(即使用CMake的开发人员)隐藏,并为其提供一个干净统一的界面。缺点是
find_package
需要一种“驱动程序”,它将“驱动”包含外部库的过程。可以在上找到CMake直接支持的所有库(向下滚动到“查找模块”)

锦上添花的是,几乎所有的find模块都创建了所谓的“导入库”(在您的例子中是
OpenGL::GL
OpenGL::GLU
),它们是包含第三方库所有需求的cmake目标。所有这些数据都是通过链接导入库来继承的,从而使代码更加清晰


不幸的是,对于创建的导入库的命名没有“强制措施”(只是准则),因此唯一的解决方案是检查文档。对于
OpenGL
模块,可以在第页找到它。

CMake命令
target\u link\u libraries
只需将库名传递给链接器即可。反过来,链接器在预定义的位置搜索库以及通过
link\u目录添加的库。此功能似乎与QMake中的
LIBS
提供的功能非常相似,不是吗?CMake命令
find_包
为搜索某些库提供了更灵活的方法。这种方式是跨平台的,甚至适用于安装到自定义(用户定义)位置的库。这是一个奇妙的分解!非常感谢你。我想我的问题是,从概念上讲,包与库的区别是什么?我怎么知道OpenGL是
find_library(GL_LIB opengl32)
fund_library(GLU_LIB glu32)