0

I'm building crossplatform shared library with onnxruntime dependency as static library. I have built onnxruntime from official repo. After that I created empty project and linked onnxruntime to it via CMake:

add_library(mylib SHARED ${MY_SOURCES})
target_include_directories(mylib PRIVATE ${ONNXRUNTIME_INCLUDE_DIRS})
target_link_libraries(mylib ${ONNXRUNTIME_LIBRARIES})

This works fine on Windows, Linux, MacOS and 64-bit Android. When I build Android x86 (on Ubuntu 22.04 x86_64) I get this error on linking step:

ld: error: relocation R_386_PC32 cannot be used against symbol '__x86.get_pc_thunk.bx'; recompile with -fPIC
>>> defined in libonnxruntime_mlas.a(x86.get_pc_thunk.S.o)
>>> referenced by SgemmKernelAvx.S.o:(.text+0x31F) in archive libonnxruntime_mlas.

After some research I came up with some ideas:

recompile with -fPIC: I have used the same polly toolchain for all libraries. -fPIC is included to flags:

set(ANDROID_NDK_VERSION "r25b")
set(CMAKE_SYSTEM_VERSION "21")
set(ANDROID_ABI "x86")
set(CMAKE_ANDROID_ARCH_ABI ${ANDROID_ABI})
set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION "clang")
set(ANDROID_STL "c++_static") # LLVM libc++ static
set(CMAKE_ANDROID_STL_TYPE ${ANDROID_STL})
include("${CMAKE_CURRENT_LIST_DIR}/utilities/polly_common.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/flags/cxx17.cmake") # before toolchain!
include("${CMAKE_CURRENT_LIST_DIR}/flags/fpic.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/flags/hidden.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/flags/lto.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/os/android.cmake")

fpic.cmake:

string(COMPARE EQUAL "${ANDROID_NDK_VERSION}" "" _not_android)
if(_not_android)
  polly_add_cache_flag(CMAKE_CXX_FLAGS "-fPIC")
  polly_add_cache_flag(CMAKE_C_FLAGS "-fPIC")
else()
  polly_add_cache_flag(CMAKE_CXX_FLAGS_INIT "-fPIC")
  polly_add_cache_flag(CMAKE_C_FLAGS_INIT "-fPIC")
endif()

set(
    CMAKE_POSITION_INDEPENDENT_CODE
    TRUE
    CACHE
    BOOL
    "Position independent code"
    FORCE
)

defined in libonnxruntime_mlas.a: I have checked CMake file for this lib and have found this code:

# In r23, NDK remove __x86.get_pc_thunk.* from libatomic. Add our own
# implementation to avoid external dependency.
if(ANDROID)
    set(mlas_platform_srcs
        ${mlas_platform_srcs}
        ${MLAS_SRC_DIR}/x86/x86.get_pc_thunk.S
    )
endif()

This is how x86.get_pc_thunk.S file looks like so this function exists:

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT License.

Module Name:
    x86.get_pc_thunk.S

Abstract:
    This module implements __x86.get_pc_thunk.* to avoid external dependency.

--*/

        .intel_syntax noprefix

/*++

Routine Description:
    The routine loads its return address -- which is the address of the
    instruction that immediately follows -- into the ebx register.

--*/

        .p2align 4
        .weak  __x86.get_pc_thunk.bx
        .type   __x86.get_pc_thunk.bx,@function
__x86.get_pc_thunk.bx:
        mov ebx, [esp]
        ret

I'm using Android NDK r25 and don't understand why this error appears. Maybe I need to enable -fPIC for ASM files? Thanks in advance for your help!

Egor
  • 107
  • 1
  • 8

0 Answers0