从 qmake 转换为 cmake,如何以相同的方式查找库?
Converting from qmake to cmake, how do I find libraries in the same way?
在 qmake 中我可以有这样的东西:
LIBS += -lopengl32 \
-lglu32
这将自动找到并 link 我的应用程序的 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
)并为您设置各种有用的变量。
此外,大多数软件包还将定义 so-called 导入库,在您的情况下,OpenGL::GL
和 OpenGL::GLU
可用于链接。针对 CMake 目标 进行链接的美妙之处在于,您的可执行文件将从用于链接的目标继承所有相关的 compile/link 要求。当然,“导入库”也是 CMake 的目标:)
请注意,有 NO 额外的 compile/link 选项,包括目录、编译定义等...用于您的可执行文件。一切必要的东西都继承自 OpenGL::GL
和 OpenGL::GLU
.
CMake 还为 many standard libraries 提供包(向下滚动到“查找模块”)。
关于搜索库
您始终可以直接使用 find_library
,在这种情况下,您有责任满足图书馆提出的所有要求。
确定搜索库的位置可能相当复杂,并且由各种 CMake
变量以及传递给 find_library
的参数驱动。在最简单的情况下,当没有相关的 CMAKE_*
变量发生变化时,当 find_library 被调用时使用基本语法,如:
find_library(GL_LIB opengl32)
fund_library(GLU_LIB glu32)
搜索 openGL32
和 glu32
将由 CMAKE_SYSTEM_PREFIX_PATH
、CMAKE_SYSTEM_LIBRARY_PATH
CMake 变量控制。
最后,这里是 find_library, find_package, cmake supported libraries (scroll down to "Find Modules"), target_link_libraries
的完整文档
[更新]
find_library 对比 find_package
有人提出了 find_library
和 find_package
之间的区别的问题。
简而言之,这两个命令不是“竞争”而是“互补”。人们可能会将 find_library
视为包含库的 low-level 接口。在这种情况下,find_package
将是一个更高级的接口,更易于使用。另一方面,find_package
需要库维护者或直接来自 CMake 的额外支持。
深入挖掘问题:
假设使用
find_library (SOME_OTHER_LIB some_other_lib_name)
。如果找到 lib,变量 SOME_OTHER_LIB
将包含库的路径,这足以用于链接,使用 target_link_libraries
.
但要真正使用该库,源需要包含 SOME_OTHER_LIB
具体 headers,即需要引入另一个 find_path(...)
,以定位 headers,然后target_include_directories(...)
。此外,库所需的编译选项也需要以某种方式提取,并使用 target_compile_options(...)
引入
当然,如果SOME_OTHER_LIB用在一处以上,则target_include_directories
、target_compile_options
、target_link_libraries
都必须全部用到。
必须对每个使用的外国库重复相同的过程。
人们可以快速发现规律,这正是 find_package
派上用场的地方。所有 low-level 的工作对 end-user(即使用 CMake 的开发人员)都是隐藏的,并且 she/he 以干净统一的界面呈现。缺点是 find_package
需要一种“某种 driver” 来“驱动”包含外国图书馆的过程。 CMake 直接支持的所有库都可以在 cmake-modules 上找到(向下滚动到“查找模块”)。
锦上添花,几乎所有查找模块还创建 so-called“导入库”(在您的情况下为 OpenGL::GL
和 OpenGL::GLU
),它们是 cmake 目标,包含所有要求第 3 方库。所有这些数据都是通过链接导入库来继承的,使代码更简洁。
不幸的是,对于创建的导入库的命名没有“强制执行”(只是指南),所以唯一的解决办法是检查文档。对于 OpenGL
模块,可以在 FindOpenGL 页面上找到。
在 qmake 中我可以有这样的东西:
LIBS += -lopengl32 \
-lglu32
这将自动找到并 link 我的应用程序的 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
)并为您设置各种有用的变量。
此外,大多数软件包还将定义 so-called 导入库,在您的情况下,OpenGL::GL
和 OpenGL::GLU
可用于链接。针对 CMake 目标 进行链接的美妙之处在于,您的可执行文件将从用于链接的目标继承所有相关的 compile/link 要求。当然,“导入库”也是 CMake 的目标:)
请注意,有 NO 额外的 compile/link 选项,包括目录、编译定义等...用于您的可执行文件。一切必要的东西都继承自 OpenGL::GL
和 OpenGL::GLU
.
CMake 还为 many standard libraries 提供包(向下滚动到“查找模块”)。
关于搜索库
您始终可以直接使用 find_library
,在这种情况下,您有责任满足图书馆提出的所有要求。
确定搜索库的位置可能相当复杂,并且由各种 CMake
变量以及传递给 find_library
的参数驱动。在最简单的情况下,当没有相关的 CMAKE_*
变量发生变化时,当 find_library 被调用时使用基本语法,如:
find_library(GL_LIB opengl32)
fund_library(GLU_LIB glu32)
搜索 openGL32
和 glu32
将由 CMAKE_SYSTEM_PREFIX_PATH
、CMAKE_SYSTEM_LIBRARY_PATH
CMake 变量控制。
最后,这里是 find_library, find_package, cmake supported libraries (scroll down to "Find Modules"), target_link_libraries
的完整文档[更新]
find_library 对比 find_package
有人提出了 find_library
和 find_package
之间的区别的问题。
简而言之,这两个命令不是“竞争”而是“互补”。人们可能会将 find_library
视为包含库的 low-level 接口。在这种情况下,find_package
将是一个更高级的接口,更易于使用。另一方面,find_package
需要库维护者或直接来自 CMake 的额外支持。
深入挖掘问题:
假设使用
find_library (SOME_OTHER_LIB some_other_lib_name)
。如果找到 lib,变量 SOME_OTHER_LIB
将包含库的路径,这足以用于链接,使用 target_link_libraries
.
但要真正使用该库,源需要包含 SOME_OTHER_LIB
具体 headers,即需要引入另一个 find_path(...)
,以定位 headers,然后target_include_directories(...)
。此外,库所需的编译选项也需要以某种方式提取,并使用 target_compile_options(...)
当然,如果SOME_OTHER_LIB用在一处以上,则target_include_directories
、target_compile_options
、target_link_libraries
都必须全部用到。
必须对每个使用的外国库重复相同的过程。
人们可以快速发现规律,这正是 find_package
派上用场的地方。所有 low-level 的工作对 end-user(即使用 CMake 的开发人员)都是隐藏的,并且 she/he 以干净统一的界面呈现。缺点是 find_package
需要一种“某种 driver” 来“驱动”包含外国图书馆的过程。 CMake 直接支持的所有库都可以在 cmake-modules 上找到(向下滚动到“查找模块”)。
锦上添花,几乎所有查找模块还创建 so-called“导入库”(在您的情况下为 OpenGL::GL
和 OpenGL::GLU
),它们是 cmake 目标,包含所有要求第 3 方库。所有这些数据都是通过链接导入库来继承的,使代码更简洁。
不幸的是,对于创建的导入库的命名没有“强制执行”(只是指南),所以唯一的解决办法是检查文档。对于 OpenGL
模块,可以在 FindOpenGL 页面上找到。