From bfd89ecb8fa173b18c9a42a866b3bfd6ee4de964 Mon Sep 17 00:00:00 2001 From: Mulham Fetna Date: Sat, 22 Aug 2026 14:25:31 +0300 Subject: [PATCH] cmake: check every hb_raster_* symbol used before selecting system HarfBuzz The system-HarfBuzz probe referenced only hb_raster_draw_create_or_fail() and hb_raster_draw_render(), while modules/imgproc/src/drawing_text.cpp calls ten hb_raster_* entry points. A HarfBuzz that declares the whole hb-raster API in its header but exports only part of it passes the probe, so OpenCV links against it instead of falling back to the bundled copy, and the build then fails with undefined reference to `hb_raster_draw_destroy' Reference all ten symbols in the probe. The array is volatile because the check compiles at -O3: a plain function address is never null, so the compiler folds the test away and emits no relocations, which lets a partial library pass. Closes #29458 --- cmake/OpenCVFindHarfBuzz.cmake | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/cmake/OpenCVFindHarfBuzz.cmake b/cmake/OpenCVFindHarfBuzz.cmake index 26ec7824e4..a632c72804 100644 --- a/cmake/OpenCVFindHarfBuzz.cmake +++ b/cmake/OpenCVFindHarfBuzz.cmake @@ -37,8 +37,15 @@ if(WITH_HARFBUZZ) set(_hb_libs "${HARFBUZZ_LIBRARIES}") endif() - # Verify the header and symbol actually compile and link with the chosen + # Verify the header and symbols actually compile and link with the chosen # libraries; otherwise fall back to the bundled copy. + # Reference every hb_raster_* entry point used by + # modules/imgproc/src/drawing_text.cpp: a system HarfBuzz may declare the + # whole hb-raster API in its header while exporting only part of it, which + # passes a narrower probe and then fails at link time. The array is + # volatile so the initializers are not optimized away at -O3 (a function + # address is never null, so the compiler would otherwise fold the test + # away and emit no relocations, letting a partial library pass). ocv_clear_vars(HAVE_HARFBUZZ) set(CMAKE_REQUIRED_INCLUDES "${_hb_inc}") set(CMAKE_REQUIRED_LIBRARIES "${_hb_libs}") @@ -46,9 +53,19 @@ if(WITH_HARFBUZZ) #include #include int main() { - hb_raster_draw_t* rd = hb_raster_draw_create_or_fail(); - hb_raster_draw_render(rd); - return rd ? 0 : 1; + void (*volatile fns[])() = { + (void(*)())&hb_raster_draw_create_or_fail, + (void(*)())&hb_raster_draw_destroy, + (void(*)())&hb_raster_draw_set_scale_factor, + (void(*)())&hb_raster_draw_set_extents, + (void(*)())&hb_raster_draw_set_glyph_extents, + (void(*)())&hb_raster_draw_glyph, + (void(*)())&hb_raster_draw_render, + (void(*)())&hb_raster_draw_recycle_image, + (void(*)())&hb_raster_image_get_extents, + (void(*)())&hb_raster_image_get_buffer, + }; + return fns[0] ? 0 : 1; }" HARFBUZZ_HAS_RASTER) unset(CMAKE_REQUIRED_INCLUDES) unset(CMAKE_REQUIRED_LIBRARIES)