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!