Skip to content

Build failure for ARM targets: Neon undefined #123

@C0LDfinch

Description

@C0LDfinch

About

Neon is a hardware acceleration feature that is enabled by default in libpng, for builds targeting Arm processors. However, thtk does not include the neon source files from the libpng/arm/ directory when building the libpng static library, causing the linking step to fail with undefined symbols. Nor does thtk disable the neon optimization to prevent the error from occurring.

Affected Architectures

  • armv7
  • aarch64

Related Issues

  • Compile failure under macOS Monterey ARM #94: user managed to circumvent this problem by linking a system library instead of building a new libpng, where they used the -DWITH_LIBPNG_SOURCE=OFF option while making the buildsystem

Observations

For mysterious reasons, this bug also affects armv7, even though the logic of libpng's cmakelists implies that neon should only be enabled in 64-bit arm execution contexts.

Proposed Fixes

To fix the issue, I suggest one of the following revisions to extlib/CMakeLists.txt

Disable neon:

add_compile_definitions(PNG_ARM_NEON_OPT=0)

or...

Include neon implementation source files for all ARM targets:

string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} cpu)
if("${cpu}" MATCHES "^(arm|aarch)")
  set(arm_deps libpng/arm/arm_init.c libpng/arm/filter_neon_intrinsics.c libpng/arm/palette_neon_intrinsics.c)
endif()
add_library(png STATIC libpng/png.c libpng/png.h ${arm_deps}
everything_else...)

Disclaimer

I don't know much about the arm platform, and can't guarantee that thtk will continue to work normally with neon optimizations turned on. Is it safer to disable them until thoroughly tested?

Steps to Reproduce

  1. Install a cross-toolchain that can target Arm processors.

    • I used llvm-mingw for Ubuntu host (it's compatible with other Linuxes)
  2. Create a cmake toolchain file for some arm platform

    • Suppose we call this file win32-arm64.cmake
set(CMAKE_SYSTEM_NAME      Windows)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(base /path/to/your/toolchain)
set(CMAKE_C_COMPILER   ${base}/bin/aarch64-w64-mingw32-clang)
set(CMAKE_CXX_COMPILER ${base}/bin/aarch64-w64-mingw32-clang++)
set(CMAKE_RC_COMPILER  ${base}/bin/aarch64-w64-mingw32-windres)
set(CMAKE_FIND_ROOT_PATH ${base}/aarch64-w64-mingw32/)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
  1. Make a build folder in the thtk source and switch to it

  2. Generate thtk's buildsystem, adding your toolchain
    cmake .. -DCMAKE_TOOLCHAIN_FILE=/where/you/placed/win32-arm64.cmake

  3. Try to build thtk
    cmake --build . or make

    • You will get the following errors:
ld.lld: error: undefined symbol: png_init_filter_functions_neon
>>> referenced by libpng.a(pngrutil.c.obj):(png_init_filter_functions)

ld.lld: error: undefined symbol: png_riffle_palette_neon
>>> referenced by libpng.a(pngrtran.c.obj):(png_do_read_transformations)

ld.lld: error: undefined symbol: png_do_expand_palette_rgba8_neon
>>> referenced by libpng.a(pngrtran.c.obj):(png_do_expand_palette)

ld.lld: error: undefined symbol: png_do_expand_palette_rgb8_neon
>>> referenced by libpng.a(pngrtran.c.obj):(png_do_expand_palette)
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Disabling Neon (or adding its dependencies) in extlib/CMakeLists.txt should solve the issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions