imgui_bundle icon indicating copy to clipboard operation
imgui_bundle copied to clipboard

_BrotliDecoderDecompress missing on macOS 14.5 intel

Open virtuald opened this issue 1 year ago • 3 comments

ImportError: dlopen(... site-packages/imgui_bundle/_imgui_bundle.cpython-312-darwin.so, 0x0002): symbol not found in flat namespace '_BrotliDecoderDecompress'

Works fine on my M3 mac, but not on the intel mac. Any thoughts on what's missing?

virtuald avatar Oct 03 '24 19:10 virtuald

freetype is used by imgui to improve font rendering. And freetype uses Brotli.

You might try to compile from source and comment out those lines: https://github.com/pthom/imgui_bundle/blob/f8db311b9c0828330e6b277238243ae3ccb8db76/CMakeLists.txt#L167-L168

pthom avatar Oct 03 '24 20:10 pthom

Hm. But isn't all of that in the wheel? Or is it expecting something to be installed at runtime (maybe via brew?)

virtuald avatar Oct 03 '24 21:10 virtuald

Ok, so https://files.pythonhosted.org/packages/29/1b/155fb7bc2605e2e8d8134befa48870f24252d0010931b429c0a45116195e/imgui_bundle-1.5.2-cp312-cp312-macosx_14_0_x86_64.whl does not have .dylibs, but https://files.pythonhosted.org/packages/87/f7/e0c7f1461743fee24373156aa134f6822881bab6794807992b32916dbaa3/imgui_bundle-1.5.2-cp312-cp312-macosx_14_0_arm64.whl does. So it's something about the build?

virtuald avatar Oct 03 '24 22:10 virtuald

Hi Dustin,

Building Python libraries with native linked libraries is always complex. Below is an analysis of what I see.

Main CMakeLists:

in the main CMakeLists of imgui_bundle, we call ibd_force_freetype_static_for_python()

https://github.com/pthom/imgui_bundle/blob/f8db311b9c0828330e6b277238243ae3ccb8db76/CMakeLists.txt#L165-L168

 ibd_check_freetype_availability(freetype_default) 
 # Note: to reduce wasm size, you may want to disable freetype on emscripten. 
 option(HELLOIMGUI_USE_FREETYPE "Use freetype for text rendering" ${freetype_default}) 
 ibd_force_freetype_static_for_python() 

ibd_check_freetype_availability & ibd_force_freetype_static_for_python

This sets HELLOIMGUI_FREETYPE_STATIC=ON

https://github.com/pthom/imgui_bundle/blob/f8db311b9c0828330e6b277238243ae3ccb8db76/imgui_bundle_cmake/imgui_bundle_build_lib.cmake#L27-L50

function(ibd_force_freetype_static_for_python)
    # For python bindings, we force the usage of a static version of freetype
    if(IMGUI_BUNDLE_BUILD_PYTHON AND HELLOIMGUI_USE_FREETYPE)
        # if using vcpkg, we suppose it uses the static version of freetype
        if(NOT "$ENV{CMAKE_TOOLCHAIN_FILE}" MATCHES "vcpkg")
            set(HELLOIMGUI_FREETYPE_STATIC ON CACHE BOOL "" FORCE)
        endif()
    endif()
endfunction()

# Check if freetype is available: ON by default, except on Android and MinGW
# On MacOS, if building a distributable wheel with cibuilwheel for a version less than 14.0, we disable freetype
function(ibd_check_freetype_availability result_var)
    # freetype is available by default
    set(${result_var} ON PARENT_SCOPE)

    # Except on Android and MinGW
    # Freetype is not available on Android. The mix SDL + Freetype cause issues (cannot find SDL.h)
    # Freetype currently fails to build on MinGW
    if(ANDROID OR MINGW)
        set(${result_var} OFF PARENT_SCOPE)
        return()
    endif()

hello_imgui_build_lib.cmake: build a static version of freetype (without Brolti) and links with it

hello_imgui_build_lib.cmake will

  • downloads a build freetype if HELLOIMGUI_FREETYPE_STATIC (we can see in the logs that this is done)
  • Call
set(freetype_linked_library freetype) # We would like this to be the result of our compilation...
target_link_libraries(imgui PUBLIC ${freetype_linked_library})

