googletest icon indicating copy to clipboard operation
googletest copied to clipboard

doc: wrong description about gtest_main

Open yaojingguo opened this issue 4 years ago • 7 comments

https://github.com/google/googletest/blob/master/docs/primer.md says:

Most users should not need to write their own main function and instead link with gtest_main (as opposed to with gtest), which defines a suitable entry point.

If it fits your needs, then just link your test with the gtest_main library and you are good to go.

Actually, if users don't want to write their own main methods, they need to link with both gtest and gtest_main. I have verified it on macOS. And the following commands show that InitGoogleTest is only defined in gtest

$ nm build/lib/libgtest.a| grep InitGoogleTest
00000000000235f0 T __ZN7testing14InitGoogleTestEPiPPc
0000000000023710 T __ZN7testing14InitGoogleTestEPiPPw
0000000000023830 T __ZN7testing14InitGoogleTestEv
0000000000023620 T __ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT_
0000000000023740 T __ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT_
$ nm build/lib/libgtest_main.a| grep InitGoogleTest
                 U __ZN7testing14InitGoogleTestEPiPPc

yaojingguo avatar Jan 28 '21 03:01 yaojingguo

I think the document can be misleading and should be updated
Because the way of using gtest_main in the guide cannot be successful if gtest_main is linked alone
And so linking both libraries (gtest, gtest_main) is one of the workaround for the case

The document seems to be written assuming that a user uses some build tools
For example, if you use cmake you can find gtest_main links gtest in the build script and so libgtest will be transitively linked when libgtest_main is imported with find_package() as below

// file name : /usr/local/lib/cmake/GTest/GTestTargets-noconfig.cmake
...
set_target_properties(GTest::gtest_main PROPERTIES
  IMPORTED_LINK_INTERFACE_LANGUAGES_NOCONFIG "CXX"
  IMPORTED_LINK_INTERFACE_LIBRARIES_NOCONFIG "Threads::Threads;GTest::gtest"
  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libgtest_main.a"
  )
...

It looks like Bazel behaves the same as described here

ghost avatar Jan 28 '21 17:01 ghost

It looks like @hyukmyeong's answer is correct to me. @yaojingguo, can you provide the exact build file that you are using to link this?

derekmauro avatar Feb 01 '21 20:02 derekmauro

https://github.com/google/googletest/blob/273f8cb059a4e7b089731036392422b5ef489791/BUILD.bazel @derekmauro

yaojingguo avatar Feb 06 '21 14:02 yaojingguo

@yaojingguo I meant the build file for your project so that we can reproduce this. Or a reduced example build file.

derekmauro avatar Feb 08 '21 20:02 derekmauro

I did the build on a Mac.

$ clang --version
Apple clang version 11.0.3 (clang-1103.0.32.62)
Target: x86_64-apple-darwin19.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ c++ -std=c++11 foo_test.cc -lgtest
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

foo_test.cc:

#include "gtest/gtest.h"

int Factorial(int n) {
    if (n == 0) return 1;
    return n * Factorial(n - 1);
}

// Tests factorial of 0.
TEST(FactorialTest, HandlesZeroInput) {
  EXPECT_EQ(Factorial(0), 1);
}

// Tests factorial of positive numbers.
TEST(FactorialTest, HandlesPositiveInput) {
  EXPECT_EQ(Factorial(1), 1);
  EXPECT_EQ(Factorial(2), 2);
  EXPECT_EQ(Factorial(3), 6);
  EXPECT_EQ(Factorial(8), 40320);
}

yaojingguo avatar Feb 13 '21 04:02 yaojingguo

Try c++ -std=c++11 foo_test.cc -lgtest_main -lgtest and let us know if that solves your problem.

-lgtest gives you the gtest library, but expect you to supply the main function. -lgtest_main supplies the main function.

derekmauro avatar Feb 18 '21 18:02 derekmauro

Oh I see, your issue is that the docs say gtest_main implies gtest is automatically linked. That is true for our supported build systems (Bazel and CMake). If you are linking manually as you are doing, this isn't true. We can probably make this more clear in the documentation.

@ericschmidtatwork

derekmauro avatar Feb 18 '21 18:02 derekmauro