我已经满意地解决了这个问题!我现在将完全继续前进。这基本上是要求一个教程。有很多必须做出的决定,希望是合乎逻辑的,以便 Google 测试与自动工具很好地吻合。所以我提前为冗长的答案道歉,但所有细节都应该在那里。
第一个问题
为了理解答案,需要稍微改写问题。我们正在将 Google Test 编译为我们的测试代码将链接到的库。将不会安装该库。我们要问的问题是
"我们如何配置 autotools 以将 Google Test 编译为库
我们的测试代码可以链接到哪个?”
为此,我们需要下载 Google Test 并将其放入我们的项目中。我使用 Github,所以我通过在我的项目的根路径中添加一个子模块来做到这一点:
$ git submodule add git@github.com:google/googletest.git
$ git submodule init
$ git submodule update
这会将 googletest 下载到我的项目的根目录中:
/:
Makefile.am
configure.ac
src/:
(files for my project)
tests/:
(test files)
googletest/:
googletest/:
include/:
(headers, etc., to be included)
gtest/:
gtest.h
m4/:
(directory for m4 scripts and things)
src/:
(source files for Google Test)
我需要按照instructions 进行编译。我只希望在运行make check 时构建 Google 测试库,所以我将使用 check_LTLIBRARIES。我在 /tests 中的测试 Makefile.am 中添加以下内容:
check_LTLIBRARIES = libgtest.la
libgtest_la_SOURCES = ../googletest/googletest/src/gtest-all.cc
libgtest_la_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googletest
libgtest_la_LDFLAGS = -pthread
这需要在 configure.ac 中启用子目录对象。这是通过将其添加到 AM_INIT_AUTOMAKE 行来完成的。我还需要在 AC_CONFIG_FILES 中包含 makefile。我们还想使用 libtool,因为我们正在编译库文件(我稍后会解释为什么以及如何工作)。要使用 libtool,我们添加 AM_PROG_AR、LT_INIT。我们希望 autoreconf 将 m4 宏安装到 /m4,然后我们希望 automake 找到它们,所以我们需要 AC_CONFIG_MACRO_DIRS。我的 configure.ac 更新了行:
AM_INIT_AUTOMAKE([-Wall -Werror subdir-objects])
...
AM_PROG_AR
LT_INIT
AC_CONFIG_MACRO_DIRS([m4])
...
AC_CONFIG_FILES([Makefile
src/Makefile
tests/Makefile
])
我还需要在 /Makefile.am 的 /m4 宏目录中包含子目录和指向宏的行:
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src tests
这做了什么? Libtool 已启用 AM_PROG_AR 和 LT_INIT。 check_LTLIBRARIES 意味着我们将使用 libtool 创建一个名为 libgtest.la 的便利库。启用 subdir-objects 后,它将被构建到 /tests 目录中,但不会安装。这意味着,无论何时我们想要更新我们的测试,我们都不必重新编译 Google 测试库 libgtest.la。这将节省测试时间并帮助我们更快地迭代。然后,我们将希望稍后在更新它们时针对它编译我们的单元测试。该库只会在运行make check 时编译,如果我们只想make 或make install 时不编译它可以节省时间。
第二个问题
现在,需要改进第二个问题:您如何 (a) 创建一个测试 (b) 链接到 Google 测试库并因此使用它们?这些问题有点交织在一起,所以我们马上回答。
创建测试只需将以下代码放入位于/tests/gtest.cpp 的gtest.cpp 文件中:
#include "gtest/gtest.h" // we will add the path to C preprocessor later
TEST(CategoryTest, SpecificTest)
{
ASSERT_EQ(0, 0);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
这仅运行简单的测试 0=0。要为您的库创建测试,您需要阅读primer。您会注意到我们(还)不需要标题。我们正在链接到文件“gtest/gtest.h”,因此我们需要确保我们告诉 automake 包含一个具有 gtest/gtest.h 的目录。
接下来,我们需要告诉 automake 我们要构建一个测试并运行它。该测试将构建到我们不想安装的可执行文件中。然后 automake 将运行该可执行文件。它将报告该可执行文件是否表明测试通过或失败。
Automake 通过在 makefile 中查找变量 check_PROGRAMS 来做到这一点。这些是它将编译的程序,但不一定会运行它们。所以我们添加到/tests/Makefile.am:
check_PROGRAMS = gtest
gtest_SOURCES = gtest.cpp
gtest_LDADD = libgtest.la
gtest_LDFLAGS = -pthread
gtest_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googletest -pthread
gtest_SOURCES 找到/tests/gtest.cpp 文件并编译它。 gtest_LDADD 链接到 libgtest.la,它将被编译到 /tests 目录中。 Google 希望我们使用 gtest_LDFLAGS 行来启用 pthread。最后,我们需要包含头文件“gtest/gtest.h”所在的位置,即 gtest_CPPFLAGS 行。 Google 还希望我们包含 /googletest/googletest 位置,并包含
现状: Google Test 库libgtest.la 将与make 一起编译到目录/tests 中,但不会被安装。二进制 gtest 只会用make check 编译,但不会安装。
接下来我们要告诉 automake 实际运行编译后的二进制 gtest 并报告错误。这是通过在/tests/Makefile.am 中添加一行来完成的:
TESTS = gtest
最终的 /tests/Makefile.am 如下所示:
check_LTLIBRARIES = libgtest.la
libgtest_la_SOURCES = ../googletest/googletest/src/gtest-all.cc
libgtest_la_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googletest -pthread
check_PROGRAMS = gtest demo
gtest_SOURCES = gtest.cpp ../src/fields.cpp
gtest_LDADD = libgtest.la
gtest_LDFLAGS = -pthread
gtest_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/src
demo_SOURCES = demo.cpp ../src/fields.cpp
demo_CPPFLAGS = -I$(top_srcdir)/src
TESTS = gtest
现在,来自/ 和make check 的autoreconf -fiv(注意任何错误并希望修复它们),你应该得到一个运行的测试:
build(dev)$ make check
Making check in tests
/Applications/Xcode.app/Contents/Developer/usr/bin/make gtest
make[2]: `gtest' is up to date.
/Applications/Xcode.app/Contents/Developer/usr/bin/make check-TESTS
PASS: gtest
============================================================================
Testsuite summary for IonMotion 0.0.1
============================================================================
# TOTAL: 1
# PASS: 1
# SKIP: 0
# XFAIL: 0
# FAIL: 0
# XPASS: 0
# ERROR: 0
============================================================================