Search code examples
c++eclipsegoogletest

Undefined reference to 'getcwd' and 'mkdir' when building Google test project


even if I have been strictly following the tutorials from this post, I can't get my google test demo program to compile. I'm using Eclipse on Windows 10 x64, and the ARM GCC embedded toolchain to compile my code, since I will eventually need to run unit tests on embedded devices. My problem is that when I try to Build the project I get those errors :

c:/program files (x86)/gnu tools arm embedded/9 2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: ./contrib/gtest/gtest-all.o: in function `testing::internal::FilePath::GetCurrentDir()':
C:\Users\Hugo\eclipse\eclipse-workspace\test_gtest\Debug/../contrib/gtest/gtest-all.cc:9598: undefined reference to `getcwd'
c:/program files (x86)/gnu tools arm embedded/9 2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: ./contrib/gtest/gtest-all.o: in function `testing::internal::FilePath::CreateFolder() const':
C:\Users\Hugo\eclipse\eclipse-workspace\test_gtest\Debug/../contrib/gtest/gtest-all.cc:9823: undefined reference to `mkdir'
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:61: test_gtest.elf] Error 1

It comes more precisely from those lines of code in the gtest_all.cc file:

For the undefined reference to 'getcwd'

FilePath FilePath::GetCurrentDir() {
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
    GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32
  // These platforms do not have a current directory, so we just return
  // something reasonable.
  return FilePath(kCurrentDirectoryString);
#elif GTEST_OS_WINDOWS
  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
  return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd);
#else
  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
  char* result = getcwd(cwd, sizeof(cwd));
# if GTEST_OS_NACL
  // getcwd will likely fail in NaCl due to the sandbox, so return something
  // reasonable. The user may have provided a shim implementation for getcwd,
  // however, so fallback only when failure is detected.
  return FilePath(result == nullptr ? kCurrentDirectoryString : cwd);
# endif  // GTEST_OS_NACL
  return FilePath(result == nullptr ? "" : cwd);
#endif  // GTEST_OS_WINDOWS_MOBILE
}

For the undefined reference to 'mkdir' :

bool FilePath::CreateFolder() const {
#if GTEST_OS_WINDOWS_MOBILE
  FilePath removed_sep(this->RemoveTrailingPathSeparator());
  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
  int result = CreateDirectory(unicode, nullptr) ? 0 : -1;
  delete [] unicode;
#elif GTEST_OS_WINDOWS
  int result = _mkdir(pathname_.c_str());
#elif GTEST_OS_ESP8266
  // do nothing
  int result = 0;
#else
  int result = mkdir(pathname_.c_str(), 0777);
#endif  // GTEST_OS_WINDOWS_MOBILE

  if (result == -1) {
    return this->DirectoryExists();  // An error is OK if the directory exists.
  }
  return true;  // No error.
}

I have checked that unistd.h was included. I've been searching a lot but can't seem to find any similar error as mine. The closest I could find has been solved by people using CMake to compile it, but I'm not using CMake at all here.


Solution

  • AFAIK, getcwd() and mkdir() is platform dependent. It seem there have been similar issue with other library: https://github.com/purduesigbots/pros/issues/176

    As above link, you can try to define stub for missing symbols.

    In my working platform, getcwd() and mkdir() even get removed from the header. In such case, you can edit gtest directly, for example:

    FilePath FilePath::GetCurrentDir() {
    #if GTEST_OS_CUSTOM_PLATFORM
      return kCurrentDirectoryString;
    ...