mariadb-connector-cpp-1.0.1:cjportedtests.exe 的链接错误
mariadb-connector-cpp-1.0.1: Linking error for cjportedtests.exe
环境
- Windows 10
- MinGW-W64 x86_64-ucrt-posix-seh, 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): 在函数中 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:错误: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] 错误 2
评论
在第 298 行产生错误的文件(标记为注释)
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 在src/SQLString.cpp 中定义,我认为它应该是libmariadbcpp.dll.a 库的一部分。但是在修改 test/CJUnitTestsPort/CMakeLists.txt 之后
包括
SET(MY_TARGET_LINK_LIBRARIES ${LIBRARY_NAME} C:/Libraries/mariadb/lib/libmariadbcpp.dll.a test_framework)
它产生同样的错误。
我执行了
build/test/driver_test.exe
build/test/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/test_common.cpp:40-42] 替换为#include
- [test/test_common.cpp:99-113] 替换为
- #define L64(x) x##LL
- #define UL64(x) x##ULL
- [test/ccppTypes.h:41-49] 替换为 #include
- [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} 的顺序
根据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} 的顺序
环境
- Windows 10
- MinGW-W64 x86_64-ucrt-posix-seh, 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): 在函数中 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:错误: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] 错误 2
评论
在第 298 行产生错误的文件(标记为注释)
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 在src/SQLString.cpp 中定义,我认为它应该是libmariadbcpp.dll.a 库的一部分。但是在修改 test/CJUnitTestsPort/CMakeLists.txt 之后 包括
SET(MY_TARGET_LINK_LIBRARIES ${LIBRARY_NAME} C:/Libraries/mariadb/lib/libmariadbcpp.dll.a test_framework)
它产生同样的错误。
我执行了 build/test/driver_test.exe build/test/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/test_common.cpp:40-42] 替换为#include
- [test/test_common.cpp:99-113] 替换为
- #define L64(x) x##LL
- #define UL64(x) x##ULL
- [test/ccppTypes.h:41-49] 替换为 #include
- [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} 的顺序
根据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} 的顺序