mariadb-connector-cpp-1.0.1:cjportedtests.exe 的链接错误

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

提问人:Alexander123456 提问时间:4/2/2022 最后编辑:Alexander123456 更新时间:4/7/2022 访问量:129

问:

环境

  • 视窗 10
  • MinGW-W64 x86_64-ucrt-posix-she, 11.2.0
  • CMake 版本 3.19.5

错误提示如下:

[ 74%]链接 CXX 可执行文件。\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):在函数 __imp__ZN3sqlneERKNS_9SQLStringEPKc' 中 collect2.exe:错误:ld 返回 1 退出状态 make[2]: *** [test\CJUnitTestsPort\CMakeFiles\CJUnitTestsPort.dir\build.make:347: test/cjportedtests.exe] 错误 1 make[1]: *** [CMakeFiles\Makefile2:411: test/CJUnitTestsPort/CMakeFiles/CJUnitTestsPort.dir/all] 错误 2 make: *** [makefile:124: all] 错误 2testsuite::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

评论

在第 298 行产生错误的文件(标记为注释)

测试/框架/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 在 src/SQLString.cpp 中定义,我认为它应该是 libmariadbcpp.dll.a 库的一部分。但是,修改测试/CJUnitTestsPort/CMakeLists.txt 包括

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

它会产生相同的错误。

我执行了 构建/测试/driver_test.exe 构建/测试/static_test.exe 并且没有错误。

问题

为什么链接器在这里找不到引用?

对原始 src/cmake 文件进行更改,使其在 mingw 上运行:

在单个文件中进行多次更改时,行号表示之前更改后的行号(从上到下)

  • 删除 libmariadb 子文件夹
  • 在 CMakeLists.txt 注释掉行: 524,525
  • [src/CArrayImp.h:59-63] 替换为 #define ZEROI64 0LL
  • [src/CArray.cpp] 注释行 25-28
  • [测试/test_common.cpp:40-42] 替换为 #include < inttypes.h>
  • [测试/test_common.cpp:99-113] 替换为
    • #define L64(x) x##LL
    • #define UL64(x) x##ULL
  • [test/ccppTypes.h:41-49] 替换为 #include < string.h>
  • [test/ccppTypes.h:64-78] 替换为
    • #define L64(x) x##LL
    • #define UL64(x) x##ULL
  • [test/unit/unit_fixture.cpp:37-43] 替换为 #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添加了 -lsecur32 -lcrypt32 C:/path/to/ShLwApi.Lib

编辑以响应评论

SQLString.cpp

在 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;
}

溶液

已在 github.com 上发出了拉取请求(这些更改将来可能会变得不合时宜)

  • [test/CJUnitTestsPort/CMakeLists.txt:35,41] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序
  • [test/unit/CMakeLists.txt:31] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序
  • [test/unit/example/CMakeLists.txt:48] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序
  • [test/unit/classes/CMakeLists.txt:46,66,87,107,127,147,167,208] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序
  • [test/unit/performance/CMakeLists.txt:45] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序
  • [test/unit/bugs/CMakeLists.txt:45] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序
MariaDB 链接器错误未 定义引用

评论

0赞 Lawrin Novitsky 4/4/2022
看起来找不到运算符 !=。static_test和driver_test不使用 SQLString,因此不存在这些链接问题。
0赞 Lawrin Novitsky 4/4/2022
SET(MY_TARGET_LINK_LIBRARIES ${LIBRARY_NAME} test_framework) 中的 ${LIBRARY_NAME} 代表 C/C++ 库目标,因此应该进行测试以链接到构建的库。C:/Libraries/mariadb/lib/libmariadbcpp.dll.a有点多余,不管它是什么。也许图书馆的顺序在这里很重要?如果在test_framework后移动 ${LIBRARY_NAME} 怎么办。另外,我不确定 WIN32 在 mingw(正确设置MY_TARGET_LINK_LIBRARIES)下的 cmake 中是否正确,但我想您知道得更多。
0赞 Alexander123456 4/4/2022
(见我在问题中的编辑)运算符已经定义,但链接的顺序是问题所在。我根据您的评论更改了顺序,并且奏效了。我不得不为许多测试库执行此操作。(编辑我的问题将包括解决方案)
0赞 Alexander123456 4/4/2022
不幸的是,我无法将您的回复标记为答案,因为它是“评论”,所以我自己提供了答案。
0赞 Lawrin Novitsky 4/6/2022
我将:) stackoverflow 声誉低下幸存下来看起来您做了相当多的更改以使其可在 mingw 上构建。我不认为 MariaDB 支持 mingw,但是如果您在 github 上提出带有更改的拉取请求,并且如果它们没有破坏任何东西,则可以合并它们。

答:

0赞 Alexander123456 4/4/2022 #1

根据劳林·诺维茨基(Lawrin Novitsky)的评论,解决问题的方法是链接的顺序。对问题进行了编辑,以包括解决方案。

溶液

已在 github.com 上发出了拉取请求(这些更改将来可能会变得不合时宜)

  • [test/CJUnitTestsPort/CMakeLists.txt:35,41] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序
  • [test/unit/CMakeLists.txt:31] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序
  • [test/unit/example/CMakeLists.txt:48] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序
  • [test/unit/classes/CMakeLists.txt:46,66,87,107,127,147,167,208] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序
  • [test/unit/performance/CMakeLists.txt:45] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序
  • [test/unit/bugs/CMakeLists.txt:45] test_framework后更改链接到 ${LIBRARY_NAME} 的顺序