0

I'm trying to use gtest to test a shared library. I use CMake and everyting builds and compiles without any error, but the hello_test.exe exits with error:

Entry Point Not Found. The procedure entry point _ZNKSt7__cxx112basic_stringlcSt11char_traitslcESalcEE4findEPKcyy could not be located in the dynamic link library.

I'm on Windows Server 2016 Standard connected via rdp (looks like windows10)

I'm using MinGW 8.1.0 (x86_64/win32/seh) as a compiler.

CMake 3.17.3

I've tried to replicate this environment in another computer and everything works, so I need a little help finding what is missing in this environment so i can fix it.

I´ve seen this questions

This is the MWE. The cmake folder contains two utilities found in https://github.com/robotology/idyntree/tree/master/cmake

  • InstallBasicPackageFiles
  • AddInstallRPATHSupport
CMakeLists.txt
cmake/
include/
    hello.h
src/
    CMakeLists.txt
    hello.c
test/
    CMakeLists.txt
    main_test.cpp
    hello_test.cpp

CMakeLists.txt

cmake_minimum_required(VERSION 3.14...3.17 FATAL_ERROR)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

project(hello
        LANGUAGES CXX C
        VERSION 1.2.3
        DESCRIPTION "hello project"
        )

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED True)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_CXX_EXTENSIONS OFF)

include(GNUInstallDirs)

set(BUILD_DIR ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${BUILD_DIR}/${CMAKE_INSTALL_BINDIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_DIR}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${BUILD_DIR}/${CMAKE_INSTALL_LIBDIR}")

if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  set(CMAKE_INSTALL_PREFIX ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} CACHE PATH "..." FORCE)
endif()

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

enable_testing()

include(AddInstallRPATHSupport)
add_install_rpath_support(BIN_DIRS "${CMAKE_INSTALL_FULL_BINDIR}"
                          LIB_DIRS "${CMAKE_INSTALL_FULL_LIBDIR}"
                          INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}"
                          USE_LINK_PATH)

add_subdirectory(${PROJECT_SOURCE_DIR}/src)

include(InstallBasicPackageFiles)
install_basic_package_files(${PROJECT_NAME}
                            VERSION ${${PROJECT_NAME}_VERSION}
                            COMPATIBILITY AnyNewerVersion
                            VARS_PREFIX ${PROJECT_NAME}
                            NO_CHECK_REQUIRED_COMPONENTS_MACRO)

add_subdirectory(${PROJECT_SOURCE_DIR}/test)

include/hello.h

#ifndef HELLO_INCLUDE_HELLO_H
#define HELLO_INCLUDE_HELLO_H
#ifdef __cplusplus
extern "C" {
#endif

void sayHello(char *tag);

#ifdef __cplusplus
}  // extern "C"
#endif
#endif  //HELLO_INCLUDE_HELLO_H

src/CmakeLists.txt

set(LIBRARY_TARGET_NAME ${PROJECT_NAME})

set(${LIBRARY_TARGET_NAME}_SRC
        ${CMAKE_SOURCE_DIR}/src/hello.c
)

set(${LIBRARY_TARGET_NAME}_HDR
        ${CMAKE_SOURCE_DIR}/include/hello.h
)

add_library(${LIBRARY_TARGET_NAME} SHARED ${${LIBRARY_TARGET_NAME}_SRC} ${${LIBRARY_TARGET_NAME}_HDR})

set_target_properties(${LIBRARY_TARGET_NAME} PROPERTIES VERSION       ${${PROJECT_NAME}_VERSION}
                                                        PUBLIC_HEADER "${${LIBRARY_TARGET_NAME}_HDR}")

set_target_properties(${LIBRARY_TARGET_NAME} PROPERTIES PREFIX "")

target_include_directories(${LIBRARY_TARGET_NAME} PUBLIC  
                          "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>/include"
                          "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>"
                          )

