# SPDX-FileCopyrightText: 2014 David Faure # # SPDX-License-Identifier: BSD-3-Clause #[=======================================================================[.rst: ECMGeneratePriFile ------------------ Generate a ``.pri`` file for the benefit of qmake-based projects. As well as the function below, this module creates the cache variable ``ECM_MKSPECS_INSTALL_DIR`` and sets the default value to ``mkspecs/modules``. This assumes Qt and the current project are both installed to the same non-system prefix. Packagers who use ``-DCMAKE_INSTALL_PREFIX=/usr`` will certainly want to set ``ECM_MKSPECS_INSTALL_DIR`` to something like ``share/qt5/mkspecs/modules``. The main thing is that this should be the ``modules`` subdirectory of either the default qmake ``mkspecs`` directory or of a directory that will be in the ``$QMAKEPATH`` environment variable when qmake is run. :: ecm_generate_pri_file(BASE_NAME LIB_NAME [VERSION ] # since 5.83 [DEPS " [ [...]]"] [FILENAME_VAR ] [INCLUDE_INSTALL_DIRS [ [...]]] # since 5.92 [INCLUDE_INSTALL_DIR ] # deprecated since 5.92 [LIB_INSTALL_DIR ]) If your CMake project produces a Qt-based library, you may expect there to be applications that wish to use it that use a qmake-based build system, rather than a CMake-based one. Creating a ``.pri`` file will make use of your library convenient for them, in much the same way that CMake config files make things convenient for CMake-based applications. ``ecm_generate_pri_file()`` generates just such a file. VERSION specifies the version of the library the ``.pri`` file describes. If not set, the value is taken from the context variable ``PROJECT_VERSION``. This variable is usually set by the ``project(... VERSION ...)`` command or, if CMake policy CMP0048 is not NEW, by :module:`ECMSetupVersion`. For backward-compatibility with older ECM versions the ``PROJECT_VERSION_STRING`` variable as set by :module:`ECMSetupVersion` will be preferred over ``PROJECT_VERSION`` if set, unless the minimum required version of ECM is 5.83 and newer. Since 5.83. BASE_NAME specifies the name qmake project (.pro) files should use to refer to the library (eg: KArchive). LIB_NAME is the name of the actual library to link to (ie: the first argument to add_library()). DEPS is a space-separated list of the base names of other libraries (for Qt libraries, use the same names you use with the ``QT`` variable in a qmake project file, such as "core" for QtCore). FILENAME_VAR specifies the name of a variable to store the path to the generated file in. INCLUDE_INSTALL_DIRS are the paths (relative to ``CMAKE_INSTALL_PREFIX``) that include files will be installed to. It defaults to ``${INCLUDE_INSTALL_DIR}/`` if the ``INCLUDE_INSTALL_DIR`` variable is set. If that variable is not set, the ``CMAKE_INSTALL_INCLUDEDIR`` variable is used instead, and if neither are set ``include`` is used. LIB_INSTALL_DIR operates similarly for the installation location for libraries; it defaults to ``${LIB_INSTALL_DIR}``, ``${CMAKE_INSTALL_LIBDIR}`` or ``lib``, in that order. INCLUDE_INSTALL_DIR is the old variant of INCLUDE_INSTALL_DIRS, taking only one directory. Example usage: .. code-block:: cmake ecm_generate_pri_file( BASE_NAME KArchive LIB_NAME KF5KArchive DEPS "core" FILENAME_VAR pri_filename VERSION 4.2.0 ) install(FILES ${pri_filename} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) A qmake-based project that wished to use this would then do:: QT += KArchive in their ``.pro`` file. Since pre-1.0.0. #]=======================================================================] # Replicate the logic from KDEInstallDirs.cmake as we can't depend on it # Ask qmake if we're using the same prefix as Qt set(_should_query_qt OFF) if(NOT DEFINED KDE_INSTALL_USE_QT_SYS_PATHS) include(ECMQueryQt) ecm_query_qt(qt_install_prefix_dir QT_INSTALL_PREFIX TRY) if(qt_install_prefix_dir STREQUAL "${CMAKE_INSTALL_PREFIX}") set(_should_query_qt ON) endif() endif() if(KDE_INSTALL_USE_QT_SYS_PATHS OR _should_query_qt) include(ECMQueryQt) ecm_query_qt(qt_install_prefix_dir QT_INSTALL_PREFIX) ecm_query_qt(qt_host_data_dir QT_HOST_DATA) if(qt_install_prefix_dir STREQUAL "${CMAKE_INSTALL_PREFIX}") file(RELATIVE_PATH qt_host_data_dir ${qt_install_prefix_dir} ${qt_host_data_dir}) endif() if(qt_host_data_dir STREQUAL "") set(mkspecs_install_dir mkspecs/modules) else() set(mkspecs_install_dir ${qt_host_data_dir}/mkspecs/modules) endif() set(ECM_MKSPECS_INSTALL_DIR ${mkspecs_install_dir} CACHE PATH "The directory where mkspecs will be installed to.") else() set(ECM_MKSPECS_INSTALL_DIR mkspecs/modules CACHE PATH "The directory where mkspecs will be installed to.") endif() function(ECM_GENERATE_PRI_FILE) set(options INTERFACE) set(oneValueArgs BASE_NAME LIB_NAME DEPS FILENAME_VAR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR VERSION) set(multiValueArgs INCLUDE_INSTALL_DIRS) cmake_parse_arguments(EGPF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(EGPF_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unknown keywords given to ECM_GENERATE_PRI_FILE(): \"${EGPF_UNPARSED_ARGUMENTS}\"") endif() if(ECM_GLOBAL_FIND_VERSION VERSION_LESS 5.83.0) set(_support_backward_compat_version_string_var TRUE) else() set(_support_backward_compat_version_string_var FALSE) endif() if(NOT EGPF_BASE_NAME) message(FATAL_ERROR "Required argument BASE_NAME missing in ECM_GENERATE_PRI_FILE() call") endif() if(NOT EGPF_LIB_NAME) message(FATAL_ERROR "Required argument LIB_NAME missing in ECM_GENERATE_PRI_FILE() call") endif() if(NOT EGPF_VERSION) if(_support_backward_compat_version_string_var) if(NOT PROJECT_VERSION_STRING AND NOT PROJECT_VERSION) message(FATAL_ERROR "Required variable PROJECT_VERSION_STRING or PROJECT_VERSION not set before ECM_GENERATE_PRI_FILE() call. Missing call of ecm_setup_version() or project(VERSION)?") endif() else() if(NOT PROJECT_VERSION) message(FATAL_ERROR "Required variable PROJECT_VERSION not set before ECM_GENERATE_PRI_FILE() call. Missing call of ecm_setup_version() or project(VERSION)?") endif() endif() endif() if(EGPF_INCLUDE_INSTALL_DIR) if(EGPF_INCLUDE_INSTALL_DIRS) message(FATAL_ERROR "Only one argument of INCLUDE_INSTALL_DIR & INCLUDE_INSTALL_DIRS can be used in ECM_GENERATE_PRI_FILE() call") endif() set(EGPF_INCLUDE_INSTALL_DIRS ${EGPF_INCLUDE_INSTALL_DIR}) endif() if(NOT EGPF_INCLUDE_INSTALL_DIRS) if(INCLUDE_INSTALL_DIR) set(EGPF_INCLUDE_INSTALL_DIRS "${INCLUDE_INSTALL_DIR}/${EGPF_BASE_NAME}") elseif(CMAKE_INSTALL_INCLUDEDIR) set(EGPF_INCLUDE_INSTALL_DIRS "${CMAKE_INSTALL_INCLUDEDIR}/${EGPF_BASE_NAME}") else() set(EGPF_INCLUDE_INSTALL_DIRS "include/${EGPF_BASE_NAME}") endif() endif() if(NOT EGPF_LIB_INSTALL_DIR) if(LIB_INSTALL_DIR) set(EGPF_LIB_INSTALL_DIR "${LIB_INSTALL_DIR}") elseif(CMAKE_INSTALL_LIBDIR) set(EGPF_LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}") else() set(EGPF_LIB_INSTALL_DIR "lib") endif() endif() if(EGPF_VERSION) set(PRI_VERSION "${EGPF_VERSION}") else() if(_support_backward_compat_version_string_var AND PROJECT_VERSION_STRING) set(PRI_VERSION "${PROJECT_VERSION_STRING}") if(NOT PROJECT_VERSION_STRING STREQUAL PROJECT_VERSION) message(DEPRECATION "ECM_GENERATE_PRI_FILE() will no longer support PROJECT_VERSION_STRING when the required minimum version of ECM is 5.83 or newer. Set VERSION parameter or use PROJECT_VERSION instead.") endif() else() set(PRI_VERSION "${PROJECT_VERSION}") endif() endif() string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" PRI_VERSION_MAJOR "${PRI_VERSION}") string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" PRI_VERSION_MINOR "${PRI_VERSION}") string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PRI_VERSION_PATCH "${PRI_VERSION}") # Prepare the right number of "../.." to go from ECM_MKSPECS_INSTALL_DIR to the install prefix # This allows to make the generated pri files relocatable (no absolute paths) if (IS_ABSOLUTE ${ECM_MKSPECS_INSTALL_DIR}) set(BASEPATH ${CMAKE_INSTALL_PREFIX}) else() string(REGEX REPLACE "[^/]+" ".." PRI_ROOT_RELATIVE_TO_MKSPECS ${ECM_MKSPECS_INSTALL_DIR}) set(BASEPATH "$$PWD/${PRI_ROOT_RELATIVE_TO_MKSPECS}") endif() set(PRI_TARGET_BASENAME ${EGPF_BASE_NAME}) set(PRI_TARGET_LIBNAME ${EGPF_LIB_NAME}) set(PRI_TARGET_QTDEPS ${EGPF_DEPS}) set(PRI_TARGET_INCLUDES) foreach(_dir ${EGPF_INCLUDE_INSTALL_DIRS}) # separate list entries with space if(IS_ABSOLUTE "${_dir}") string(APPEND PRI_TARGET_INCLUDES " ${_dir}") else() string(APPEND PRI_TARGET_INCLUDES " ${BASEPATH}/${_dir}") endif() endforeach() if(IS_ABSOLUTE "${EGPF_LIB_INSTALL_DIR}") set(PRI_TARGET_LIBS "${EGPF_LIB_INSTALL_DIR}") else() set(PRI_TARGET_LIBS "${BASEPATH}/${EGPF_LIB_INSTALL_DIR}") endif() set(PRI_TARGET_DEFINES "") set(PRI_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/qt_${PRI_TARGET_BASENAME}.pri) if (EGPF_FILENAME_VAR) set(${EGPF_FILENAME_VAR} ${PRI_FILENAME} PARENT_SCOPE) endif() set(PRI_TARGET_MODULE_CONFIG "") # backward compat: it was not obvious LIB_NAME needs to be a target name, # and some projects where the target name was not the actual library output name # passed the output name for LIB_NAME, so .name & .module prperties are correctly set. # TODO: improve API dox, allow control over module name if target name != output name if(TARGET ${EGPF_LIB_NAME}) get_target_property(target_type ${EGPF_LIB_NAME} TYPE) if (target_type STREQUAL "STATIC_LIBRARY") set(PRI_TARGET_MODULE_CONFIG "staticlib") endif() endif() if (EGPF_INTERFACE) set(PRI_TARGET_MODULE "") else() set(PRI_TARGET_MODULE "${PRI_TARGET_LIBNAME}") endif() file(GENERATE OUTPUT ${PRI_FILENAME} CONTENT "QT.${PRI_TARGET_BASENAME}.VERSION = ${PRI_VERSION} QT.${PRI_TARGET_BASENAME}.MAJOR_VERSION = ${PRI_VERSION_MAJOR} QT.${PRI_TARGET_BASENAME}.MINOR_VERSION = ${PRI_VERSION_MINOR} QT.${PRI_TARGET_BASENAME}.PATCH_VERSION = ${PRI_VERSION_PATCH} QT.${PRI_TARGET_BASENAME}.name = ${PRI_TARGET_LIBNAME} QT.${PRI_TARGET_BASENAME}.module = ${PRI_TARGET_MODULE} QT.${PRI_TARGET_BASENAME}.defines = ${PRI_TARGET_DEFINES} QT.${PRI_TARGET_BASENAME}.includes = ${PRI_TARGET_INCLUDES} QT.${PRI_TARGET_BASENAME}.private_includes = QT.${PRI_TARGET_BASENAME}.libs = ${PRI_TARGET_LIBS} QT.${PRI_TARGET_BASENAME}.depends = ${PRI_TARGET_QTDEPS} QT.${PRI_TARGET_BASENAME}.module_config = ${PRI_TARGET_MODULE_CONFIG} " ) endfunction()