chore: baseline usable version
This commit is contained in:
374
libs/qwindowkit/qmsetup/cmake/modules/Translate.cmake
Normal file
374
libs/qwindowkit/qmsetup/cmake/modules/Translate.cmake
Normal file
@@ -0,0 +1,374 @@
|
||||
include_guard(DIRECTORY)
|
||||
|
||||
#[[
|
||||
Add qt translation target.
|
||||
|
||||
qm_add_translation(<target>
|
||||
[LOCALES locales]
|
||||
[PREFIX prefix]
|
||||
[SOURCES files... | DIRECTORIES dirs... | TARGETS targets... | TS_FILES files...]
|
||||
[TS_DIR dir]
|
||||
[QM_DIR dir]
|
||||
[TS_OPTIONS options...]
|
||||
[QM_OPTIONS options...]
|
||||
[TS_DEPENDS targets...]
|
||||
[QM_DEPENDS targets...]
|
||||
[CREATE_ONCE]
|
||||
)
|
||||
|
||||
Arguments:
|
||||
LOCALES: language names, e.g. zh_CN en_US, must specify if SOURCES or TARGETS is specified
|
||||
PREFIX: translation file prefix, default to target name
|
||||
|
||||
SOURCES: source files
|
||||
DIRECTORIES: source directories
|
||||
TARGETS: target names, the source files of which will be collected
|
||||
TS_FILES: ts file names, add the specified ts file
|
||||
|
||||
TS_DIR: ts files destination, default to `CMAKE_CURRENT_SOURCE_DIR`
|
||||
QM_DIR: qm files destination, default to `CMAKE_CURRENT_BINARY_DIR`
|
||||
|
||||
TS_DEPENDS: add lupdate task as a dependency to the given targets
|
||||
QM_DEPENDS: add lrelease task as a dependency to the given targets
|
||||
|
||||
CREATE_ONCE: create translations at configure phase if not exist
|
||||
|
||||
]] #
|
||||
function(qm_add_translation _target)
|
||||
set(options CREATE_ONCE)
|
||||
set(oneValueArgs PREFIX TS_DIR QM_DIR)
|
||||
set(multiValueArgs LOCALES SOURCES DIRECTORIES TARGETS TS_FILES TS_OPTIONS QM_OPTIONS TS_DEPENDS QM_DEPENDS)
|
||||
cmake_parse_arguments(FUNC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
# Get linguist tools
|
||||
if(NOT TARGET Qt${QT_VERSION_MAJOR}::lupdate OR NOT TARGET Qt${QT_VERSION_MAJOR}::lrelease)
|
||||
message(FATAL_ERROR "qm_add_translation: linguist tools not defined. Add find_package(Qt\${QT_VERSION_MAJOR} COMPONENTS LinguistTools) to CMake to enable.")
|
||||
endif()
|
||||
|
||||
set(_src_files)
|
||||
set(_include_dirs)
|
||||
|
||||
# Collect source files
|
||||
if(FUNC_SOURCES)
|
||||
list(APPEND _src_files ${FUNC_SOURCES})
|
||||
endif()
|
||||
|
||||
# Collect source files
|
||||
if(FUNC_TARGETS)
|
||||
foreach(_item IN LISTS FUNC_TARGETS)
|
||||
get_target_property(_type ${_item} TYPE)
|
||||
|
||||
if((_type STREQUAL "UTILITY") OR(_type STREQUAL "INTERFACE_LIBRARY"))
|
||||
continue()
|
||||
endif()
|
||||
|
||||
set(_tmp_files)
|
||||
get_target_property(_tmp_files ${_item} SOURCES)
|
||||
set(_qml_files)
|
||||
get_target_property(_qml_files ${_item} QT_QML_MODULE_QML_FILES)
|
||||
if (NOT _qml_files STREQUAL ${_item}-NOTFOUND)
|
||||
list(APPEND _tmp_files ${_qml_files})
|
||||
endif()
|
||||
list(FILTER _tmp_files INCLUDE REGEX ".+\\.(h|hh|hpp|hxx|c|cc|cpp|cxx|m|mm|qml|js|mjs)$")
|
||||
list(FILTER _tmp_files EXCLUDE REGEX "^(qasc|moc)_.+")
|
||||
|
||||
# Need to convert to absolute path
|
||||
get_target_property(_target_dir ${_item} SOURCE_DIR)
|
||||
|
||||
foreach(_file IN LISTS _tmp_files)
|
||||
get_filename_component(_abs_file ${_file} ABSOLUTE BASE_DIR ${_target_dir})
|
||||
list(APPEND _src_files ${_abs_file})
|
||||
endforeach()
|
||||
|
||||
unset(_tmp_files)
|
||||
|
||||
get_target_property(_tmp_dirs ${_item} INCLUDE_DIRECTORIES)
|
||||
list(APPEND _include_dirs ${_tmp_dirs})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Collect source directories
|
||||
if(FUNC_DIRECTORIES)
|
||||
foreach(_item IN LISTS FUNC_DIRECTORIES)
|
||||
file(GLOB _tmp
|
||||
${_item}/*.h ${_item}/*.hpp
|
||||
${_item}/*.hh ${_item}/*.hxx
|
||||
${_item}/*.cpp ${_item}/*.cxx
|
||||
${_item}/*.c ${_item}/*.cc
|
||||
${_item}/*.m ${_item}/*.mm
|
||||
)
|
||||
list(APPEND _src_files ${_tmp})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(_src_files)
|
||||
if(NOT FUNC_LOCALES)
|
||||
message(FATAL_ERROR "qm_add_translation: source files collected but LOCALES not specified!")
|
||||
endif()
|
||||
elseif(NOT FUNC_TS_FILES)
|
||||
message(FATAL_ERROR "qm_add_translation: no source files or ts files collected!")
|
||||
endif()
|
||||
|
||||
add_custom_target(${_target})
|
||||
|
||||
set(_qm_depends)
|
||||
|
||||
if(FUNC_TS_OPTIONS)
|
||||
set(_ts_options ${FUNC_TS_OPTIONS})
|
||||
endif()
|
||||
|
||||
if(FUNC_QM_OPTIONS)
|
||||
set(_qm_options ${FUNC_QM_OPTIONS})
|
||||
endif()
|
||||
|
||||
if(_src_files)
|
||||
if(FUNC_PREFIX)
|
||||
set(_prefix ${FUNC_PREFIX})
|
||||
else()
|
||||
set(_prefix ${_target})
|
||||
endif()
|
||||
|
||||
if(FUNC_TS_DIR)
|
||||
set(_ts_dir ${FUNC_TS_DIR})
|
||||
else()
|
||||
set(_ts_dir ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
set(_ts_files)
|
||||
|
||||
foreach(_loc IN LISTS FUNC_LOCALES)
|
||||
list(APPEND _ts_files ${_ts_dir}/${_prefix}_${_loc}.ts)
|
||||
endforeach()
|
||||
|
||||
# Include options
|
||||
set(_include_options)
|
||||
|
||||
foreach(_inc IN LISTS _include_dirs)
|
||||
list(APPEND _include_options "-I${_inc}")
|
||||
endforeach()
|
||||
|
||||
# May be an lupdate bug, so we skip passing include directories
|
||||
# list(APPEND _ts_options ${_include_options})
|
||||
if(_ts_options)
|
||||
list(PREPEND _ts_options OPTIONS)
|
||||
endif()
|
||||
|
||||
set(_create_once)
|
||||
|
||||
if(FUNC_CREATE_ONCE)
|
||||
set(_create_once CREATE_ONCE)
|
||||
endif()
|
||||
|
||||
_qm_add_lupdate_target(${_target}_lupdate
|
||||
INPUT ${_src_files}
|
||||
OUTPUT ${_ts_files}
|
||||
${_ts_options}
|
||||
${_create_once}
|
||||
)
|
||||
|
||||
# Add update dependencies
|
||||
# add_dependencies(${_target} ${_target}_lupdate)
|
||||
foreach(_item IN LISTS FUNC_TS_DEPENDS)
|
||||
add_dependencies(${_item} ${_target}_lupdate)
|
||||
endforeach()
|
||||
|
||||
# list(APPEND _qm_depends DEPENDS ${_target}_lupdate)
|
||||
else()
|
||||
if(FUNC_PREFIX)
|
||||
message(WARNING "qm_add_translation: no source files collected, PREFIX ignored")
|
||||
endif()
|
||||
|
||||
if(FUNC_TS_DIR)
|
||||
message(WARNING "qm_add_translation: no source files collected, TS_DIR ignored")
|
||||
endif()
|
||||
|
||||
if(FUNC_TS_DEPENDS)
|
||||
message(WARNING "qm_add_translation: no source files collected, TS_DEPENDS ignored")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(FUNC_QM_DIR)
|
||||
set(_qm_dir ${FUNC_QM_DIR})
|
||||
else()
|
||||
set(_qm_dir ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
set(_qm_target)
|
||||
|
||||
if(_qm_options)
|
||||
list(PREPEND _qm_options OPTIONS)
|
||||
endif()
|
||||
|
||||
_qm_add_lrelease_target(${_target}_lrelease
|
||||
INPUT ${_ts_files} ${FUNC_TS_FILES}
|
||||
DESTINATION ${_qm_dir}
|
||||
${_qm_options}
|
||||
${_qm_depends}
|
||||
)
|
||||
|
||||
add_dependencies(${_target} ${_target}_lrelease)
|
||||
|
||||
# Add release dependencies
|
||||
if(FUNC_TARGETS)
|
||||
foreach(_item IN LISTS FUNC_TARGETS)
|
||||
add_dependencies(${_item} ${_target}_lrelease)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
foreach(_item IN LISTS FUNC_QM_DEPENDS)
|
||||
add_dependencies(${_item} ${_target}_lrelease)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------
|
||||
# Private functions
|
||||
# ----------------------------------
|
||||
# Input: cxx source files
|
||||
# Output: target ts files
|
||||
function(_qm_add_lupdate_target _target)
|
||||
set(options CREATE_ONCE)
|
||||
set(oneValueArgs)
|
||||
set(multiValueArgs INPUT OUTPUT OPTIONS DEPENDS)
|
||||
|
||||
cmake_parse_arguments(_LUPDATE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
set(_lupdate_deps ${_LUPDATE_DEPENDS})
|
||||
|
||||
set(_my_sources ${_LUPDATE_INPUT})
|
||||
set(_my_tsfiles ${_LUPDATE_OUTPUT})
|
||||
|
||||
add_custom_target(${_target} DEPENDS ${_lupdate_deps})
|
||||
qm_get_executable_location(Qt${QT_VERSION_MAJOR}::lupdate _lupdate_exe)
|
||||
|
||||
set(_create_once_warning)
|
||||
set(_create_once_warning_printed off)
|
||||
|
||||
# Prepare for create once
|
||||
if(_LUPDATE_CREATE_ONCE)
|
||||
# Check if all src files are available
|
||||
foreach(_file IN LISTS _my_sources)
|
||||
get_filename_component(_abs_file ${_file} ABSOLUTE)
|
||||
|
||||
if(NOT EXISTS ${_abs_file})
|
||||
get_filename_component(_file ${_file} NAME)
|
||||
set(_create_once_warning "source file \"${_file}\" is not available, skip generating ts file now")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Check if options contain generator expressions
|
||||
if(NOT _create_once_warning)
|
||||
foreach(_opt IN LISTS _LUPDATE_OPTIONS)
|
||||
string(GENEX_STRIP "${_opt}" _no_genex)
|
||||
|
||||
if(NOT _no_genex STREQUAL _opt)
|
||||
set(_create_once_warning "lupdate options contain generator expressions, skip generating ts file now")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(_ts_file IN LISTS _my_tsfiles)
|
||||
# make a list file to call lupdate on, so we don't make our commands too
|
||||
# long for some systems
|
||||
get_filename_component(_ts_name ${_ts_file} NAME)
|
||||
set(_ts_lst_file "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_ts_name}_lst_file")
|
||||
set(_lst_file_srcs)
|
||||
|
||||
foreach(_lst_file_src IN LISTS _my_sources)
|
||||
set(_lst_file_srcs "${_lst_file_src}\n${_lst_file_srcs}")
|
||||
endforeach()
|
||||
|
||||
get_directory_property(_inc_DIRS INCLUDE_DIRECTORIES)
|
||||
|
||||
foreach(_pro_include IN LISTS _inc_DIRS)
|
||||
get_filename_component(_abs_include "${_pro_include}" ABSOLUTE)
|
||||
set(_lst_file_srcs "-I${_pro_include}\n${_lst_file_srcs}")
|
||||
endforeach()
|
||||
|
||||
file(WRITE ${_ts_lst_file} "${_lst_file_srcs}")
|
||||
|
||||
get_filename_component(_ts_abs ${_ts_file} ABSOLUTE)
|
||||
|
||||
if(_LUPDATE_CREATE_ONCE AND NOT EXISTS ${_ts_abs})
|
||||
if(_create_once_warning)
|
||||
if(NOT _create_once_warning_printed)
|
||||
message(WARNING "qm_add_translation: ${_create_once_warning}")
|
||||
set(_create_once_warning_printed on)
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Lupdate: Generating ${_ts_name}")
|
||||
get_filename_component(_abs_file ${_ts_file} ABSOLUTE)
|
||||
get_filename_component(_dir ${_abs_file} DIRECTORY)
|
||||
file(MAKE_DIRECTORY ${_dir})
|
||||
execute_process(
|
||||
COMMAND ${_lupdate_exe} ${_LUPDATE_OPTIONS} "@${_ts_lst_file}" -ts ${_ts_file}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
OUTPUT_QUIET
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${_target} POST_BUILD
|
||||
COMMAND ${_lupdate_exe}
|
||||
ARGS ${_LUPDATE_OPTIONS} "@${_ts_lst_file}" -ts ${_ts_file}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
BYPRODUCTS ${_ts_lst_file}
|
||||
VERBATIM
|
||||
)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# Input: ts files
|
||||
# Output: list to append qm files
|
||||
function(_qm_add_lrelease_target _target)
|
||||
set(options)
|
||||
set(oneValueArgs DESTINATION OUTPUT)
|
||||
set(multiValueArgs INPUT OPTIONS DEPENDS)
|
||||
|
||||
cmake_parse_arguments(_LRELEASE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
set(_lrelease_files ${_LRELEASE_INPUT})
|
||||
set(_lrelease_deps ${_LRELEASE_DEPENDS})
|
||||
|
||||
qm_get_executable_location(Qt${QT_VERSION_MAJOR}::lrelease _lrelease_exe)
|
||||
|
||||
set(_qm_files)
|
||||
|
||||
foreach(_file IN LISTS _lrelease_files)
|
||||
get_filename_component(_abs_FILE ${_file} ABSOLUTE)
|
||||
get_filename_component(_qm_file ${_file} NAME)
|
||||
|
||||
# everything before the last dot has to be considered the file name (including other dots)
|
||||
string(REGEX REPLACE "\\.[^.]*$" "" FILE_NAME ${_qm_file})
|
||||
get_source_file_property(output_location ${_abs_FILE} OUTPUT_LOCATION)
|
||||
|
||||
if(output_location)
|
||||
set(_out_dir ${output_location})
|
||||
elseif(_LRELEASE_DESTINATION)
|
||||
set(_out_dir ${_LRELEASE_DESTINATION})
|
||||
else()
|
||||
set(_out_dir ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
set(_qm_file "${_out_dir}/${FILE_NAME}.qm")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${_qm_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${_out_dir}
|
||||
COMMAND ${_lrelease_exe} ARGS ${_LRELEASE_OPTIONS} ${_abs_FILE} -qm ${_qm_file}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DEPENDS ${_lrelease_files}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
list(APPEND _qm_files ${_qm_file})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(${_target} ALL DEPENDS ${_lrelease_deps} ${_qm_files})
|
||||
|
||||
if(_LRELEASE_OUTPUT)
|
||||
set(${_LRELEASE_OUTPUT} ${_qm_files} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
Reference in New Issue
Block a user