Use 'copy' but not 'copy_if_different' on Windows platforms
Use custom script to copy big Android artifacts on Windows platforms. The script uses 'copy' but not 'copy_if_different' when source file size is bigger than 2GB. 'cmake -E copy_if_different' only compares first 2GB of files because of cmake issue, so this step only workaround the problem. Task-number: QTBUG-99491 Change-Id: Id076734700e334dfc3330da412462c2b53829b33 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> (cherry picked from commit 2201934efa1b9889d474347e705784bf6925e120)
This commit is contained in:
parent
ff96047a69
commit
7b48f9ce5d
@ -218,6 +218,7 @@ qt_copy_or_install(FILES
|
||||
cmake/QtCompilerFlags.cmake
|
||||
cmake/QtCompilerOptimization.cmake
|
||||
cmake/QtConfigDependencies.cmake.in
|
||||
cmake/QtCopyFileIfDifferent.cmake
|
||||
cmake/QtDeferredDependenciesHelpers.cmake
|
||||
cmake/QtDbusHelpers.cmake
|
||||
cmake/QtDocsHelpers.cmake
|
||||
@ -297,6 +298,7 @@ qt_copy_or_install(DIRECTORY
|
||||
set(__public_cmake_helpers
|
||||
cmake/QtFeature.cmake
|
||||
cmake/QtFeatureCommon.cmake
|
||||
cmake/QtPublicCMakeHelpers.cmake
|
||||
cmake/QtPublicCMakeVersionHelpers.cmake
|
||||
cmake/QtPublicFinalizerHelpers.cmake
|
||||
cmake/QtPublicPluginHelpers.cmake
|
||||
|
@ -91,6 +91,7 @@ include("${CMAKE_CURRENT_LIST_DIR}/QtPublicTargetHelpers.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicWalkLibsHelpers.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicFindPackageHelpers.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicDependencyHelpers.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicCMakeHelpers.cmake")
|
||||
|
||||
if(NOT DEFINED QT_CMAKE_EXPORT_NAMESPACE)
|
||||
set(QT_CMAKE_EXPORT_NAMESPACE @QT_CMAKE_EXPORT_NAMESPACE@)
|
||||
|
15
cmake/QtCopyFileIfDifferent.cmake
Normal file
15
cmake/QtCopyFileIfDifferent.cmake
Normal file
@ -0,0 +1,15 @@
|
||||
# copy_if_different works incorrect in Windows if file size if bigger than 2GB.
|
||||
# See https://gitlab.kitware.com/cmake/cmake/-/issues/23052 and QTBUG-99491 for details.
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(copy_strategy "copy_if_different")
|
||||
if(CMAKE_HOST_WIN32)
|
||||
file(SIZE "${SRC_FILE_PATH}" size)
|
||||
# If file size is bigger than 2GB copy it unconditionally
|
||||
if(size GREATER_EQUAL 2147483648)
|
||||
set(copy_strategy "copy")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E ${copy_strategy} "${SRC_FILE_PATH}" "${DST_FILE_PATH}")
|
20
cmake/QtPublicCMakeHelpers.cmake
Normal file
20
cmake/QtPublicCMakeHelpers.cmake
Normal file
@ -0,0 +1,20 @@
|
||||
# copy_if_different works incorrect in Windows if file size if bigger than 2GB.
|
||||
# See https://gitlab.kitware.com/cmake/cmake/-/issues/23052 and QTBUG-99491 for details.
|
||||
function(_qt_internal_copy_file_if_different_command out_var src_file dst_file)
|
||||
# The CMake version higher than 3.23 doesn't contain the issue
|
||||
if(CMAKE_HOST_WIN32 AND CMAKE_VERSION VERSION_LESS 3.23)
|
||||
set(${out_var} "${CMAKE_COMMAND}"
|
||||
"-DSRC_FILE_PATH=${src_file}"
|
||||
"-DDST_FILE_PATH=${dst_file}"
|
||||
-P "${_qt_6_config_cmake_dir}/QtCopyFileIfDifferent.cmake"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
else()
|
||||
set(${out_var} "${CMAKE_COMMAND}"
|
||||
-E copy_if_different
|
||||
"${src_file}"
|
||||
"${dst_file}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
@ -336,11 +336,13 @@ function(qt6_android_add_apk_target target)
|
||||
|
||||
# This target is used by Qt Creator's Android support and by the ${target}_make_apk target
|
||||
# in case DEPFILEs are not supported.
|
||||
_qt_internal_copy_file_if_different_command(copy_command
|
||||
"$<TARGET_FILE:${target}>"
|
||||
"${apk_final_dir}/libs/${CMAKE_ANDROID_ARCH_ABI}/$<TARGET_FILE_NAME:${target}>"
|
||||
)
|
||||
add_custom_target(${target}_prepare_apk_dir ALL
|
||||
DEPENDS ${target} ${extra_deps}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-E copy_if_different $<TARGET_FILE:${target}>
|
||||
"${apk_final_dir}/libs/${CMAKE_ANDROID_ARCH_ABI}/$<TARGET_FILE_NAME:${target}>"
|
||||
COMMAND ${copy_command}
|
||||
COMMENT "Copying ${target} binary to apk folder"
|
||||
)
|
||||
|
||||
|
@ -0,0 +1,73 @@
|
||||
# How to run the test:
|
||||
# 1. Create the build directory, e.g. /home/user/build_test_copy_file_if_different
|
||||
# 2. cd /home/user/build_test_copy_file_if_different
|
||||
# 3. /path/to/Qt/bin/qt-cmake /path/to/Qt/Sources/qtbase/tests/manual/cmake/test_copy_file_if_different_command
|
||||
# 4. cmake --build . --parallel
|
||||
# 5. ctest
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(test_copy_file_if_different_command
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
if(NOT CMAKE_HOST_WIN32)
|
||||
message("Test only applicable for WIN32 platform. Nothing to do.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
message("Test should only be run on host system. Crosscompiling is not supported.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_program(fsutil NAMES fsutil fsutil.exe)
|
||||
if(NOT fsutil)
|
||||
message(WARNING "Unable to find 'fsutil' executable. Skipping the test")
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core)
|
||||
|
||||
function(test_copy_file_command output_file test_data_base_name size)
|
||||
set(testdatasrc1 "${CMAKE_CURRENT_BINARY_DIR}/${test_data_base_name}1.bin")
|
||||
set(testdatasrc2 "${CMAKE_CURRENT_BINARY_DIR}/${test_data_base_name}2.bin")
|
||||
set(testdatadst "${CMAKE_CURRENT_BINARY_DIR}/${test_data_base_name}.bin")
|
||||
|
||||
# Remove existing data first
|
||||
file(REMOVE "${testdatasrc1}" "${testdatasrc2}" "${testdatadst}")
|
||||
|
||||
file(TO_NATIVE_PATH "${testdatasrc1}" native_testdatasrc)
|
||||
execute_process(COMMAND ${fsutil} file createNew "${native_testdatasrc}" ${size}
|
||||
RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
message(FATAL_ERROR "Unable to allocate file ${native_testdatasrc}"
|
||||
" of size ${size} for test"
|
||||
)
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${testdatasrc1}" "${testdatasrc2}"
|
||||
RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
message(FATAL_ERROR "Unable to copy test data from ${testdatasrc1} to ${testdatasrc2}")
|
||||
endif()
|
||||
|
||||
foreach(src_file_num RANGE 1 2)
|
||||
set(src_file "${testdatasrc${src_file_num}}")
|
||||
file(APPEND "${src_file}" "${src_file_num}")
|
||||
_qt_internal_copy_file_if_different_command(copy_command "${src_file}" "${testdatadst}")
|
||||
execute_process(COMMAND ${copy_command} RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
message(FATAL_ERROR "Unable to execute the copy command ${copy_command}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(${output_file} "${testdatadst}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
test_copy_file_command(output_file1K testdata1K 1024)
|
||||
test_copy_file_command(output_file2GB testdata2GB 2147483648)
|
||||
|
||||
add_executable(test_copy_if_different_command main.cpp)
|
||||
|
||||
enable_testing()
|
||||
add_test(NAME "test_copy_if_different_command" COMMAND test_copy_if_different_command "${output_file1K}" "${output_file2GB}")
|
@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
int checkFileLastByte(const std::string &filename, std::fstream::off_type offset)
|
||||
{
|
||||
std::ifstream file(filename, std::ios_base::in);
|
||||
if (!file.is_open()) {
|
||||
std::cerr << "Unable to open test data file: " << filename << std::endl;
|
||||
return 1;
|
||||
}
|
||||
file.seekg(offset, std::ios_base::beg);
|
||||
char data = 0;
|
||||
file.read(&data, sizeof(data));
|
||||
if (data != '2') { // We always expect it's the second copy of the file
|
||||
std::cerr << "Invalid data inside the file: " << filename << std::endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 3) {
|
||||
std::cerr << "Test requires exact 2 arguments that point to the test data" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int result = checkFileLastByte(argv[1], 1024);
|
||||
if (result != 0)
|
||||
return result;
|
||||
return checkFileLastByte(argv[2], 2147483648);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user