Skip to content
New issue

Have a question about this project? Sign 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

Library can not be used in android (arm64) #523

Closed
atopavirgil opened this issue Jan 17, 2022 · 24 comments · Fixed by #573
Closed

Library can not be used in android (arm64) #523

atopavirgil opened this issue Jan 17, 2022 · 24 comments · Fixed by #573
Milestone

Comments

@atopavirgil
Copy link

Not sure why, maybe some building flags. The library is build using VCPKG and works under Windows and Linux x64. However build using an android triplet when linked in an execurable or another shared library getting this for a static build:

/home/adrian/Dev/android/android-ndk-r23b/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/21/liblog.so -llog -landroid -static-libstdc++ -latomic -lm && :
ld: error: /home/cc/Dev/vcpkg/installed/arm64-android/lib/libtommath.a(bn_mp_abs.o) is incompatible with aarch64linux
ld: error: /home/cc/Dev/vcpkg/installed/arm64-android/lib/libtommath.a(bn_mp_add.o) is incompatible with aarch64linux
ld: error: /home/cc/Dev/vcpkg/installed/arm64-android/lib/libtommath.a(bn_mp_and.o) is incompatible with aarch64linux
ld: error: /home/cc/Dev/vcpkg/installed/arm64-android/lib/libtommath.a(bn_mp_clear.o) is incompatible with aarch64linux
...

If a dynamic build is used, same aerror but reffering to the full lib.

Any build flags missing ? Does the library work under arm64 ?

@czurnieden
Copy link
Contributor

Sorry for the long delay!

Is this still a problem or did you find a solution?

If it is still a problem I need to replicate the problem so I need the data of your environment (version numbers etc) and how you came to it, that is what were your individual steps.

And yes, it is most likely a matter of build flags (probably LDFLAGS?). ARM64 itself is supported.

@atopavirgil
Copy link
Author

Yes still not solved the problem. The library builds and can be used in Linux and Windows. We are trying to port the project using it to Android. I'm using latest NDK, and the triplet used is this one:
set(VCPKG_TARGET_ARCHITECTURE arm64)
set(VCPKG_CRT_LINKAGE static)
set(VCPKG_LIBRARY_LINKAGE dynamic)
set(VCPKG_CMAKE_SYSTEM_NAME Android)

All libraries required build in VCPKG properly. Even this library builds, I get both a static and a shared library.
If I'm using the static library and linking it on another static library it works. However if my main library is dynamic the link fails with this error.( I tried to link with the dynamic build of libtommath, to check, same error but this time refers to all library, not to functions. I'm using a few other libraries build with the same triplet in VCPKG and I do not get any link errors, so something is different with this one. I'm new to Android build, so maybe I miss something.

Thanks for your help.

@atopavirgil
Copy link
Author

This is the port file used in VCPKG to build the library:

vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO libtom/libtommath
REF v1.2.0
SHA512 500bce4467d6cdb0b014e6c66d3b994a8d63b51475db6c3cd77c15c8368fbab4e3b5c458fcd5b35838b74c457a33c15b42d2356964f5ef2a0bd31fd544735c9a
HEAD_REF develop
)

if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_check_linkage(ONLY_STATIC_LIBRARY)

if(VCPKG_CRT_LINKAGE STREQUAL "dynamic")
    set(CRTFLAG "/MD")
else()
    set(CRTFLAG "/MT")
endif()

# Make sure we start from a clean slate
vcpkg_execute_build_process(
    COMMAND nmake -f ${SOURCE_PATH}/makefile.msvc clean
    WORKING_DIRECTORY ${SOURCE_PATH}
    LOGNAME clean-${TARGET_TRIPLET}-dbg
)

#Debug Build
vcpkg_execute_build_process(
    COMMAND nmake -f ${SOURCE_PATH}/makefile.msvc CFLAGS="${CRTFLAG}d"
    WORKING_DIRECTORY ${SOURCE_PATH}
    LOGNAME build-${TARGET_TRIPLET}-dbg
)

file(INSTALL
    ${SOURCE_PATH}/tommath.lib
    DESTINATION ${CURRENT_PACKAGES_DIR}/debug/lib
)

# Clean up necessary to rebuild without debug symbols
vcpkg_execute_build_process(
    COMMAND nmake -f ${SOURCE_PATH}/makefile.msvc clean
    WORKING_DIRECTORY ${SOURCE_PATH}
    LOGNAME clean-${TARGET_TRIPLET}-rel
)

