cmake 在MSYS2环境中,当我使用std::string时,CTest失败,并出现0xc0000135错误

zf9nrax1  于 2023-04-06  发布在  其他
关注(0)|答案(1)|浏览(212)

对不起,实际上我不知道这是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将通过。

wydwbb8l

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}”)

相关问题