Skip to content

CMake -E tar doesn't support NTFS file/directory symlinks and junctions

Here's a script I've made to reproduce this problem:

cmake_minimum_required(VERSION 3.8)

project(windows_symlinks LANGUAGES)

function(test_file_read test_name path)
    set(success OFF)
    if(EXISTS "${path}")
        file(READ ${path} text)
        if(text)
            set(success ON)
        endif()
    endif()
    
    if(success)
        message("[OK] ${test_name}")
    else()
        message("[FAIL] ${test_name}")
    endif()
endfunction()

file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/test_data)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/test_data/dir)
file(WRITE ${CMAKE_BINARY_DIR}/test_data/file.txt "test")
file(WRITE ${CMAKE_BINARY_DIR}/test_data/dir/file.txt "test")

execute_process(
    COMMAND cmd /c mklink /H file_hardlink.txt file.txt
    COMMAND cmd /c mklink file_symlink.txt file.txt
    COMMAND cmd /c mklink /J dir_junction dir
    COMMAND cmd /c mklink /D dir_symlink dir
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test_data)

execute_process(COMMAND ${CMAKE_COMMAND} -E tar cvf ${CMAKE_BINARY_DIR}/test_data.zip --format=zip -- test_data
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/zip)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ${CMAKE_BINARY_DIR}/test_data.zip
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/zip)

test_file_read("cmake -E tar + file hard link" ${CMAKE_BINARY_DIR}/zip/test_data/file_hardlink.txt)
test_file_read("cmake -E tar + file symlink" ${CMAKE_BINARY_DIR}/zip/test_data/file_symlink.txt)
test_file_read("cmake -E tar + dir junction" ${CMAKE_BINARY_DIR}/zip/test_data/dir_junction/file.txt)
test_file_read("cmake -E tar + dir symlink" ${CMAKE_BINARY_DIR}/zip/test_data/dir_symlink/file.txt)

On Windows 10 (Version 1703, OS Build 15063.1387) using CMake v3.13, it prints as follows:

CMake Error: Problem with archive_write_header(): Can't create '\\?\<path>\zip\test_data\dir_symlink'
CMake Error: Current file: test_data/dir_symlink
CMake Error: Problem extracting tar: <path>/test_data.zip
[FAIL] cmake -E tar + file hard link
[FAIL] cmake -E tar + file symlink
[FAIL] cmake -E tar + dir junction
[FAIL] cmake -E tar + dir symlink

Meaning that cmake -E tar doesn't follow file symlinks and directory junctions / symlinks.

Additional points:

Edited by Alexander Sharov
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information