set(_Fcitx5Macro_SELF "${CMAKE_CURRENT_LIST_FILE}") get_filename_component(_Fcitx5Macro_SELF_DIR "${_Fcitx5Macro_SELF}" PATH) option(BUILD_SHARED_FCITX_ADDON "Build addon as shared library" On) if (BUILD_SHARED_FCITX_ADDON) set(FCITX_ADDON_CMAKE_LIBRARY_TYPE MODULE) set(FCITX_ADDON_TYPE "SharedLibrary") else() set(FCITX_ADDON_CMAKE_LIBRARY_TYPE STATIC) set(FCITX_ADDON_TYPE "StaticLibrary") endif() include(WriteBasicConfigVersionFile) function(fcitx5_import_addons target) set(options) set(one_value_args REGISTRY_VARNAME) set(multi_value_args ADDONS) cmake_parse_arguments(FCITX5_IMPORT "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN}) foreach(addon IN LISTS FCITX5_IMPORT_ADDONS) set(filename "${CMAKE_CURRENT_BINARY_DIR}/${target}-${addon}-import-addon.cpp") file(WRITE "${filename}" " #include extern fcitx::StaticAddonRegistry &${FCITX5_IMPORT_REGISTRY_VARNAME}(); FCITX_IMPORT_ADDON_FACTORY(${FCITX5_IMPORT_REGISTRY_VARNAME}, ${addon}); ") target_sources(${target} PRIVATE ${filename}) target_link_libraries(${target} ${addon}) endforeach() endfunction() function(fcitx5_get_addon_targets OUT) cmake_parse_arguments(ARG "" "" "" ${ARGN}) set(dirs ${ARG_UNPARSED_ARGUMENTS}) set(_addon_targets) foreach(dir IN LISTS dirs) get_property(targets DIRECTORY "${dir}" PROPERTY BUILDSYSTEM_TARGETS) foreach(target IN LISTS targets) get_target_property(is_fcitx_addon ${target} FCITX_ADDON) if (is_fcitx_addon) list(APPEND _addon_targets ${target}) endif() endforeach() get_property(subdirs DIRECTORY "${dir}" PROPERTY SUBDIRECTORIES) fcitx5_get_addon_targets(_subdir_addon_targets ${subdirs}) list(APPEND _addon_targets ${_subdir_addon_targets}) endforeach() set(${OUT} ${_addon_targets} PARENT_SCOPE) endfunction() function(fcitx5_download tgt_name url output sha256sum) get_filename_component(output "${output}" ABSOLUTE) set(FCITX5_DOWNLOAD_URL "${url}") set(FCITX5_DOWNLOAD_DEST "${output}") set(FCITX5_DOWNLOAD_SHA256 "${sha256sum}") configure_file("${_Fcitx5Macro_SELF_DIR}/Fcitx5Download.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/${tgt_name}-download.cmake" @ONLY) add_custom_target("${tgt_name}" ALL COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/${tgt_name}-download.cmake") # This is the rule to create the target file, it is depending of the target # that does the real download so any files/targets that is depending on this # file will be run after the download finished. # # Since this rule doesn't have any command or file dependencies, cmake # won't notice any change in the rule and therefore it won't remove the # target file (and therefore triggers an unwilling redownload) if the real # rule (which is in the target defined above) has changed. # # This behavior is designed to be friendly for a build from cache with all # necessary files already downloaded so that a change in the # build options/url/checksum will not cause cmake to remove the target file # if it has already been updated correctly. add_custom_command(OUTPUT "${output}" DEPENDS "${tgt_name}") endfunction() function(fcitx5_extract tgt_name ifile) set(options) set(one_value_args) set(multi_value_args OUTPUT DEPENDS) cmake_parse_arguments(FCITX5_EXTRACT "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN}) set(STAMP_FILE "${CMAKE_CURRENT_BINARY_DIR}/.${tgt_name}.stamp") get_filename_component(ifile "${ifile}" ABSOLUTE) add_custom_command(OUTPUT "${STAMP_FILE}" COMMAND "${CMAKE_COMMAND}" -E tar x "${ifile}" COMMAND "${CMAKE_COMMAND}" -E touch "${STAMP_FILE}" COMMAND "${CMAKE_COMMAND}" -E touch_nocreate ${FCITX5_EXTRACT_OUTPUT} DEPENDS ${FCITX5_EXTRACT_DEPENDS} "${ifile}") add_custom_target("${tgt_name}" ALL DEPENDS "${STAMP_FILE}") add_custom_command(OUTPUT ${FCITX5_EXTRACT_OUTPUT} DEPENDS "${tgt_name}") endfunction() set(_Fcitx5ModuleMacros_SELF "${CMAKE_CURRENT_LIST_FILE}") get_filename_component(_Fcitx5ModuleMacros_SELF_DIR "${_Fcitx5ModuleMacros_SELF}" PATH) macro(fcitx5_export_module EXPORTNAME) set(options INSTALL) set(one_value_args BUILD_INCLUDE_DIRECTORIES TARGET INCLUDE_INSTALL_DIR LIB_INSTALL_DIR COMPATIBILITY VERSION) set(multi_value_args HEADERS) cmake_parse_arguments(FEM "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN}) if (FEM_INCLUDE_INSTALL_DIR) set(_MODULE_HEADER_DIR "${FEM_INCLUDE_INSTALL_DIR}") else() set(_MODULE_HEADER_DIR "${FCITX_INSTALL_MODULE_HEADER_DIR}/${FEM_TARGET}") endif() if (NOT FEM_LIB_INSTALL_DIR) set(FEM_LIB_INSTALL_DIR "${FCITX_INSTALL_LIBDIR}") endif() set(FEM_EXPORTNAME "${EXPORTNAME}") add_library(${FEM_TARGET}-interface INTERFACE) add_library(Fcitx5::Module::${EXPORTNAME} ALIAS ${FEM_TARGET}-interface) set_target_properties(${FEM_TARGET}-interface PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FEM_BUILD_INCLUDE_DIRECTORIES}") configure_file( "${_Fcitx5Macro_SELF_DIR}/Fcitx5ModuleTemplate.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/Fcitx5Module${EXPORTNAME}.cmake" @ONLY) configure_file( "${_Fcitx5Macro_SELF_DIR}/Fcitx5ModuleTemplate.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/Fcitx5Module${EXPORTNAME}Config.cmake" @ONLY) if (NOT FEM_VERSION) set(FEM_VERSION ${PROJECT_VERSION}) endif() write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/Fcitx5Module${EXPORTNAME}ConfigVersion.cmake" VERSION "${FEM_VERSION}" COMPATIBILITY AnyNewerVersion) if(FEM_INSTALL) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Fcitx5Module${EXPORTNAME}Config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/Fcitx5Module${EXPORTNAME}ConfigVersion.cmake" DESTINATION "${FEM_LIB_INSTALL_DIR}/cmake/Fcitx5Module${EXPORTNAME}") install(FILES ${FEM_HEADERS} DESTINATION "${_MODULE_HEADER_DIR}" COMPONENT header) endif() endmacro() function(_fcitx5_get_unique_target_name _name _unique_name) set(propertyName "_FCITX5_UNIQUE_COUNTER_${_name}") get_property(currentCounter GLOBAL PROPERTY "${propertyName}") if(NOT currentCounter) set(${_unique_name} "${_name}" PARENT_SCOPE) set(currentCounter 1) else() set(${_unique_name} "${_name}${currentCounter}" PARENT_SCOPE) math(EXPR currentCounter "${currentCounter} + 1") endif() set_property(GLOBAL PROPERTY ${propertyName} ${currentCounter} ) endfunction() function(fcitx5_translate_desktop_file SRC DEST) set(options XML) set(one_value_args PO_DIRECTORY) set(multi_value_args KEYWORDS) cmake_parse_arguments(FCITX5_TRANSLATE "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN}) if (NOT IS_ABSOLUTE ${SRC}) set(SRC "${CMAKE_CURRENT_SOURCE_DIR}/${SRC}") endif() if (NOT IS_ABSOLUTE ${DEST}) set(DEST "${CMAKE_CURRENT_BINARY_DIR}/${DEST}") endif() get_filename_component(SRC_BASE ${SRC} NAME) set(KEYWORD_ARGS) if (NOT FCITX5_TRANSLATE_PO_DIRECTORY) set(FCITX5_TRANSLATE_PO_DIRECTORY "${PROJECT_SOURCE_DIR}/po") endif() file(GLOB PO_FILES "${FCITX5_TRANSLATE_PO_DIRECTORY}/*.po") if (FCITX5_TRANSLATE_KEYWORDS) list(APPEND KEYWORD_ARGS "--keyword=") foreach(KEYWORD IN LISTS FCITX5_TRANSLATE_KEYWORDS) list(APPEND KEYWORD_ARGS "--keyword=${KEYWORD}") endforeach() endif() if (FCITX5_TRANSLATE_XML) set(TYPE_ARG "--xml") else() set(TYPE_ARG "--desktop") endif() add_custom_command(OUTPUT "${DEST}" COMMAND "${GETTEXT_MSGFMT_EXECUTABLE}" "${TYPE_ARG}" -d ${FCITX5_TRANSLATE_PO_DIRECTORY} ${KEYWORD_ARGS} --template "${SRC}" -o "${DEST}" DEPENDS "${SRC}" ${PO_FILES}) _fcitx5_get_unique_target_name("${SRC_BASE}-fmt" uniqueTargetName) add_custom_target("${uniqueTargetName}" ALL DEPENDS "${DEST}") if (TARGET generate-desktop-file) add_dependencies(generate-desktop-file "${uniqueTargetName}") endif() endfunction() # Gettext function are not good for our use case. # GETTEXT_CREATE_TRANSLATIONS will call msgmerge which may update po file function(fcitx5_install_translation domain) file(GLOB PO_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.po) set(MO_FILES) foreach(PO_FILE IN LISTS PO_FILES) get_filename_component(PO_LANG ${PO_FILE} NAME_WE) get_filename_component(ABS_PO_FILE ${PO_FILE} ABSOLUTE) set(MO_FILE ${CMAKE_CURRENT_BINARY_DIR}/${domain}-${PO_LANG}.mo) add_custom_command( OUTPUT ${MO_FILE} COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${MO_FILE} ${ABS_PO_FILE} DEPENDS ${ABS_PO_FILE} ) install(FILES ${MO_FILE} RENAME ${domain}.mo DESTINATION ${FCITX_INSTALL_LOCALEDIR}/${PO_LANG}/LC_MESSAGES COMPONENT translation) set(MO_FILES ${MO_FILES} ${MO_FILE}) endforeach () add_custom_target("${domain}-translation" ALL DEPENDS ${MO_FILES}) if (TARGET translation-file) add_dependencies(translation-file "${domain}-translation") endif() endfunction() function(fcitx5_add_i18n_definition) set(options) set(one_value_args LOCALE_INSTALL_DIR) set(multi_value_args TARGETS) cmake_parse_arguments(FCITX5_AID "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN}) if (FCITX5_AID_LOCALE_INSTALL_DIR) set(_LOCALE_DIR "${FCITX5_AID_LOCALE_INSTALL_DIR}") else() set(_LOCALE_DIR "${FCITX_INSTALL_LOCALEDIR}") endif() string(CONFIGURE ${_LOCALE_DIR} LOCALE_DIR ESCAPE_QUOTES) if(FCITX5_AID_TARGETS) message(${FCITX5_AID_TARGETS}) foreach(TARGET_NAME IN LISTS FCITX5_AID_TARGETS) target_compile_definitions(${TARGET_NAME} PRIVATE -DFCITX_INSTALL_LOCALEDIR=\"${LOCALE_DIR}\") endforeach() else() add_definitions(-DFCITX_INSTALL_LOCALEDIR=\"${LOCALE_DIR}\") endif() endfunction() if (NOT TARGET generate-desktop-file) add_custom_target(generate-desktop-file) endif() if (NOT TARGET translation-file) add_custom_target(translation-file) endif() function(add_fcitx5_addon target_name) cmake_parse_arguments(ARG "" "" "" ${ARGN}) set(srcs ${ARG_UNPARSED_ARGUMENTS}) add_library(${target_name} ${FCITX_ADDON_CMAKE_LIBRARY_TYPE} ${srcs} ) set_target_properties(${target_name} PROPERTIES FCITX_ADDON TRUE) endfunction()