Filesystem.cmake 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. include_guard(DIRECTORY)
  2. if(NOT QMSETUP_MODULES_DIR)
  3. get_filename_component(QMSETUP_MODULES_DIR ${CMAKE_CURRENT_LIST_DIR} DIRECTORY)
  4. endif()
  5. #[[
  6. Initialize the build output directories of targets and resources.
  7. qm_init_directories()
  8. ]] #
  9. macro(qm_init_directories)
  10. if(NOT DEFINED QMSETUP_BUILD_DIR)
  11. set(QMSETUP_BUILD_DIR "${CMAKE_BINARY_DIR}/out-$<LOWER_CASE:${CMAKE_SYSTEM_PROCESSOR}>-$<CONFIG>")
  12. endif()
  13. if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
  14. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QMSETUP_BUILD_DIR}/bin)
  15. endif()
  16. if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
  17. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${QMSETUP_BUILD_DIR}/lib)
  18. endif()
  19. if(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
  20. set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${QMSETUP_BUILD_DIR}/lib)
  21. endif()
  22. if(NOT DEFINED CMAKE_BUILD_SHARE_DIR)
  23. set(CMAKE_BUILD_SHARE_DIR ${QMSETUP_BUILD_DIR}/share)
  24. endif()
  25. endmacro()
  26. #[[
  27. Add a resources copying command for whole project.
  28. qm_add_copy_command(<target>
  29. [CUSTOM_TARGET <target>]
  30. [EXTRA_ARGS <args...>]
  31. [DEPENDS <targets...>]
  32. [VERBOSE] [SKIP_BUILD] [SKIP_INSTALL]
  33. SOURCES <file/dir...> [DESTINATION <dir>] [INSTALL_DIR <dir>]
  34. )
  35. CUSTOM_TARGET: Use a custom target to control the copy command
  36. EXTRA_ARGS: Extra arguments to pass to file(INSTALL) statement
  37. DEPENDS: Targets that the copy command depends
  38. SOURCES: Source files or directories, directories ending with "/" will have their contents copied
  39. DESTINATION: Copy the source file to the destination path. If the given value is a relative path,
  40. the base directory depends on the type of the target
  41. - `$<TARGET_FILE_DIR>`: real target
  42. - `QMSETUP_BUILD_DIR`: custom target
  43. INSTALL_DIR: Install the source files into a subdirectory in the given path. The subdirectory is the
  44. relative path from the `QMSETUP_BUILD_DIR` to `DESTINATION`.
  45. ]] #
  46. function(qm_add_copy_command _target)
  47. set(options VERBOSE SKIP_BUILD SKIP_INSTALL)
  48. set(oneValueArgs CUSTOM_TARGET DESTINATION INSTALL_DIR)
  49. set(multiValueArgs SOURCES EXTRA_ARGS DEPENDS)
  50. cmake_parse_arguments(FUNC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  51. if(NOT FUNC_SOURCES)
  52. message(FATAL_ERROR "qm_add_copy_command: SOURCES not specified.")
  53. endif()
  54. if(NOT TARGET ${_target})
  55. add_custom_target(${_target})
  56. endif()
  57. # Determine destination
  58. set(_dest .)
  59. if(FUNC_DESTINATION)
  60. set(_dest ${FUNC_DESTINATION})
  61. endif()
  62. # Determine destination base directory
  63. get_target_property(_type ${_target} TYPE)
  64. if(_type STREQUAL "UTILITY")
  65. if(QMSETUP_BUILD_DIR)
  66. set(_dest_base ${QMSETUP_BUILD_DIR})
  67. else()
  68. set(_dest_base ${CMAKE_CURRENT_SOURCE_DIR})
  69. endif()
  70. else()
  71. set(_dest_base "$<TARGET_FILE_DIR:${_target}>")
  72. endif()
  73. # Set deploy target
  74. if(FUNC_CUSTOM_TARGET)
  75. set(_deploy_target ${FUNC_CUSTOM_TARGET})
  76. if(NOT TARGET ${_deploy_target})
  77. add_custom_target(${_deploy_target})
  78. endif()
  79. else()
  80. set(_deploy_target ${_target})
  81. endif()
  82. if(FUNC_DEPENDS)
  83. add_dependencies(${_deploy_target} ${FUNC_DEPENDS})
  84. endif()
  85. # Prepare arguments
  86. set(_extra_args)
  87. set(_ignore_stdout)
  88. if(FUNC_EXTRA_ARGS)
  89. list(APPEND _extra_args -D "args=${FUNC_EXTRA_ARGS}")
  90. endif()
  91. if(NOT FUNC_VERBOSE)
  92. set(_ignore_stdout ${QMSETUP_IGNORE_STDOUT})
  93. endif()
  94. if(NOT FUNC_SKIP_BUILD)
  95. # Build phase
  96. add_custom_command(TARGET ${_deploy_target} POST_BUILD
  97. COMMAND ${CMAKE_COMMAND}
  98. -D "src=${FUNC_SOURCES}"
  99. -D "dest=${_dest}"
  100. -D "dest_base=${_dest_base}"
  101. ${_extra_args}
  102. -P "${QMSETUP_MODULES_DIR}/scripts/copy.cmake" ${_ignore_stdout}
  103. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  104. VERBATIM
  105. )
  106. endif()
  107. if(FUNC_INSTALL_DIR AND NOT FUNC_SKIP_INSTALL)
  108. if(NOT QMSETUP_BUILD_DIR)
  109. message(FATAL_ERROR "qm_add_copy_command: `QMSETUP_BUILD_DIR` not defined, the install directory cannot be determined.")
  110. endif()
  111. # Install phase
  112. install(CODE "
  113. set(_src \"${FUNC_SOURCES}\")
  114. set(_extra_args \"${FUNC_EXTRA_ARGS}\")
  115. # Calculate the relative path from build phase destination to build directory
  116. get_filename_component(_build_dir \"${_dest}\" ABSOLUTE BASE_DIR \"${_dest_base}\")
  117. file(RELATIVE_PATH _rel_path \"${QMSETUP_BUILD_DIR}\" \${_build_dir})
  118. # Calculate real install directory
  119. get_filename_component(_dest \"${FUNC_INSTALL_DIR}/\${_rel_path}\" ABSOLUTE BASE_DIR \${CMAKE_INSTALL_PREFIX})
  120. execute_process(
  121. COMMAND \${CMAKE_COMMAND}
  122. -D \"src=\${_src}\"
  123. -D \"dest=\${_dest}\"
  124. \${_extra_args}
  125. -P \"${QMSETUP_MODULES_DIR}/scripts/copy.cmake\"
  126. WORKING_DIRECTORY \"${CMAKE_CURRENT_SOURCE_DIR}\"
  127. )
  128. ")
  129. endif()
  130. endfunction()
  131. #[[
  132. Add a custom command to run `configure_file`.
  133. qm_future_configure_file(<_input> <output>
  134. [FORCE]
  135. [EXTRA_ARGS <args...>]
  136. [DEPENDS <deps...>]
  137. [VARIABLES <var...>]
  138. )
  139. ]] #
  140. function(qm_future_configure_file _input _output)
  141. set(options FORCE)
  142. set(oneValueArgs)
  143. set(multiValueArgs VARIABLES EXTRA_ARGS DEPENDS)
  144. cmake_parse_arguments(FUNC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  145. set(_options)
  146. foreach(_item IN LISTS FUNC_VARIABLES)
  147. list(APPEND _options -D "${_item}=${${_item}}")
  148. endforeach()
  149. if(FUNC_FORCE)
  150. list(APPLE _options -D "force=TRUE")
  151. endif()
  152. add_custom_command(OUTPUT ${_output}
  153. COMMAND ${CMAKE_COMMAND}
  154. -D "input=${_input}"
  155. -D "output=${_output}"
  156. -D "args=${FUNC_EXTRA_ARGS}"
  157. ${_options}
  158. -P "${QMSETUP_MODULES_DIR}/scripts/configure_file.cmake"
  159. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  160. DEPENDS ${FUNC_DEPENDS}
  161. VERBATIM
  162. )
  163. endfunction()