[英]Converting from qmake to cmake, how do I find libraries in the same way?
in qmake I can have something like this:在 qmake 我可以有这样的东西:
LIBS += -lopengl32 \
-lglu32
This will automatically find and link the OpenGL and GLU with my application.这将自动找到 OpenGL 和 GLU 并将其链接到我的应用程序。 How can I do the same in cmake?
我怎样才能在 cmake 中做同样的事情? Is it as simple as:
是不是很简单:
target_link_libraries(${TARGET_NAME} opengl32 glu32)
If so, how does cmake know where to find these libraries?如果是这样,cmake 怎么知道在哪里可以找到这些库? Is there a way to do this that involves a
find_libraries
call instead?有没有办法做到这一点,而不是涉及
find_libraries
调用? The above (if it works), would give me anxiety.以上(如果有效)会让我感到焦虑。
Yes, there is a way.是的,有办法。
target_link_libraries(${TARGET_NAME} opengl32 glu32)
In this case, when you just list libraries to be linked against, CMake will just pass them to the linker, without any additional work;在这种情况下,当您仅列出要链接的库时,CMake 只会将它们传递给 linker,无需任何额外工作; it is the linker, who must find them.
必须找到他们的是 linker。
However, CMake may help you much much more.但是,CMake 可能会帮助您更多。 Pls take a look at the following code snippet, that represents the preferred way of finding libraries in 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)
Instead of using find_library
directly, use find_package
.不要直接使用
find_library
,而是使用find_package
。 It will find the libraries you need (by employing find_library
internally) and set various helpful variables for you.它将找到您需要的库(通过在内部使用
find_library
)并为您设置各种有用的变量。
Also, most of the packages will also define so-called import libraries, OpenGL::GL
and OpenGL::GLU
in your case, that can be used for linking.此外,大多数包还将定义所谓的导入库
OpenGL::GL
和OpenGL::GLU
在您的情况下,可用于链接。 The wonderful thing about linking against the CMake targets is that your executable will inherit all relevant compile/link requirements from the target used for linking.与CMake 目标链接的美妙之处在于,您的可执行文件将从用于链接的目标继承所有相关的编译/链接要求。 Of course, "import libraries" are also CMake targets:)
当然,“导入库”也是 CMake 目标:)
Please note that there are NO additional compile/link options, include directories, compile definitions, etc... for your executable.请注意,您的可执行文件没有额外的编译/链接选项、包含目录、编译定义等。 Everything that is necessary is inherited from
OpenGL::GL
and OpenGL::GLU
.一切必要的东西都继承自
OpenGL::GL
和OpenGL::GLU
。
CMake also provides packages formany standard libraries (scroll down to "Find Modules"). CMake 还为许多标准库提供包(向下滚动到“查找模块”)。
You can always use find_library
directly, and in that case, it is your responsibility to take care of all requirements the library imposes.您始终可以直接使用
find_library
,在这种情况下,您有责任处理库强加的所有要求。
Determining the places to search for libraries may be quite complex, and is driven by various CMake
variables, as well as parameters passed to find_library
.确定搜索库的位置可能非常复杂,并且由各种
CMake
变量以及传递给find_library
的参数驱动。 In the simplest case, when no related CMAKE_*
variables are changed, and when the find_library is called with basic syntax, like:在最简单的情况下,当没有更改相关
CMAKE_*
变量时,并且使用基本语法调用 find_library 时,例如:
find_library(GL_LIB opengl32)
fund_library(GLU_LIB glu32)
Search for openGL32
and glu32
will be controlled by CMAKE_SYSTEM_PREFIX_PATH
, CMAKE_SYSTEM_LIBRARY_PATH
CMake variables.搜索
openGL32
和glu32
将由CMAKE_SYSTEM_PREFIX_PATH
、 CMAKE_SYSTEM_LIBRARY_PATH
CMake 变量控制。
In the end, here is the complete documentation for find_library , find_package ,cmake supported libraries (scroll down to "Find Modules"), target_link_libraries最后,这里是find_library 、 find_package 、cmake 支持的库(向下滚动到“查找模块”)、 target_link_libraries的完整文档
The question was raised about the difference between find_library
and find_package
.有人提出了关于
find_library
和find_package
之间区别的问题。
Briefly, these two commands do not "compete" but rather "complement" each other.简而言之,这两个命令不是“竞争”而是“互补”。 One may think about
find_library
as a low-level interface for including libraries.人们可能
find_library
视为包含库的低级接口。 In this context, find_package
would be a much higher interface, that is easier to use.在这种情况下,
find_package
将是一个更高的接口,更易于使用。 On the other hand, find_package
requires additional support from the library maintainers, or from the CMake directly.另一方面,
find_package
需要库维护者或直接从 CMake 获得额外支持。
Digging a little deeper into the problem:深入挖掘问题:
Suppose that some library is introduced using find_library (SOME_OTHER_LIB some_other_lib_name)
.假设使用
find_library (SOME_OTHER_LIB some_other_lib_name)
引入了某个库。 If the lib was found, the variable SOME_OTHER_LIB
will contain the path to the library, which is enough for linking, using target_link_libraries
.如果找到了库,变量
SOME_OTHER_LIB
将包含库的路径,这足以使用target_link_libraries
进行链接。
But to really use the library, sources need to include SOME_OTHER_LIB
specific headers, ie another find_path(...)
needs to be introduced, to locate headers, followed by target_include_directories(...)
.但是要真正使用该库,源需要包含
SOME_OTHER_LIB
特定的头文件,即需要引入另一个find_path(...)
来定位头文件,然后是target_include_directories(...)
。 Also, compile options required by the library also need to be extracted somehow, and introduced using target_compile_options(...)
此外,库所需的编译选项也需要以某种方式提取,并使用
target_compile_options(...)
Of course, if the SOME_OTHER_LIB is used on more than one place, all target_include_directories
, target_compile_options
, and target_link_libraries
must be used all over.当然,如果在多个地方使用了 SOME_OTHER_LIB,则必须全部使用所有
target_include_directories
、 target_compile_options
和target_link_libraries
。
The same process must be repeated for every foreign library that is used.必须对使用的每个外部库重复相同的过程。
One can quickly spot the pattern, and this is exactly where find_package
becomes handy.人们可以快速发现这种模式,而这正是
find_package
派上用场的地方。 All that low-level work is hidden from the end-user (ie developer using CMake), and she/he is presented with a clean and unified interface.所有底层工作都对最终用户(即使用 CMake 的开发人员)隐藏,并且为她/他提供了一个干净统一的界面。 The downside is that
find_package
requires a "kind of driver" that will "drive" the process of including the foreign library.缺点是
find_package
需要一种“驱动程序”来“驱动”包含外部库的过程。 All libraries that are directly supported by CMake may be found oncmake-modules (scroll down to "Find Modules"). CMake 直接支持的所有库都可以在cmake-modules上找到(向下滚动到“查找模块”)。
The icing on the cake, almost all find modules also create so-called "import libraries" ( OpenGL::GL
and OpenGL::GLU
in your case) that are cmake targets holding all requirements of the 3rd party library.锦上添花,几乎所有查找模块还创建所谓的“导入库”(
OpenGL::GL
和OpenGL::GLU
在您的情况下)是 Z272CEADB8458515B2AE4B5630A6029CC.Z 目标的所有要求All those data are inherited by just linking against the import library, making the code much cleaner.所有这些数据都是通过链接导入库来继承的,从而使代码更加简洁。
Unfortunately, there are no "enforcements" about the naming of created import libraries (just guidelines), so the only solution is to check the documentation.不幸的是,对于创建的导入库的命名没有“强制执行”(只是指南),所以唯一的解决方案是检查文档。 For
OpenGL
module, it can be found on FindOpenGL page.对于
OpenGL
模块,可以在FindOpenGL页面上找到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.