| 1 | # SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | # Build configuration for ibm.d.plugin which requires CGO |
| 3 | |
| 4 | include(FetchContent) |
| 5 | include(NetdataUtil) |
| 6 | |
| 7 | # add_ibm_plugin_target: Add target for building ibm.d.plugin with CGO |
| 8 | # |
| 9 | # This plugin requires CGO and IBM DB2/MQ headers for compilation. |
| 10 | # The plugin will download IBM libraries on first run. |
| 11 | macro(add_ibm_plugin_target) |
| 12 | set(IBM_MQ_DIR_NAME "ibm-mqclient") |
| 13 | set(IBM_MQ_BUILD_DIR "${CMAKE_BINARY_DIR}/${IBM_MQ_DIR_NAME}") |
| 14 | set(IBM_MQ_INSTALL_SUFFIX "lib/netdata/${IBM_MQ_DIR_NAME}") |
| 15 | |
| 16 | get_vendored_url_and_hash(ibm_mq IBM_MQ) |
| 17 | |
| 18 | FetchContent_Declare( |
| 19 | ibm_mq |
| 20 | SOURCE_DIR "${IBM_MQ_BUILD_DIR}" |
| 21 | CONFIGURE_COMMAND "${CMAKE_COMMAND} -E true" |
| 22 | BUILD_COMMAND "${CMAKE_COMMAND} -E true" |
| 23 | INSTALL_COMMAND "${CMAKE_COMMAND} -E true" |
| 24 | DOWNLOAD_NO_PROGRESS True |
| 25 | STEP_TARGETS build |
| 26 | URL ${IBM_MQ_URL} |
| 27 | URL_HASH SHA256=${IBM_MQ_HASH} |
| 28 | ) |
| 29 | |
| 30 | if(FETCHCONTENT_SOURCE_DIR_IBM_MQ) |
| 31 | message(STATUS "Copying IBM MQ client library sources from ${FETCHCONTENT_SOURCE_DIR_IBM_MQ} to ${IBM_MQ_BUILD_DIR}") |
| 32 | file(REMOVE_RECURSE "${IBM_MQ_BUILD_DIR}") |
| 33 | execute_process( |
| 34 | COMMAND ${CMAKE_COMMAND} -E copy_directory ${FETCHCONTENT_SOURCE_DIR_IBM_MQ} ${IBM_MQ_BUILD_DIR} |
| 35 | RESULT_VARIABLE IBM_MQ_COPY_STATUS |
| 36 | ) |
| 37 | |
| 38 | if(IBM_MQ_COPY_STATUS) |
| 39 | message(FATAL_ERROR "Failed to prepare IBM MQ client library directory") |
| 40 | endif() |
| 41 | FetchContent_MakeAvailable(ibm_mq) |
| 42 | else() |
| 43 | message(STATUS "Fetching IBM MQ client libraries for build") |
| 44 | FetchContent_MakeAvailable(ibm_mq) |
| 45 | endif() |
| 46 | |
| 47 | # Find all Go source files - resolve symlinks for consistent dependency tracking |
| 48 | get_filename_component(RESOLVED_SOURCE_DIR "${CMAKE_SOURCE_DIR}" REALPATH) |
| 49 | file(GLOB_RECURSE IBM_PLUGIN_DEPS CONFIGURE_DEPENDS "${RESOLVED_SOURCE_DIR}/src/go/*.go") |
| 50 | list(APPEND IBM_PLUGIN_DEPS |
| 51 | "${RESOLVED_SOURCE_DIR}/src/go/go.mod" |
| 52 | "${RESOLVED_SOURCE_DIR}/src/go/go.sum" |
| 53 | ) |
| 54 | |
| 55 | # Configure build flags for hybrid approach: |
| 56 | # - Database collectors (AS/400, DB2) use unixODBC exclusively (no IBM headers needed) |
| 57 | # - MQ collector requires IBM MQ headers and libraries |
| 58 | set(IBM_CGO_CFLAGS "") |
| 59 | set(IBM_CGO_LDFLAGS "") |
| 60 | set(IBM_RPATH_FLAGS "") |
| 61 | |
| 62 | # Add MQ support if MQ client libraries are available |
| 63 | if(EXISTS "${IBM_MQ_BUILD_DIR}/inc/cmqc.h") |
| 64 | set(IBM_CGO_CFLAGS "-I${IBM_MQ_BUILD_DIR}/inc") |
| 65 | set(IBM_CGO_LDFLAGS "-L${IBM_MQ_BUILD_DIR}/lib64 -lmqic_r") |
| 66 | set(IBM_RPATH_FLAGS "-Wl,-rpath,$ORIGIN/../../../${IBM_MQ_INSTALL_SUFFIX}/lib64") |
| 67 | set(MQ_INSTALLATION_PATH "${IBM_MQ_BUILD_DIR}") |
| 68 | else() |
| 69 | message(WARNING "IBM MQ client libraries not found - MQ PCF collector will be disabled") |
| 70 | set(MQ_INSTALLATION_PATH "") |
| 71 | endif() |
| 72 | |
| 73 | # Build with CGO enabled and multiple rpath entries for different installation methods |
| 74 | add_custom_command( |
| 75 | OUTPUT ibm.d.plugin |
| 76 | COMMAND "${CMAKE_COMMAND}" -E env |
| 77 | GOROOT=${GO_ROOT} |
| 78 | CGO_ENABLED=1 |
| 79 | CGO_CFLAGS=${IBM_CGO_CFLAGS} |
| 80 | CGO_LDFLAGS=${IBM_CGO_LDFLAGS} |
| 81 | LD_LIBRARY_PATH=${IBM_MQ_BUILD_DIR}/lib64:$LD_LIBRARY_PATH |
| 82 | MQ_INSTALLATION_PATH=${MQ_INSTALLATION_PATH} |
| 83 | GOPROXY=https://proxy.golang.org,direct |
| 84 | "${GO_EXECUTABLE}" build |
| 85 | -buildvcs=false |
| 86 | -tags "ibm_mq" |
| 87 | -ldflags "${GO_LDFLAGS} -extldflags '${IBM_RPATH_FLAGS}'" |
| 88 | -o "${CMAKE_BINARY_DIR}/ibm.d.plugin" "./cmd/ibmdplugin" |
| 89 | DEPENDS ${IBM_PLUGIN_DEPS} |
| 90 | COMMENT "Building ibm.d.plugin (with CGO)" |
| 91 | WORKING_DIRECTORY "${RESOLVED_SOURCE_DIR}/src/go" |
| 92 | VERBATIM |
| 93 | ) |
| 94 | |
| 95 | add_custom_target( |
| 96 | ibm-plugin ALL |
| 97 | DEPENDS ibm.d.plugin |
| 98 | ) |
| 99 | endmacro() |
| 100 | |
| 101 | # Install the runtime components for the IBM MQ client libraries. |
| 102 | # |
| 103 | # This generates the list of files to install by parsing the manifest |
| 104 | # file that’s included with the libraries. |
| 105 | function(install_ibm_runtime component) |
| 106 | file(READ "${IBM_MQ_BUILD_DIR}/MANIFEST.Redist" _ibm_manifest) |
| 107 | string(REPLACE "\n" ";" _ibm_manifest_lines "${_ibm_manifest}") |
| 108 | set(_files "") |
| 109 | |
| 110 | foreach(line IN LISTS _ibm_manifest_lines) |
| 111 | if("${line}" STREQUAL "" OR "${line}" MATCHES "^#") |
| 112 | continue() |
| 113 | endif() |
| 114 | |
| 115 | if(NOT "${line}" MATCHES ",(Client|Runtime|GSKit),") |
| 116 | continue() |
| 117 | endif() |
| 118 | |
| 119 | string(REPLACE "," ";" _fields "${line}") |
| 120 | |
| 121 | list(GET _fields 0 _file) |
| 122 | |
| 123 | if(NOT "${_file}" MATCHES "^samp/") |
| 124 | list(APPEND _files "${_file}") |
| 125 | endif() |
| 126 | endforeach() |
| 127 | |
| 128 | list(LENGTH _files _file_count) |
| 129 | math(EXPR _max_idx "${_file_count} - 1") |
| 130 | |
| 131 | foreach(i RANGE 0 7) |
| 132 | foreach(_idx RANGE "${i}" "${_max_idx}" 8) |
| 133 | list(GET _files "${_idx}" _file) |
| 134 | list(APPEND _files_${i} "${_file}") |
| 135 | endforeach() |
| 136 | |
| 137 | list(JOIN _files_${i} "|" _file_group_${i}) |
| 138 | endforeach() |
| 139 | |
| 140 | install(DIRECTORY ${IBM_MQ_BUILD_DIR} |
| 141 | DESTINATION usr/lib/netdata |
| 142 | COMPONENT plugin-ibm-libs |
| 143 | USE_SOURCE_PERMISSIONS |
| 144 | FILES_MATCHING REGEX "(${_file_group_0})" |
| 145 | REGEX "(${_file_group_1})" |
| 146 | REGEX "(${_file_group_2})" |
| 147 | REGEX "(${_file_group_3})" |
| 148 | REGEX "(${_file_group_4})" |
| 149 | REGEX "(${_file_group_5})" |
| 150 | REGEX "(${_file_group_6})" |
| 151 | REGEX "(${_file_group_7})") |
| 152 | endfunction() |