CTest、CMake和MinGW:可执行文件生成,但无法运行,因为未找到新的DLL

dddzy1tm  于 2023-10-20  发布在  其他
关注(0)|答案(2)|浏览(165)

顶级CMakeLists.txt包含:

include(CTest)
add_subdirectory(lib)
add_subdirectory(demo)
add_subdirectory(test)

lib/CMakeLists.txt基本上是:

add_library(MyLib <sources>)

demo/CMakeLists.txt基本上是:

add_executable(Demo demo.c)
target_link_libraries(Demo MyLib)

test/CMakeLists.txt是:

add_test(NAME Demo COMMAND Demo)

从一个gitlab-runner,我们执行:

cmake -G "Ninja" -DCMAKE_INSTALL_PREFIX=C:\opt\x64 -B. ..
cmake --build
ctest --output-on-failure

前两步成功;第三个失败的原因是:

Start 1: Demo
1/1 Test #1: Demo .......................Exit code 0xc0000135
***Exception:   0.03 sec

如果我重试:

cmake --install
ctest

则测试成功。所以唯一的问题是在运行ctest时找不到build/lib/mylib.dll。而C:\opt\x64\lib位于PATH中,因此DLL位于cmake --install之后。然而,这并不是我们想要的:ctest应始终使用当前版本的最新DLL,而不是已安装的版本。
在Linux下,一切正常。为什么不支持Windows和MinGW?这是CMake中的一个bug吗?我们如何解决这个问题,使ctest在所有平台上都能正确执行?

aydmsdu9

aydmsdu91#

您的问题似乎是Windows DLL搜索过程无法找到mylib.dll时,您的Demo可执行文件是由ctest运行。Windows DLL搜索顺序在此处指定:
1.从其中加载应用程序的目录。
1.系统目录。使用GetSystemDirectory函数获取此目录的路径。

  1. 16位系统目录。没有获取此目录路径的函数,但会搜索它。
  2. Windows目录。使用GetWindowsDirectory函数获取此目录的路径。
    1.当前目录。
    1.在PATH环境变量中列出的目录。请注意,这不包括App Paths注册表项指定的每个应用程序的路径。在计算DLL搜索路径时不使用App Paths键。
    因此,您可以修改您的PATH环境变量,以 * 还 * 包括当前构建的新DLL的位置。
    一个更好、更少出错的解决方案可能是将DLL放在Demo可执行文件所在的目录中。您可以通过修改顶级CMake文件,强制CMake对DLL和可执行文件使用相同的binary目录:
include(CTest)
add_subdirectory(lib ${CMAKE_BINARY_DIR}/demo)
add_subdirectory(demo ${CMAKE_BINARY_DIR}/demo)
add_subdirectory(test)

或者,作为一种本地化程度较低的方法,您可以通过设置CMAKE_RUNTIME_OUTPUT_DIRECTORY将DLL放置在与可执行文件相同的目录中:

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

另一种选择:

add_test(NAME Demo COMMAND Demo WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
jucafojl

jucafojl2#

使用生成器表达式并附加到测试环境PATH的更现代的方法:

add_test(NAME mytest ...)

set_tests_properties(mytest PROPERTIES ENVIRONMENT_MODIFICATION
                     "PATH=path_list_prepend:$<$<BOOL:${WIN32}>:$<TARGET_FILE_DIR:my_library>>")

这将把包含“my_library”的目录附加到测试运行器在Windows上构建时使用的PATH中,否则不会有任何更改。不需要复制库或弄乱构建产品的位置,也不需要直接更改PATH或使用特定的工作目录。

相关问题