NetdataUtil.cmake 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. # SPDX-License-Identifier: GPL-3.0-or-later
  2. # Utility functions used by other modules.
  3. include_guard()
  4. # Fix up CMAKE_SYSTEM_PROCESSOR to actually match the build target
  5. function(netdata_fixup_system_processor)
  6. if(OS_WINDOWS)
  7. return()
  8. endif()
  9. if(CMAKE_TOOLCHAIN_FILE)
  10. return()
  11. endif()
  12. execute_process(
  13. COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -dumpmachine
  14. COMMAND cut -f 1 -d -
  15. RESULT_VARIABLE return_code
  16. OUTPUT_VARIABLE output_data
  17. )
  18. if(return_code EQUAL 0)
  19. set(CMAKE_SYSTEM_PROCESSOR "${output_data}" PARENT_SCOPE)
  20. else()
  21. message(WARNING "Failed to detect target processor architecture, using CMake default")
  22. endif()
  23. endfunction()
  24. # Determine the version of the host kernel.
  25. #
  26. # Only works on UNIX-like systems, stores the version in the cache
  27. # variable HOST_KERNEL_VERSION.
  28. function(netdata_detect_host_kernel_version)
  29. if(DEFINED HOST_KERNEL_VERSION)
  30. return()
  31. endif()
  32. message(CHECK_START "Determining host kernel version")
  33. if(NOT CMAKE_CROSSCOMPILING)
  34. include(CheckIncludeFile)
  35. check_include_file("linux/version.h" CAN_USE_VERSION_H)
  36. if(CAN_USE_VERSION_H)
  37. message(CHECK_START "Checking version using linux/version.h")
  38. file(WRITE "${CMAKE_BINARY_DIR}/kversion-test.c" "
  39. #include <stdio.h>
  40. #include <linux/version.h>
  41. int main() {
  42. printf(\"%i.%i.%i\", LINUX_VERSION_MAJOR, LINUX_VERSION_PATCHLEVEL, LINUX_VERSION_SUBLEVEL);
  43. }
  44. ")
  45. try_run(_run_success _compile_success
  46. ${CMAKE_BINARY_DIR}
  47. SOURCES ${CMAKE_BINARY_DIR}/kversion-test.c
  48. RUN_OUTPUT_VARIABLE _kversion_output)
  49. if(_compile_success AND _run_success EQUAL 0)
  50. message(CHECK_PASS "success")
  51. set(_kversion_value "${_kversion_output}")
  52. else()
  53. message(CHECK_FAIL "failed")
  54. endif()
  55. endif()
  56. endif()
  57. if(NOT DEFINED _kversion_value)
  58. message(CHECK_START "Checking version using uname")
  59. execute_process(COMMAND uname -r
  60. RESULT_VARIABLE _uname_result
  61. OUTPUT_VARIABLE _uname_output)
  62. if(NOT _uname_result EQUAL 0)
  63. message(CHECK_FAIL "failed")
  64. message(CHECK_FAIL "unknown")
  65. set(HOST_KERNEL_VERSION "0.0.0" CACHE STRING "Detected host kernel version")
  66. return()
  67. else()
  68. message(CHECK_PASS "success")
  69. endif()
  70. set(_kversion_value "${_uname_output}")
  71. endif()
  72. string(REGEX REPLACE "-.+$" "" _kversion "${_kversion_value}")
  73. message(CHECK_PASS "${_kversion}")
  74. set(HOST_KERNEL_VERSION "${_kversion}" CACHE STRING "Detected host kernel version")
  75. endfunction()
  76. # Check what libc we're using.
  77. #
  78. # Sets the specified variable to the name of the libc or "unknown"
  79. function(netdata_identify_libc _libc_name)
  80. if(NOT DEFINED _ND_DETECTED_LIBC)
  81. message(CHECK_START "Detecting libc implementation using ldd")
  82. execute_process(COMMAND ldd --version
  83. COMMAND grep -q -i -E "glibc|gnu libc"
  84. RESULT_VARIABLE LDD_RESULT
  85. OUTPUT_VARIABLE LDD_OUTPUT
  86. ERROR_VARIABLE LDD_OUTPUT)
  87. if(NOT LDD_RESULT)
  88. set(${_libc_name} glibc PARENT_SCOPE)
  89. set(_ND_DETECTED_LIBC glibc CACHE INTERNAL "")
  90. message(CHECK_PASS "glibc")
  91. return()
  92. endif()
  93. execute_process(COMMAND sh -c "ldd --version 2>&1 | grep -q -i 'musl'"
  94. RESULT_VARIABLE LDD_RESULT
  95. OUTPUT_VARIABLE LDD_OUTPUT
  96. ERROR_VARIABLE LDD_OUTPUT)
  97. if(NOT LDD_RESULT)
  98. set(${_libc_name} musl PARENT_SCOPE)
  99. set(_ND_DETECTED_LIBC musl CACHE INTERNAL "")
  100. message(CHECK_PASS "musl")
  101. return()
  102. endif()
  103. message(CHECK_FAIL "unknown")
  104. message(CHECK_START "Looking for libc.so.6")
  105. find_program(LIBC_PATH libc.so.6
  106. PATHS /lib /lib64 /usr/lib /usr/lib64
  107. NO_DEFAULT_PATH
  108. NO_PACKAGE_ROOT_PATH
  109. NO_CMAKE_PATH
  110. NO_CMAKE_ENVIRONMENT_PATH
  111. NO_SYSTEM_ENVIRONMENT_PATH
  112. NO_CMAKE_SYSTEM_PATH
  113. NO_CMAKE_INSTALL_PREFIX
  114. NO_CMAKE_FIND_ROOT_PATH)
  115. if(NOT "${LIBC_PATH}" EQUAL "LIBC_PATH-NOTFOUND")
  116. message(CHECK_PASS "found")
  117. message(CHECK_START "Detecting libc implementation using libc.so.6")
  118. execute_process(COMMAND "${LIBC_PATH}"
  119. COMMAND head -n 1
  120. COMMAND grep -q -i -E "gnu libc|gnu c library"
  121. RESULT_VARIABLE LIBC_RESULT
  122. OUTPUT_VARIABLE LIBC_OUTPUT
  123. ERROR_VARIABLE LIBC_ERROR)
  124. if(NOT LIBC_RESULT)
  125. set(${_libc_name} glibc PARENT_SCOPE)
  126. set(_ND_DETECTED_LIBC glibc CACHE INTERNAL "")
  127. message(CHECK_PASS "glibc")
  128. return()
  129. else()
  130. message(CHECK_FAIL "unknown")
  131. endif()
  132. else()
  133. message(CHECK_FAIL "not found")
  134. endif()
  135. set(${_libc_name} unknown PARENT_SCOPE)
  136. set(_ND_DETECTED_LIBC unknown CACHE INTERNAL "")
  137. else()
  138. set(${_libc_name} ${_ND_DETECTED_LIBC} PARENT_SCOPE)
  139. endif()
  140. endfunction()
  141. # Extract a tar archive.
  142. #
  143. # This will use CMake’s native support if available, but will still
  144. # fall back cleanly if CMake is too old.
  145. function(extract_gzipped_tarball tarball target)
  146. if(CMAKE_VERSION VERSION_LESS 3.18)
  147. find_program(TAR NAMES tar bsdtar DOC "TAR archive program")
  148. if(TAR STREQUAL "TAR-NOTFOUND")
  149. message(FATAL_ERROR "Unable to find tar command")
  150. endif()
  151. find_program(GZIP NAMES gzip DOC "GZIP compression program")
  152. if(GZIP STREQUAL "GZIP-NOTFOUND")
  153. message(FATAL_ERROR "Unable to find gzip command")
  154. endif()
  155. file(MAKE_DIRECTORY "${target}")
  156. execute_process(COMMAND tar -x -z -f "${tarball}" -C "${target}"
  157. RESULT_VARIABLE result)
  158. if(result)
  159. message(FATAL_ERROR "Failed to extract ${tarball}")
  160. endif()
  161. else()
  162. file(ARCHIVE_EXTRACT
  163. INPUT "${tarball}"
  164. DESTINATION "${target}")
  165. endif()
  166. endfunction()
  167. # Get a recursive list of all sub-directories of the specified directory,
  168. # relative to that directory.
  169. function(subdirlist result curdir)
  170. file(GLOB_RECURSE children
  171. LIST_DIRECTORIES TRUE
  172. RELATIVE ${curdir}
  173. ${curdir}/*)
  174. set(dirlist "")
  175. foreach(child ${children})
  176. if(IS_DIRECTORY ${curdir}/${child})
  177. list(APPEND dirlist ${child})
  178. endif()
  179. endforeach()
  180. set(${result} ${dirlist} PARENT_SCOPE)
  181. endfunction()
  182. # Precompile python code in the specified directory relative to the
  183. # CMake install prefix at install time.
  184. # This must be called _after_ the install directive for the python code
  185. # in the specified directory
  186. function(precompile_python dir component)
  187. find_package(Python3)
  188. if(NOT ${Python3_Interpreter_FOUND})
  189. message(STATUS "Could not find Python3, skipping precompilation of Python code.")
  190. return()
  191. endif()
  192. set(prefix [=[${CMAKE_INSTALL_PREFIX}]=])
  193. install(
  194. CODE "message(STATUS \"Precompiling Python3 code in ${prefix}/${dir}\")"
  195. COMPONENT ${component}
  196. )
  197. install(
  198. CODE "execute_process(COMMAND ${Python3_Interpreter} -O -m compileall -j0 -o2 ${prefix}/${dir} WORKING_DIRECTORY ${prefix}/${dir})"
  199. COMPONENT ${component}
  200. )
  201. endfunction()