vcpkg_execute_build_process(
    COMMAND nmake -f ${SOURCE_PATH}/makefile.msvc CFLAGS="${CRTFLAG}"
    WORKING_DIRECTORY ${SOURCE_PATH}
    LOGNAME build-${TARGET_TRIPLET}-rel
)

file(INSTALL
    ${SOURCE_PATH}/tommath.lib
    DESTINATION ${CURRENT_PACKAGES_DIR}/lib
)

file(INSTALL
    ${SOURCE_PATH}/tommath.h
    DESTINATION ${CURRENT_PACKAGES_DIR}/include
)

else()
if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic")
set(MAKE_FILE "makefile.shared")
else()
set(MAKE_FILE "makefile")
endif()

vcpkg_execute_build_process(
    COMMAND make -f ${MAKE_FILE} clean
    WORKING_DIRECTORY ${SOURCE_PATH}
)

vcpkg_execute_build_process(
    COMMAND make -j${VCPKG_CONCURRENCY} -f ${MAKE_FILE} PREFIX=${CURRENT_PACKAGES_DIR}/debug COMPILE_DEBUG=1 install
    WORKING_DIRECTORY ${SOURCE_PATH}
)
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")

vcpkg_execute_build_process(
    COMMAND make -f ${MAKE_FILE} clean
    WORKING_DIRECTORY ${SOURCE_PATH}
)

vcpkg_execute_build_process(
    COMMAND make -j${VCPKG_CONCURRENCY} -f ${MAKE_FILE} PREFIX=${CURRENT_PACKAGES_DIR} install
    WORKING_DIRECTORY ${SOURCE_PATH}
)

endif()

file(INSTALL
${SOURCE_PATH}/LICENSE
DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT} RENAME copyright
)

@atopavirgil
Copy link
Author

Any suggestion what needs to be changed in this "port" file to fix the problem ? As I mentioned, the port file and the library work for an x86 standard Linux build, the problem is only when trying to use the library on an Android ARM64 build, when I get the errors. The build is cross-compiled from Linux using the android NDK tools, which works properly for other libraries build., except this one so the toolchain is properly setup.

@czurnieden
Copy link
Contributor

I tried your triplet and port (you just changed VCPKG_LIBRARY_LINKAGE in $(vcpkg)/triplets/community/arm64-android.cmake and nothing in $(vcpkg)/ports/libtommath/portfile.cmake if I read it correctly?) and was not able to build for ARM64, it builds x86 binaries. But I don't use VCPKG for ARM development, so I might have made something wrong.

There should be a file $(vcpkg)/buildtrees/libtommath/stdout-arm64-android.log and two files $(vcpkg)/buildtrees/libtommath/build-*.log if you didn't change it. Would you do me a favor and post them here?

And please run objdump -f $(vcpkg)/installed/arm64-android/lib/libtommath.so.1.2.0 (path and name may vary, I mean the build dynamic version), too, while you are at it, thanks.

@czurnieden
Copy link
Contributor

Can you use the develop branch instead?
You would need to change the vcpkg_from_github function in the portfile to:

vcpkg_from_github(
    OUT_SOURCE_PATH SOURCE_PATH
    REPO libtom/libtommath
    REF 04e9d1e7a0493910b2eb5e757d623870692ada04
    SHA512 804d1c1b416eebb27f78a6c67d7d0c0b120e4c73c0876f4b6002c4dc6759b2e08407fceb89f642435041a9ca2ccaa91ef41c1f64e9430b5c4a7e598643b34150
    HEAD_REF develop
)

to do so.

@atopavirgil
Copy link
Author

atopavirgil commented Feb 16, 2022

I think this is the problem. Looking at objdump, for libtommath and the other libraries build in the same folder, it looks like libtommath is not cross-compiled but build for x86 ? See the architecture for other libs (all build with the same triplet, in the same environment). All are using same triplet/environment and I did not touch the port file for any libs. What is different which may explain something, the build triplet asks for "dynamic build". For libtommath the build generates both a static and a dynamic library (I think in Windows we just get the static one, this is why we link with the static one in every environment). I suppose the static one is also not cross-compiled.

adrian@HX90-MINT:~/Dev/vcpkg/installed/arm64-android/lib$ objdump -f libtommath.so.1.2.0

libtommath.so.1.2.0: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000005090

adrian@HX90-MINT:~/Dev/vcpkg/installed/arm64-android/lib$ objdump -f libgtest.so

