对不起,实际上我不知道这是CMake,MSYS 2还是g++的问题?我创建了一个简单的CMake项目,如下所示:
Hello/
|__build/
|__CMakeLists.txt
|__lib/
|__CMakeLists.txt
|__foo.cpp
|__foo.h
|__tests/
|__CMakeLists.txt
|__test0.cpp
foo.cpp和foo.h定义了一个简单的函数foo(),test0.cpp调用foo(),就是这样。
这个项目在MSYS 2/mingw 64(和MSYS 2/clang 64)env中运行正常,如果foo()没有声明std::string。但是如果我在foo()中声明std::string,CTest将失败,并返回0xc 0000135错误。我的意思是如果foo()看起来像这样
int foo(int in) {
printf("HELLO %d\n", in);
return in;
}
一切都很好,但是
int foo(int in) {
str::string msg = "HELLO";
printf("HELLO %d\n", in);
return in;
}
ctest将失败,并显示以下错误消息!!!
> ctest
Test project D:/Hello/build
Start 1: test0
1/1 Test #1: test0 ............................Exit code 0xc0000135
***Exception: 0.02 sec
0% tests passed, 1 tests failed out of 1
Total Test time (real) = 0.02 sec
The following tests FAILED:
1 - test0 (Exit code 0xc0000135
)
Errors while running CTest
Output from these tests are in: D:/KC/msys64/home/user/hello-07.std/build/Testing/Temporary/LastTest.log
任何建议都很感激。非常感谢。
源代码和CMakeLists.txt如下所示:环境是Win 11 + MSYS 2(msys2-x86_64-20230318.exe)我在mingw 64和clang 64上测试了它们,两者都有相同的行为。
Hello/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(Hello)
enable_testing()
include(CTest)
subdirs(lib)
Hello/lib/CMakeLists.txt
set(CMAKE_CXX_FLAGS "-D_WINDLL")
add_library(foo SHARED foo.cpp foo.h)
target_include_directories(foo PRIVATE .)
subdirs(tests)
Hello/lib/tests/CMakeLists.txt
add_executable(test0 test0.cpp)
target_include_directories(test0 PRIVATE ${PROJECT_SOURCE_DIR}/lib)
target_link_libraries(test0 foo)
add_test(NAME test0 COMMAND test0)
if (WIN32)
set_tests_properties(test0 PROPERTIES ENVIRONMENT "PATH=${CMAKE_CURRENT_BINARY_DIR}\\..;$ENV{PATH}" )
endif()
Hello/lib/foo.h
#ifndef __FOO_H
#define __FOO_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#ifdef _WINDLL
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif
#else
#define API
#endif
API int foo(int in);
#ifdef __cplusplus
}
#endif
#endif /* __FOO_H */
Hello/lib/foo.cpp
#include <foo.h>
API int foo(int i)
{
// std::string msg = "HELLO"; // uncomment this will cause strange error !!
printf("hello %d\n", i);
return i;
}
Hello/lib/tests/test0.cpp
#include <foo.h>
int main(int argc, char *argv[])
{
return foo(0);
}
除了Win 11下的MSYS 2/mingw 64和MSYS 2/clang 64 env,我也在CentOS 7 x和Rocky 9 x下使用了相同的代码。在Linux下,一切正常。ctest将通过。
1条答案
按热度按时间wydwbb8l1#
在做了更多的研究之后,仍然不清楚为什么std::string会导致0xc 0000135错误。但我很确定std::string与这个问题无关。这纯粹是CTest无法读取PATH的问题,所以它无法找到DLL。
有三种方法可以解决这个问题:
1)在add_test()中添加WORKING_DIRECTORY,设置为DLL的位置:
add_test(NAME test0 COMMAND test0 WORKING_DIRECTORY“${CMAKE_BINARY_DIR}/lib”)
2)使用ENVIRONMENT_MODIFICATION属性,将DLL的路径添加到PATH中:
set_tests_properties(test0 PROPERTIES ENVIRONMENT_MODIFICATION“PATH=path_list_prepend:${CMAKE_BINARY_DIR}/lib”)
3)这也是导致原始错误的根本原因,直接修改ENVIRONMENT属性时,PATH的分隔符必须用反斜杠转义!!
set_tests_properties(test0 PROPERTIES ENVIRONMENT“PATH=${CMAKE_BINARY_DIR}/lib;$ENV{PATH}”)