/usr/share/ECM/modules/ECMWinResolveSymlinks.cmake is in extra-cmake-modules 5.44.0-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | #.rst:
# ECMWinResolveSymlinks
# --------------------------
#
# Resolve pseudo-symlinks created by git when cloning on Windows.
#
# ::
#
# ecm_win_resolve_symlinks(<dir>)
#
# When git checks out a repository with UNIX symlinks on Windows machine,
# it creates a text file for each symlink, containing a relative path to the
# real file.
# This function would recursively walk over specified directory and replace
# pseudo-symlinks with corresponding real file's contents. It would then run
# git update-index --assume-unchanged on them to trick git.
#
# This is useful for projects like "breeze-icons" that contain many identical
# icons implemented as symlinks.
#
# Since 5.28
#=============================================================================
# Copyright 2016 Gleb Popov <6yearold@gmail.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file COPYING-CMAKE-SCRIPTS for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of extra-cmake-modules, substitute the full
# License text for the above reference.)
function(ECM_WIN_RESOLVE_SYMLINKS _dir)
get_filename_component(dir ${_dir} ABSOLUTE)
find_program(GIT_EXECUTABLE git)
if(NOT GIT_EXECUTABLE)
message(SEND_ERROR "Git executable not found!")
endif()
message(STATUS "Resolving symlinks in ${dir}...")
_find_symlinks(${dir} symlinks)
_portioned_list(symlinks ${symlinks})
foreach(s IN LISTS symlinks)
string(REPLACE ":" ";" s ${s})
_assume_unchanged(NO ${dir} "${s}")
_checkout_symlinks(${dir} "${s}")
_resolve_symlinks(${dir} "${s}")
_assume_unchanged(YES ${dir} "${s}")
endforeach()
message(STATUS "Resolving symlinks in ${dir}... Done.")
# touch cache every build to force CMake to re-run these functions everytime
if(NOT TARGET wrs_touch_cache)
add_custom_target(wrs_touch_cache ALL
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/CMakeCache.txt
)
endif()
endfunction()
function(_assume_unchanged mode dir symlinks)
if(mode)
set(flag --assume-unchanged)
else()
set(flag --no-assume-unchanged)
endif()
execute_process(COMMAND ${GIT_EXECUTABLE} update-index ${flag} ${symlinks}
WORKING_DIRECTORY ${dir}
)
endfunction()
function(_find_symlinks dir outvar)
execute_process(COMMAND ${GIT_EXECUTABLE} ls-files -s
WORKING_DIRECTORY ${dir}
OUTPUT_VARIABLE out
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(${outvar})
if(out)
string(REPLACE "\n" ";" out ${out})
foreach(f IN LISTS out)
# 120000 0db97052931e18484b6705f3bc644484ef9403b0 0 <tab> icons-dark/actions/16/CVnamespace.svg
string(REPLACE "\t" ";" f "${f}")
string(REPLACE " " ";" f "${f}")
list(GET f 0 mode)
if(mode STREQUAL "120000")
list(GET f 3 symlink)
list(APPEND ${outvar} ${symlink})
endif()
endforeach()
endif()
set(${outvar} ${${outvar}} PARENT_SCOPE)
endfunction()
# In functions like _checkout_symlinks() the command line can become too lengthy for Windows.
# So we partition it, but in a hacky way due to CMake doesn't have list of lists.
function(_portioned_list outvar)
list(LENGTH ARGN arglen)
if(arglen EQUAL 0)
set(${outvar} "" PARENT_SCOPE)
return()
endif()
set(init)
set(tail)
math(EXPR range "${arglen} - 1")
foreach(i RANGE ${range})
list(GET ARGN ${i} v)
string(LENGTH "${init}" initlen)
string(LENGTH ${v} vlen)
math(EXPR sumlen "${initlen} + ${vlen}")
if(sumlen LESS 8192)
list(APPEND init ${v})
else()
list(APPEND tail ${v})
endif()
endforeach()
_portioned_list(tail_portioned ${tail})
string(REPLACE ";" ":" init "${init}") # Generally this is not safe, because filepath can contain ':' character. But not on Windows. Phew.
set(${outvar} ${init} ${tail_portioned} PARENT_SCOPE)
endfunction()
function(_checkout_symlinks dir symlinks)
execute_process(COMMAND ${GIT_EXECUTABLE} checkout ${symlinks}
WORKING_DIRECTORY ${dir}
)
endfunction()
function(_resolve_symlinks dir symlinks)
foreach(s IN LISTS symlinks)
file(READ ${dir}/${s} sdata)
get_filename_component(sdir ${dir}/${s} DIRECTORY)
set(f "${sdir}/${sdata}")
file(READ ${f} fdata)
file(WRITE ${dir}/${s} ${fdata})
endforeach()
endfunction()
|