CTest、CMake&;MinGW:可执行文件已生成,但无法运行,因为找不到新的DLL
顶级CTest、CMake&;MinGW:可执行文件已生成,但无法运行,因为找不到新的DLL,dll,cmake,environment-variables,mingw,ctest,Dll,Cmake,Environment Variables,Mingw,Ctest,顶级CMakeLists.txt包含: include(CTest) add_subdirectory(lib) add_subdirectory(demo) add_subdirectory(test) lib/CMakeLists.txt基本上是: add_library(MyLib <sources>) add_executable(Demo demo.c) target_link_libraries(Demo MyLib) test/CMakeLists.txt只是:
CMakeLists.txt
包含:
include(CTest)
add_subdirectory(lib)
add_subdirectory(demo)
add_subdirectory(test)
lib/CMakeLists.txt
基本上是:
add_library(MyLib <sources>)
add_executable(Demo demo.c)
target_link_libraries(Demo MyLib)
test/CMakeLists.txt
只是:
add_test(NAME Demo COMMAND Demo)
从gitlab运行程序,我们执行:
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
位于路径中,因此在cmake--install
之后可以找到DLL。然而,这并不是我们想要的:ctest
将始终使用当前版本的新DLL,而不是安装的版本
在Linux下,一切都正常工作。为什么它不适合Windows和MinGW?这是CMake中的错误吗?我们如何解决这个问题,使ctest
在所有平台上都能正确执行?您的问题似乎是当ctest
运行您的Demo
可执行文件时,Windows DLL搜索过程未能找到mylib.DLL
。指定了Windows DLL搜索顺序:
从中加载应用程序的目录
系统目录。使用GetSystemDirectory
函数获取此目录的路径
16位系统目录。没有获取此目录路径的函数,但会对其进行搜索
Windows目录。使用GetWindowsDirectory
函数获取此目录的路径
当前目录
PATH
环境变量中列出的目录。请注意,这不包括指定的每个应用程序路径
应用程序路径
注册表项。在以下情况下不使用应用程序路径
键:
计算DLL搜索路径
因此,您可以修改PATH
环境变量,使其也包含当前生成的新DLL的位置
更好的、不易出错的解决方案可能是将DLL与Demo
可执行文件放在同一目录中。通过修改顶级CMake文件,可以强制CMake为DLL和可执行文件使用相同的二进制目录:
include(CTest)
add_subdirectory(lib ${CMAKE_BINARY_DIR}/demo)
add_subdirectory(demo ${CMAKE_BINARY_DIR}/demo)
add_subdirectory(test)
或者,作为一种本地化程度较低的方法,您可以通过以下设置将DLL放置在与可执行文件相同的目录中:
还有另一种选择:
add_test(NAME Demo COMMAND Demo WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
我更喜欢使用CMAKE_RUNTIME_OUTPUT_目录
将DLL
和exe
放在同一个文件夹中,而不是通过add_subdirectory()
@fdk1342强制二进制文件夹位置。是的,这也是一种有效的方法,尽管似乎本地化程度较低,因为我相信它适用于所有目标。但是,您可以使用设置特定于目标的属性;演示程序和测试是辅助的。因此,我不喜欢将库从lib移动到demo。在CMake中有没有一种惯用的方法告诉演示程序在哪里可以找到DLL?如果你不介意,我将编辑你的答案,添加第三种方法:调用add\u test
,使WORKING\u目录指向lib。@JoachimW,您可以通过将${CMAKE\u BINARY\u DIR}/demo
更改为${CMAKE\u BINARY\u DIR}/lib,将demo
构建工件放在lib
文件夹中。通常,您可以通过更新PATH
环境变量来修改运行时环境,也可以通过使用我的答案中建议的解决方法之一来更新它,或者使用已经记录的方法。这是否回答了您的问题?我对我的问题进行了编辑,以明确这不仅是一个解决方案,而且是关于理解为什么清洁的标准CMake代码不起作用。它确实起作用了。您的运行时环境错误,您需要修复它。如果您构建了一个已安装的共享库,并且需要使用正确的库,那么这与在Linux上设置RPATH没有什么区别。
add_test(NAME Demo COMMAND Demo WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/lib)