5

I am trying to build the C++ POCO library for an Android target in a fresh Ubuntu that I just installed for that.

I have installed the Android NDK in /home/user/dev/Android/android-ndk-r9-x86 and added the path to the NDK in the environement variables using :

export ANDROID_NDK_ROOT=/home/user/dev/Android/android-ndk-r9-x86

To build the libraries I first move to the root directory of the POCO library, and configure it using :

./configure --omit=NetSSL_OpenSSL,Crypto,Data/ODBC,Data/MySQL --static --config=Android

So that it compiles static .a libraries, doesn't compile the modules I don't want and compiles for an Android target.

But than calling make causes the following error :

user@user-VirtualBox:~/dev/Lib/POCO/poco-1.6.1$ make
make -C /home/user/dev/Lib/POCO/poco-1.6.1/Foundation
make[1]: Entering directory `/home/user/dev/Lib/POCO/poco-1.6.1/Foundation'
** Compiling src/ArchiveStrategy.cpp (debug, static)
arm-linux-androideabi-g++  -Iinclude -I/home/user/dev/Lib/POCO/poco-1.6.1/CppUnit/include -I/home/user/dev/Lib/POCO/poco-1.6.1/CppUnit/WinTestRunner/include -I/home/user/dev/Lib/POCO/poco-1.6.1/Foundation/include -I/home/user/dev/Lib/POCO/poco-1.6.1/XML/include -I/home/user/dev/Lib/POCO/poco-1.6.1/JSON/include -I/home/user/dev/Lib/POCO/poco-1.6.1/Util/include -I/home/user/dev/Lib/POCO/poco-1.6.1/Net/include -mthumb -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 -frtti -fexceptions -DPOCO_BUILD_HOST=user-VirtualBox  -DPOCO_ANDROID -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_WSTRING -DPOCO_NO_SHAREDMEMORY  -g -D_DEBUG  -c src/ArchiveStrategy.cpp -o /home/user/dev/Lib/POCO/poco-1.6.1/Foundation/obj/Android/armeabi/debug_static/ArchiveStrategy.o
sh: 1: arm-linux-androideabi-g++: not found
make[1]: *** [/home/user/dev/Lib/POCO/poco-1.6.1/Foundation/obj/Android/armeabi/debug_static/ArchiveStrategy.o] Error 127
make[1]: Leaving directory `/home/user/dev/Lib/POCO/poco-1.6.1/Foundation'
make: *** [Foundation-libexec] Error 2

Make seems unable to find the compiler used for Android, and I have no idea why ? What am I missing ? Did i forget something when "installing" the NDK ?

Thank you.

Virus721
  • 8,061
  • 12
  • 67
  • 123
  • You did not install the ARM (`arm-linux-androideabi`) toolchain. – Shark Feb 03 '16 at 13:24
  • @Shark Thanks for your answer. Doesn't the toolchain come with the NDK ? I'm very unfamiliar with the toolchain things. Could you point me into the right direction ? – Virus721 Feb 03 '16 at 13:25
  • Actually, yes I can. Lemme write it up for you... – Shark Feb 03 '16 at 13:26
  • You actually need to install the standalone toolchain as well as the NDK, and then you should be good to go. the NDK doesn't actually contain anything **but** the NDK sources. the NDK won't help you build it. – Shark Feb 03 '16 at 13:37

1 Answers1

5

The error you're getting is caused by a missing toolchain invocation - rather, the arm-linux-androideabi-g++ command/executable/binary was nowhere to be found.

Luckily, we can get around that by installing the Standalone toolchain - that one actually has the exact thing you're missing, a general purpose arm-linux-androideabi cross-compiler instead of some other, a bit more obscure, vendor/platform-specific crosscompiler/toolchain, such as armv7a-marvell-linux-android which is what marvell uses, or arm-linux-android which is what Clang uses. For more info on Clang, look here. I could be wrong though and that Clang actually produces a arm-linux-androideabi toolchain out of the box, but I'm unsure. I know you can use it easily, I'm just unsure if it can be used "straight out of the box" which is what you're looking for. The "rest of the work" is just a few path exports - but still. We're aiming for the laziest solution here.

The standalone toolchain should be quite sufficient for your task, so try using it as much as possible over any other cross-compilation solutions.

