qt6-bb10/src/corelib/QtCompressMimeDatabase.cmake

157 lines
6.4 KiB
CMake

# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
get_filename_component(output_directory "${OUTPUT_FILE}" DIRECTORY)
file(MAKE_DIRECTORY "${output_directory}")
find_program(xmlstarlet NAMES xmlstarlet xml)
if(xmlstarlet)
set(XML_STARLET_COMMAND COMMAND "${xmlstarlet}" sel -D -B -t -c / "${INPUT_FILE}")
else()
get_filename_component(mime_types_resource_filename "${INPUT_FILE}" NAME)
message(STATUS "xmlstarlet command was not found. ${mime_types_resource_filename}"
" will not be minified.")
endif()
# The function tries to minify 'input_file' using the globally defined 'XML_STARLET_COMMAND'.
# Sets the full path of the output file to the 'out_var' argument. If 'XML_STARLET_COMMAND' fails
# to minify the 'input_file', 'out_var' is set to 'input_file'.
function(try_minify_xml out_var input_file output_directory)
get_filename_component(output_filename "${input_file}" NAME)
set(minified_output "${output_directory}/${output_filename}")
# Assume XML_STARLET_COMMAND is globally defined.
if(XML_STARLET_COMMAND)
execute_process(${XML_STARLET_COMMAND}
OUTPUT_FILE "${minified_output}"
RESULT_VARIABLE failed_to_minify
)
if(NOT failed_to_minify)
set(${out_var} "${minified_output}" PARENT_SCOPE)
return()
endif()
endif()
set(${out_var} "${input_file}" PARENT_SCOPE)
endfunction()
unset(archive_command)
if(COMPRESSION_TYPE STREQUAL "none")
try_minify_xml(qmimeprovider_db_data_file "${INPUT_FILE}" "${output_directory}")
else()
# CMake versions less than 3.26 don't support the value of the zstd compression level higher
# than 9. We want zstd to compress with level 19 if it's possible, so if zstd executable is
# found on a file system we prefer to use the 'External' archiving API instead of the CMake API.
# See for details: https://gitlab.kitware.com/cmake/cmake/-/issues/24160
if(COMPRESSION_TYPE STREQUAL "zstd" AND CMAKE_VERSION VERSION_LESS 3.26)
find_program(archive_command NAMES zstd zstd.exe)
if(archive_command)
set(ARCHIVING_API "External")
endif()
endif()
set(qmimeprovider_db_data_file "${OUTPUT_FILE}.archive")
if(ARCHIVING_API STREQUAL "External")
message(STATUS "Using external archive command to compress the mime type database")
if(COMPRESSION_TYPE STREQUAL "zstd")
find_program(archive_command NAMES zstd zstd.exe)
if(archive_command)
set(archive_command_args -cq19 -T1)
else()
message(WARNING
"Unable to use the preffered ${COMPRESSION_TYPE} compression for the mime type database."
" ${COMPRESSION_TYPE} binary is not found. Trying gzip.")
endif()
endif()
if(NOT archive_command)
# Trying to use gzip if zstd is binary is not found.
set(COMPRESSION_TYPE "gzip")
find_program(archive_command NAMES gzip gzip.exe)
set(archive_command_args -nc9)
endif()
if(archive_command)
if(NOT XML_STARLET_COMMAND)
set(intput_file_arg INPUT_FILE "${INPUT_FILE}")
endif()
execute_process(${XML_STARLET_COMMAND}
COMMAND ${archive_command}
${archive_command_args}
${intput_file_arg}
OUTPUT_FILE "${qmimeprovider_db_data_file}"
RESULTS_VARIABLE results
ERROR_VARIABLE error_string
)
foreach(result IN LISTS results)
if(NOT result EQUAL 0)
message(WARNING "Unable to compress mime type database: ${error_string}")
endif()
endforeach()
else()
message(WARNING "Unable to find ${COMPRESSION_TYPE} binary."
" Please make sure that the ${COMPRESSION_TYPE} binary is in PATH."
" Adding the uncompressed mime type database.")
set(COMPRESSION_TYPE "none")
set(qmimeprovider_db_data_file "${INPUT_FILE}")
endif()
else()
message(STATUS "Using CMake archive command to compress the mime type database")
try_minify_xml(mimetypes_resource_file_minified "${INPUT_FILE}" "${output_directory}")
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.26 AND COMPRESSION_TYPE STREQUAL "zstd")
set(additional_file_archive_create_parameters COMPRESSION_LEVEL 19)
elseif(CMAKE_VERSION VERSION_GREATER_EQUAL 3.19)
set(additional_file_archive_create_parameters COMPRESSION_LEVEL 9)
endif()
if(COMPRESSION_TYPE STREQUAL "gzip")
set(cmake_compression_type "GZip")
elseif(COMPRESSION_TYPE STREQUAL "zstd")
set(cmake_compression_type "Zstd")
endif()
file(ARCHIVE_CREATE OUTPUT "${qmimeprovider_db_data_file}"
PATHS "${mimetypes_resource_file_minified}"
FORMAT raw
COMPRESSION ${cmake_compression_type}
${additional_file_archive_create_parameters}
)
if(NOT mimetypes_resource_file_minified STREQUAL INPUT_FILE)
file(REMOVE "${mimetypes_resource_file_minified}")
endif()
endif()
endif()
file(READ "${qmimeprovider_db_data_file}" qmime_db_data HEX)
file(SIZE "${qmimeprovider_db_data_file}" qmime_db_data_size)
if(NOT qmimeprovider_db_data_file STREQUAL INPUT_FILE)
file(SIZE "${INPUT_FILE}" qmime_db_resource_size)
file(REMOVE "${qmimeprovider_db_data_file}")
else()
set(qmime_db_resource_size ${qmime_db_data_size})
endif()
string(REGEX MATCHALL "([a-f0-9][a-f0-9])" qmime_db_hex "${qmime_db_data}")
list(TRANSFORM qmime_db_hex PREPEND "0x")
math(EXPR qmime_db_data_size "${qmime_db_data_size} - 1")
foreach(index RANGE 0 ${qmime_db_data_size} 12)
list(APPEND index_list ${index})
endforeach()
list(TRANSFORM qmime_db_hex PREPEND "\n " AT ${index_list})
list(JOIN qmime_db_hex ", " qmime_db_hex_joined)
if(NOT COMPRESSION_TYPE STREQUAL "none")
string(TOUPPER "${COMPRESSION_TYPE}" compression_type_upper)
set(qmime_db_content "#define MIME_DATABASE_IS_${compression_type_upper}\n")
endif()
string(APPEND qmime_db_content
"static const unsigned char mimetype_database[] = {"
"${qmime_db_hex_joined}"
"\n};\n"
"static constexpr size_t MimeTypeDatabaseOriginalSize = ${qmime_db_resource_size};\n"
)
file(WRITE "${OUTPUT_FILE}" "${qmime_db_content}")