如何在将测试 exe 与 gradle 链接时排除第二个主程序?
How to exclude second main while linking test exe with gradle?
我正在尝试将单元测试集成到本机 (C++) gradle 项目中,但我似乎找不到可行的解决方案。链接测试可执行文件时会出现问题,因为有两个可用的 wmains(一个用于主应用程序,一个用于单元测试)。有谁知道如何在链接步骤中排除其中之一?
这是我的设置的一个最小示例:
项目结构
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\mainTestCpp1ezc0ay5ubap2l962cnectq\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
非常感谢任何帮助!
您的问题是因为尝试使用 googletest 做错事。
Googletest 是一个 unit-testing 框架。这意味着它用于测试
libraries - 这里的 library 表示 一堆函数 and/or 类
不包括 main
函数。它不是用于测试应用程序,
具有 main
功能。您通过 运行ning 来测试应用程序
应用和进行可控的——可能是自动化的——观察
其公开行为。这种测试有不同的名称,但是
不是 unit-testing,unit-testing 排在第一位。
要使用 googletest 测试库,您需要创建一个应用程序来
运行 你的 googletest 测试用例。该应用程序 test-runner 需要
它自己的 main
函数,除了 运行 测试用例之外什么都不做:
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
有人拥有包含以下内容的应用程序很常见
一堆特定于应用程序的功能 and/or 类 他们会
喜欢 unit-test 与 googletest。这样做的方法是:-
将应用程序重构为:
- 一个库 - 称之为 app 库 - 包含你想要的函数 and/or 类
unit-test,不包括
main
函数。
- 余数,包括
main
函数。
通过 link使用应用程序库构建应用程序。
创建一个 test-runner 应用程序,包含您的 googletest 测试用例
和一个 googletest main
函数。当然,测试用例,#include
应用程序库的headers。
通过 link 使用应用程序库构建测试用例和主要功能来构建 test-runner。
Unit-test 应用程序库 运行 宁 test-runner.
最简单快捷的方法就是将所有应用程序,
main
函数除外,进入应用程序库。但这可能更明智
仅在开发过程中 将内容从应用程序移动到应用程序库
单元测试覆盖它,所以你随时知道应用程序库中的任何内容
有单元测试,其余的没有。以这种方式进行,直到除了
main
函数在应用程序库中,并且有单元测试。
你几乎肯定会发现分解出 app-library 的过程
这样你就可以 link 它与应用程序和测试 运行ner exposes
应用程序中的设计缺陷并迫使您做得更好。这可以启动一个
应用程序库正在成熟为 multi-app 库,一个稳定的 high-quality
软件资产。
所以你从一个项目开始,应用程序项目,你最终
三个项目:
- 构建应用程序库的项目
- 构建应用程序的项目
- 构建测试的项目运行ner
无论哪种方式,您拥有的任何构建系统都可以让您自动创建
这些项目之间的依赖关系。显然,您想要:
- 构建应用程序需要构建应用程序库
- 构建 test-runner 需要构建应用程序库
但你可以更进一步,让构建应用程序需要
构建 test-runner - 这将构建应用程序库 - 并成功
运行测试 运行ner。这样,您将永远不会构建应用程序
除非单元测试成功。这对你来说可能有点矫枉过正
桌面开发周期,但不适用于 CI 构建。
对于下一个应用程序,您可以开始 这个 3 项目模式,
并仅在您可以从
app库,单元测试必须覆盖,必须通过
在 test-runner。那么你就是在以正确的方式使用 googletest。
我正在尝试将单元测试集成到本机 (C++) gradle 项目中,但我似乎找不到可行的解决方案。链接测试可执行文件时会出现问题,因为有两个可用的 wmains(一个用于主应用程序,一个用于单元测试)。有谁知道如何在链接步骤中排除其中之一?
这是我的设置的一个最小示例:
项目结构
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\mainTestCpp1ezc0ay5ubap2l962cnectq\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
非常感谢任何帮助!
您的问题是因为尝试使用 googletest 做错事。
Googletest 是一个 unit-testing 框架。这意味着它用于测试
libraries - 这里的 library 表示 一堆函数 and/or 类
不包括 main
函数。它不是用于测试应用程序,
具有 main
功能。您通过 运行ning 来测试应用程序
应用和进行可控的——可能是自动化的——观察
其公开行为。这种测试有不同的名称,但是
不是 unit-testing,unit-testing 排在第一位。
要使用 googletest 测试库,您需要创建一个应用程序来
运行 你的 googletest 测试用例。该应用程序 test-runner 需要
它自己的 main
函数,除了 运行 测试用例之外什么都不做:
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
有人拥有包含以下内容的应用程序很常见 一堆特定于应用程序的功能 and/or 类 他们会 喜欢 unit-test 与 googletest。这样做的方法是:-
将应用程序重构为:
- 一个库 - 称之为 app 库 - 包含你想要的函数 and/or 类
unit-test,不包括
main
函数。 - 余数,包括
main
函数。
- 一个库 - 称之为 app 库 - 包含你想要的函数 and/or 类
unit-test,不包括
通过 link使用应用程序库构建应用程序。
创建一个 test-runner 应用程序,包含您的 googletest 测试用例 和一个 googletest
main
函数。当然,测试用例,#include
应用程序库的headers。通过 link 使用应用程序库构建测试用例和主要功能来构建 test-runner。
Unit-test 应用程序库 运行 宁 test-runner.
最简单快捷的方法就是将所有应用程序,
main
函数除外,进入应用程序库。但这可能更明智
仅在开发过程中 将内容从应用程序移动到应用程序库
单元测试覆盖它,所以你随时知道应用程序库中的任何内容
有单元测试,其余的没有。以这种方式进行,直到除了
main
函数在应用程序库中,并且有单元测试。
你几乎肯定会发现分解出 app-library 的过程 这样你就可以 link 它与应用程序和测试 运行ner exposes 应用程序中的设计缺陷并迫使您做得更好。这可以启动一个 应用程序库正在成熟为 multi-app 库,一个稳定的 high-quality 软件资产。
所以你从一个项目开始,应用程序项目,你最终 三个项目:
- 构建应用程序库的项目
- 构建应用程序的项目
- 构建测试的项目运行ner
无论哪种方式,您拥有的任何构建系统都可以让您自动创建 这些项目之间的依赖关系。显然,您想要:
- 构建应用程序需要构建应用程序库
- 构建 test-runner 需要构建应用程序库
但你可以更进一步,让构建应用程序需要 构建 test-runner - 这将构建应用程序库 - 并成功 运行测试 运行ner。这样,您将永远不会构建应用程序 除非单元测试成功。这对你来说可能有点矫枉过正 桌面开发周期,但不适用于 CI 构建。
对于下一个应用程序,您可以开始 这个 3 项目模式, 并仅在您可以从 app库,单元测试必须覆盖,必须通过 在 test-runner。那么你就是在以正确的方式使用 googletest。