install(TARGETS ${LIBRARY_TARGET_NAME}
        EXPORT  ${PROJECT_NAME}
        LIBRARY       DESTINATION "${CMAKE_INSTALL_LIBDIR}"                            COMPONENT shlib
        ARCHIVE       DESTINATION "${CMAKE_INSTALL_LIBDIR}"                            COMPONENT lib
        RUNTIME       DESTINATION "${CMAKE_INSTALL_BINDIR}"                            COMPONENT bin
        PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"                        COMPONENT dev)

message(STATUS "Created target ${LIBRARY_TARGET_NAME} for export ${PROJECT_NAME}.")

src/hello.c

#include <hello.h>
#include <stdio.h>

void sayHello(char *tag) {
  printf("%s: Hello!\n", tag);
};

test/CMakeLists.txt

set(TEST_TARGET_NAME hello_test)

set(${TEST_TARGET_NAME}_SRC
        ${CMAKE_SOURCE_DIR}/test/main_test.cpp
        ${CMAKE_SOURCE_DIR}/test/hello_test.cpp
)

set(GTEST_LOCAL //path/to/local/google/test/repo)

include(FetchContent)
FetchContent_Declare(
  googletest
  GIT_REPOSITORY ${GTEST_LOCAL}
  GIT_TAG        release-1.10.0
)

FetchContent_MakeAvailable(googletest)

list(APPEND EXTRA_LIBS
                  hello
                  gtest_main
    )

list(APPEND EXTRA_INCLUDES
        ${CMAKE_BINARY_DIR}/include
)

add_executable(${TEST_TARGET_NAME} ${${TEST_TARGET_NAME}_SRC})

target_link_libraries(${TEST_TARGET_NAME} PUBLIC ${EXTRA_LIBS})

target_include_directories(${TEST_TARGET_NAME} PUBLIC
                           ${EXTRA_INCLUDES}
                          )

add_test(NAME ${TEST_TARGET_NAME}
         COMMAND ${TEST_TARGET_NAME}
         WORKING_DIRECTORY $<TARGET_FILE_DIR:${TEST_TARGET_NAME}>)

test/main_test.cpp

#include <gtest/gtest.h>

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

test/hello_test.cpp

#include <gtest/gtest.h>
#include <hello.h>

TEST(ExpectTrue1, test1) {
  EXPECT_TRUE(1);
}

TEST(ExpectTrue2, test2) {
  EXPECT_TRUE(0);
}
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
piptin
  • 365
  • 1
  • 4
  • 16
  • Probably, your library or gtest library is already installed on your Server, and test executable picks wrong library. – Tsyvarev Mar 03 '21 at 10:44
  • I dont have permissions to install anything. Do you know where can i look to check where is this could be installed? – piptin Mar 03 '21 at 10:47
  • By using `AddInstallRPATHSupport` and `InstallBasicPackageFiles` **external** modules, you example doesn't look as "reprodusible". However, I don't see how using these modules affects on your problem: RPATH support, added by the first module, is absent on Windows, and `InstallBasicPackageFiles` seems only about finding your project with `find_package`. Could you try your code without those modules (and functions from them)? – Tsyvarev Mar 03 '21 at 10:50
  • 1
    You could check which **actual libraries** are loaded by your test executable. See that question: https://stackoverflow.com/questions/1993673/what-is-the-equivalent-of-linuxs-ldd-on-windows. – Tsyvarev Mar 03 '21 at 10:51
  • 1
    Thanks, I found the offending library c:\cae\matlab\r2014b\bin\win64\LIBSTDC++-6.DLL I'll try to remove this from the path, since it should be somehting like this c:\cae\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\bin\LIBSTDC++-6.DLL – piptin Mar 03 '21 at 10:56
  • 1
    Oh, so it is libstdc++ library which is picked wrongly, as described in the [referenced question](https://stackoverflow.com/questions/18668003/the-procedure-entry-point-gxx-personality-v0-could-not-be-located). "This answer works, but why is cmake not linking this correctly?" - CMake **links** with the proper library. But CMake is not responsible for the library which will be picked at **runtime**. – Tsyvarev Mar 03 '21 at 11:00
  • I see, so if I understood correctly, removing the dlls from the path will fix this problem? – piptin Mar 03 '21 at 11:04
  • 1
    Yes, either physically removing dll or removing its directory from `PATH` variable should help. – Tsyvarev Mar 03 '21 at 11:10

0 Answers0