libgtest.so: file format elf64-little
architecture: UNKNOWN!, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x00000000000cd4cc

adrian@HX90-MINT:~/Dev/vcpkg/installed/arm64-android/lib$ objdump -f libz.so

libz.so: file format elf64-little
architecture: UNKNOWN!, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000008a54

adrian@HX90-MINT:~/Dev/vcpkg/installed/arm64-android/lib$ objdump -f libcrypto.so

libcrypto.so: file format elf64-little
architecture: UNKNOWN!, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x00000000000f923c

adrian@HX90-MINT:~/Dev/vcpkg/installed/arm64-android/lib$ objdump -f libssl.so.1.1

libssl.so.1.1: file format elf64-little
architecture: UNKNOWN!, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x000000000003418c

@atopavirgil
Copy link
Author

atopavirgil commented Feb 16, 2022

stdout-arm64-android.log
stdout-arm64-android.log

@atopavirgil
Copy link
Author

atopavirgil commented Feb 16, 2022

build-out.log

build-out.log

@atopavirgil
Copy link
Author

atopavirgil commented Feb 16, 2022

I will try later with the "develop" branch, if you think that fixes the problem.

I tried ( changed the port file, remove, install libtommath again in vcpkg). I hope this used the modified port file (the file did not changed, it stayed as the modified one, I hope it did get used for the new install, I see in downloads a libtom package with 04e9... in name so probably did) but the objdump still shows an x86 build. I think the use of libtool is breaking the cross compiling, the other libs do not seem to use it.

@atopavirgil
Copy link
Author

atopavirgil commented Feb 16, 2022

I did the dump for the static lib, and also for another static build one Goggle "benchmark". The "benchmark" lib is also build as static only even if the triplet requires dynamic build, but I don't think it uses libtool, and it is correct. Libtommath builds however for x86 not for ARM64. Can the build be fixed and not use libtool (just build the static lib same as benchmark ? I'm not familiar with the procedure. I also think that cross-compile with libtool is a known problem, not sure if it was solved or not)

Here is the dump file:

staticdump.txt

@czurnieden
Copy link
Contributor

Thanks for the dumps, were helpful!

I also think that cross-compile with libtool is a known problem, not sure if it was solved or not

Yes, it is still not easy.

The port-file does the standard build only. We would need to set CC to the correct compiler (from the Android-NDK) and the linker, too, of course. Path to the NDK is assumed to be in the shell variable ANDROID_NDK_HOME. Binaries are in $(android-ndk)/toolchains/llvm/prebuilt/$(local-architectur)/bin/ (scripts, actually, calling the compiler with the correct arguments). You need aarch64. There are also optimizing versions for 10 different Android versions. I don't know which one you need, would use 31.

I doubt it would be as easy as to just set CC to one of the NDK scripts and manipulate libtool to use the NDK linker, so it might need a couple of tries, especially the libtool part. Are you willing and able to help me out with it? The "trying" part I mean?

BTW: your objdump does not seem to know the ARM architecture, you can try the llvm-objdump in the NDK.

One of the main reasons for the complex build-process of LibTomMath is the broad support: about a dozen operating systems for about a dozen architectures.

@sjaeckel
Copy link
Member

Can you please try out if using the add-cmake-support branch solves your issue?

I guess this also simplifies your build recipe a lot.

@atopavirgil
Copy link
Author

Can you please try out if using the add-cmake-support branch solves your issue?

I guess this also simplifies your build recipe a lot.

Thank I will try. I will have to move the project out of the vcpkg build and build it separately but if it solves the problem it's worth the effort. I have a combination of projects some are available in vcpkg (great!), other not. Most if not all of other projects I encountered are build using CMake.

@atopavirgil
Copy link
Author

atopavirgil commented Feb 17, 2022

You are correct , the path to NDK is in the environment variable. In fact there is a good description here for building Android via VCPKG , and it works well for all other projects I tried.

https://vcpkg.readthedocs.io/en/latest/users/android/

For the second question. of course. Would be great to get this fixed, and if works get the port updated in VCPKG also, may help others. The cross-compile problem can be in any environment not only Android (can be also for Apple M1, if same procedure is used).

@atopavirgil
Copy link
Author

atopavirgil commented Feb 17, 2022

Can you please try out if using the add-cmake-support branch solves your issue?

I guess this also simplifies your build recipe a lot.