https://github.com/pthom/hello_imgui/blob/6f96155f5cb90dff93da21444d8586aca1ade17b/hello_imgui_cmake/hello_imgui_build_lib.cmake#L391-L421

        if(HELLOIMGUI_FREETYPE_STATIC AND NOT HELLOIMGUI_FETCH_FORBIDDEN)
            message("Forcing download of Freetype because HELLOIMGUI_FREETYPE_STATIC is ON")
            set(download_freetype ON)
        endif()

        if (download_freetype)
            message(STATUS "HelloImGui: downloading and building freetype")

            set(backup_shared_lib ${BUILD_SHARED_LIBS})
            set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)

            if (NOT HELLOIMGUI_INSTALL)
                set(SKIP_INSTALL_ALL ON CACHE INTERNAL "" FORCE) # disable Freetype install
            endif()

            include(FetchContent)
            if(IOS)
                set(FT_DISABLE_HARFBUZZ ON CACHE BOOL "" FORCE)
                set(FT_DISABLE_BROTLI ON CACHE BOOL "" FORCE)
            endif()
            FetchContent_Declare(
                freetype
                GIT_REPOSITORY https://github.com/freetype/freetype.git
                GIT_TAG        VER-2-13-2
                GIT_PROGRESS TRUE
            )
            FetchContent_MakeAvailable(freetype)
            set(freetype_linked_library freetype)

and then freetype_linked_library is used with:

    target_link_libraries(imgui PUBLIC ${freetype_linked_library})

Wheel build log:

Below, I include extracts from the build logs on GitHub CI

We can see this lines, which shows that

  1. Freetype was built
  2. However, the link did not use our built version, but instead a version at '/opt/homebrew/Cellar/brotli/1.1.0/lib/libbrotlidec.1.1.0.dylib which is not for the correct architecture

Some extracts:

Build of freetype: https://github.com/pthom/imgui_bundle/actions/runs/11166142777/job/31039470761#step:3:5460 " -- HelloImGui: downloading and building freetype" https://github.com/pthom/imgui_bundle/actions/runs/11166142777/job/31039470761#step:3:7678 " [173/308] Building C object _deps/freetype-build/CMakeFiles/freetype.dir/src/autofit/autofit.c.o"

https://github.com/pthom/imgui_bundle/actions/runs/11166142777/job/31039470761#step:3:7868

Link step, extract

    [306/308] Linking CXX shared module _imgui_bundle.cpython-312-darwin.so
    ld: warning: ignoring duplicate libraries: '-ldl', 'external/hello_imgui/hello_imgui/src/hello_imgui/libimgui_test_engine.a', 'external/immapp/immapp/libimmapp.a', 'external/libimgui.a', 'external/libimgui_md.a', 'external/libimgui_node_editor.a'
    ld: warning: ignoring file '/opt/homebrew/Cellar/libpng/1.6.44/lib/libpng16.16.dylib': found architecture 'arm64', required architecture 'x86_64'
    ld: warning: ignoring file '/opt/homebrew/Cellar/libpng/1.6.44/lib/libpng16.16.dylib': found architecture 'arm64', required architecture 'x86_64'
    ld: warning: ignoring file '/opt/homebrew/Cellar/harfbuzz/9.0.0/lib/libharfbuzz.0.dylib': found architecture 'arm64', required architecture 'x86_64'
    ld: warning: ignoring file '/opt/homebrew/Cellar/brotli/1.1.0/lib/libbrotlidec.1.1.0.dylib': found architecture 'arm64', required architecture 'x86_64'
    [307/308] cd /var/folders/0g/hj_q_pzx65bbjnslxz9n0src0000gn/T/tmplel4blzs/build && /opt/homebrew/Cellar/cmake/3.30.3/bin/cmake -E copy /var/folders/0g/hj_q_pzx65bbjnslxz9n0src0000gn/T/tmplel4blzs/build/_imgui_bundle.cpython-312-darwin.so /Users/runner/work/imgui_bundle/imgui_bundle/bindings/imgui_bundle/_imgui_bundle.cpython-312-darwin.so
    [308/308] cd /var/folders/0g/hj_q_pzx65bbjnslxz9n0src0000gn/T/tmplel4blzs/build && /opt/homebrew/Cellar/cmake/3.30.3/bin/cmake -E copy /var/folders/0g/hj_q_pzx65bbjnslxz9n0src0000gn/T/tmplel4blzs/build/_imgui_bundle.cpython-312-darwin.so /private/var/folders/0g/hj_q_pzx65bbjnslxz9n0src0000gn/T/cibw-run-k97iif_g/cp312-macosx_x86_64/build/venv/lib/python3.12/site-packages/imgui_bundle/_imgui_bundle.cpython-312-darwin.so

