# Copyright (c) 2025 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. cmake_minimum_required(VERSION 3.22) set(input_variables PROJECT_SOURCE_DIR COPYRIGHT_HOLDERS LCONVERT_EXECUTABLE LUPDATE_EXECUTABLE XGETTEXT_EXECUTABLE ) foreach(var IN LISTS input_variables) if(NOT DEFINED ${var}) message(FATAL_ERROR "Variable '${var}' is not defined!") endif() endforeach() # Extract _("...") strings for translation and convert to Qt stringdefs so that # they can be picked up by Qt linguist. function(extract_strings output) execute_process( COMMAND ${XGETTEXT_EXECUTABLE} --output=bitcoinstrings.po --no-location --from-code=utf-8 --keyword=_ ${ARGN} COMMAND_ERROR_IS_FATAL ANY ) file(STRINGS "bitcoinstrings.po" text ENCODING "UTF-8") set(messages "${COPYRIGHT_HOLDERS}") foreach(line IN LISTS text) if(line MATCHES "^msgid \"(.*)\"$") set(msgid "${CMAKE_MATCH_1}") elseif(line MATCHES "^\"(.*)\"$") string(APPEND msgid "${CMAKE_MATCH_1}") elseif(line MATCHES "^msgstr .*$" AND NOT msgid STREQUAL "") # CMake uses ';' as a list separator. # We need to temporarily replace that in order to keep strings intact. string(REPLACE ";" "" msgid "${msgid}") list(APPEND messages "${msgid}") endif() endforeach() set(content [[// Automatically generated by translate.cmake #include #ifdef __GNUC__ #define UNUSED __attribute__((unused)) #else #define UNUSED #endif static const char UNUSED *bitcoin_strings[] = { ]]) set(prefix "QT_TRANSLATE_NOOP(\"bitcoin-core\", \"") set(suffix "\"),\n") list(SORT messages) list(JOIN messages "${suffix}${prefix}" messages_str) string(APPEND content "${prefix}${messages_str}${suffix}") string(APPEND content "};\n") string(REPLACE "" ";" content "${content}") file(WRITE "${output}" "${content}") endfunction() file(GLOB_RECURSE translatable_sources "${PROJECT_SOURCE_DIR}/src/*.h" "${PROJECT_SOURCE_DIR}/src/*.cpp" "${PROJECT_SOURCE_DIR}/src/*.mm" ) file(GLOB_RECURSE qt_translatable_sources "${PROJECT_SOURCE_DIR}/src/qt/*.h" "${PROJECT_SOURCE_DIR}/src/qt/*.cpp" "${PROJECT_SOURCE_DIR}/src/qt/*.mm" ) file(GLOB ui_files "${PROJECT_SOURCE_DIR}/src/qt/forms/*.ui" ) set(subtrees crc32c crypto/ctaes leveldb minisketch secp256k1) set(exclude_dirs bench compat crypto support test univalue) foreach(directory IN LISTS subtrees exclude_dirs) list(FILTER translatable_sources EXCLUDE REGEX "${PROJECT_SOURCE_DIR}/src/${directory}/.*" ) endforeach() extract_strings("${PROJECT_SOURCE_DIR}/src/qt/bitcoinstrings.cpp" ${translatable_sources} ) execute_process( COMMAND ${LUPDATE_EXECUTABLE} -no-obsolete -I ${PROJECT_SOURCE_DIR}/src -locations relative ${ui_files} ${qt_translatable_sources} ${PROJECT_SOURCE_DIR}/src/qt/bitcoinstrings.cpp -ts ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.ts COMMAND_ERROR_IS_FATAL ANY ) execute_process( COMMAND ${LCONVERT_EXECUTABLE} -drop-translations -o ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf -i ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.ts COMMAND_ERROR_IS_FATAL ANY ) file(READ "${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf" bitcoin_en) string(REPLACE "source-language=\"en\" target-language=\"en\"" "source-language=\"en\"" bitcoin_en "${bitcoin_en}" ) string(REGEX REPLACE " *\n" "" bitcoin_en "${bitcoin_en}" ) file(WRITE "${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf" "${bitcoin_en}")