Thanks, I tried. It build without problems in Windows, Linux x86 and cross-compile properly this time in ARM64 Android. Using CMake really puts this project in line with most other ones. Would be nice if vcpkg guys will use this branch (or manage to fix the standard one), pretty sure that currently because of that libtool any cross-compile is broken.

With "cmake branch":

llvm-objdump -f libtommath.a

libtommath.a(mp_2expt.c.o): file format ELF64-aarch64-little
architecture: aarch64
start address: 0x0000000000000000
libtommath.a(mp_abs.c.o): file format ELF64-aarch64-little
architecture: aarch64
start address: 0x0000000000000000
libtommath.a(mp_add.c.o): file format ELF64-aarch64-little
architecture: aarch64
start address: 0x0000000000000000

...

I managed to build my project using this lib. I see that a number of functions disappeared are they obsolete ? (they are still in master).
mp_decr,mp_incr,mp_init,mp_expt_u32

@atopavirgil
Copy link
Author

Any chance that the "cmake branch" is going to get in the main ? Would simplify a lot of work. I switch between a few OS-es all other projects we include are CMake based. Current Visual Studio (using now 2022) has very good support, for CMake projects, you can get rid of that old VS2008 solution. Until this problem I did not pay to much atention, using vcpkg for supported projects, but looks like all works until it does not.

@sjaeckel
Copy link
Member

Any chance that the "cmake branch" is going to get in the main ?

Yes, definitely. Should be in develop pretty soon. When we'll get a new release is not clear yet...

@czurnieden
Copy link
Contributor

@atopavirgil does it work with the (original) "add-cmake-support" branch well enough? No need to meddle with the port-file anymore?

Ok, ok, ok, I give up: we need cmake. But I'm still allowed to hate it, am I not? ;-)

I see the "add-cmake-support" makes good progress, nice!

Took the liberty to make "test" work with the shared lib (setting of -DLTM_TEST_DYNAMIC) in my fork and started gathering the environment variables listed in makefile_include.mk but I couldn't find a place to talk to @mrpelotazo regarding the branch (no issue/pull request or am I blind?); don't want to meddle in Adrian's affairs, he might be already working at it with a much better solution than mine.

@atopavirgil
Copy link
Author

atopavirgil commented Feb 20, 2022

I can build the "cmake branch" yes ( all OS-es, including cross-compiling, cmake is good at this), but from what I understand it's going to be a long time until there is an "official release" with this changes on it (maybe I'm wrong, you guys know better...)..The problem is that tommath is available for some time in vcpkg , which is quite popular as can be used in multiple OS-es and the cross-compile build in there is broken, pretty sure others will hit the same problem sooner or later. I'm pretty sure that only "official releases" are included in vcpkg, so if an "easy" fix that can be implemented in the "port" file can be found, would be great, I'm sure would help others. If it requires using another branch, so needs to be build separately anyway, the CMake branch already solves the problem. For my own projects I start doing changes, adding flags to use tommath build in vcpkg or separately from sources.

By the way, there is any replacement for mp_expt_u32 ? The code I'm trying to integrate is using this function, which is gone in the develop branch . There is some equivalent one ? I'm not even the one who wrote the code, I just integrate a project using this in a larger project.

@czurnieden
Copy link
Contributor

if an "easy" fix that can be implemented in the "port" file can be found, would be great

Yepp, feared that. ;-)
But it might take a bit.

By the way, there is any replacement for mp_expt_u32 ?

It is mp_err mp_expt_n(const mp_int *a, int b, mp_int *c) now. The theoretically largest number possible in LTM is -1+2^(2^k) where k = sizeof(int) * CHAR_BIT (1) and because we support a lot of architectures int can come in several sizes, some of them smaller than 32-bits.

(1) The exact number is MP_MAX_DIGIT_COUNT * MP_DIGIT_BIT. For example with 32 bit int and MP_64BIT (most modern desktops) 2^k = 71582788 and log_2(71582788) ~ 26.0931 .

@atopavirgil
Copy link
Author

atopavirgil commented Feb 21, 2022

Thanks for the help. Out of context but related to CMake build, for building in Windows using Visual Studio (CMake projects), this is my batch build (I did not see it around so it may help others). This is to build the lib (any project in fact) from command line. Of course, you can just load the "folder" in VS IDE and build it from there, VS knows to deal with CMake projects. This uses the same output folder structure as VS does by default from IDE. It may help others. This script assumes that is run from a "subfolder" from the project root where CMakeList.txt is supposed to be. For Linux, Android build I'm using more or less similar Linux script files.

