ECMGeneratePriFile.cmake 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #.rst:
  2. # ECMGeneratePriFile
  3. # ------------------
  4. #
  5. # Generate a ``.pri`` file for the benefit of qmake-based projects.
  6. #
  7. # As well as the function below, this module creates the cache variable
  8. # ``ECM_MKSPECS_INSTALL_DIR`` and sets the default value to ``mkspecs/modules``.
  9. # This assumes Qt and the current project are both installed to the same
  10. # non-system prefix. Packagers who use ``-DCMAKE_INSTALL_PREFIX=/usr`` will
  11. # certainly want to set ``ECM_MKSPECS_INSTALL_DIR`` to something like
  12. # ``share/qt5/mkspecs/modules``.
  13. #
  14. # The main thing is that this should be the ``modules`` subdirectory of either
  15. # the default qmake ``mkspecs`` directory or of a directory that will be in the
  16. # ``$QMAKEPATH`` environment variable when qmake is run.
  17. #
  18. # ::
  19. #
  20. # ecm_generate_pri_file(BASE_NAME <baseName>
  21. # LIB_NAME <libName>
  22. # [DEPS "<dep> [<dep> [...]]"]
  23. # [FILENAME_VAR <filename_variable>]
  24. # [INCLUDE_INSTALL_DIR <dir>]
  25. # [LIB_INSTALL_DIR <dir>])
  26. #
  27. # If your CMake project produces a Qt-based library, you may expect there to be
  28. # applications that wish to use it that use a qmake-based build system, rather
  29. # than a CMake-based one. Creating a ``.pri`` file will make use of your
  30. # library convenient for them, in much the same way that CMake config files make
  31. # things convenient for CMake-based applications.
  32. #
  33. # ecm_generate_pri_file() generates just such a file. It requires the
  34. # ``PROJECT_VERSION_STRING`` variable to be set. This is typically set by
  35. # :module:`ECMSetupVersion`, although the project() command in CMake 3.0.0 and
  36. # later can also set this.
  37. #
  38. # BASE_NAME specifies the name qmake project (.pro) files should use to refer to
  39. # the library (eg: KArchive). LIB_NAME is the name of the actual library to
  40. # link to (ie: the first argument to add_library()). DEPS is a space-separated
  41. # list of the base names of other libraries (for Qt libraries, use the same
  42. # names you use with the ``QT`` variable in a qmake project file, such as "core"
  43. # for QtCore). FILENAME_VAR specifies the name of a variable to store the path
  44. # to the generated file in.
  45. #
  46. # INCLUDE_INSTALL_DIR is the path (relative to ``CMAKE_INSTALL_PREFIX``) that
  47. # include files will be installed to. It defaults to
  48. # ``${INCLUDE_INSTALL_DIR}/<baseName>`` if the ``INCLUDE_INSTALL_DIR`` variable
  49. # is set. If that variable is not set, the ``CMAKE_INSTALL_INCLUDEDIR`` variable
  50. # is used instead, and if neither are set ``include`` is used. LIB_INSTALL_DIR
  51. # operates similarly for the installation location for libraries; it defaults to
  52. # ``${LIB_INSTALL_DIR}``, ``${CMAKE_INSTALL_LIBDIR}`` or ``lib``, in that order.
  53. #
  54. # Example usage:
  55. #
  56. # .. code-block:: cmake
  57. #
  58. # ecm_generate_pri_file(
  59. # BASE_NAME KArchive
  60. # LIB_NAME KF5KArchive
  61. # DEPS "core"
  62. # FILENAME_VAR pri_filename
  63. # )
  64. # install(FILES ${pri_filename} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
  65. #
  66. # A qmake-based project that wished to use this would then do::
  67. #
  68. # QT += KArchive
  69. #
  70. # in their ``.pro`` file.
  71. #
  72. # Since pre-1.0.0.
  73. #=============================================================================
  74. # SPDX-FileCopyrightText: 2014 David Faure <faure@kde.org>
  75. #
  76. # SPDX-License-Identifier: BSD-3-Clause
  77. # Replicate the logic from KDEInstallDirs.cmake as we can't depend on it
  78. # Ask qmake if we're using the same prefix as Qt
  79. set(_askqmake OFF)
  80. if(NOT DEFINED KDE_INSTALL_USE_QT_SYS_PATHS)
  81. include(ECMQueryQmake)
  82. query_qmake(qt_install_prefix_dir QT_INSTALL_PREFIX TRY)
  83. if(qt_install_prefix_dir STREQUAL "${CMAKE_INSTALL_PREFIX}")
  84. set(_askqmake ON)
  85. endif()
  86. endif()
  87. if(KDE_INSTALL_USE_QT_SYS_PATHS OR _askqmake)
  88. include(ECMQueryQmake)
  89. query_qmake(qt_host_data_dir QT_HOST_DATA)
  90. set(ECM_MKSPECS_INSTALL_DIR ${qt_host_data_dir}/mkspecs/modules CACHE PATH "The directory where mkspecs will be installed to.")
  91. else()
  92. set(ECM_MKSPECS_INSTALL_DIR mkspecs/modules CACHE PATH "The directory where mkspecs will be installed to.")
  93. endif()
  94. function(ECM_GENERATE_PRI_FILE)
  95. set(options )
  96. set(oneValueArgs BASE_NAME LIB_NAME DEPS FILENAME_VAR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
  97. set(multiValueArgs )
  98. cmake_parse_arguments(EGPF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  99. if(EGPF_UNPARSED_ARGUMENTS)
  100. message(FATAL_ERROR "Unknown keywords given to ECM_GENERATE_PRI_FILE(): \"${EGPF_UNPARSED_ARGUMENTS}\"")
  101. endif()
  102. if(NOT EGPF_BASE_NAME)
  103. message(FATAL_ERROR "Required argument BASE_NAME missing in ECM_GENERATE_PRI_FILE() call")
  104. endif()
  105. if(NOT EGPF_LIB_NAME)
  106. message(FATAL_ERROR "Required argument LIB_NAME missing in ECM_GENERATE_PRI_FILE() call")
  107. endif()
  108. if(NOT PROJECT_VERSION_STRING)
  109. message(FATAL_ERROR "Required variable PROJECT_VERSION_STRING not set before ECM_GENERATE_PRI_FILE() call. Did you call ecm_setup_version?")
  110. endif()
  111. if(NOT EGPF_INCLUDE_INSTALL_DIR)
  112. if(INCLUDE_INSTALL_DIR)
  113. set(EGPF_INCLUDE_INSTALL_DIR "${INCLUDE_INSTALL_DIR}/${EGPF_BASE_NAME}")
  114. elseif(CMAKE_INSTALL_INCLUDEDIR)
  115. set(EGPF_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}/${EGPF_BASE_NAME}")
  116. else()
  117. set(EGPF_INCLUDE_INSTALL_DIR "include/${EGPF_BASE_NAME}")
  118. endif()
  119. endif()
  120. if(NOT EGPF_LIB_INSTALL_DIR)
  121. if(LIB_INSTALL_DIR)
  122. set(EGPF_LIB_INSTALL_DIR "${LIB_INSTALL_DIR}")
  123. elseif(CMAKE_INSTALL_LIBDIR)
  124. set(EGPF_LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}")
  125. else()
  126. set(EGPF_LIB_INSTALL_DIR "lib")
  127. endif()
  128. endif()
  129. string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" PROJECT_VERSION_MAJOR "${PROJECT_VERSION_STRING}")
  130. string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" PROJECT_VERSION_MINOR "${PROJECT_VERSION_STRING}")
  131. string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PROJECT_VERSION_PATCH "${PROJECT_VERSION_STRING}")
  132. # Prepare the right number of "../.." to go from ECM_MKSPECS_INSTALL_DIR to the install prefix
  133. # This allows to make the generated pri files relocatable (no absolute paths)
  134. if (IS_ABSOLUTE ${ECM_MKSPECS_INSTALL_DIR})
  135. set(BASEPATH ${CMAKE_INSTALL_PREFIX})
  136. else()
  137. string(REGEX REPLACE "[^/]+" ".." PRI_ROOT_RELATIVE_TO_MKSPECS ${ECM_MKSPECS_INSTALL_DIR})
  138. set(BASEPATH "$$PWD/${PRI_ROOT_RELATIVE_TO_MKSPECS}")
  139. endif()
  140. set(PRI_TARGET_BASENAME ${EGPF_BASE_NAME})
  141. set(PRI_TARGET_LIBNAME ${EGPF_LIB_NAME})
  142. set(PRI_TARGET_QTDEPS ${EGPF_DEPS})
  143. if(IS_ABSOLUTE "${EGPF_INCLUDE_INSTALL_DIR}")
  144. set(PRI_TARGET_INCLUDES "${EGPF_INCLUDE_INSTALL_DIR}")
  145. else()
  146. set(PRI_TARGET_INCLUDES "${BASEPATH}/${EGPF_INCLUDE_INSTALL_DIR}")
  147. endif()
  148. if(IS_ABSOLUTE "${EGPF_LIB_INSTALL_DIR}")
  149. set(PRI_TARGET_LIBS "${EGPF_LIB_INSTALL_DIR}")
  150. else()
  151. set(PRI_TARGET_LIBS "${BASEPATH}/${EGPF_LIB_INSTALL_DIR}")
  152. endif()
  153. set(PRI_TARGET_DEFINES "")
  154. set(PRI_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/qt_${PRI_TARGET_BASENAME}.pri)
  155. if (EGPF_FILENAME_VAR)
  156. set(${EGPF_FILENAME_VAR} ${PRI_FILENAME} PARENT_SCOPE)
  157. endif()
  158. set(PRI_TARGET_MODULE_CONFIG "")
  159. # backward compat: it was not obvious LIB_NAME needs to be a target name,
  160. # and some projects where the target name was not the actual library output name
  161. # passed the output name for LIB_NAME, so .name & .module prperties are correctly set.
  162. # TODO: improve API dox, allow control over module name if target name != output name
  163. if(TARGET ${EGPF_LIB_NAME})
  164. get_target_property(target_type ${EGPF_LIB_NAME} TYPE)
  165. if (target_type STREQUAL "STATIC_LIBRARY")
  166. set(PRI_TARGET_MODULE_CONFIG "staticlib")
  167. endif()
  168. endif()
  169. file(GENERATE
  170. OUTPUT ${PRI_FILENAME}
  171. CONTENT
  172. "QT.${PRI_TARGET_BASENAME}.VERSION = ${PROJECT_VERSION_STRING}
  173. QT.${PRI_TARGET_BASENAME}.MAJOR_VERSION = ${PROJECT_VERSION_MAJOR}
  174. QT.${PRI_TARGET_BASENAME}.MINOR_VERSION = ${PROJECT_VERSION_MINOR}
  175. QT.${PRI_TARGET_BASENAME}.PATCH_VERSION = ${PROJECT_VERSION_PATCH}
  176. QT.${PRI_TARGET_BASENAME}.name = ${PRI_TARGET_LIBNAME}
  177. QT.${PRI_TARGET_BASENAME}.module = ${PRI_TARGET_LIBNAME}
  178. QT.${PRI_TARGET_BASENAME}.defines = ${PRI_TARGET_DEFINES}
  179. QT.${PRI_TARGET_BASENAME}.includes = ${PRI_TARGET_INCLUDES}
  180. QT.${PRI_TARGET_BASENAME}.private_includes =
  181. QT.${PRI_TARGET_BASENAME}.libs = ${PRI_TARGET_LIBS}
  182. QT.${PRI_TARGET_BASENAME}.depends = ${PRI_TARGET_QTDEPS}
  183. QT.${PRI_TARGET_BASENAME}.module_config = ${PRI_TARGET_MODULE_CONFIG}
  184. "
  185. )
  186. endfunction()