简体   繁体   English

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

[英]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.是的,有办法。

About the sample you provided:关于您提供的样品:

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。

About the CMake way of including libraries:关于 CMake 包含库的方式:

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::GLOpenGL::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::GLOpenGL::GLU

CMake also provides packages formany standard libraries (scroll down to "Find Modules"). CMake 还为许多标准库提供包(向下滚动到“查找模块”)。

About searching for libraries关于搜索库

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.搜索openGL32glu32将由CMAKE_SYSTEM_PREFIX_PATHCMAKE_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_libraryfind_packagecmake 支持的库(向下滚动到“查找模块”)、 target_link_libraries的完整文档

[update] [更新]

find_library vs find_package find_library vs find_package

The question was raised about the difference between find_library and find_package .有人提出了关于find_libraryfind_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_directoriestarget_compile_optionstarget_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::GLOpenGL::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM