Victor
Victor

Reputation: 14622

libwebp Undefined symbols for architecture arm64: _SharpYuvConvert

Trying to compile the go-webp package using Bazel. This involves compiling libwebp from sources.

Here's how I'm retrieving libwebp's sources:

# WORKSPACE
git_repository(
    name = "libwebp",
    remote = "https://chromium.googlesource.com/webm/libwebp",
    commit = "9ce982fdf21764ef7b273f91d6d72721656c3e03",
    build_file = "//:bazel/libwebp/BUILD.bazel",
)

# //:bazel/libwebp/BUILD.bazel
filegroup(
    name = "srcs",
    srcs = glob(
        ["**/*"],
        # https://github.com/bazelbuild/rules_foreign_cc/issues/1034#issuecomment-2009876928
        exclude = ["bazel*/**"],
    ),
    visibility = ["//visibility:public"],
)

Then, here's how I'm (apparently successfully) compiling it:

# //:external/libwebp/BUILD.bazel
load("@rules_foreign_cc//foreign_cc:defs.bzl", "configure_make")

configure_make(
    name = "libwebp",
    autogen = True,
    configure_in_place = True,
    configure_options = [],
    env = select({
        "@platforms//os:macos": {
            "AR": "/usr/bin/ar",
        },
        "//conditions:default": {},
    }),
    lib_source = "@libwebp//:srcs",
    visibility = ["//visibility:public"],
)

Finally, the go-webp Go repository:

go_repository(
    name = "com_github_kolesa_team_go_webp",
    importpath = "github.com/kolesa-team/go-webp",
    patches = ["//:bazel/com_github_kolesa_team_go_webp/build.patch"],  # keep
    sum = "h1:wQvU4PLG/X7RS0vAeyhiivhLRoxfLVRlDq4I3frdxIQ=",
    version = "v1.0.4",
)

Where the patch contains:

--- encoder/BUILD.bazel
+++ encoder/BUILD.bazel
@@ -7,7 +7,7 @@
         "options.go",
     ],
     cgo = True,
-    clinkopts = ["-lwebp"],
+    cdeps = ["@asset-tracker//external/libwebp"],
     importpath = "github.com/kolesa-team/go-webp/encoder",
     visibility = ["//visibility:public"],
 )

Trying to build a service that depends on go-webp results in linker not finding some symbols from the webp library:

