InstallDependencies.cmake 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. include(GetPrerequisites)
  2. include(CMakeParseArguments)
  3. CMAKE_POLICY(SET CMP0011 NEW)
  4. CMAKE_POLICY(SET CMP0057 NEW)
  5. function(make_absolute var)
  6. get_filename_component(abs "${${var}}" ABSOLUTE BASE_DIR "${CMAKE_INSTALL_PREFIX}")
  7. set(${var} ${abs} PARENT_SCOPE)
  8. endfunction()
  9. # Reads lines of a file into a list, skipping '#' comment lines
  10. function(READ_LIST_FILE FILE VAR)
  11. file(STRINGS "${FILE}" list)
  12. set(result "")
  13. foreach(item ${list})
  14. string(STRIP "${item}" item)
  15. if(item STREQUAL "" OR item MATCHES "^\#")
  16. continue()
  17. endif()
  18. list(APPEND result "${item}")
  19. endforeach()
  20. set(${VAR} ${result} PARENT_SCOPE)
  21. endfunction()
  22. function(make_all_absolute list_var)
  23. set(result "")
  24. foreach(file ${${list_var}})
  25. make_absolute(file)
  26. list(APPEND result ${file})
  27. endforeach()
  28. set(${list_var} ${result} PARENT_SCOPE)
  29. endfunction()
  30. if(CMAKE_BINARY_DIR)
  31. set(tmp_lib_dir "${CMAKE_BINARY_DIR}/bundled-libraries")
  32. elseif(CMAKE_HOST_UNIX)
  33. set(tmp_lib_dir "/tmp/bundled-libraries")
  34. elseif(DEFINED ENV{TEMP})
  35. set(tmp_lib_dir "$ENV{TMP}/bundled-libraries")
  36. else()
  37. message(FATAL_ERROR "Can't find a temp dir for libraries")
  38. endif()
  39. # Like file(INSTALL), but resolves symlinks
  40. function(install_file_resolved file destination)
  41. get_filename_component(file_name "${file}" NAME)
  42. if(IS_SYMLINK "${file}")
  43. get_filename_component(real_path "${file}" REALPATH)
  44. get_filename_component(real_name "${real_path}" NAME)
  45. file(COPY "${real_path}" DESTINATION "${tmp_lib_dir}")
  46. file(RENAME "${tmp_lib_dir}/${real_name}" "${tmp_lib_dir}/${file_name}")
  47. set(file_path "${tmp_lib_dir}/${file_name}")
  48. else()
  49. set(file_path "${file}")
  50. endif()
  51. file(INSTALL "${file_path}" DESTINATION "${destination}")
  52. endfunction()
  53. function(install_resolved)
  54. cmake_parse_arguments("" "" "DESTINATION" "FILES" ${ARGN})
  55. foreach(file ${_FILES})
  56. install_file_resolved("${file}" "${_DESTINATION}")
  57. endforeach()
  58. endfunction()
  59. if(CMAKE_CROSSCOMPILING)
  60. # If we're cross-compiling, GetPrerequisites may not be able to find system libraries such as kernel32.dll because
  61. # they're supplied by the toolchain. To suppress thousands of lines of warnings being printed to the console, we
  62. # override gp_resolved_file_type to return "system" for any library in ${IGNORE_LIBS} without trying to resolve the
  63. # file first.
  64. # GetPrerequisites supports using an override function called gp_resolved_file_type_override, but it's not suited
  65. # for our purpose because it's only called by gp_resolved_file_type *after* trying to resolve the file.
  66. function(gp_resolved_file_type original_file file exepath dirs type_var)
  67. set(file_find "${file}")
  68. if(_IGNORE_CASE)
  69. # On case-insensitive systems, convert to upper characters to respect it
  70. string(TOUPPER "${file_find}" file_find)
  71. endif()
  72. SET(IGNORE_LIBS ${_IGNORE_LIBS} CACHE INTERNAL "Ignored library names" FORCE)
  73. if(IGNORE_LIBS AND ${file_find} IN_LIST IGNORE_LIBS)
  74. set(${type_var} system PARENT_SCOPE)
  75. else()
  76. #_gp_resolved_file_type(${ARGV})
  77. _gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "${dirs}" "${type_var}" ${ARGN})
  78. endif()
  79. endfunction()
  80. endif()
  81. function(INSTALL_DEPENDENCIES)
  82. cmake_parse_arguments("" "INCLUDE_SYSTEM;IGNORE_CASE" "GP_TOOL;DESTINATION;IGNORE_LIBS_FILE" "FILES;LIB_DIRS;SEARCH_PATHS;IGNORE_LIBS" ${ARGN})
  83. # Make paths absolute
  84. make_absolute(_DESTINATION)
  85. make_all_absolute(_FILES)
  86. make_all_absolute(_LIB_DIRS)
  87. make_all_absolute(_SEARCH_PATHS)
  88. if(_INCLUDE_SYSTEM)
  89. set(EXCLUDE_SYSTEM 0)
  90. else()
  91. set(EXCLUDE_SYSTEM 1)
  92. endif()
  93. if(_IGNORE_LIBS_FILE)
  94. READ_LIST_FILE("${_IGNORE_LIBS_FILE}" _IGNORE_LIBS)
  95. if(_IGNORE_CASE)
  96. # On case-insensitive systems, convert to upper characters to respect it
  97. string(TOUPPER "${_IGNORE_LIBS}" _IGNORE_LIBS)
  98. endif()
  99. SET(IGNORE_LIBS ${_IGNORE_LIBS} CACHE INTERNAL "Ignored library names" FORCE)
  100. endif()
  101. if(_GP_TOOL)
  102. set(gp_tool "${_GP_TOOL}")
  103. endif()
  104. set(prereqs "")
  105. foreach(file ${_FILES})
  106. get_filename_component(file_name "${file}" NAME)
  107. message("-- Finding prerequisites of ${file_name}")
  108. find_prerequisites("${file}" _prereqs
  109. ${EXCLUDE_SYSTEM} # exclude system files
  110. 1 # recurse
  111. ""
  112. "${_LIB_DIRS}"
  113. "${_SEARCH_PATHS}"
  114. "${_IGNORE_LIBS}"
  115. )
  116. list(APPEND prereqs ${_prereqs})
  117. endforeach()
  118. list(REMOVE_DUPLICATES prereqs)
  119. foreach(prereq ${prereqs})
  120. get_filename_component(prereq_name "${prereq}" NAME)
  121. foreach(rpath ${_SEARCH_PATHS})
  122. if(EXISTS "${rpath}/${prereq_name}")
  123. list(REMOVE_ITEM prereqs "${prereq}")
  124. break()
  125. endif()
  126. endforeach()
  127. endforeach()
  128. #file(INSTALL ${prereqs} DESTINATION ${_DESTINATION})
  129. install_resolved(FILES ${prereqs} DESTINATION "${_DESTINATION}")
  130. endfunction()
  131. # Like get_prerequisites, but returns full paths
  132. function(FIND_PREREQUISITES target RESULT_VAR exclude_system recurse
  133. exepath dirs rpaths)
  134. set(RESULTS)
  135. get_prerequisites("${target}" _prereqs ${exclude_system} ${recurse}
  136. "" "${dirs}" "${rpaths}")
  137. foreach(prereq ${_prereqs})
  138. get_filename_component(prereq_name "${prereq}" NAME)
  139. if(_IGNORE_CASE)
  140. # Windows is case insensitive.
  141. # Use upper characters to respect it.
  142. string(TOUPPER "${prereq_name}" prereq_name)
  143. endif()
  144. if("${prereq_name}" IN_LIST IGNORE_LIBS)
  145. continue()
  146. endif()
  147. gp_resolve_item("${LIB_DLL}" "${prereq}" "" "${dirs}" RESOLVED_PREREQ "${rpaths}")
  148. if(RESOLVED_PREREQ AND IS_ABSOLUTE ${RESOLVED_PREREQ} AND EXISTS ${RESOLVED_PREREQ})
  149. list(APPEND RESULTS ${RESOLVED_PREREQ})
  150. else()
  151. message(FATAL_ERROR "Can't resolve dependency ${prereq}.")
  152. endif()
  153. endforeach()
  154. set(${RESULT_VAR} ${RESULTS} PARENT_SCOPE)
  155. endfunction()