3

I was using rather obsolete version of GoogleTest and have used hack for custom printing, found here: How to send custom message in Google C++ Testing Framework?

My sources contain the following code from the link above

namespace testing
{
 namespace internal
 {
  enum GTestColor {
      COLOR_DEFAULT,
      COLOR_RED,
      COLOR_GREEN,
      COLOR_YELLOW
  };

  extern void ColoredPrintf(GTestColor color, const char* fmt, ...);
 }
}
#define PRINTF(...)  do { testing::internal::ColoredPrintf(testing::internal::COLOR_GREEN, "[          ] "); testing::internal::ColoredPrintf(testing::internal::COLOR_YELLOW, __VA_ARGS__); } while(0)

I have updated sources of GoogleTest in my project to master version and now I have link errors saying that ColoredPrintf is not defined.

error LNK2019: unresolved external symbol "void __cdecl testing::internal::ColoredPrintf(enum testing::internal::`anonymous namespace'::GTestColor,char const *,...)" (?ColoredPrintf@internal@testing@@YAXW4GTestColor@?A0x313d419f@12@PEBDZZ) referenced in function

Studying fresh gtest.cc shows that they have changed GTestColor to enum class and put it into an anonymous namespace inside the namespace testing::internal: https://github.com/google/googletest/blob/master/googletest/src/gtest.cc#L3138

I've changed the snippet in my sources to:

namespace testing {
    namespace internal
    {
        enum class GTestColor { kDefault, kRed, kGreen, kYellow };

        extern void ColoredPrintf(GTestColor color, const char* fmt, ...);
    }
}

And as a quick fix I have removed namespace { ... } around GTestColor in gtest.cc.

The question: is it possible to avoid editing gtest.cc and still have access to their function?

wl2776
  • 4,099
  • 4
  • 35
  • 77
  • I've submitted FR https://github.com/google/googletest/issues/4185 to have this addressed somehow :) – AntonK Mar 11 '23 at 16:01

2 Answers2

1

You cannot access members in an anonymous namespace outside of the compilation unit. See also this question.

Depending on your use-case alternatives may be:

  • Use event listeners to replace the standard output.
  • Pipe the output through a script that modifies the output.
  • Have Google Test generate an XML or JSON report and generate output based on the XML/JSON report.
rveerd
  • 3,620
  • 1
  • 14
  • 30
  • 1
    Or create PR in the googletest repository, making this function publicly available. – wl2776 Aug 29 '20 at 06:36
  • 1
    @wl2776 that is not necessary because you can get the same result with the standard _event listeners_ API. I have updated my question to include this option. – rveerd Sep 08 '20 at 09:26
  • The fixed link to event listeners is https://github.com/google/googletest/blob/main/docs/advanced.md#extending-googletest-by-handling-test-events . But this approach doesn't make colorful output as easy as it was with `ColoredPrintf` – AntonK Mar 11 '23 at 10:56
0

I've faced similar issue when switching from gtest built from old sources to a more recent version inside NuGet package, and the trick with modifying gtest.cc isn't possible in this case, because there is no such file in the package distribution.
After some investigation I've finally ended with copy'n'pasted functions from gtest.cc (namely GetColorAttribute, GetBitOffset, GetNewColor and ColoredPrintf), which are then built as a part of my project (don't forget to add #define GTEST_HAS_FILE_SYSTEM 1 at the beginning).
And you'll need an extra header like this one:

namespace testing
{
  namespace internal
  {
    // namespace {
      enum class GTestColor { kDefault, kRed, kGreen, kYellow };
    //}  // namespace

    void ColoredPrintf(GTestColor color, const char* fmt, ...);
    bool ShouldUseColor(bool stdout_is_tty);
  }
}
#define PRINTF(...)  do \
  { \
    testing::internal::ColoredPrintf(testing::internal::GTestColor::kGreen, "[          ] "); \
    testing::internal::ColoredPrintf(testing::internal::GTestColor::kYellow, __VA_ARGS__); \
  } while(0)

static modifier should also be removed from ColoredPrintf definition. The rest of code can be used as is, and it works as expected:
Custom colored output

Hopefully this issue will be properly resolved in the context of FR#4185 :)

AntonK
  • 1,210
  • 1
  • 16
  • 22