As a note, do not use any CMake "generators" other than ninja. All old "VS" generators are obsolete, as Visual Studio itself uses the ninja when it builds CMake projects. In general VS assumes that for CMake projects we also use VCPKG as many open source projects are build via vcpkg, but for this project the build does not really require it except for the toolchain.

SET mypath=%~dp0
PUSHD %CD%
CD ..
SET newpath=%CD%
POPD

SET prpath=%newpath:~0%

echo Project path: %prpath%

echo Building for Windows

@Rem This must point to VCPKG location (may be different in another system )
SET vcpkg="C:/Dev/vcpkg/scripts/buildsystems/vcpkg.cmake"

@Rem echo VCPKG path: %vcpkg%

@Rem This must point to VisualStudio 2022 vcvars64.bat location (may be different in another system)
CALL "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"

echo Building x64 Release...

SET instd=%prpath%\out\install\x64-Release

@Rem We must call cmake from the output build folder. Create it and go there
mkdir %prpath%\out\build\x64-Release
cd %prpath%\out\build\x64-Release

echo Output build folder is: %cd%

@Rem Use Cmake to create the cache file
cmake.exe -G "Ninja" -DCMAKE_BUILD_TYPE:STRING="RelWithDebInfo" -DCMAKE_INSTALL_PREFIX:PATH=%instd% -DCMAKE_C_COMPILER:FILEPATH="cl.exe" -DCMAKE_CXX_COMPILER:FILEPATH="cl.exe" -DCMAKE_MAKE_PROGRAM="ninja.exe" -DCMAKE_TOOLCHAIN_FILE=%vcpkg% %prpath%

@Rem Use cmake to build, install and create the packages
cmake --build .
cmake --install .

@Rem cmake --build . --target Packages

@bbslucky
Copy link

i'm use ndk too,it can create static.a file ,but wen i use in .so,
ld: error: relocation R_AARCH64_ADR_PREL_PG_HI21 cannot be used against symbol 's_mp_rand_source'; recompile with -fPIC

,
,
i have added the -fPIC flag
but,you see,like this

defined in /tmp/third_party/lib/libtommath-aarch64-unknown-linux-android.a(bn_mp_rand.o)
referenced by bn_mp_rand.c
bn_mp_rand.o:(mp_rand_source) in archive /tmp/third_party/lib/libtommath-aarch64-unknown-linux-android.a

ld: error: relocation R_AARCH64_LDST64_ABS_LO12_NC cannot be used against symbol 's_mp_rand_source'; recompile with -fPIC

defined in /tmp/third_party/lib/libtommath-aarch64-unknown-linux-android.a(bn_mp_rand.o)
referenced by bn_mp_rand.c
bn_mp_rand.o:(mp_rand_source) in archive /tmp/third_party/lib/libtommath-aarch64-unknown-linux-android.a

ld: error: relocation R_AARCH64_ADR_PREL_PG_HI21 cannot be used against symbol 's_mp_rand_source'; recompile with -fPIC

defined in /tmp/third_party/lib/libtommath-aarch64-unknown-linux-android.a(bn_mp_rand.o)
referenced by bn_mp_rand.c
bn_mp_rand.o:(mp_rand) in archive /tmp/third_party/lib/libtommath-aarch64-unknown-linux-android.a

ld: error: relocation R_AARCH64_LDST64_ABS_LO12_NC cannot be used against symbol 's_mp_rand_source'; recompile with -fPIC

defined in /tmp/third_party/lib/libtommath-aarch64-unknown-linux-android.a(bn_mp_rand.o)
referenced by bn_mp_rand.c
bn_mp_rand.o:(mp_rand) in archive /tmp/third_party/lib/libtommath-aarch64-unknown-linux-android.a

ld: error: relocation R_AARCH64_LDST64_ABS_LO12_NC cannot be used against symbol 's_mp_rand_source'; recompile with -fPIC

defined in /tmp/third_party/lib/libtommath-aarch64-unknown-linux-android.a(bn_mp_rand.o)
referenced by bn_mp_rand.c
bn_mp_rand.o:(mp_rand) in archive /tmp/third_party/lib/libtommath-aarch64-unknown-linux-android.a

@sjaeckel
Copy link
Member

This should be fixed now.

Please update to 1.3.0 and report any potential bugs by opening a new issue or post other questions to that release in #575

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants