8000 Cmake cross-compilation uses native sysroot · Issue #6901 · onnx/onnx · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Cmake cross-compilation uses native sysroot #6901

New issue

Have a question about this project? Si 8000 gn up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
loblik opened this issue Apr 16, 2025 · 6 comments
Open

Cmake cross-compilation uses native sysroot #6901

loblik opened this issue Apr 16, 2025 · 6 comments
Labels
bug topic: build Issues related to ONNX builds and packages

Comments

@loblik
Copy link
loblik commented Apr 16, 2025

Cmake mixes target and native sysroot when cross-compiling

Bug description

I'm building ONNX using Yocto/OE toolchain. Project builds fine, but during linking phase I get the following error:

/home/user/build/tmp/work/armv8a-poky-linux/onnx/1.18.0/recipe-sysroot-native/usr/bin/aarch64-poky-linux/../../libexec/aarch64-poky-linux/gcc/aarch64-poky-linux/13.3.0/ld: /home/user/build/tmp/work/armv8a-poky-linux/onnx/1.18.0/recipe-sysroot-native/usr/lib/libprotobuf.so: error adding symbols: file in wrong format

This happens because ONNX's CMakeList makes linker to look for libraries inside native-sysroot, where protobuf host compiler is located. This causes an error as linker is mixing host (x86_64) and target (aarch64) objects.

I verified this by hacking CMakeLists.txt (see bellow).

System information

Build Configuration:
BB_VERSION           = "2.8.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
DISTRO               = "poky"
DISTRO_VERSION       = "5.0.8"
TUNE_FEATURES        = "aarch64 armv8a crc"
TARGET_FPU           = ""

Reproduction instructions

This is a Yocto recipe I use to compile ONNX. It's pretty standard, it just fetches the ONNX from repository, sets up the build environment, installs dependencies and runs cmake with target toolchain.

DESCRIPTION = "Open standard for machine learning interoperability"
HOMEPAGE = "https://onnx.ai/"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"

SRC_URI = "git://github.com/onnx/onnx.git;protocol=https;branch=rel-${PV}"

SRCREV = "7fc2b81a275223f5b02a522d9d2649837542a7be"

DEPENDS = "protobuf protobuf-native"

S = "${WORKDIR}/git"

EXTRA_OECMAKE = "-DBUILD_SHARED_LIBS=ON"

inherit cmake

Expected behavior

I would expect the project to just compile without extra tweaks or patches.

Notes

In the end I was able to link it by making this hack:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6fe5c96e4b96..eefbbd65cf26 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -142,16 +142,12 @@ if(ONNX_BUILD_TESTS)
 endif()

 if(NOT ONNX_BUILD_CUSTOM_PROTOBUF)
-if((ONNX_USE_LITE_PROTO AND TARGET protobuf::libprotobuf-lite) OR ((NOT ONNX_USE_LITE_PROTO) AND TARGET protobuf::libprotobuf))
-  # Sometimes we need to use protoc compiled for host architecture while linking
-  # libprotobuf against target architecture. See https://github.com/caffe2/caffe
-  # 2/blob/96f35ad75480b25c1a23d6e9e97bccae9f7a7f9c/cmake/ProtoBuf.cmake#L92-L99
-  if(EXISTS "${ONNX_CUSTOM_PROTOC_EXECUTABLE}")
-    message(STATUS "Using custom protoc executable")
-    set(ONNX_PROTOC_EXECUTABLE ${ONNX_CUSTOM_PROTOC_EXECUTABLE})
-  else()
-    set(ONNX_PROTOC_EXECUTABLE $<TARGET_FILE:protobuf::protoc>)
-  endif()
+if(TRUE)
+  find_package(Protobuf)
+  find_program(Protobuf_PROTOC_EXECUTABLE
+               NAMES protoc
+               DOC "The Google Protocol Buffers Compiler")
+  set(ONNX_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
 else()
   # Customized version of find Protobuf. We need to avoid situations mentioned
   # in https://github.com/caffe2/caffe2/blob/b7d983f255ef5496474f1ea188edb5e0ac4

Both find_package() and find_program() which I used seems pretty standard to me. So can't they be in "default path", so even people using well-behaving toolchains can compile the project without issues?

@loblik loblik added the bug label Apr 16, 2025
@justinchuby
Copy link
Contributor

cc @cyyever @andife

@justinchuby justinchuby added the topic: build Issues related to ONNX builds and packages label Apr 17, 2025
@cyyever
Copy link
Contributor
cyyever commented Apr 17, 2025

@loblik Can you specify ONNX_BUILD_CUSTOM_PROTOBUF=on to let ONNX build its own protobuf?

@loblik
Copy link
Author
loblik commented Apr 17, 2025

@loblik Can you specify ONNX_BUILD_CUSTOM_PROTOBUF=on to let ONNX build its own protobuf?

Then cmake fails with Protobuf compiler not found.

But this is not what I want. If someone wants to use this project in real life deployments, they probably have to also manage CVEs and licence compliance. The last thing you want, is a project secretly pulling something from somewhere and putting that in your product, without your build system knowing it (no CVE scanning, no version in SBOM). For this reason in some build systems (like bitbake from Yocto), the compile step is executed in sandbox with no access to network. So suggested ONNX_BUILD_CUSTOM_PROTOBUF would not work anyway without some other hacking.

We already have protobuf in our system, as other components are using it too. I want to use that version. I believe find_package and find_program which do this, should be the default behavior or at least there should be an option for it (-DONNX_REGULAR_BUILD).

@cyyever
Copy link
Contributor
cyyever commented Apr 18, 2025

@loblik Help check my fix

@loblik
Copy link
Author
loblik commented Apr 23, 2025

@loblik Help check my fix

No, it does not seem to fix it. The problem seems to be in the way _PROTOBUF_INSTALL_PREFIX is initialized.

    set(ONNX_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
    get_filename_component(_PROTOBUF_INSTALL_PREFIX
                          ${Protobuf_PROTOC_EXECUTABLE} DIRECTORY)
    get_filename_component(_PROTOBUF_INSTALL_PREFIX
                          ${_PROTOBUF_INSTALL_PREFIX}/.. REALPATH)

It seems the cmake code assumes, the protoc is located in the same install prefix as target library. But this is not the case if you are cross-compiling. Because in that case protoc is native binary, which runs on host system, but we want build against target libraries. Therefore deriving library path from protoc installation dir is probably wrong thing to do.

Do we really need to do these install prefix tricks? Can't we just rely on find_package to handle it as that seems to work.

@cyyever
Copy link
Contributor
cyyever commented Apr 23, 2025

It depends on the Protobuf module of your CMake version. They are needed to help CMake 3.18 find the lib. For higher versions, there may be some fixes that they can be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug topic: build Issues related to ONNX builds and packages
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants
0