是的,有办法。
关于您提供的样本:
target_link_libraries(${TARGET_NAME} opengl32 glu32)
在这种情况下,当您仅列出要链接的库时,CMake 只会将它们传递给链接器,而无需任何额外工作;是链接器,必须找到它们。
关于 CMake 包含库的方式:
但是,CMake 可以为您提供更多帮助。请看下面的代码 sn-p,它代表了在 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 还为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(向下滚动到“查找模块”)、target_link_libraries 的完整文档
[更新]
find_library 与 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,则必须全部使用target_include_directories、target_compile_options 和target_link_libraries。
必须对使用的每个外部库重复相同的过程。
人们可以快速发现这种模式,而这正是find_package 派上用场的地方。所有底层工作都对最终用户(即使用 CMake 的开发人员)隐藏,并且为她/他提供了一个干净统一的界面。缺点是find_package 需要一种“驱动程序”,它将“驱动”包含外部库的过程。 CMake 直接支持的所有库都可以在cmake-modules 上找到(向下滚动到“查找模块”)。
锦上添花,几乎所有 find 模块还创建所谓的“导入库”(OpenGL::GL 和 OpenGL::GLU 在您的情况下),它们是包含第 3 方库的所有要求的 cmake 目标。所有这些数据都是通过链接导入库来继承的,从而使代码更加简洁。
不幸的是,对于创建的导入库的命名没有“强制措施”(只是指南),因此唯一的解决方案是查看文档。对于OpenGL 模块,可以在FindOpenGL 页面找到。