However, if you're feeling adventurous - you're free to make your own cross-compiler (or the whole toolchain!) using the crosstool-ng tool. However, try to stick with the Linaro libc branch; personal experience showed me that one somehow works the best and causes the least amount of problems/time wasted.

Also, make sure you download the right one for your architecture (arch) and OS, 32bit vs 64bit matters here as well. After a lengthy discussion, we realized it was a "32bit vs 64bit" problem. Here's a link to read more about it.

AStopher
  • 4,207
  • 11
  • 50
  • 75
Shark
  • 6,513
  • 3
  • 28
  • 50
  • Thanks for taking the time to answer. I will try to setup this toolchain. – Virus721 Feb 03 '16 at 14:01
  • Thanks for taking the time to accept the answer if it helped you. – Shark Feb 03 '16 at 14:41
  • 1
    So what I have done is (according to the procedure described in the link you gave me) : **1)** install g++, install cmake (not sure that was needed), install the NDK r9, **2)** define the env var `ANDROID_NDK_ROOT` to point to the root directory of the NDK, **3)** `export APP_ABI=arm-linux-androideabi-4.8`, **4)** `SYSROOT=$ANDROID_NDK_ROOT/platforms/android-18/arch-arm`, **5)** Created a toolchain using `$ANDROID_NDK_ROOT/build/tools/make-standalone-toolchain.sh --arch=arm --platform=android-18 --install-dir=/tmp/my-android-toolchain --toolchain=arm-linux-androideabi-4.8` – Virus721 Feb 03 '16 at 14:48
  • **6)** `export PATH=/tmp/my-android-toolchain/bin:$PATH`, **7)** `export CC=arm-linux-androideabi-gcc`, **8)** `export CXX=arm-linux-androideabi-g++` **9)** Configured the POCO lib build using : `./configure --omit=NetSSL_OpenSSL,Crypto,Data/ODBC,Data/MySQL --static --config=Android --cflags="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"` **10)** `make`. But i'm still getting the error so I must be missing something. Do you have any idea ? Thank you. – Virus721 Feb 03 '16 at 14:50
  • do your POCO lib `Makefile`s/`Android.mk` files reference `CC` or do they target `arm-linux-androideabi-g++` directly? – Shark Feb 03 '16 at 14:59
  • I'm very unfamiliar with make files so I'm not sure, but I think they do reference the CC and CXX variables. There are things like : `$(OBJPATH_DEBUG_STATIC)/%.o: $(SRCDIR)/%.cpp $(DEPPATH)/%.d @echo "** Compiling" $< "(debug, static)" $(CXX) $(INCLUDE) $(CXXFLAGS) $(DEBUGOPT_CXX) $(STATICOPT_CXX) -c $< -o $@` – Virus721 Feb 03 '16 at 15:04
  • Should I redefine the value of `$CC` and `$CXX` so that they directly point to tine gcc and g++ binaries located to `/tmp/my-custom-toolchain/arm-linux-androideabi/bin/gcc` and g++ binaries ? Or maybe that I should just set $CC to gcc and $CXX to g++ – Virus721 Feb 03 '16 at 15:13
  • Yes and no. `CC` should always point to `gcc` and `CXX` to `g++` Export `CC` to point to the `-gcc` binary, and export `CXX` to point to `-g++` binary and retry please :) – Shark Feb 03 '16 at 15:19
  • I have tried both options **1)** setting `CC` to just `gcc` and `CXX` to just `g++`, but it didn't work since `gcc` and `g++` are located in `/tmp/my-android-toolchain/bin/arm-linux-androideabi/` while the path added to `$PATH` is just `/tmp/my-android-toolchain/bin/` **2)** Setting `CC` and `CXX` with an absolute path to `/tmp/my-android-toolchain/bin/arm-linux-androideabi/gcc` (and `g++` too), but I'm getting the same result. – Virus721 Feb 03 '16 at 15:30
  • In that case, we need to go a bit deeper... please post the lines (output) of a few compilation lines, we need to see if it's actually 'hitting' the compiler at all and if the compiler is throwing an error, or if we're 'missing' and the OS is giving us "I can't find that thing there" error. But don't post them in the comments please :) P.S. so far the error I see in your opening post is the OS telling you "i can't find that thing there" – Shark Feb 03 '16 at 15:32
  • Well the compilation ends with the error i posted in my question. It doesn't go any farther since it can't find `arm-linux-androideabi-g++` which DOES exist in `/tmp/my-android-toolchain/` and thus in the path. – Virus721 Feb 03 '16 at 15:36
  • try invoking it from terminal if it **should** work ? if you can't invoke it from terminal, don't expect the script to be able to either :) when terminal invocation works fine, then you can tackle fixing the script. – Shark Feb 03 '16 at 15:39
  • 1
    Good point ! It is not found when called directly from the terminal. – Virus721 Feb 03 '16 at 15:41
  • if you're not quite sure what will be ran, add a `--just-print` C tag / build flag. that one should print everything but not do anything. should help you in figuring out the root cause of the problem :) – Shark Feb 03 '16 at 15:42
  • It's strange. It keeps saying `/tmp/my-android-toolchain/bin/arm-linux-androideabi-g++: No such file or directory` even if I specify a full path. Maybe that it's just not an executable file. – Virus721 Feb 03 '16 at 15:50
  • run `file arm-linux-androideabi-g++` or `chmod 777 arm-linux-androideabi-g++` – Shark Feb 03 '16 at 15:52
  • `file` says : `/tmp/my-android-toolchain/bin/arm-linux-androideabi-g++: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, stripped` and chmod didn't help :( **EDIT** Maybe that one of the dynamically loaded .so files required by this executable is missing ? – Virus721 Feb 03 '16 at 15:57
  • no, you're not missing anything, the file is just missing the `executable` flag, but `chmod 777` will take care of all those silly file-permission-related problems for you :) Run `ls -all` and see if the file has an `x` somewhere next to it. – Shark Feb 03 '16 at 16:06
  • Well the file does have the X flag in all three columns of `ls`, but I still tried to `chmod 777`on that file and nothing changed. – Virus721 Feb 03 '16 at 16:08
  • **IF** the file has an `x` next to it, yet still can't be ran - download the one for your OS instead of the windows `x86` one. – Shark Feb 03 '16 at 16:08
  • Well this file was created by toolchain creator of the NDK for Linux, which indeed I transfered from my host Windows to my Linux VM, but it was zipped and as I downloaded it. Where else could I get this ? – Virus721 Feb 03 '16 at 16:09
  • ... you didn't make a Windows->ARM crosscompiler (on win) and transferred that to the Linux machine, did you? :) try invoking the compiler on teh windows machine, if it runs - then that's the problem. it shouldn't run. you're not making a canadian-cross toolchain (machine1 making a toolchain for machine2 which will build for machine3), just a cross-compiler (machine1 makes a toolchain and builds for machine2) – Shark Feb 03 '16 at 16:11
  • No no. I transfered the compressed NDK as I downloaded it from my WIndows to my Linux VM, extracted and installed it on Linux and done all the operations explained in the link you gave me on Linux. Nothing was done on windows, except downloading the NDK. EDIT Ok i will try copying it to windows. – Virus721 Feb 03 '16 at 16:13
  • downloading the NDK has nothing to do with it, not being able to run the linux compiler on linux is the problem. that should be fixed somehow before attempting to run the makefile again. once `gcc --version` gives an output, then run the makefile :) **but make sure you run your gcc, and not the default one present on the system** – Shark Feb 03 '16 at 16:14
  • and by the way - the NDK and the crosscompiler are *still* unrelated things. once the crosscompiler starts working, then they'll start relating. – Shark Feb 03 '16 at 16:16
  • 1
    It doesn't run on Windows as I expected. Anyway, thank you very much for your help. I'll try to find out why it won't execute. – Virus721 Feb 03 '16 at 16:16
  • I forgot to mentio that `ls` displays that file in green, if it matters. – Virus721 Feb 03 '16 at 16:18
  • green is good. that means it's executable. just go to it's folder and try running it to get an output from it or the OS about why can't it execute it :) – Shark Feb 03 '16 at 16:27
  • I found the solution : http://unix.stackexchange.com/questions/259636/file-does-exist-but-wont-execute/259637#259637 Please add it to your answer :) – Virus721 Feb 03 '16 at 16:40