Those warnings explain the failure:

    ld: warning: ignoring file '/opt/homebrew/Cellar/libpng/1.6.44/lib/libpng16.16.dylib': found architecture 'arm64', required architecture 'x86_64

Conclusion

We did build a static version of freetype. Unfortunately, the lines

     set(freetype_linked_library freetype)
    target_link_libraries(imgui PUBLIC ${freetype_linked_library})

Do not give precedence to our static libraries and instead it uses a library found on the OS which does not have the good architecture.

pthom avatar Oct 04 '24 09:10 pthom

I'm trying two patches:

  • https://github.com/pthom/imgui_bundle/commit/2bbce5b3b91aa8627f47cc2d3151306930faa805: disable the use of system libraries. CMake is happily ignoring this, and still tries to link brotli, harfbuzz from homebrew...
  • https://github.com/pthom/hello_imgui/commit/67e0cc8b2e20ec5f31e4ac9759d24448c939ebec: build freetype without harfbuzz, brotli and png

For more details, see https://chatgpt.com/share/66ffb718-6408-8004-be5b-9e74064a8709

Please keep in touch and answer the two questions below:

  1. Try the previous wheel, after having installed freetype
brew install freetype

The idea is that I guess that the stock version of freetype is built with harfbuzz, brotli and png. Maybe they will be found once you run. Keep me informed whether it works or not.

  1. Try the wheels at https://github.com/pthom/imgui_bundle/actions/runs/11178781726/job/31077057633 They are using those two patches and I hope they will work.

Conclusions and follow-up

  • Building freetype without support for brotli, png, and harfbuzz might limit the range of possible fonts (see chatgpt analysis below)
  • building python libraries with native dependencies is a nightmare: I'm begin to think I might have to switch to conan, instead (or in addition to) pip.

Effect of disabling features in freetype, according to ChatGPT:

Disabling Harfbuzz, Brotli, and PNG in FreeType primarily affects fonts with advanced layout features and bitmap compression.

Harfbuzz: Without it, complex text shaping (for scripts like Arabic, Hindi, etc.) won’t work, but most Latin-based fonts will be unaffected. Brotli: Disabling it affects fonts using Brotli compression, mostly impacting modern Google Fonts or web-based fonts. PNG: Disabling PNG impacts bitmap glyphs that use PNG, typically affecting embedded bitmaps in some fonts (e.g., emoji fonts).

For most general-purpose fonts, the impact will be minimal.

pthom avatar Oct 04 '24 11:10 pthom

Hi! I also happened to encounter this problem today.

I can verify that using the wheel at: https://github.com/pthom/imgui_bundle/actions/runs/11178781726/artifacts/2015448630 imgui_bundle-1.5.2-cp312-cp312-macosx_14_0_x86_64.whl

Fixed the problem for me. Thank you!

dwgrth avatar Oct 04 '24 16:10 dwgrth

@dwgrth : Thanks! If you have time, could you also try other the alternative (brew install freetype + install the standard wheel), and tell me if it works for you.

Thanks!

pthom avatar Oct 04 '24 17:10 pthom

Maybe you could uninstall the system freetype? I hate cmake.

virtuald avatar Oct 04 '24 17:10 virtuald

However, the wheel fixed the problem for me too.

virtuald avatar Oct 04 '24 17:10 virtuald

Are you planning to do a release with this fix in the near future?

virtuald avatar Oct 10 '24 02:10 virtuald

Yes, I think I will make a release in about a month.

pthom avatar Oct 10 '24 04:10 pthom

So.. no.

virtuald avatar Oct 10 '24 05:10 virtuald