NetdataLibBPF.cmake 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. # Handling for libbpf (used by the eBPF plugin)
  2. #
  3. # Copyright (c) 2024 Netdata Inc.
  4. # SPDX-License-Identifier: GPL-3.0-or-later
  5. include(ExternalProject)
  6. include(NetdataUtil)
  7. set(libbpf_SOURCE_DIR "${CMAKE_BINARY_DIR}/libbpf")
  8. # Check what libc we're using.
  9. #
  10. # Sets the specified variable to the name of the libc or "unknown"
  11. function(netdata_identify_libc _libc_name)
  12. message(INFO "Detecting libc implementation")
  13. execute_process(COMMAND ldd --version
  14. COMMAND grep -q -i -E "glibc|gnu libc"
  15. RESULT_VARIABLE LDD_IS_GLIBC
  16. OUTPUT_VARIABLE LDD_OUTPUT
  17. ERROR_VARIABLE LDD_OUTPUT)
  18. if(LDD_IS_GLIBC)
  19. set(${_libc_name} glibc PARENT_SCOPE)
  20. return()
  21. endif()
  22. execute_process(COMMAND ldd --version
  23. COMMAND grep -q -i -E "musl"
  24. RESULT_VARIABLE LDD_IS_MUSL
  25. OUTPUT_VARIABLE LDD_OUTPUT
  26. ERROR_VARIABLE LDD_OUTPUT)
  27. if(LDD_IS_MUSL)
  28. set(${_libc_name} musl PARENT_SCOPE)
  29. return()
  30. endif()
  31. set(${_libc_name} unknown PARENT_SCOPE)
  32. endfunction()
  33. # Check if the kernel is old enough that we need to use a legacy copy of eBPF.
  34. function(_need_legacy_libbpf _var)
  35. if(FORCE_LEGACY_LIBBPF)
  36. set(${_var} TRUE PARENT_SCOPE)
  37. return()
  38. endif()
  39. netdata_detect_host_kernel_version()
  40. if(HOST_KERNEL_VERSION VERSION_LESS "4.14.0")
  41. set(${_var} TRUE PARENT_SCOPE)
  42. else()
  43. set(${_var} FALSE PARENT_SCOPE)
  44. endif()
  45. endfunction()
  46. # Prepare a vendored copy of libbpf
  47. function(netdata_bundle_libbpf)
  48. _need_legacy_libbpf(USE_LEGACY_LIBBPF)
  49. if(USE_LEGACY_LIBBPF)
  50. set(_libbpf_tag 673424c56127bb556e64095f41fd60c26f9083ec) # v0.0.9_netdata-1
  51. else()
  52. set(_libbpf_tag b981a3a138e3a30024e4e143d62cff2dc307121e) # v1.4.0p_netdata
  53. endif()
  54. netdata_identify_libc(_libc)
  55. string(REGEX MATCH "glibc|musl" _libc_supported "${_libc}")
  56. if(NOT _libc_supported)
  57. message(FATAL_ERROR "This system’s libc (detected: ${_libc}) is not not supported by the eBPF plugin.")
  58. endif()
  59. find_program(MAKE_COMMAND make)
  60. if(MAKE_COMMAND STREQUAL MAKE_COMMAND-NOTFOUND)
  61. message(FATAL_ERROR "GNU Make is required when building the eBPF plugin, but could not be found.")
  62. endif()
  63. pkg_check_modules(ELF REQUIRED libelf)
  64. pkg_check_modules(ZLIB REQUIRED zlib)
  65. set(_libbpf_lib_dir lib)
  66. if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
  67. set(_libbpf_lib_dir lib64)
  68. endif()
  69. set(_libbpf_library "${libbpf_SOURCE_DIR}/usr/${_libbpf_lib_dir}/libbpf.a")
  70. ExternalProject_Add(
  71. libbpf
  72. GIT_REPOSITORY https://github.com/netdata/libbpf.git
  73. GIT_TAG ${_libbpf_tag}
  74. SOURCE_DIR "${libbpf_SOURCE_DIR}"
  75. CONFIGURE_COMMAND ""
  76. BUILD_COMMAND ${MAKE_COMMAND} -C src BUILD_STATIC_ONLY=1 OBJDIR=build/ DESTDIR=../ install
  77. BUILD_IN_SOURCE 1
  78. BUILD_BYPRODUCTS "${_libbpf_library}"
  79. INSTALL_COMMAND ""
  80. EXCLUDE_FROM_ALL 1
  81. )
  82. add_library(libbpf_library STATIC IMPORTED GLOBAL)
  83. set_property(
  84. TARGET libbpf_library
  85. PROPERTY IMPORTED_LOCATION "${_libbpf_library}"
  86. )
  87. set_property(
  88. TARGET libbpf_library
  89. PROPERTY INTERFACE_LINK_LIBRARIES "${ELF_LIBRARIES};${ZLIB_LIBRARIES}"
  90. )
  91. set(NETDATA_LIBBPF_INCLUDE_DIRECTORIES "${libbpf_SOURCE_DIR}/usr/include;${libbpf_SOURCE_DIR}/include;${ELF_INCLUDE_DIRECTORIES};${ZLIB_INCLUDE_DIRECTORIES}" PARENT_SCOPE)
  92. set(NETDATA_LIBBPF_COMPILE_DEFINITIONS "${ELF_CFLAGS_OTHER};${ZLIB_CFLAGS_OTHER}" PARENT_SCOPE)
  93. endfunction()
  94. # Add libbpf as a link dependency for the given target.
  95. function(netdata_add_libbpf_to_target _target)
  96. target_link_libraries(${_target} PUBLIC libbpf_library)
  97. target_include_directories(${_target} BEFORE PUBLIC "${NETDATA_LIBBPF_INCLUDE_DIRECTORIES}")
  98. target_compile_definitions(${_target} PUBLIC "${NETDATA_LIBBPF_COMPILE_DEFINITIONS}")
  99. add_dependencies(${_target} libbpf)
  100. endfunction()