OpenSSL Compiled to Run on Android x86 Architecture - android

I've been knocking my head against the wall this one: I've gotten openssl to compile just fine for the android armeabi architecture, but there's so much less aid for x86, and nothing on it that I can find on openSSL's site.
Something I eventually found was an intel article (https://software.intel.com/en-us/articles/using-intel-advanced-encryption-standard-new-instructions-on-android#openssl) on using openssl for x86 architecture's, and after creating a standalone toolchain, and going through their provided code and fixing some of it, I'm at the point where make will get almost all the way through compilation before failing with a bunch of undefined reference to 'XXX' statements. I cannot figure out how to get past this at this point, any help would be greatly appreciated.
I apologize if this ends up being somewhat trivial, I am very new to make.
Trace:
/private/tmp/my-android-toolchain/bin/../lib/gcc/i686-linux-android/4.6/../../../../i686-linux-android/bin/ld: ts.o: in function ts_main:ts.c(.text+0x1e8a): error: undefined reference to 'TS_RESP_set_tst_info'
/private/tmp/my-android-toolchain/bin/../lib/gcc/i686-linux-android/4.6/../../../../i686-linux-android/bin/ld: ts.o: in function ts_main:ts.c(.text+0x1ea2): error: undefined reference to 'TS_TST_INFO_free'
/private/tmp/my-android-toolchain/bin/../lib/gcc/i686-linux-android/4.6/../../../../i686-linux-android/bin/ld: srp.o: in function srp_verify_user:srp.c(.text+0xb3): error: undefined reference to 'SRP_create_verifier'
/private/tmp/my-android-toolchain/bin/../lib/gcc/i686-linux-android/4.6/../../../../i686-linux-android/bin/ld: srp.o: in function srp_create_user:srp.c(.text+0x1e3): error: undefined reference to 'SRP_create_verifier'
/private/tmp/my-android-toolchain/bin/../lib/gcc/i686-linux-android/4.6/../../../../i686-linux-android/bin/ld: srp.o: in function srp_main:srp.c(.text+0x1014): error: undefined reference to 'X509_get_default_cert_area'
/private/tmp/my-android-toolchain/bin/../lib/gcc/i686-linux-android/4.6/../../../../i686-linux-android/bin/ld: srp.o: in function srp_main:srp.c(.text+0x10c0): error: undefined reference to 'SRP_get_default_gN'
/private/tmp/my-android-toolchain/bin/../lib/gcc/i686-linux-android/4.6/../../../../i686-linux-android/bin/ld: srp.o: in function srp_main:srp.c(.text+0x16dd): error: undefined reference to 'TXT_DB_insert'
Edit:
Sorry, by the fact that they were specifying eabi in the setenv script, I thought that meant you could only select one of the ARM eabi's, since the other architectures weren't specified with it. I've been to openSSL's instructions on android for compiling ARM, but I wasn't aware it would also function for x86. If that's the case then I feel dumb.
I set the --sysroot option to the sysroot on the android independent keychain.
These are the commands I used for x86 compilation, as per the intel article on the subject.
export CC="$STANDALONE_TOOCHAIN_PATH/bin/i686-linux-android-gcc -mtune=atom -march=atom --sysroot=$STANDALONE_TOOCHAIN_PATH/sysroot"
export AR=$STANDALONE_TOOCHAIN_PATH/bin/i686-linux-android-ar
export RANLIB=/private/tmp/my-android-toolchain/bin/i686-li
./Configure android-x86 -DOPENSSL_IA32_SSE2 -DAES_ASM -DVPAES_ASM

It seems I've figured it out. Using the code I posted (as the code in the article is slightly syntactically incorrect, but the idea is right) and after having made a custom android toolchain, I was able to run make successfully after a fresh installation of OpenSSL. My guess is that the work I did on it in order to compile the ARM architecture *.a and *.so files probably goofed something up when I went back to it for the x86 architecture.
If unsure of how to create a standalone toolchain (use the easy way option): http://www.kandroid.org/ndk/docs/STANDALONE-TOOLCHAIN.html

but there's so much less aid for x86, and nothing on it that I can find on openSSL's site
I believe the OpenSSL wiki covers the topic: OpenSSL and Android.
Something I eventually found was an intel article... on using openssl for x86 architecture
You simply select the correct abi. According to the Android wiki page, you adjust the following in the setenv-android.sh script:
_ANDROID_NDK – the version of the NDK. For example, android-ndk-r8e
_ANDROID_EABI – the version of the EABI tools. For example, arm-linux-androideabi-4.6
_ANDROID_API – the API level. For example, android-14
There's an entire subsection on it at the wiki: Adjust the Cross-Compile Script. Please let us know if there are any gaps. (I tested it against ARM, but not x86).
There's plenty of ABI's to select. You probably want x86-4.6 and API 14 or API 18.
You might have to modify Configure, but it does not appear you are that far so its hard to say at the moment. You don't need to modify configure - the android-x86 target is already present.
/private/tmp/my-android-toolchain/bin/../lib/gcc/i686-linux-android/4.6/../../../../i686-linux-android/bin/ld: ts.o:
in function ts_main:ts.c(.text+0x1e8a): error: undefined reference to 'TS_RESP_set_tst_info' /private/tmp/my-android-toolchain/bin/../lib/gcc/i686-linux-android/4.6/../../../../i686-linux-android/bin/ld
This almost looks like you are missing --sysroot. Something is munged up for sure.
You should probably show us one of your compile line and a link line (what one of the C files looks like, not a dump of all of them).

I have a similar answer here https://stackoverflow.com/a/37043683/2210080 but this is for ArmV7. Just do the same procedure as what I did in the previous but use this particular setenv-android.sh script: https://github.com/rjmangubat23/OpenSSL/blob/master/x86/setenv-android.sh

Related

Native C Android - Issue in building executable with libptrhead

I'm trying to build an executable from a c file (not written by me) so that I can use it on my phone.
I'm using a toolchain directly from the Android NDK (that use Clang) built for arm64.
The c file needs, as expressed in the makefile, libpthread librtlsdr libmysqlclient, so I downloaded the arm64 versions of these libraries in my toolchain sysroot directory. First question: is this the right way of doing this?
Anyway, after doing this and executing make, it fails saying that it cannot find libpthread.so.0 and libpthread_nonshared.a.
To solve this I copy in the sysroot folder the file it wants from the libc6 arm 64 package (that are not only the two written above, but many others needed in cascade): this way the "make" seems to work fine but once I push it in my device, with the libraries it needs, and run it, I got a runtime error saying:
cannot find verneed/verdef for version index=32770 referenced by symbol "_res" at "/data/local/tmp/TEMP/libc6.so.6"
In this case the problem should be libc6, but I can't figure how to solve this.
This one is related to the libpthread I've downloaded, so the libc6 package, which is probably not suited for Android.
So the real problem is: is there a way to get rid of the first error I mentioned using just the pthread included in Android?
What I hope is that I'm just missing something or using in the wrong way.
Thanks
No, this is not how you are expected to build an executable for Android. You can either use the NDK toolchain, or an alternative toolchain, as described here: Cross compiling static C hello world for Android using arm-linux-gnueabi-gcc.

Visual Studio Android building assembly files into app

We've got a Visual Studio Android solution with (among others) a static library project that contains functionality implemented in assembly. Like:
my.S -> libMine.a -> libMyApp.so
Some hoops (below) have already been jumped through, to get it to compile. Then, the linking of the main app shared library project fails (on both architectures that we care about - x64 and arm64), with undefined references to the functions that are implemented in [the] assembly [file].
It appears that Visual Studio (or its Cross Platform Mobile Dev / Android plug-in) doesn't handle assembly file project items quite correctly - treated as C/C++ Compiler files, it'll error out on the first dot character (i.e. in .text); and the Microsoft Macro Assembler is "not supported on this platform". So I looked into setting up a custom build step, with the following command:
$(ClangToolExe) %(FullPath) --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o
This will preprocess, compile and link - but with the wrong linker: instead of the one for the particular Android toolchain, it'll go for the one in my MinGW install, which doesn't recognise the emulation mode - anyway, that's not the location of my NDK toolchain.
We can skip the linking of the object for now (add -c to the above command). Much to our dismay, the resulting object file still doesn't get added to the static library, as confirmed by {Rest of the toolchain path}ar t libMine.a. And indeed, the library will have undefined symbols for our functions, as shown by {Rest of the toolchain path}objdump -t libMine.a.
Let's add the object file to the resulting library quite manually, as a post build step. Command:
$(ToolChainPrebuiltPath){Rest of the toolchain path}ar.exe ru $(TargetPath) $(IntDir)my.o
objdump -t libMine.a will now show that we've got the symbols. There is however also the *UND*efined pair.
Fast forward:
Adding my.o with ar rub otherObjectThatReferencesMyFunctions.o libMine.a, to have the good symbols show up before the undefined ones doesn't make a difference.
Linking my compiled assembly file with a second custom build step, $(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(IntDir)%(FileName).o -o $(IntDir)%(FileName).o doesn't make a meaningful difference.
Running the linker again on the static library, as a second post-build step $(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(TargetPath) doesn't make a meaningful difference.
The last two steps result in a warning about a missing symbol _start (entry point?). I'm guessing this is in reference to linking an executable, which we don't want.
What am I doing wrong? How can I resolve those undefined references?
What seems to have worked was to:
1, Make sure that the extension of the assembly file is .S, i.e. capital S. This is one of the few instances I've found, where the case of a filename matters on Windows.
2, Configure the project so that the assembly file is built with clang.exe {full/path/to/assembly.S, i.e. %(FullPath)} -c --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o. In the case of VS Android, we need to specify the build output separately, which is the $(IntDir)%(FileName).o part all over again.
3, Run ar as a post build command: {correct toolchain}/ar.exe rus $(TargetPath) {output from assembly compilation}, for each assembly file.
One thing this solution is lacking is detecting [a lack of] changes, meaning that the assembly file will be rebuilt on each compilation, and everything that depends on it.

"Undefined reference to `mcount'" when trying to use -pg [Termux]

I've completed the first part of my project, and I want to know how well / bad it performs by profiling it with gprof. I am working on Android using a Linux emulator named Termux, and I am using g++ as the compiler.
Everything compiles without errors and even warnings, and the binary runs perfectly.
So I decided to put the -pg flag among the other flags in my makefile, (meaning that both compilation and linking is performed with -pg) and tried recompiling everything. But something seems to not work properly: during compilation, everything is normal. But when linking I get a argument unused during compilation: '-pg' warning and then a lot of undefined reference to 'mcount' (it doesn't even display all of them, after a bit it says more undefined references to 'mcount' follows) errors, and at the end a linker command failed with exit code 1 error.
What is causing this behaviour? Is something broken / missing on the platform I am using? Can I fix that? How?
Sorry for the short answer, but I'm on mobile. Making a community wiki.
In Termux, g++ is a symlink to clang. -pg is a gnu feature, so does not function when linking using clang.
You could use clang-appropriate techniques for profiling, or install a real g++. One reference is https://android.stackexchange.com/questions/182130/use-gcc-compiler-in-termux but there is also "google performance tools" for profiling out there somewhere.

Setting up an Android build environment for JNI applications

I've got a hold of a proprietary JNI application which I need to build for a MIPS device. I've read "Initializing a Build Environment", parts of the NDK docs, some Google Groups threads and numerous StackOverflow questions, but I'm still short of my answer.
So far, I've checked out the Android source using Google's repo script and have it under ~/AndroidSource. I've also separately downloaded the SDK under ~/AndroidSDK and the NDK under ~/AndroidNDK. The code I'm trying to build is in a separate location. The SDK and NDK binaries are in my path. For building, I tried to use two different versions of the NDK as well as the one under the Android source tree, and experienced different sets of problems. My current setup uses NDK r8b, downloaded separately from the Android source.
The application has its Android.mk and jni/Android.mk. However, several directives in the latter point to paths such as
frameworks/base/include
system/core/include
with no prefixes. I thought these were meant to point to the respective directories in the Android source, so I symlinked them to the current directory. After some more symlinking and makefile and source hacking, I got the application to compile, but am currently stuck on the linking phase with lots of references to missing method bodies. During the whole time I knew I was doing something wrong.
I'm on a Linux x86_64 host, if it is of any concern.
So my question is:
What is the proper method to set up a build environment for JNI applications? What environment variables, symlinks and/or path expansions should I set up? Do I need to call any scripts once or before each ndk-build invocation?
Also, I'd be happy if you corrected me on any concepts or terminology I've gotten wrong.
Your approach wiyh symlinking the AOSP tree for system headers is correct. What you need now are the system libraries compiled for MIPS. The easiest way to get them is to adb pull them from a target device (or emulator image). But you can also build these libraries yourself, as part of the AOSP build (see build instructions for the source tree you downloaded).
If you still have any problems remaining, run your ndk-build with parameter V=1 and publish the link command and its results.
I use the following in my build (YMMV).
Explicitly invoke arm-linux-androideabi-gcc as your compiler or linker (should be in PATH).
NDK_PLATFORM=/path/to/android-ndk-r*/platforms/android-14
Pass -I"$(NDK_PLATFORM)/arch-arm/usr/include" to the compiler
Pass -nostdlib -L"$(NDK_PLATFORM)/arch-arm/usr/lib/" -lgcc -lc -lm to the linker

Ubuntu-to-Android Cross Compile linking for clock_gettime

I recently developed a project in C which makes use of the function clock_gettime() in linux. The linking for this on my Ubuntu desktop is achieved using the linker flag:
gcc -lrt foo.c
I was excited to read that I could cross-compile my project for the Android in the post below.
http://benno.id.au/blog/2007/11/13/android-native-apps
I've tried this on trivial projects though using the command:
arm-linux-gnueabi-gcc -static foo.c -o foo
Rather than the command:
arm-none-linux-gnueabi-gcc -static foo.c -o foo
referred to in the link, and they do indeed compile and link fine, but when I try with my project requiring clock_gettime() and the linking:
-ltr
It fails with:
undefined reference to `clock_gettime'
I've read that library specified by -lrt doesn't exist for the Android, and I've found posts other places claiming that folks are using clock_gettime() on Android projects, but I haven't been able to find the right library to link to for this. Can anyone tell me what I need to link to for the ARM to make this work?
Or make any other suggestions as to alternatives that will work on the Android.
I am very much interested in leveraging my existing makefiles from my Desktop linux projects to what extent I can, but reconfiguring them to work with the cross-compile tool chain if possible, so any suggestions which would allow for that would be very greatly appreciated.
Android's "bionic" C library has a wrapper for the clock_gettime() syscall. If you build using the Android NDK you'll get that automatically. Otherwise you need to add a bionic library to your toolchain somehow.
Alternatively, you could call the syscall directly via assembly (from memory, the first argument goes in R0, the second in R1, you put the syscall number in R7, issue "SWI $0" and find the result code in R0).
Alternatively: why are you bothering with clock_gettime? Is there any reason you can't simply use gettimeofday()?

Categories

Resources