ld: warning: ignoring duplicate libraries: '-lc++', '-lm'
Undefined symbols for architecture arm64:
  "_SharpYuvConvert", referenced from:
      _PreprocessARGB in libwebp.a[87](libwebpencode_la-picture_csp_enc.o)
  "_SharpYuvGetConversionMatrix", referenced from:
      _PreprocessARGB in libwebp.a[87](libwebpencode_la-picture_csp_enc.o)
  "_SharpYuvInit", referenced from:
      _ImportYUVAFromRGBA in libwebp.a[87](libwebpencode_la-picture_csp_enc.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

link: error running subcommand external/go_sdk/pkg/tool/darwin_arm64/link: exit status 2

Some info about my system:

Darwin 23.5.0 Darwin Kernel Version 23.5.0: Wed May  1 20:14:38 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6020 arm64
bazel 7.2.1

Had a really hard time figuring out the configure_make build on macOS for the webp library and now I am not sure where I have gone wrong about it.

Now, the question(s): How would I go about debugging this? Is there any known issue that I might have missed in my research?


Disclaimer: I initially thought this would belong on someone's GitHub Issues page, but honestly I'm not sure on which repository this would even belong.

Upvotes: 1

Views: 244

Answers (1)

Kip
Kip

Reputation: 131

G'day! I think this was found and fixed by the maintainers (after tag 1.3.2, by the look of it). I'd suggest trying to upgrade the version of the dependency or even adding the fix to your patch.

I'll dump it below, for posterity sake:

diff --git a/iosbuild.sh b/iosbuild.sh
index cd3a24c..d0fb557 100755
--- a/iosbuild.sh
+++ b/iosbuild.sh
@@ -41,6 +41,7 @@
 readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.framework"
 readonly MUXTARGETDIR="${TOPDIR}/WebPMux.framework"
 readonly DEMUXTARGETDIR="${TOPDIR}/WebPDemux.framework"
+readonly SHARPYUVTARGETDIR="${TOPDIR}/SharpYuv.framework"
 readonly DEVELOPER=$(xcode-select --print-path)
 readonly PLATFORMSROOT="${DEVELOPER}/Platforms"
 readonly LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
@@ -63,7 +64,8 @@
 echo "iOS SDK Version: ${SDK}"
 
 if [[ -e "${BUILDDIR}" || -e "${TARGETDIR}" || -e "${DECTARGETDIR}" \
-      || -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" ]]; then
+      || -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" \
+      || -e "${SHARPYUVTARGETDIR}" ]]; then
   cat << EOF
 WARNING: The following directories will be deleted:
 WARNING:   ${BUILDDIR}
@@ -71,14 +73,16 @@
 WARNING:   ${DECTARGETDIR}
 WARNING:   ${MUXTARGETDIR}
 WARNING:   ${DEMUXTARGETDIR}
+WARNING:   ${SHARPYUVTARGETDIR}
 WARNING: The build will continue in 5 seconds...
 EOF
   sleep 5
 fi
 rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \
-    ${MUXTARGETDIR} ${DEMUXTARGETDIR}
+    ${MUXTARGETDIR} ${DEMUXTARGETDIR} ${SHARPYUVTARGETDIR}
 mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/ \
-    ${MUXTARGETDIR}/Headers/ ${DEMUXTARGETDIR}/Headers/
+    ${MUXTARGETDIR}/Headers/ ${DEMUXTARGETDIR}/Headers/ \
+    ${SHARPYUVTARGETDIR}/Headers/
 
 if [[ ! -e ${SRCDIR}/configure ]]; then
   if ! (cd ${SRCDIR} && sh autogen.sh); then
@@ -134,13 +138,14 @@
   set +x
 
   # Build only the libraries, skip the examples.
-  make V=0 -C sharpyuv
+  make V=0 -C sharpyuv install
   make V=0 -C src install
 
   LIBLIST+=" ${ROOTDIR}/lib/libwebp.a"
   DECLIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a"
   MUXLIBLIST+=" ${ROOTDIR}/lib/libwebpmux.a"
   DEMUXLIBLIST+=" ${ROOTDIR}/lib/libwebpdemux.a"
+  SHARPYUVLIBLIST+=" ${ROOTDIR}/lib/libsharpyuv.a"
 
   make clean
 
@@ -165,4 +170,9 @@
     ${DEMUXTARGETDIR}/Headers/
 ${LIPO} -create ${DEMUXLIBLIST} -output ${DEMUXTARGETDIR}/WebPDemux
 
+echo "SHARPYUVLIBLIST = ${SHARPYUVLIBLIST}"
+cp -a ${SRCDIR}/sharpyuv/{sharpyuv,sharpyuv_csp}.h \
+    ${SHARPYUVTARGETDIR}/Headers/
+${LIPO} -create ${SHARPYUVLIBLIST} -output ${SHARPYUVTARGETDIR}/SharpYuv
+
 echo  "SUCCESS"
diff --git a/xcframeworkbuild.sh b/xcframeworkbuild.sh
index 8d484c2..14b987d 100755
--- a/xcframeworkbuild.sh
+++ b/xcframeworkbuild.sh
@@ -69,6 +69,7 @@
 readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.xcframework"
 readonly MUXTARGETDIR="${TOPDIR}/WebPMux.xcframework"
 readonly DEMUXTARGETDIR="${TOPDIR}/WebPDemux.xcframework"
+readonly SHARPYUVTARGETDIR="${TOPDIR}/SharpYuv.xcframework"
 readonly DEVELOPER=$(xcode-select --print-path)
 readonly DEVROOT="${DEVELOPER}/Toolchains/XcodeDefault.xctoolchain"
 readonly PLATFORMSROOT="${DEVELOPER}/Platforms"
@@ -94,8 +95,15 @@
   local subdir
   for d in $(find "$1" -path "*/Headers"); do
     subdir="$d/$framework_name"
-    mkdir "$subdir"
-    mv "$d/"*.h "$subdir"
+    if [[ -d "$subdir" ]]; then
+      # SharpYuv will have a sharpyuv subdirectory. macOS is case insensitive,
+      # but for consistency with the other frameworks, rename the directory to
+      # match the case of the framework name.
+      mv "$(echo ${subdir} | tr 'A-Z' 'a-z')" "$subdir"
+    else
+      mkdir "$subdir"
+      mv "$d/"*.h "$subdir"
+    fi
   done
 }
 
@@ -104,7 +112,8 @@
 echo "MacOS SDK Version: ${SDK[$MACOS]}"
 
 if [[ -e "${BUILDDIR}" || -e "${TARGETDIR}" || -e "${DECTARGETDIR}" \
-      || -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" ]]; then
+      || -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" \
+      || -e "${SHARPYUVTARGETDIR}" ]]; then
   cat << EOF
 WARNING: The following directories will be deleted:
 WARNING:   ${BUILDDIR}
@@ -112,12 +121,13 @@
 WARNING:   ${DECTARGETDIR}
 WARNING:   ${MUXTARGETDIR}
 WARNING:   ${DEMUXTARGETDIR}
+WARNING:   ${SHARPYUVTARGETDIR}
 WARNING: The build will continue in 5 seconds...
 EOF
   sleep 5
 fi
 rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \
-  ${MUXTARGETDIR} ${DEMUXTARGETDIR}
+  ${MUXTARGETDIR} ${DEMUXTARGETDIR} ${SHARPYUVTARGETDIR}
 
 if [[ ! -e ${SRCDIR}/configure ]]; then
   if ! (cd ${SRCDIR} && sh autogen.sh); then
@@ -137,6 +147,7 @@
   DECLIBLIST=()
   MUXLIBLIST=()
   DEMUXLIBLIST=()
+  SHARPYUVLIBLIST=()
 
   for PLATFORM in ${PLATFORMS[$i]}; do
     ROOTDIR="${BUILDDIR}/${PLATFORM}"
@@ -187,23 +198,26 @@
     set +x
 
     # Build only the libraries, skip the examples.
-    make V=0 -C sharpyuv
+    make V=0 -C sharpyuv install
     make V=0 -C src install
 
     LIBLIST+=("${ROOTDIR}/lib/libwebp.a")
     DECLIBLIST+=("${ROOTDIR}/lib/libwebpdecoder.a")
     MUXLIBLIST+=("${ROOTDIR}/lib/libwebpmux.a")
     DEMUXLIBLIST+=("${ROOTDIR}/lib/libwebpdemux.a")
+    SHARPYUVLIBLIST+=("${ROOTDIR}/lib/libsharpyuv.a")
     # xcodebuild requires a directory for the -headers option, these will match
     # for all builds.
     make -C src install-data DESTDIR="${ROOTDIR}/lib-headers"
     make -C src install-commonHEADERS DESTDIR="${ROOTDIR}/dec-headers"
     make -C src/demux install-data DESTDIR="${ROOTDIR}/demux-headers"
     make -C src/mux install-data DESTDIR="${ROOTDIR}/mux-headers"
+    make -C sharpyuv install-data DESTDIR="${ROOTDIR}/sharpyuv-headers"
     LIB_HEADERS="${ROOTDIR}/lib-headers/${ROOTDIR}/include/webp"
     DEC_HEADERS="${ROOTDIR}/dec-headers/${ROOTDIR}/include/webp"
     DEMUX_HEADERS="${ROOTDIR}/demux-headers/${ROOTDIR}/include/webp"
     MUX_HEADERS="${ROOTDIR}/mux-headers/${ROOTDIR}/include/webp"
+    SHARPYUV_HEADERS="${ROOTDIR}/sharpyuv-headers/${ROOTDIR}/include/webp"
 
     make distclean
 
@@ -220,16 +234,20 @@
   target_declib="${target_dir}/$(basename ${DECLIBLIST[0]})"
   target_demuxlib="${target_dir}/$(basename ${DEMUXLIBLIST[0]})"
   target_muxlib="${target_dir}/$(basename ${MUXLIBLIST[0]})"
+  target_sharpyuvlib="${target_dir}/$(basename ${SHARPYUVLIBLIST[0]})"
 
   mkdir -p "${target_dir}"
   ${LIPO} -create ${LIBLIST[@]} -output "${target_lib}"
   ${LIPO} -create ${DECLIBLIST[@]} -output "${target_declib}"
   ${LIPO} -create ${DEMUXLIBLIST[@]} -output "${target_demuxlib}"
   ${LIPO} -create ${MUXLIBLIST[@]} -output "${target_muxlib}"
+  ${LIPO} -create ${SHARPYUVLIBLIST[@]} -output "${target_sharpyuvlib}"
   FAT_LIBLIST+=(-library "${target_lib}" -headers "${LIB_HEADERS}")
   FAT_DECLIBLIST+=(-library "${target_declib}" -headers "${DEC_HEADERS}")
   FAT_DEMUXLIBLIST+=(-library "${target_demuxlib}" -headers "${DEMUX_HEADERS}")
   FAT_MUXLIBLIST+=(-library "${target_muxlib}" -headers "${MUX_HEADERS}")
+  FAT_SHARPYUVLIBLIST+=(-library "${target_sharpyuvlib}")
+  FAT_SHARPYUVLIBLIST+=(-headers "${SHARPYUV_HEADERS}")
 done
 
 # lipo will not put archives with the same architecture (e.g., x86_64
@@ -246,10 +264,13 @@
   -output ${DEMUXTARGETDIR}
 xcodebuild -create-xcframework "${FAT_MUXLIBLIST[@]}" \
   -output ${MUXTARGETDIR}
+xcodebuild -create-xcframework "${FAT_SHARPYUVLIBLIST[@]}" \
+  -output ${SHARPYUVTARGETDIR}
 update_headers_path "${TARGETDIR}"
 update_headers_path "${DECTARGETDIR}"
 update_headers_path "${DEMUXTARGETDIR}"
 update_headers_path "${MUXTARGETDIR}"
+update_headers_path "${SHARPYUVTARGETDIR}"
 set +x
 
 echo  "SUCCESS"

Upvotes: 0

Related Questions