Reputation: 102
I have a CMake (3.14) C++ (11) application that I build both on (native) Windows and Linux. It has many external dependencies. On both systems, it compiles without any problems.
On Windows, if I just launch the unit tests after a clean build, I get a "The code execution cannot proceed because *.dll was not found" for all my dependencies. To solve the problem, I copy them all by hand to the build folder. I find that I have to copy them by hand because the generator expression TARGET_RUNTIME_DLLS does not find all dependencies post-build (for example, it doesn't find Boost):
if (${WIN32})
add_custom_command( TARGET mytests POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_RUNTIME_DLLS:mytests>
$<TARGET_FILE_DIR:mytests>
COMMAND_EXPAND_LISTS)
endif()
Is there a better approach to be able to run Windows executables created with CMake? Am I missing something?
Is there a way to propagate the dll paths used during compile time to the exe so that it can find them during runtime (without adding individual library dependency dll folders to environment path)?
I tried playing around with VS_DEBUGGER:
set_target_properties(myapp PROPERTIES
VS_DEBUGGER_WORKING_DIRECTORY "$<TARGET_FILE_DIR:myapp>"
VS_DEBUGGER_COMMAND "$<TARGET_FILE:myapp>"
VS_DEBUGGER_ENVIRONMENT "PATH=%PATH%;${CMAKE_BINARY_DIR}/$<CONFIG>")
but that made no difference. I still had to copy all the dependency dlls to the build folder.
Is there any way to not have to copy dlls to the build folder?
Upvotes: 0
Views: 1149
Reputation: 1
Maybe you can specify the runtime directory where the program will run on the windows system, similar to how you open a cmd in the dll directory and open the program through the cmd
For example, clion's runtime program can specify the runtime directory in the configuration
Upvotes: 0
Reputation: 1638
dreschejrm already answered with the best possible solution there is, the main reason being that it is universal and will guarantee that it runs correctly on different machines. This is the standard for almost any application out there.
However you also asked for other options. For this I will refer you to the MSDN documentation here, more precisely the following section:
If SafeDllSearchMode is enabled, the search order is as follows:
- The directory from which the application loaded.
- The system directory. Use the GetSystemDirectory function to get the path of this directory.
- The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The current directory.
- The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
If SafeDllSearchMode is disabled, the search order is as follows:
- The directory from which the application loaded.
- The current directory.
- The system directory. Use the GetSystemDirectory function to get the path of this directory.
- The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
Meaning that you can update your PATH
environment variable, so that your application can find the DLLs for you.
However this is not an ideal solution and I highly advise to take the advice provided in the comment section by dreschejrm. I will repost the link he provided here
Upvotes: 1