From 3b730f2ef158ead8e277ed6f51430ab8903feae8 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sun, 21 Jun 2026 12:33:02 +0200 Subject: [PATCH] cmake: drop auto-copying runtime DLLs next to targets This feature has been permanently enabled since the initial commit adding CMake builds to libssh2. Limited to libssh2's own DLL (if built that way), and OpenSSL's crypto DLL. While limited to these two DLLs (and not supporting other dependencies), history shows this feature was prone to break, and recently started breaking parallel builds, due to MSBuild failing while copying the DLLs to the same location in concurrent threads. This recently made MSVC GHA jobs flaky. It's also a potential performance and disk trashing issue when copying large DLLs (OpenSSL `libcrypto-*.dll`) on each build, for each of the 52 (at the time of this commit) targets. That's potentially 104 copy operations. Perhaps this could be limited to once per each target directory, but that's adding even more complexity and development time. There is also no generalized/trivial way to pick up the complete set of DLL dependencies; e.g. libcrypto.dll may need other DLLs. Another disadvantage is copying around DLLs eventually ends up contributing to DLL-hell, copies may go stale, picked up when undesired, or due the heuristic detection, they may not match the dependency version/instance actually linked. The copying was done on all platforms, while typically the issue is exclusive to Windows MSVC (and it's also where it breaks.) As a replacement, I propose to add any necessary DLL location to `PATH` before running examples or tests. It works well in CI. Also in curl. Fixing: ``` Version: 20260616.203.1 [...] MSBuild version 17.14.40+3e7442088 for .NET Framework [...] D:/a/libssh2/libssh2/bld/tests/Release\libssh2.dll: message: deploying dependencies D:/a/libssh2/libssh2/bld/tests/Release\libcrypto-3-x64.dll: message: deploying dependencies The process cannot access the file because it is being used by another process. [...] C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(166,5): error MSB3073: :cmDone [D:\a\libssh2\libssh2\bld\tests\test_auth_pubkey_ok_rsa_sha2_256_signed.vcxproj] C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(166,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd [D:\a\libssh2\libssh2\bld\tests\test_auth_pubkey_ok_rsa_sha2_256_signed.vcxproj] C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(166,5): error MSB3073: :VCEnd" exited with code 32. [D:\a\libssh2\libssh2\bld\tests\test_auth_pubkey_ok_rsa_sha2_256_signed.vcxproj] D:/a/libssh2/libssh2/bld/tests/Release/test_auth_keyboard_info_request.exe: message: deploying dependencies D:/a/libssh2/libssh2/bld/tests/Release\libcrypto-3-x64.dll: message: deploying dependencies test_auth_pubkey_ok_rsa_openssh.vcxproj -> D:\a\libssh2\libssh2\bld\tests\Release\test_auth_pubkey_ok_rsa_openssh.exe ``` Refs (MSVC): https://github.com/libssh2/libssh2/actions/runs/27838566519/job/82392203784 OpenSSL https://github.com/libssh2/libssh2/actions/runs/27838566519/job/82392203753 WinCNG https://github.com/libssh2/libssh2/actions/runs/27823077802/job/82340632890 WinCNG UWP Examples, with shared libssh2: combined with WINCNG: Before: https://github.com/libssh2/libssh2/actions/runs/27891639324/job/82535960547 (277 steps) After: https://github.com/libssh2/libssh2/actions/runs/27901568257/job/82562736781 (229 steps) combined with OpenSSL: Before: https://github.com/libssh2/libssh2/actions/runs/27902131772/job/82564199274 (326 steps) After: https://github.com/libssh2/libssh2/actions/runs/27902733625/job/82565870012 (229 steps) Observe these steps no longer performed: ``` D:/a/libssh2/libssh2/bld/example/Release\libcrypto-3-x64.dll: message: deploying dependencies D:/a/libssh2/libssh2/bld/example/Release\libssh2.dll: message: deploying dependencies ``` Ref: #2078 Ref: https://github.com/libssh2/libssh2/pull/2078/commits/1e5e2923f71a6624ee9ca46bba7fa8d33611e80e Follow-up to a95a02c8fb66d5150f641252968d0245b3bf70b0 #2093 Follow-up to 97d8e8d49a3f32d7fa0e7bd20257c68475477c39 #2091 Follow-up to d652ba0205ca8e9da872a2eb14d4a423ae6f310b #2090 Follow-up to dd50a41152f6684c9e4b31b6804c1be65f98180c #1638 Follow-up to 694b9d964ba3cc3654a2d975e330256c7f2f6e5c #1610 Follow-up to 97417ad37f117a3f7a2e2c949412f1bb3a563431 #899 Follow-up to 19884e5055b6c65f0df93d7cc776a01c518a2f06 #818 Follow-up to 6bf898336889b5151503f882e1f76eecd480a191 Closes #2101 --- CMakeLists.txt | 20 --------- cmake/CopyRuntimeDependencies.cmake | 68 ----------------------------- example/CMakeLists.txt | 7 --- src/CMakeLists.txt | 3 -- tests/CMakeLists.txt | 7 --- 5 files changed, 105 deletions(-) delete mode 100644 cmake/CopyRuntimeDependencies.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 5910507a..b5ae4f78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -407,9 +407,6 @@ configure_file("src/libssh2_config_cmake.h.in" ## Cryptography backend choice -# Files that must be in the same directory as the executables at runtime -set(LIBSSH2_RUNTIME_DEPENDENCIES "") - set(CRYPTO_BACKEND "" CACHE STRING "The backend to use for cryptography: Libgcrypt, mbedTLS, OpenSSL, WinCNG, wolfSSL, or empty to try any available") @@ -438,23 +435,6 @@ if(CRYPTO_BACKEND STREQUAL "OpenSSL" OR NOT CRYPTO_BACKEND) # Statically linking to OpenSSL requires crypt32 for some Windows APIs. # This should really be handled by FindOpenSSL.cmake. list(APPEND LIBSSH2_LIBS "crypt32" "bcrypt") - - #set(CMAKE_FIND_DEBUG_MODE ON) - - find_file(DLL_LIBCRYPTO - NAMES "crypto.dll" - "libcrypto-1_1.dll" "libcrypto-1_1-x64.dll" - "libcrypto-3.dll" "libcrypto-3-x64.dll" - HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS} - PATH_SUFFIXES "bin" NO_DEFAULT_PATH) - if(DLL_LIBCRYPTO) - list(APPEND LIBSSH2_RUNTIME_DEPENDENCIES ${DLL_LIBCRYPTO}) - message(STATUS "Found libcrypto DLL: ${DLL_LIBCRYPTO}") - else() - message(WARNING "Unable to find OpenSSL libcrypto DLL, executables may not run") - endif() - - #set(CMAKE_FIND_DEBUG_MODE OFF) endif() find_package(ZLIB) diff --git a/cmake/CopyRuntimeDependencies.cmake b/cmake/CopyRuntimeDependencies.cmake deleted file mode 100644 index b495f773..00000000 --- a/cmake/CopyRuntimeDependencies.cmake +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (C) Alexander Lamaison -# -# Redistribution and use in source and binary forms, -# with or without modification, are permitted provided -# that the following conditions are met: -# -# Redistributions of source code must retain the above -# copyright notice, this list of conditions and the -# following disclaimer. -# -# Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials -# provided with the distribution. -# -# Neither the name of the copyright holder nor the names -# of any other contributors may be used to endorse or -# promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -# OF SUCH DAMAGE. -# -# SPDX-License-Identifier: BSD-3-Clause - -include(CMakeParseArguments) - -# Add target to copy dependencies -function(libssh2_add_target_to_copy_dependencies) - set(_options) - set(_one_value_args TARGET) - set(_multi_value_args DEPENDENCIES BEFORE_TARGETS) - cmake_parse_arguments(COPY "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN}) - - if(NOT COPY_DEPENDENCIES) - return() - endif() - - # Using a custom target to drive custom commands stops multiple - # parallel builds trying to kick off the commands at the same time - add_custom_target(${COPY_TARGET}) - - foreach(_target IN LISTS COPY_BEFORE_TARGETS) - add_dependencies(${_target} ${COPY_TARGET}) - endforeach() - - foreach(_dependency IN LISTS COPY_DEPENDENCIES) - add_custom_command( - TARGET ${COPY_TARGET} POST_BUILD - # Make directory first otherwise file is copied in place of - # directory instead of into it - COMMAND ${CMAKE_COMMAND} ARGS -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" - COMMAND ${CMAKE_COMMAND} ARGS -E copy ${_dependency} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" - VERBATIM) - endforeach() -endfunction() diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 683d66aa..159464bd 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -36,8 +36,6 @@ # # SPDX-License-Identifier: BSD-3-Clause -include(CopyRuntimeDependencies) - list(APPEND LIBSSH2_LIBS ${LIBSSH2_LIBS_SOCKET}) libssh2_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") @@ -55,8 +53,3 @@ foreach(_example IN LISTS noinst_PROGRAMS) set_property(TARGET ${_example} APPEND PROPERTY COMPILE_OPTIONS "${LIBSSH2_PICKY_C_FLAGS}") set_target_properties(${_example} PROPERTIES UNITY_BUILD OFF) endforeach() - -libssh2_add_target_to_copy_dependencies( - TARGET copy_example_dependencies - DEPENDENCIES ${LIBSSH2_RUNTIME_DEPENDENCIES} - BEFORE_TARGETS ${_example_targets}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 05ad62d8..c4e4d460 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -145,9 +145,6 @@ if(BUILD_SHARED_LIBS) PUBLIC "$" "$/${CMAKE_INSTALL_INCLUDEDIR}>") - - list(APPEND LIBSSH2_RUNTIME_DEPENDENCIES $) - set(LIBSSH2_RUNTIME_DEPENDENCIES "${LIBSSH2_RUNTIME_DEPENDENCIES}" PARENT_SCOPE) endif() add_library(${PROJECT_NAME}::${LIB_NAME} ALIAS ${LIB_SELECTED}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e4657677..9758d5ed 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -36,8 +36,6 @@ # # SPDX-License-Identifier: BSD-3-Clause -include(CopyRuntimeDependencies) - list(APPEND LIBSSH2_LIBS ${LIBSSH2_LIBS_SOCKET}) libssh2_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") @@ -170,11 +168,6 @@ add_custom_target(coverage add_custom_target(clean-coverage COMMAND ${CMAKE_COMMAND} -E rm -rf -- "${CMAKE_CURRENT_BINARY_DIR}/coverage") -libssh2_add_target_to_copy_dependencies( - TARGET copy_test_dependencies - DEPENDENCIES ${LIBSSH2_RUNTIME_DEPENDENCIES} - BEFORE_TARGETS ${_test_targets}) - if(BUILD_OSSFUZZ) add_subdirectory(ossfuzz) endif()