从各种构建系统中使用 GoogleTest
GoogleTest 附带 pkg-config 文件,可用于确定编译和链接到 GoogleTest(和 GoogleMock)所需的所有标志。 Pkg-config 是一种标准化的纯文本格式,包含
- includedir (-I) 路径
- 必要的宏 (-D) 定义
- 进一步需要的标志 (-pthread)
- 库 (-L) 路径
- 要链接到的库 (-l)
所有当前的构建系统都以某种方式支持 pkg-config。 对于此处的全部示例,我们假定您想编译示例 samples/sample3_unittest.cc
。
CMake
在 CMake 中使用 pkg-config
非常容易
find_package(PkgConfig)
pkg_search_module(GTEST REQUIRED gtest_main)
add_executable(testapp)
target_sources(testapp PRIVATE samples/sample3_unittest.cc)
target_link_libraries(testapp PRIVATE ${GTEST_LDFLAGS})
target_compile_options(testapp PRIVATE ${GTEST_CFLAGS})
enable_testing()
add_test(first_and_only_test testapp)
通常建议您使用 target_compile_options
+ _CFLAGS
而不是 target_include_directories
+ _INCLUDE_DIRS
,因为前者不仅包含 -I 标志(GoogleTest 可能需要一个宏来指示内部头文件,表明所有库都已启用线程进行编译。此外,GoogleTest 可能还需要在编译步骤中使用 -pthread
,因此将 pkg-config Cflags
变量拆分为 include 目录和宏以用于 target_compile_definitions()
可能仍然会遗漏此标志)。 同样的建议也适用于使用 _LDFLAGS
而不是更常见的 _LIBRARIES
,后者会丢弃 -L
标志和 -pthread
。
救命!pkg-config 找不到 GoogleTest!
假设您有一个类似于本教程中的 CMakeLists.txt
,并且您尝试运行 cmake
。 您很可能会遇到类似于以下的失败
-- Checking for one of the modules 'gtest_main'
CMake Error at /usr/share/cmake/Modules/FindPkgConfig.cmake:640 (message):
None of the required 'gtest_main' found
如果您自己安装了 GoogleTest,并且没有从发行版或其他软件包管理器中获取它,则这些故障很常见。 如果是这样,您需要告诉 pkg-config 在哪里可以找到包含信息的 .pc
文件。 假设您将 GoogleTest 安装到 /usr/local
,那么 .pc
文件可能会安装在 /usr/local/lib64/pkgconfig
下。 如果您设置了
export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
pkg-config 还会尝试在 PKG_CONFIG_PATH
中查找 gtest_main.pc
。
在交叉编译设置中使用 pkg-config
Pkg-config 也可以用于交叉编译设置。 为此,让我们假设交叉编译安装的最终前缀将是 /usr
,并且您的 sysroot 是 /home/MYUSER/sysroot
。 使用以下命令配置并安装 GTest
mkdir build && cmake -DCMAKE_INSTALL_PREFIX=/usr ..
使用 DESTDIR
安装到 sysroot 中
make -j install DESTDIR=/home/MYUSER/sysroot
在我们继续之前,建议在交叉编译设置中始终为 pkg-config 定义以下两个变量
export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=yes
export PKG_CONFIG_ALLOW_SYSTEM_LIBS=yes
否则,pkg-config
将根据标准前缀(例如 /usr
)过滤 -I
和 -L
标志(有关为什么通常需要进行此剥离的原因,请参阅 https://bugs.freedesktop.org/show_bug.cgi?id=28264#c3)。
如果您查看生成的 pkg-config 文件,它看起来像
libdir=/usr/lib64
includedir=/usr/include
Name: gtest
Description: GoogleTest (without main() function)
Version: 1.11.0
URL: https://github.com/google/googletest
Libs: -L${libdir} -lgtest -lpthread
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1 -lpthread
请注意,sysroot 未包含在 libdir
和 includedir
中! 如果您尝试使用正确的 PKG_CONFIG_LIBDIR=/home/MYUSER/sysroot/usr/lib64/pkgconfig
对此 .pc
文件运行 pkg-config
,您将得到
$ pkg-config --cflags gtest
-DGTEST_HAS_PTHREAD=1 -lpthread -I/usr/include
$ pkg-config --libs gtest
-L/usr/lib64 -lgtest -lpthread
这显然是错误的,并指向 CBUILD
而不是 CHOST
根。 为了在交叉编译设置中使用它,我们需要告诉 pkg-config 将实际的 sysroot 注入到 -I
和 -L
变量中。 现在让我们告诉 pkg-config 关于实际的 sysroot
export PKG_CONFIG_DIR=
export PKG_CONFIG_SYSROOT_DIR=/home/MYUSER/sysroot
export PKG_CONFIG_LIBDIR=${PKG_CONFIG_SYSROOT_DIR}/usr/lib64/pkgconfig
再次运行 pkg-config
,我们得到
$ pkg-config --cflags gtest
-DGTEST_HAS_PTHREAD=1 -lpthread -I/home/MYUSER/sysroot/usr/include
$ pkg-config --libs gtest
-L/home/MYUSER/sysroot/usr/lib64 -lgtest -lpthread
现在包含正确的 sysroot。 有关在构建系统调用中也包括 ${CHOST}
的更全面指南,请参阅 Diego Elio Pettenò 的优秀教程:https://autotools.io/pkgconfig/cross-compiling.html