如何在将test exe与gradle链接时排除第二个main?

时间:2017-03-10 07:59:43

标签: c++ gradle linker googletest

我试图将单元测试集成到本机(C ++)gradle项目中,但我似乎无法找到可行的解决方案。链接测试可执行文件时会出现问题,因为有两个可用的域(一个用于主应用程序,一个用于单元测试)。有没有人知道如何在链接步骤中排除其中一个?

以下是我的设置的最小示例:

项目结构

build.gradle
src
    -> main
        -> cpp
            -> main.cpp
            -> registry.cpp
        -> headers
            -> registry.hpp
    -> test
        -> cpp
            -> main_test.cpp
            -> test_registry.cpp
libs
    -> googletest
        -> 1.7.0
            -> include
                -> ...
            -> lib
                -> libgtest.a

的build.gradle

apply plugin: 'cpp'
apply plugin: 'google-test-test-suite'

model {
    platforms {
        x86 {
            architecture "x86"
        }
        x64 {
            architecture "x86_64"
        }
    }

    components {
        main(NativeExecutableSpec) {
            baseName "Registry"
            targetPlatform "x86"
            binaries.all {
                cppCompiler.args "-std=c++11", "-municode", "-mwindows"
                linker.args "-municode", "-mwindows"
            }
        }
    }

    testSuites {
        mainTest(GoogleTestTestSuiteSpec) {
            testing $.components.main

            sources {
                cpp.source.srcDir 'src/test/cpp'
            }
        }
    }

    repositories {
        libs(PrebuiltLibraries) {
            googleTest {
                headers.srcDir "libs/googletest/1.7.0/include"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile =
                        file("libs/googletest/1.7.0/lib/libgtest.a")
                }
            }
        }
    }
}

model {
    binaries {
        withType(GoogleTestTestSuiteBinarySpec) {
            lib library: "googleTest", linkage: "static"

            cppCompiler.args "-std=c++11", "-municode"
            linker.args "-municode"
        }
    }
}

错误消息

:compileMainExecutableMainCpp
:linkMainExecutable
:mainExecutable
:assemble
:compileMainTestGoogleTestExeMainCpp
:compileMainTestGoogleTestExeMainTestCpp
:linkMainTestGoogleTestExe
C:\Users\minimal\build\objs\mainTest\mainCpp\e7f4uxujatdodel7e7qw5uhsp\main.obj:main.cpp:(.text+0x0): multiple definition of `wmain'
C:\Users\minimal\build\objs\mainTest\mainTestCpp\271ezc0ay5ubap2l962cnectq\main_test.obj:main_test.cpp:(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

:linkMainTestGoogleTestExe FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':linkMainTestGoogleTestExe'.
> A build operation failed.
      Linker failed while linking mainTest.exe.

options.txt

-o
C:\\Users\\minimal\\build\\exe\\mainTest\\mainTest.exe
C:\\Users\\minimal\\build\\objs\\mainTest\\mainTestCpp\\271ezc0ay5ubap2l962cnectq\\main_test.obj
C:\\Users\\minimal\\build\\objs\\mainTest\\mainTestCpp\\dp6ieaohq04qqqa31sdfwrsxj\\test_registry.obj
C:\\Users\\minimal\\build\\objs\\mainTest\\mainCpp\\68sxcjmhakj69ha7wqtijofs3\\Registry.obj
C:\\Users\\minimal\\build\\objs\\mainTest\\mainCpp\\e7f4uxujatdodel7e7qw5uhsp\\main.obj
C:\\Users\\minimal\\libs\\googletest\`.7.0\\lib\\libgtest.a
-municode
-m32

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

你的问题来自于试图用googletest做错事。

Googletest是单元测试框架。这意味着它是用于测试 - 其中这里意味着一堆函数和/或类 不包含 main 功能。它不适用于测试应用程序, 具有main功能的。您可以通过运行来测试应用程序 应用和制作受控 - 可能是自动化的 - 观察 它的公开行为。这种测试有各种各样的名字,但是 不是单元测试,首先是单元测试。

要使用googletest测试库,您需要创建一个应用程序 运行你的googletest测试用例。该应用程序,测试运行器,需要 它自己的main函数,除了运行测试用例之外什么都不做:

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

对于某人拥有包含的应用程序而言,这是很常见的 他们的一堆应用程序特定的功能和/或类 喜欢用googletest进行单元测试。这样做的方法是: -

  • 将应用程序重构为:

    • 一个库 - 称之为应用程序库 - 包含您想要的函数和/或类 单元测试,不包括main函数。
    • 其余部分,包括main函数。
  • 通过将余数与应用程序库相关联来构建应用程序。

  • 创建一个测试运行器应用程序,其中包含您的googletest测试用例 和googletest main功能。当然,测试用例#include 应用程序库的标题。

  • 通过将测试用例和主要功能与应用程序库链接来构建测试运行器。

  • 通过运行test-runner对应用程序库进行单元测试。

最简单,最快捷的方法就是将所有应用程序放到 除了main函数之外,进入应用程序库。但它可能更明智 在开发过程中仅将中的内容从应用程序移动到应用程序库中 单元测试覆盖它,因此您随时都知道应用程序库中的任何内容 有单元测试,其余的没有。以这种方式进行,直到除了之外的所有事情 main函数位于应用程序库中,并具有单元测试。

您几乎肯定会发现将app-library分解出来的过程 这样您就可以将它与应用程序和测试运行器公开进行链接 设计应用程序中的缺陷并迫使您做得更好。这可以开始了 应用程序库正在逐渐成熟为一个多应用程序库,稳定的高品质 软件资产。

所以你开始使用一个项目,即应用程序项目,最后你就完成了 三个项目:

  • 构建应用程序库的项目
  • 构建应用程序的项目
  • 构建测试运行器的项目

无论如何,您拥有的任何构建系统都将允许您自动生成 这些项目之间的依赖关系。显然,你想要:

  • 构建应用程序以构建应用程序库
  • 构建测试运行器以要求构建app libary

但是你可以走得更远,并且需要构建应用程序 构建测试运行器 - 将构建应用程序库 - 并成功完成 运行测试运行器。这样,您就不会构建应用程序 除非单元测试成功。对你而言,这可能有点过头了 桌面开发周期,但不适用于CI版本。

对于下一个应用程序,您可以使用此3项目模式启动, 并且仅当您可以从应用程序获取时才向应用程序添加功能 应用程序库,必须通过必须通过的单元测试 在试运行中。然后你以正确的方式使用googletest。