我在网上看了很多这样的代码:
include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)
target_include_directories(app SYSTEM PUBLIC ${SDL2_INCLUDE_DIRS})
target_link_libraries(app ${SDL2_LIBRARIES})
然而,这样做似乎是错误的,因为它只使用了包含目录和库,而忽略了pkg-config
可能返回的定义、库路径和其他标志。
正确的方法是什么呢?如何确保pkg-config
返回的所有编译和链接标志都被编译后的app
使用?是否有一个命令可以完成这一任务,例如target_use(app SDL2)
?
参考:
6条答案
按热度按时间4szc88ey1#
首先,呼叫:
应改为:
find_package()
调用更加灵活,允许使用REQUIRED
这样的选项,它可以自动执行include()
必须手动执行的操作。第二,尽可能避免手动调用
pkg-config
。CMake附带了一组丰富的包定义,可以在Linux的/usr/share/cmake-3.0/Modules/Find*cmake
下找到。这些包定义为用户提供了比原始调用pkg_search_module()
更多的选项和选择。至于提到的假设的
target_use()
命令,CMake已经通过PUBLIC内置了该命令|私人|INTERFACE。像target_include_directories(mytarget PUBLIC ...)
这样的调用会导致include目录自动用于每个使用mytarget
的目标,例如target_link_libraries(myapp mytarget)
。但是,这种机制似乎只适用于在CMakeLists.txt
文件中创建的库,而不适用于使用pkg_search_module()
获取的库。调用add_library(bar SHARED IMPORTED)
可能用于此目的,但我还没调查过。至于主要问题,在大多数情况下,这是可行的:
SDL2_CFLAGS_OTHER
包含了成功编译所需的定义和其他标志。然而,标志SDL2_LIBRARY_DIRS
和SDL2_LDFLAGS_OTHER
仍然被忽略,不知道这会成为一个问题。此处提供更多文档http://www.cmake.org/cmake/help/latest/module/FindPkgConfig.html
njthzxwz2#
如果您以非常普通的方式使用cmake和pkg-config,则此解决方案有效。
但是,如果您有一个库存在于某个开发目录中(例如/home/me/hack/lib),那么使用此处所示的其他方法将无法配置链接器路径。在典型安装位置下找不到的库将导致链接器错误,例如
/usr/bin/ld: cannot find -lmy-hacking-library-1.0
。此解决方案修复了这种情况下的链接器错误。另一个问题可能是pkg-config文件没有安装在正常位置,需要在运行cmake时使用
PKG_CONFIG_PATH
环境变量添加项目的pkg-config路径(请参阅其他有关此问题的堆栈溢出问题)。使用
IMPORTED_TARGET
是解决上述问题的关键。此解决方案是this earlier answer的改进,并可归结为工作的CMakeLists.txt的最终版本:请注意,
target_link_libraries
不仅仅是更改链接器命令,它还传播指定目标的其他PUBLIC属性,如编译器标志、编译器定义、包含路径等,因此,请谨慎使用PUBLIC关键字。6bc51xsx3#
很少有人只需要与SDL2链接。目前流行的答案是使用
pkg_search_module()
,它检查给定的模块并使用第一个工作的模块。您更可能要链接SDL2、SDL2_Mixer和SDL2_TTF等...
pkg_check_modules()
会检查所有指定的模块。免责声明:如果我有足够的stackoverflow街头信条,我会简单地评论Grumbel的自我回答。
von4xj4u4#
大多数可用的答案都无法为
pkg-config
库配置头文件。在思考了Documentation for FindPkgConfig之后,我想出了一个解决方案,它也提供了这些功能:(* 相应地,用目标替换
<my-target>
,用任意库替换<some-lib>
。*)IMPORTED_TARGET
选项似乎很关键,它使PkgConfig::
命名空间下的所有内容都可用。这是所有需要的,也是所有 * 应该 * 需要的。sczxawaw5#
1.没有
target_use
这样的命令。但我知道有几个项目已经写了这样的命令供内部使用。但每个项目都想传递额外的标志或定义,因此在一般的CMake中使用它没有意义。另一个不使用它的原因是C++模板库,如Eigen,没有库,但你只有一堆包含文件。1.所描述的方法通常是正确的。对于某些库,它可能会有所不同,然后您必须添加
_LDFLAGS
或_CFLAGS
。这是不使用target_use
的另一个原因。如果它不适用于您,请询问有关SDL2或您要使用的任何库的新问题。sycxhyv76#
如果您也希望从库中添加定义,
add_definitions
指令可以满足您的需求。文档可以在here中找到,沿着更多添加编译器标志的方法。下列程式码片段会使用此指示将GTKGL加入至项目: