diff --git a/scripts/cmake/vcpkg_clean_executables_in_bin.cmake b/scripts/cmake/vcpkg_clean_executables_in_bin.cmake index 077e23cc3f71f0..e1cea3a958af05 100644 --- a/scripts/cmake/vcpkg_clean_executables_in_bin.cmake +++ b/scripts/cmake/vcpkg_clean_executables_in_bin.cmake @@ -21,15 +21,35 @@ Generally, there is no need to call this function manually. Instead, pass an ext * [czmq](https://github.com/microsoft/vcpkg/blob/master/ports/czmq/portfile.cmake) #]===] +function(z_vcpkg_clean_executables_in_bin_remove_directory_if_empty directory) + if(NOT EXISTS "${directory}") + return() + endif() + + if(NOT IS_DIRECTORY "${directory}") + message(FATAL_ERROR "${directory} must be a directory") + endif() + + file(GLOB items "${directory}/*") + if("${items}" STREQUAL "") + file(REMOVE_RECURSE "${directory}") + endif() +endfunction() + + function(vcpkg_clean_executables_in_bin) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 _vct "" "" "FILE_NAMES") + cmake_parse_arguments(PARSE_ARGV 0 arg "" "" "FILE_NAMES") - if(NOT DEFINED _vct_FILE_NAMES) + if(NOT DEFINED arg_FILE_NAMES) message(FATAL_ERROR "FILE_NAMES must be specified.") endif() - foreach(file_name IN LISTS _vct_FILE_NAMES) + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(WARNING "${CMAKE_CURRENT_FUNCTION} was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + + + foreach(file_name IN LISTS arg_FILE_NAMES) file(REMOVE "${CURRENT_PACKAGES_DIR}/bin/${file_name}${VCPKG_TARGET_EXECUTABLE_SUFFIX}" "${CURRENT_PACKAGES_DIR}/debug/bin/${file_name}${VCPKG_TARGET_EXECUTABLE_SUFFIX}" @@ -38,27 +58,6 @@ function(vcpkg_clean_executables_in_bin) ) endforeach() - function(try_remove_empty_directory directory) - if(NOT EXISTS "${directory}") - return() - endif() - - if(NOT IS_DIRECTORY "${directory}") - message(FATAL_ERROR "${directory} is supposed to be an existing directory.") - endif() - - # TODO: - # For an empty directory, - # file(GLOB items "${directory}" "${directory}/*") - # will return a list with one item. - file(GLOB items "${directory}/" "${directory}/*") - list(LENGTH items items_count) - - if(${items_count} EQUAL 0) - file(REMOVE_RECURSE "${directory}") - endif() - endfunction() - - try_remove_empty_directory("${CURRENT_PACKAGES_DIR}/bin") - try_remove_empty_directory("${CURRENT_PACKAGES_DIR}/debug/bin") + z_vcpkg_clean_executables_in_bin_remove_directory_if_empty("${CURRENT_PACKAGES_DIR}/bin") + z_vcpkg_clean_executables_in_bin_remove_directory_if_empty("${CURRENT_PACKAGES_DIR}/debug/bin") endfunction() diff --git a/scripts/cmake/vcpkg_copy_pdbs.cmake b/scripts/cmake/vcpkg_copy_pdbs.cmake index dd489db0219ca0..60335255a1ae95 100644 --- a/scripts/cmake/vcpkg_copy_pdbs.cmake +++ b/scripts/cmake/vcpkg_copy_pdbs.cmake @@ -27,15 +27,18 @@ This command should always be called by portfiles after they have finished rearr function(vcpkg_copy_pdbs) cmake_parse_arguments(PARSE_ARGV 0 "arg" "" "" "BUILD_PATHS") + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(WARNING "${CMAKE_CURRENT_FUNCTION} was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + if(NOT DEFINED arg_BUILD_PATHS) - set( - arg_BUILD_PATHS + set(arg_BUILD_PATHS "${CURRENT_PACKAGES_DIR}/bin/*.dll" "${CURRENT_PACKAGES_DIR}/debug/bin/*.dll" ) endif() - set(dlls_without_matching_pdbs) + set(dlls_without_matching_pdbs "") if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic" AND VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_MINGW) file(GLOB_RECURSE dlls ${arg_BUILD_PATHS}) @@ -44,17 +47,16 @@ function(vcpkg_copy_pdbs) set(ENV{VSLANG} 1033) foreach(dll IN LISTS dlls) - execute_process(COMMAND dumpbin /PDBPATH ${dll} + execute_process(COMMAND dumpbin /PDBPATH "${dll}" COMMAND findstr PDB OUTPUT_VARIABLE pdb_line ERROR_QUIET RESULT_VARIABLE error_code ) - if(NOT error_code AND pdb_line MATCHES "PDB file found at") - string(REGEX MATCH [['.*']] pdb_path "${pdb_line}") # Extract the path which is in single quotes - string(REPLACE "'" "" pdb_path "${pdb_path}") # Remove single quotes - get_filename_component(dll_dir "${dll}" DIRECTORY) + if(error_code EQUAL "0" AND pdb_line MATCHES "PDB file found at.*'(.*)'") + set(pdb_path "${CMAKE_MATCH_1}") + cmake_path(GET dll PARENT_PATH dll_dir) file(COPY "${pdb_path}" DESTINATION "${dll_dir}") else() list(APPEND dlls_without_matching_pdbs "${dll}") @@ -63,10 +65,10 @@ function(vcpkg_copy_pdbs) set(ENV{VSLANG} "${vslang_backup}") - list(LENGTH dlls_without_matching_pdbs unmatched_dlls_length) - if(unmatched_dlls_length GREATER 0) + if(NOT unmatched_dlls_length STREQUAL "") list(JOIN dlls_without_matching_pdbs "\n " message) - message(WARNING "Could not find a matching pdb file for:${message}\n") + message(WARNING "Could not find a matching pdb file for: + ${message}\n") endif() endif() diff --git a/scripts/cmake/vcpkg_copy_tool_dependencies.cmake b/scripts/cmake/vcpkg_copy_tool_dependencies.cmake index 0cb0bbcefbf48d..856a2d7fe25e94 100644 --- a/scripts/cmake/vcpkg_copy_tool_dependencies.cmake +++ b/scripts/cmake/vcpkg_copy_tool_dependencies.cmake @@ -19,29 +19,31 @@ This command should always be called by portfiles after they have finished rearr * [fltk](https://github.com/Microsoft/vcpkg/blob/master/ports/fltk/portfile.cmake) #]===] -function(vcpkg_copy_tool_dependencies TOOL_DIR) - if (VCPKG_TARGET_IS_WINDOWS) - find_program(PWSH_EXE pwsh) - if (NOT PWSH_EXE) - if(UNIX AND NOT CYGWIN) - message(FATAL_ERROR "Could not find PowerShell Core; install PowerShell Core as described here: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-linux") - endif() +function(z_vcpkg_copy_tool_dependencies_search tool_dir path_to_search) + file(GLOB tools "${tool_dir}/*.exe" "${tool_dir}/*.dll" "${tool_dir}/*.pyd") + foreach(tool IN LISTS tools) + vcpkg_execute_required_process( + COMMAND "${Z_VCPKG_POWERSHELL_CORE}" -noprofile -executionpolicy Bypass -nologo + -file "${SCRIPTS}/buildsystems/msbuild/applocal.ps1" + -targetBinary "${tool}" + -installedDir "${path_to_search}" + WORKING_DIRECTORY "${VCPKG_ROOT_DIR}" + LOGNAME copy-tool-dependencies + ) + endforeach() +endfunction() + +function(vcpkg_copy_tool_dependencies tool_dir) + if(ARGC GREATER 1) + message(WARNING "${CMAKE_CURRENT_FUNCTION} was passed extra arguments: ${ARGN}") + endif() + + if(VCPKG_TARGET_IS_WINDOWS) + find_program(Z_VCPKG_POWERSHELL_CORE pwsh) + if (NOT Z_VCPKG_POWERSHELL_CORE) message(FATAL_ERROR "Could not find PowerShell Core; please open an issue to report this.") endif() - macro(search_for_dependencies PATH_TO_SEARCH) - file(GLOB TOOLS "${TOOL_DIR}/*.exe" "${TOOL_DIR}/*.dll" "${TOOL_DIR}/*.pyd") - foreach(TOOL IN LISTS TOOLS) - vcpkg_execute_required_process( - COMMAND "${PWSH_EXE}" -noprofile -executionpolicy Bypass -nologo - -file "${SCRIPTS}/buildsystems/msbuild/applocal.ps1" - -targetBinary "${TOOL}" - -installedDir "${PATH_TO_SEARCH}" - WORKING_DIRECTORY "${VCPKG_ROOT_DIR}" - LOGNAME copy-tool-dependencies - ) - endforeach() - endmacro() - search_for_dependencies("${CURRENT_PACKAGES_DIR}/bin") - search_for_dependencies("${CURRENT_INSTALLED_DIR}/bin") + z_vcpkg_copy_tool_dependencies_search("${tool_dir}" "${CURRENT_PACKAGES_DIR}/bin") + z_vcpkg_copy_tool_dependencies_search("${tool_dir}" "${CURRENT_INSTALLED_DIR}/bin") endif() endfunction() diff --git a/scripts/cmake/vcpkg_copy_tools.cmake b/scripts/cmake/vcpkg_copy_tools.cmake index 18ddc3715d9a61..ef3259840ccf02 100644 --- a/scripts/cmake/vcpkg_copy_tools.cmake +++ b/scripts/cmake/vcpkg_copy_tools.cmake @@ -33,39 +33,43 @@ Auto clean executables in `${CURRENT_PACKAGES_DIR}/bin` and `${CURRENT_PACKAGES_ #]===] function(vcpkg_copy_tools) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 _vct "AUTO_CLEAN" "SEARCH_DIR;DESTINATION" "TOOL_NAMES") + cmake_parse_arguments(PARSE_ARGV 0 arg "AUTO_CLEAN" "SEARCH_DIR;DESTINATION" "TOOL_NAMES") - if(NOT DEFINED _vct_TOOL_NAMES) + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(WARNING "${CMAKE_CURRENT_FUNCTION} was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + + if(NOT DEFINED arg_TOOL_NAMES) message(FATAL_ERROR "TOOL_NAMES must be specified.") endif() - if(NOT DEFINED _vct_DESTINATION) - set(_vct_DESTINATION "${CURRENT_PACKAGES_DIR}/tools/${PORT}") + if(NOT DEFINED arg_DESTINATION) + set(arg_DESTINATION "${CURRENT_PACKAGES_DIR}/tools/${PORT}") endif() - if(NOT DEFINED _vct_SEARCH_DIR) - set(_vct_SEARCH_DIR "${CURRENT_PACKAGES_DIR}/bin") - elseif(NOT IS_DIRECTORY ${_vct_SEARCH_DIR}) - message(FATAL_ERROR "SEARCH_DIR ${_vct_SEARCH_DIR} is supposed to be a directory.") + if(NOT DEFINED arg_SEARCH_DIR) + set(arg_SEARCH_DIR "${CURRENT_PACKAGES_DIR}/bin") + elseif(NOT IS_DIRECTORY "${arg_SEARCH_DIR}") + message(FATAL_ERROR "SEARCH_DIR (${arg_SEARCH_DIR}) must be a directory") endif() - foreach(tool_name IN LISTS _vct_TOOL_NAMES) - set(tool_path "${_vct_SEARCH_DIR}/${tool_name}${VCPKG_TARGET_EXECUTABLE_SUFFIX}") - set(tool_pdb "${_vct_SEARCH_DIR}/${tool_name}.pdb") + foreach(tool_name IN LISTS arg_TOOL_NAMES) + set(tool_path "${arg_SEARCH_DIR}/${tool_name}${VCPKG_TARGET_EXECUTABLE_SUFFIX}") + set(tool_pdb "${arg_SEARCH_DIR}/${tool_name}.pdb") if(EXISTS "${tool_path}") - file(COPY "${tool_path}" DESTINATION "${_vct_DESTINATION}") + file(COPY "${tool_path}" DESTINATION "${arg_DESTINATION}") else() - message(FATAL_ERROR "Couldn't find this tool: ${tool_path}.") + message(FATAL_ERROR "Couldn't find tool \"${tool_name}\": + \"${tool_path}\" does not exist") endif() if(EXISTS "${tool_pdb}") - file(COPY "${tool_pdb}" DESTINATION "${_vct_DESTINATION}") + file(COPY "${tool_pdb}" DESTINATION "${arg_DESTINATION}") endif() endforeach() - if(_vct_AUTO_CLEAN) - vcpkg_clean_executables_in_bin(FILE_NAMES ${_vct_TOOL_NAMES}) + if(arg_AUTO_CLEAN) + vcpkg_clean_executables_in_bin(FILE_NAMES ${arg_TOOL_NAMES}) endif() - vcpkg_copy_tool_dependencies("${_vct_DESTINATION}") + vcpkg_copy_tool_dependencies("${arg_DESTINATION}") endfunction()