Warning, /frameworks/extra-cmake-modules/modules/ECMGeneratePriFile.cmake is written in an unsupported language. File is not indexed.

0001 # SPDX-FileCopyrightText: 2014 David Faure <faure@kde.org>
0002 #
0003 # SPDX-License-Identifier: BSD-3-Clause
0004 
0005 #[=======================================================================[.rst:
0006 ECMGeneratePriFile
0007 ------------------
0008 
0009 Generate a ``.pri`` file for the benefit of qmake-based projects.
0010 
0011 As well as the function below, this module creates the cache variable
0012 ``ECM_MKSPECS_INSTALL_DIR`` and sets the default value to ``mkspecs/modules``.
0013 This assumes Qt and the current project are both installed to the same
0014 non-system prefix.  Packagers who use ``-DCMAKE_INSTALL_PREFIX=/usr`` will
0015 certainly want to set ``ECM_MKSPECS_INSTALL_DIR`` to something like
0016 ``share/qt5/mkspecs/modules``.
0017 
0018 The main thing is that this should be the ``modules`` subdirectory of either
0019 the default qmake ``mkspecs`` directory or of a directory that will be in the
0020 ``$QMAKEPATH`` environment variable when qmake is run.
0021 
0022 ::
0023 
0024   ecm_generate_pri_file(BASE_NAME <baseName>
0025                         LIB_NAME <libName>
0026                         [VERSION <version>] # since 5.83
0027                         [DEPS "<dep> [<dep> [...]]"]
0028                         [FILENAME_VAR <filename_variable>]
0029                         [INCLUDE_INSTALL_DIRS <dir> [<dir> [...]]]  # since 5.92
0030                         [INCLUDE_INSTALL_DIR <dir>] # deprecated since 5.92
0031                         [LIB_INSTALL_DIR <dir>])
0032 
0033 If your CMake project produces a Qt-based library, you may expect there to be
0034 applications that wish to use it that use a qmake-based build system, rather
0035 than a CMake-based one.  Creating a ``.pri`` file will make use of your
0036 library convenient for them, in much the same way that CMake config files make
0037 things convenient for CMake-based applications. ``ecm_generate_pri_file()``
0038 generates just such a file.
0039 
0040 ``VERSION`` specifies the version of the library the ``.pri`` file describes. If
0041 not set, the value is taken from the context variable ``PROJECT_VERSION``.
0042 This variable is usually set by the ``project(... VERSION ...)`` command or,
0043 if CMake policy CMP0048 is not ``NEW``, by :module:`ECMSetupVersion`.
0044 For backward-compatibility with older ECM versions the
0045 ``PROJECT_VERSION_STRING`` variable as set by :module:`ECMSetupVersion`
0046 will be preferred over ``PROJECT_VERSION`` if set, unless the minimum
0047 required version of ECM is 5.83 and newer. Since 5.83.
0048 
0049 ``BASE_NAME`` specifies the name qmake project (.pro) files should use to refer to
0050 the library (eg: KArchive).  ``LIB_NAME`` is the name of the actual library to
0051 link to (ie: the first argument to add_library()).  ``DEPS`` is a space-separated
0052 list of the base names of other libraries (for Qt libraries, use the same
0053 names you use with the ``QT`` variable in a qmake project file, such as "core"
0054 for QtCore).  ``FILENAME_VAR`` specifies the name of a variable to store the path
0055 to the generated file in.
0056 
0057 ``INCLUDE_INSTALL_DIRS`` are the paths (relative to ``CMAKE_INSTALL_PREFIX``) that
0058 include files will be installed to. It defaults to
0059 ``${INCLUDE_INSTALL_DIR}/<baseName>`` if the ``INCLUDE_INSTALL_DIR`` variable
0060 is set. If that variable is not set, the ``CMAKE_INSTALL_INCLUDEDIR`` variable
0061 is used instead, and if neither are set ``include`` is used.  ``LIB_INSTALL_DIR``
0062 operates similarly for the installation location for libraries; it defaults to
0063 ``${LIB_INSTALL_DIR}``, ``${CMAKE_INSTALL_LIBDIR}`` or ``lib``, in that order.
0064 
0065 ``INCLUDE_INSTALL_DIR`` is the old variant of ``INCLUDE_INSTALL_DIRS``, taking only one
0066 directory.
0067 
0068 Example usage:
0069 
0070 .. code-block:: cmake
0071 
0072   ecm_generate_pri_file(
0073       BASE_NAME KArchive
0074       LIB_NAME KF5KArchive
0075       DEPS "core"
0076       FILENAME_VAR pri_filename
0077       VERSION 4.2.0
0078   )
0079   install(FILES ${pri_filename} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
0080 
0081 A qmake-based project that wished to use this would then do::
0082 
0083   QT += KArchive
0084 
0085 in their ``.pro`` file.
0086 
0087 Since pre-1.0.0.
0088 #]=======================================================================]
0089 
0090 # Replicate the logic from KDEInstallDirs.cmake as we can't depend on it
0091 # Ask qmake if we're using the same prefix as Qt
0092 set(_should_query_qt OFF)
0093 if(NOT DEFINED KDE_INSTALL_USE_QT_SYS_PATHS)
0094     include(ECMQueryQt)
0095     ecm_query_qt(qt_install_prefix_dir QT_INSTALL_PREFIX TRY)
0096     if(qt_install_prefix_dir STREQUAL "${CMAKE_INSTALL_PREFIX}")
0097         set(_should_query_qt ON)
0098     endif()
0099 endif()
0100 
0101 if(KDE_INSTALL_USE_QT_SYS_PATHS OR _should_query_qt)
0102   include(ECMQueryQt)
0103   ecm_query_qt(qt_install_prefix_dir QT_INSTALL_PREFIX)
0104   ecm_query_qt(qt_host_data_dir QT_HOST_DATA)
0105   if(qt_install_prefix_dir STREQUAL "${CMAKE_INSTALL_PREFIX}")
0106     file(RELATIVE_PATH qt_host_data_dir ${qt_install_prefix_dir} ${qt_host_data_dir})
0107   endif()
0108   if(qt_host_data_dir STREQUAL "")
0109     set(mkspecs_install_dir mkspecs/modules)
0110   else()
0111     set(mkspecs_install_dir ${qt_host_data_dir}/mkspecs/modules)
0112   endif()
0113   set(ECM_MKSPECS_INSTALL_DIR ${mkspecs_install_dir} CACHE PATH "The directory where mkspecs will be installed to.")
0114 else()
0115   set(ECM_MKSPECS_INSTALL_DIR mkspecs/modules CACHE PATH "The directory where mkspecs will be installed to.")
0116 endif()
0117 
0118 function(ECM_GENERATE_PRI_FILE)
0119   set(options )
0120   set(oneValueArgs BASE_NAME LIB_NAME DEPS FILENAME_VAR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR VERSION)
0121   set(multiValueArgs INCLUDE_INSTALL_DIRS)
0122 
0123   cmake_parse_arguments(EGPF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
0124 
0125   if(EGPF_UNPARSED_ARGUMENTS)
0126     message(FATAL_ERROR "Unknown keywords given to ECM_GENERATE_PRI_FILE(): \"${EGPF_UNPARSED_ARGUMENTS}\"")
0127   endif()
0128 
0129   if(ECM_GLOBAL_FIND_VERSION VERSION_LESS 5.83.0)
0130     set(_support_backward_compat_version_string_var TRUE)
0131   else()
0132     set(_support_backward_compat_version_string_var FALSE)
0133   endif()
0134 
0135   if(NOT EGPF_BASE_NAME)
0136     message(FATAL_ERROR "Required argument BASE_NAME missing in ECM_GENERATE_PRI_FILE() call")
0137   endif()
0138   if(NOT EGPF_LIB_NAME)
0139     message(FATAL_ERROR "Required argument LIB_NAME missing in ECM_GENERATE_PRI_FILE() call")
0140   endif()
0141   if(NOT EGPF_VERSION)
0142     if(_support_backward_compat_version_string_var)
0143       if(NOT PROJECT_VERSION_STRING AND NOT PROJECT_VERSION)
0144         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)?")
0145       endif()
0146     else()
0147       if(NOT PROJECT_VERSION)
0148         message(FATAL_ERROR "Required variable PROJECT_VERSION not set before ECM_GENERATE_PRI_FILE() call. Missing call of ecm_setup_version() or project(VERSION)?")
0149       endif()
0150     endif()
0151   endif()
0152   if(EGPF_INCLUDE_INSTALL_DIR)
0153     if(EGPF_INCLUDE_INSTALL_DIRS)
0154       message(FATAL_ERROR "Only one argument of INCLUDE_INSTALL_DIR & INCLUDE_INSTALL_DIRS can be used in ECM_GENERATE_PRI_FILE() call")
0155     endif()
0156     set(EGPF_INCLUDE_INSTALL_DIRS ${EGPF_INCLUDE_INSTALL_DIR})
0157   endif()
0158   if(NOT EGPF_INCLUDE_INSTALL_DIRS)
0159       if(INCLUDE_INSTALL_DIR)
0160           set(EGPF_INCLUDE_INSTALL_DIRS "${INCLUDE_INSTALL_DIR}/${EGPF_BASE_NAME}")
0161       elseif(CMAKE_INSTALL_INCLUDEDIR)
0162           set(EGPF_INCLUDE_INSTALL_DIRS "${CMAKE_INSTALL_INCLUDEDIR}/${EGPF_BASE_NAME}")
0163       else()
0164           set(EGPF_INCLUDE_INSTALL_DIRS "include/${EGPF_BASE_NAME}")
0165       endif()
0166   endif()
0167   if(NOT EGPF_LIB_INSTALL_DIR)
0168       if(LIB_INSTALL_DIR)
0169           set(EGPF_LIB_INSTALL_DIR "${LIB_INSTALL_DIR}")
0170       elseif(CMAKE_INSTALL_LIBDIR)
0171           set(EGPF_LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}")
0172       else()
0173           set(EGPF_LIB_INSTALL_DIR "lib")
0174       endif()
0175   endif()
0176 
0177   if(EGPF_VERSION)
0178     set(PRI_VERSION "${EGPF_VERSION}")
0179   else()
0180     if(_support_backward_compat_version_string_var AND PROJECT_VERSION_STRING)
0181       set(PRI_VERSION "${PROJECT_VERSION_STRING}")
0182       if(NOT PROJECT_VERSION_STRING STREQUAL PROJECT_VERSION)
0183         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.")
0184       endif()
0185     else()
0186       set(PRI_VERSION "${PROJECT_VERSION}")
0187     endif()
0188   endif()
0189 
0190   string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" PRI_VERSION_MAJOR "${PRI_VERSION}")
0191   string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" PRI_VERSION_MINOR "${PRI_VERSION}")
0192   string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PRI_VERSION_PATCH "${PRI_VERSION}")
0193 
0194   # Prepare the right number of "../.." to go from ECM_MKSPECS_INSTALL_DIR to the install prefix
0195   # This allows to make the generated pri files relocatable (no absolute paths)
0196   if (IS_ABSOLUTE ${ECM_MKSPECS_INSTALL_DIR})
0197      set(BASEPATH ${CMAKE_INSTALL_PREFIX})
0198   else()
0199     string(REGEX REPLACE "[^/]+" ".." PRI_ROOT_RELATIVE_TO_MKSPECS ${ECM_MKSPECS_INSTALL_DIR})
0200     set(BASEPATH "$$PWD/${PRI_ROOT_RELATIVE_TO_MKSPECS}")
0201  endif()
0202 
0203   set(PRI_TARGET_BASENAME ${EGPF_BASE_NAME})
0204   set(PRI_TARGET_LIBNAME ${EGPF_LIB_NAME})
0205   set(PRI_TARGET_QTDEPS ${EGPF_DEPS})
0206   set(PRI_TARGET_INCLUDES)
0207   foreach(_dir ${EGPF_INCLUDE_INSTALL_DIRS})
0208     # separate list entries with space
0209     if(IS_ABSOLUTE "${_dir}")
0210         string(APPEND PRI_TARGET_INCLUDES " ${_dir}")
0211     else()
0212         string(APPEND PRI_TARGET_INCLUDES " ${BASEPATH}/${_dir}")
0213     endif()
0214   endforeach()
0215   if(IS_ABSOLUTE "${EGPF_LIB_INSTALL_DIR}")
0216       set(PRI_TARGET_LIBS "${EGPF_LIB_INSTALL_DIR}")
0217   else()
0218       set(PRI_TARGET_LIBS "${BASEPATH}/${EGPF_LIB_INSTALL_DIR}")
0219   endif()
0220   set(PRI_TARGET_DEFINES "")
0221 
0222   set(PRI_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/qt_${PRI_TARGET_BASENAME}.pri)
0223   if (EGPF_FILENAME_VAR)
0224      set(${EGPF_FILENAME_VAR} ${PRI_FILENAME} PARENT_SCOPE)
0225   endif()
0226 
0227   set(PRI_TARGET_MODULE_CONFIG "")
0228   # backward compat: it was not obvious LIB_NAME needs to be a target name,
0229   # and some projects where the target name was not the actual library output name
0230   # passed the output name for LIB_NAME, so .name & .module prperties are correctly set.
0231   # TODO: improve API dox, allow control over module name if target name != output name
0232   if(TARGET ${EGPF_LIB_NAME})
0233     get_target_property(target_type ${EGPF_LIB_NAME} TYPE)
0234     if (target_type STREQUAL "STATIC_LIBRARY")
0235         set(PRI_TARGET_MODULE_CONFIG "staticlib")
0236     endif()
0237   endif()
0238 
0239   file(GENERATE
0240      OUTPUT ${PRI_FILENAME}
0241      CONTENT
0242      "QT.${PRI_TARGET_BASENAME}.VERSION = ${PRI_VERSION}
0243 QT.${PRI_TARGET_BASENAME}.MAJOR_VERSION = ${PRI_VERSION_MAJOR}
0244 QT.${PRI_TARGET_BASENAME}.MINOR_VERSION = ${PRI_VERSION_MINOR}
0245 QT.${PRI_TARGET_BASENAME}.PATCH_VERSION = ${PRI_VERSION_PATCH}
0246 QT.${PRI_TARGET_BASENAME}.name = ${PRI_TARGET_LIBNAME}
0247 QT.${PRI_TARGET_BASENAME}.module = ${PRI_TARGET_LIBNAME}
0248 QT.${PRI_TARGET_BASENAME}.defines = ${PRI_TARGET_DEFINES}
0249 QT.${PRI_TARGET_BASENAME}.includes = ${PRI_TARGET_INCLUDES}
0250 QT.${PRI_TARGET_BASENAME}.private_includes =
0251 QT.${PRI_TARGET_BASENAME}.libs = ${PRI_TARGET_LIBS}
0252 QT.${PRI_TARGET_BASENAME}.depends = ${PRI_TARGET_QTDEPS}
0253 QT.${PRI_TARGET_BASENAME}.module_config = ${PRI_TARGET_MODULE_CONFIG}
0254 "
0255   )
0256 endfunction()