'mariadb-connector-cpp-1.0.1: Linking error for cjportedtests.exe

Environment

  • Windows 10
  • MinGW-W64 x86_64-ucrt-posix-seh, 11.2.0
  • cmake version 3.19.5

Error comes message as follows:

[ 74%] Linking CXX executable ..\cjportedtests.exe c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Libraries/mariadb/lib/libtest_framework.a(test_asserts.cpp.obj): in function testsuite::assertEquals(sql::SQLString const&, char const*, char const*, int)': D:/Daten/Installation/Coding/mariadb/mariadb-connector-cpp-1.0.1-src/test/framework/test_asserts.cpp:298: undefined reference to __imp__ZN3sqlneERKNS_9SQLStringEPKc' collect2.exe: error: ld returned 1 exit status make[2]: *** [test\CJUnitTestsPort\CMakeFiles\CJUnitTestsPort.dir\build.make:347: test/cjportedtests.exe] Error 1 make[1]: *** [CMakeFiles\Makefile2:411: test/CJUnitTestsPort/CMakeFiles/CJUnitTestsPort.dir/all] Error 2 make: *** [makefile:124: all] Error 2

Comment

File which produces error at line 298 (marked as comment)

test/framework/test_asserts.cpp

void assertEquals(const sql::SQLString& expected, const char* result
                  , const char* file, int line)
{
  if (expected != result) // line 298. error here
  {
    std::stringstream errmsg;
    errmsg.str("");
    errmsg << "assertEquals(std::string) failed in" << file << ", line #" << line;
    errmsg << " expecting '" << expected << "' got '" << result << "'";
    TestsListener::testHasFailed(errmsg.str());
  }
}

sql::SQLString is defined in src/SQLString.cpp, which I think should be part of the libmariadbcpp.dll.a library. However after modifying the test/CJUnitTestsPort/CMakeLists.txt to include

SET(MY_TARGET_LINK_LIBRARIES ${LIBRARY_NAME} C:/Libraries/mariadb/lib/libmariadbcpp.dll.a test_framework)

it produces the same error.

I executed build/test/driver_test.exe build/test/static_test.exe and got zero errors.

Question

Why can the linker not find the reference here?

Changes to original src/cmake files to make it work on mingw:

When doing multiple changes in a single file, the line numbers represent the ones after the change before (from top to bottom)

  • delete libmariadb subfolder
  • in CMakeLists.txt comment out lines: 524,525
  • [src/CArrayImp.h:59-63] replace with just #define ZEROI64 0LL
  • [src/CArray.cpp] comment lines 25-28
  • [test/test_common.cpp:40-42] replace with #include <inttypes.h>
  • [test/test_common.cpp:99-113] replace with
    • #define L64(x) x##LL
    • #define UL64(x) x##ULL
  • [test/ccppTypes.h:41-49] replace with #include <string.h>
  • [test/ccppTypes.h:64-78] replace with
    • #define L64(x) x##LL
    • #define UL64(x) x##ULL
  • [test/unit/unit_fixture.cpp:37-43] replace with #define L64(x) x##LL
  • CMAKE_CXX_FLAGS -IC:/directory/for/mariadb-connector_c/include -LC:/directory/for/mariadb-connector_c/lib
  • CMAKE_C_FLAGS -IC:/directory/for/mariadb-connector_c/include -LC:/directory/for/mariadb-connector_c/lib
  • CMAKE_CXX_FLAGS_STANDARD_LIBRARIES added -lsecur32 -lcrypt32 C:/path/to/ShLwApi.Lib

EDIT in response to comments

SQLString.cpp

defines the != operator for the used case in test_asserts.cpp:

bool operator!=(const SQLString& str1, const char* str2)
{
    return str1.compare(0, str1.length(), str2, strlen(str2)) != 0;
}

bool operator!=(const char* str1, const SQLString& str2)
{
    return str2.compare(0, str2.length(), str1, strlen(str1)) != 0;
}

Solution

a pull request has been issued on github.com (these changes might be unessecary in the future)

  • [test/CJUnitTestsPort/CMakeLists.txt:35,41] change order of linking to ${LIBRARY_NAME} after test_framework
  • [test/unit/CMakeLists.txt:31] change order of linking to ${LIBRARY_NAME} after test_framework
  • [test/unit/example/CMakeLists.txt:48] change order of linking to ${LIBRARY_NAME} after test_framework
  • [test/unit/classes/CMakeLists.txt:46,66,87,107,127,147,167,208] change order of linking to ${LIBRARY_NAME} after test_framework
  • [test/unit/performance/CMakeLists.txt:45] change order of linking to ${LIBRARY_NAME} after test_framework
  • [test/unit/bugs/CMakeLists.txt:45] change order of linking to ${LIBRARY_NAME} after test_framework


Solution 1:[1]

According to the comment of Lawrin Novitsky, the solution to the problem is the order of linking. Question edited to include the solution as well.

Solution

A pull request has been issued on github.com (these changes might be unessecary in the future)

  • [test/CJUnitTestsPort/CMakeLists.txt:35,41] change order of linking to ${LIBRARY_NAME} after test_framework
  • [test/unit/CMakeLists.txt:31] change order of linking to ${LIBRARY_NAME} after test_framework
  • [test/unit/example/CMakeLists.txt:48] change order of linking to ${LIBRARY_NAME} after test_framework
  • [test/unit/classes/CMakeLists.txt:46,66,87,107,127,147,167,208] change order of linking to ${LIBRARY_NAME} after test_framework
  • [test/unit/performance/CMakeLists.txt:45] change order of linking to ${LIBRARY_NAME} after test_framework
  • [test/unit/bugs/CMakeLists.txt:45] change order of linking to ${LIBRARY_NAME} after test_framework

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1