cannot find -lgnustl_static: Compiling Android SDL port with NDK r7 - android

I'm trying to build this port of libSDL for Android, using the new Android NDK r7 release:
https://github.com/pelya/commandergenius
I know I am doing some things to some degree "unsupported": I am using cygwin&windows despite that being mentioned in the README as no longer being supported. That being said, I can hack out shell scripts and solve my problems as necessary and have it compiling but not linking.
So anyways I have compiling working until the linking (sorry for large block, relevant part trimmed below):
/cygdrive/c/and/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-ar crs obj/local/armeabi/libflac.a ./obj/local/armeabi/objs-debug/flac/src/ogg_decoder_aspect.o ./obj/local/armeabi/objs-debug/flac/src/md5.o ./obj/local/armeabi/objs-debug/flac/src/stream_decoder.o ./obj/local/armeabi/objs-debug/flac/src/fixed.o ./obj/local/armeabi/objs-debug/flac/src/memory.o ./obj/local/armeabi/objs-debug/flac/src/stream_encoder.o ./obj/local/armeabi/objs-debug/flac/src/window.o ./obj/local/armeabi/objs-debug/flac/src/cpu.o ./obj/local/armeabi/objs-debug/flac/src/ogg_encoder_aspect.o ./obj/local/armeabi/objs-debug/flac/src/lpc.o ./obj/local/armeabi/objs-debug/flac/src/float.o ./obj/local/armeabi/objs-debug/flac/src/bitmath.o ./obj/local/armeabi/objs-debug/flac/src/metadata_object.o ./obj/local/armeabi/objs-debug/flac/src/ogg_helper.o ./obj/local/armeabi/objs-debug/flac/src/metadata_iterators.o ./obj/local/armeabi/objs-debug/flac/src/bitreader.o ./obj/local/armeabi/objs-debug/flac/src/bitwriter.o ./obj/local/armeabi/objs-debug/flac/src/stream_encoder_framing.o ./obj/local/armeabi/objs-debug/flac/src/crc.o ./obj/local/armeabi/objs-debug/flac/src/format.o ./obj/local/armeabi/objs-debug/flac/src/ogg_mapping.o
C:/and/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.exe: cannot find -lgnustl_static
collect2: ld returned 1 exit status
/cygdrive/c/and/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-ar crs obj/local/armeabi-v7a/libflac.a ./obj/local/armeabi-v7a/objs-debug/flac/src/ogg_decoder_aspect.o ./obj/local/armeabi-v7a/objs-debug/flac/src/md5.o ./obj/local/armeabi-v7a/objs-debug/flac/src/stream_decoder.o ./obj/local/armeabi-v7a/objs-debug/flac/src/fixed.o ./obj/local/armeabi-v7a/objs-debug/flac/src/memory.o ./obj/local/armeabi-v7a/objs-debug/flac/src/stream_encoder.o ./obj/local/armeabi-v7a/objs-debug/flac/src/window.o ./obj/local/armeabi-v7a/objs-debug/flac/src/cpu.o ./obj/local/armeabi-v7a/objs-debug/flac/src/ogg_encoder_aspect.o ./obj/local/armeabi-v7a/objs-debug/flac/src/lpc.o ./obj/local/armeabi-v7a/objs-debug/flac/src/float.o ./obj/local/armeabi-v7a/objs-debug/flac/src/bitmath.o ./obj/local/armeabi-v7a/objs-debug/flac/src/metadata_object.o ./obj/local/armeabi-v7a/objs-debug/flac/src/ogg_helper.o ./obj/local/armeabi-v7a/objs-debug/flac/src/metadata_iterators.o ./obj/local/armeabi-v7a/objs-debug/flac/src/bitreader.o ./obj/local/armeabi-v7a/objs-debug/flac/src/bitwriter.o ./obj/local/armeabi-v7a/objs-debug/flac/src/stream_encoder_framing.o ./obj/local/armeabi-v7a/objs-debug/flac/src/crc.o ./obj/local/armeabi-v7a/objs-debug/flac/src/format.o ./obj/local/armeabi-v7a/objs-debug/flac/src/ogg_mapping.o
C:/and/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.exe: cannot find -lgnustl_static
collect2: ld returned 1 exit status
Relevant failure, if you can't parse that wall of text:
ld.exe: cannot find -lgnustl_static
Now, if I look at the Windows NDK release I find gnustl_* files here:
under ./android-ndk-r7/sources:
./cxx-stl/gnu-libstdc++/libs/armeabi/libgnustl_shared.so
./cxx-stl/gnu-libstdc++/libs/armeabi/libgnustl_static.a
./cxx-stl/gnu-libstdc++/libs/armeabi-v7a/libgnustl_shared.so
./cxx-stl/gnu-libstdc++/libs/armeabi-v7a/libgnustl_static.a
./cxx-stl/gnu-libstdc++/libs/x86/libgnustl_shared.so
./cxx-stl/gnu-libstdc++/libs/x86/libgnustl_static.a
I looked also at the linux android NDK distribution and they are packaged the same (only have libgnustl files, built, under the sources directory).
So I have 3 questions:
why would we be using -l to link libgnustl_static when it's a .a
file? Shouldn't that be just including the .a file in the object
list, or alternately be -lgnustl_shared?
why are these files only under "sources"? I would have expected them to be in the "toolchains" library NDK directory. How does anyone ever link against libgnustl?
Can I copy these files somewhere where they'll be seen by the linker? Just adding their directory with -L hasn't seemed to work, and plus I need to get the right versions linked with the right build target (armeabi vs armeabi-v7 vs x86)

This is a bug in gcc/NDK that manifests itself slightly different on Linux, Cygwin, and Windows (non Cygwin).
Here's what I did to fix it (works for Linux and for one of my developers who is blind and has to use Cygwin)...
Remove the line that says, APP_STL := gnustl_static from your Application.mk (it's broken in the NDK, and it's broken slightly differently on Linux Cygwin, Windows)
add a line to $(LOCAL_LDLIBS) in your Android.mk file that says:
$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/libgnustl_static.a
also add two lines to Android.mk that say:
LOCAL_C_INCLUDES := $(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.6/include
LOCAL_C_INCLUDES += $(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include
The foregoing will accomplish what having, APP_STL := gnustl_static in your Application.mk was supposed to.

In case this plagues anyone else, the solution is to remove -lgnustl_static and instead list
c:\path\to\armeabi\libs\libgnustl_static.a in the linker command.
Do not use /cygdrive style path, as the linker will fail to find the file. Use actual c:\...

Related

Native library not found on android build?

I am getting this error: unable to lookup library path for, native render plugin support disabled when I run my app on android. I think I am building the shared libraries incorrectly.
I am looking to build the source files from this repo. I'll say my build process and perhaps someone can spot a step I'm missing or doing incorrect.
Following this guide, I came up with this:
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libhydrogen
LOCAL_SRC_FILES := ..\hydrogen.c
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_PLATFORM := android-16
APP_OPTIM := release
APP_MODULES := libhydrogen
Next I:
Placed these files in the jni folder.
Called ndk-build.
Copied the .so files from the \libs folder and placed them in their respective folders in Unity (i.e. Hydrogen\Plugins\Android\arm64-v8a).
Made sure their platforms and CPU architectures were correct.
Built my app.
Here is the c# wrapper I am using.
Calling Hydrogen.Library.Initialize(); is then giving me this error.
Here is the full logcat related to this error.
And in the case my build process manages to be correct, and the .so files are fine; what else might cause this to happen?
Edit: I am trying to build for armeabi-v7a and `x86. Here are the .so file details, maybe there is something there that is not right? I am unfamiliar with c and since I haven't heard of anyone building this library for android, I wonder: could there be anything within the c source file that is incompatible with the NDK build process?
Native libraries are loaded by the native linker of the system, in your case, the linux dynamic linker: ld.so (it changes names sometimes, so I used that name, as you can check the man page in the documentation with that name).
For that to happen, in general, you need to provide a LD_LIBRARY_PATH environment variable to the java virtual machine, so it can effectively dlopen(3) it.
Think how different can be your development system to your target one.... and you'll easily get to that.
It was a bug with Unity! For some reason when switching the project's target platform some of my files would get corrupted. Strangely, it only seems to happen in this one project, but in any case the (temporary) solution is to re-import the plugin folder whenever I switch platforms.

Hello-Jni on Windows, Android NDK - build-local.mk: No such file

I have tried scouring the Internet and StackOverflow (too many articles to count) but cannot find assistance that is all of these things:
More recent than 2013
Does not require Cygwin if developing
on Windows
Is geared to Android Studio, NOT Eclipse.
I am diving head first into Android development for the very first time and the project I have newly joined depends on developing with the NDK. I've been reading the docs that come with the NDK but have run into a stone wall with this sample.
I am trying to build hello-jni, the sample project within the NDK. Here is my environment:
Android Studio 1.4 (most up to date, stable version currently available)
NDK version: r10e
OS: Windows 7
Contents of Application.mk file:
APP_ABI := all64 // Came with 'all', read somewhere on SO that it
// should be 'all64'. Result is the same.
Contents of Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
My PATH environment variable includes a path to my NDK root folder and to \prebuilt\windows-x86_64\bin (because I read on one of many articles that it should.) When I navigate to the hello-jni root folder though, and call ndk-build, I am only presented with errors.
c:\NDK\android-ndk-r10e\build\core\build-local.mk:40: c:/NDK/android-ndk-r10e/build/core/build/core/init.mk: No such file or directory
c:\NDK\android-ndk-r10e\build\core\build-local.mk:191: \add-application.mk: No such file or directory
c:\NDK\android-ndk-r10e\build\core\build-local.mk:206: \setup-imports.mk: No such file or directory
c:\NDK\android-ndk-r10e\build\core\build-local.mk:223: \build-all.mk: No such file or directory
make.exe: *** No rule to make target `\build-all.mk'. Stop.
If anything else is required for people to assist me, say the word I will provide what I can. All help will be greatly appreciated.
EDIT:
Most of the articles of I've seen for Windows mention Cygwin, but according to the docs, it isn't needed. If this is incorrect, please correct me?
Except from \android-ndk-r10e\docs\Programmers_Guide\html\md_3__key__topics__building__s_t_a_n_d_a_l_o_n_e-_t_o_o_l_c_h_a_i_n.html
Windows support
The Windows binaries do not depend on Cygwin. The good news is that they are thus faster, the bad news is that they do not understand the Cygwin path specification like /cygdrive/c/foo/bar (instead of C:/foo/bar).
The NDK build system ensures that all paths passed to the compiler from Cygwin are automatically translated, and deals with other horrors for you. If you have a custom build system, you may need to deal with the problem yourself.
I can't take the credit for this answer, a coworker kindly sleuthed it out for me. When he found the answer, I demanded to know what else he had done, because clearly I must have missed some magic? I only saw him switch two lines in a make file, there had to be more? Alas, no. This alone was the source of my woe.
While I'm hesitant to call it an error within the NDK because I don't know how it works with Cygwin, neither of us can understand how this has ever worked for anyone building in native Windows, as the line I will be referencing is recorded in the git repository as being added back in 2011 or 2010. ( https://android.googlesource.com/platform/ndk/+/master/build/core/build-local.mk )
To aid explanation, here is the first line of my error again:
c:\NDK\android-ndk-r10e\build\core\build-local.mk:40: c:/NDK/android-ndk-r10e/build/core/build/core/init.mk: No such file or directory
The first file that is unable to found is ...build/core/build/core/init.mk, which of course doesn't exist because build/core should not be repeated.
The command that begins the build, ndk-build.cmd, calls build\core\build-local.mk to begin the process. Inside this file the environment variable, NDK_ROOT, is recreated upon entry. Whatever my NDK_ROOT is, is irrelevant.
NDK_ROOT := $(dir $(lastword $(MAKEFILE_LIST)))
NDK_ROOT := $(strip $(NDK_ROOT:%build/core/=%))
NDK_ROOT := $(subst \,/,$(NDK_ROOT))
NDK_ROOT := $(NDK_ROOT:%/=%)
.
.
.
The second line strips the end of the current directory (the build/core/) from the end of my new NDK_ROOT, because the true root should be the parent directory of build and because it will be added back later to find all those 'missing' files. That's fine, except note the forward-slashes (/) used in the search. Windows does not use (or in my experience at least, usually does not return) forward-slashes, though it will often parse them if that is what it's given. (When changing directories, for example, I've found either to be acceptable as long as I already know where I need to go. Tab completion does not seem to function if my path ends with a /.)
Oh, but look at the third line (added way back in 2011)! A substitution is made of every backslash (\) in NDK_ROOT, replaced with forward-slash (/). So the replacement of build/core/ should go off without a hitch, right? Problem: it's too late.
The strip call has already occurred and if the NDK_ROOT received a path with backslashes instead of forward-slashes, build/core/ is never found and stripped from the variable. How did my coworker fix it? Easy. He switched the lines around:
NDK_ROOT := $(dir $(lastword $(MAKEFILE_LIST)))
NDK_ROOT := $(subst \,/,$(NDK_ROOT))
NDK_ROOT := $(strip $(NDK_ROOT:%build/core/=%))
NDK_ROOT := $(NDK_ROOT:%/=%)
My hello-jni project now builds, along with Teapot, another sample from the NDK, which I tried just to be sure. And so does native-audio, native-codec, native-media, and More Teapots. Haven't tried to run them yet... but I have no build errors.
I don't know if this fix will break Cygwin users, I don't have that on my box. I also don't know if it would break Linux environments because I don't have Linux on my box. But this may help native Windows users, and I hope so, because I uselessly beat my head on this for 3 or 4 days and read more SO articles than I ever care to at once.
Using a windows machine I encountered this error but it was saying the clear-vars.mk : No such file or directory. After I looked at the ndk-build.cmd in the directory
C:\Users\\AppData\Local\Android\Sdk\ndk-bundle\build
the file looks like this
#echo off
set NDK_ROOT=%~dp0\..
set PREBUILT_PATH=%NDK_ROOT%\prebuilt\windows-x86_64
if exist %PREBUILT_PATH% goto FOUND
set PREBUILT_PATH=%NDK_ROOT%\prebuilt\windows
:FOUND
"%PREBUILT_PATH%\bin\make.exe" -f "%NDK_ROOT%\build\core\build-local.mk" SHELL=cmd %*
But you will also find the same file name under directory
C:\Users\jmatthews\AppData\Local\Android\Sdk\ndk-bundle
and the file looks like this
#echo off
%~dp0\build\ndk-build.cmd %*
remove the second line so it looks like this with only 1 line echo off
#echo off
This file is called and messes up the Windows directory structure. After that I was able to compile on windows. Also I had issues with the project using a space in the directory so move your project location to directories without spaces.

NDK and Android 1.5

My Android mixed (Java/NDK) project was going along nicely. Then suddenly I got a report that the native library failed to load on Android 1.5.
On the emulator, it reproduced perfectly. There's an UnsatisfiedLinkError thrown on the System.loadLibrary() call. The message says "library can't be found", but it's right there. Earlier versions of the app worked on Android 1.5; but I didn't test every single build on it.
I don't remember introducing any new RTL calls recently. Moreover, I've dumped all my imported symbols with readelf -s mylib.so | grep UND and matched them against readelf -s output for libc.so and libstdc++.so, as pulled from the 1.5 emulator. All the symbols can be found in either of those libraries, with the exception of three:
__cxa_begin_cleanup
__cxa_type_match
__cxa_call_unexpected
But those are weak references. They shouldn't cause an error. And also, I couldn't find them in Android 4.2's libraries either. Where do they reside? Are they indeed to blame?
If those symbols are causing the error, I didn't insert the dependency on them - the NDK toolchain did. Probably rebuilding against an older version of NDK libraries would help; is there a way to specify the NDK platform version to use on per-CPU_ABI basis? I'm building for all four CPU_ABI; in android-ndk-r9d\platforms\android-3, only ARM can be found.
EDIT: rebuilding with
ifeq ($(TARGET_ARCH_ABI),armeabi)
TARGET_PLATFORM := android-3
endif
doesn't help. Neither does scratching all but ARM and adding
APP_PLATFORM := android-3
to Application.mk.

Android NDK code analysis not using defined variables

I think this problem started when upgrading to the Juno Eclipse. I believe the C/C++ build environment was probably upgraded as well at the same time. The NDK was not upgraded.
We have a large mass of C code that compiles under several platforms. We are using the crystax-ndk (r6) to compile our C++ code. To know when we are compiling for Android, we have defined the following in the Android.mk
LOCAL_CFLAGS := -DANDROID_NDK \
-DDISABLE_IMPORTGL \
...
Then in some files we will include different headers depending upon the platform
#ifdef ANDROID_NDK
...
Our code compiles just fine and seems to run fine. However, when opening certain files the C/C++ code analyzer will find many errors. This appears to be because the analyzer doesn't know about the ANDROID_NDK defined variable.
Any idea why the code analyzer is not using the same #defines as the compiler? The code is almost uneditable with all the bogus errors the analyzer is reporting.
I saw you're comment about the analyzer you were refering to.
Eclipse CDT (C/C++ Development Toolkit) does not support parsing Android.mk yet neither does the NDK plugin add that functionality at the time of writing this.
Possible (ugly/annoying) workaround: Set up a header file setting the defines you are missing and include that header file to all files.
Use LOCAL_CPPFLAGS for C++ files and LOCAL_CFLAGS for C files in your Android.mk

Problems compiling avahi into Android NDK project

Over the last few days I've been having a difficult time trying to build avahi into a static or shared library for use with an existing Android NDK project.
We have a few games in the App and Play stores and my task is to get multiplayer working in the Android versions.
Specifically the task involves replacing the Bonjour component so that these games can connect to each other via zeroconf.
Research seemed to indicate that avahi is the lib that we're looking for, but at this point I'm open to anything that will work!
I'm hoping that someone here can either help me get avahi compiling or suggest another more appropriate (and easier to install) lib.
Project uses android-ndk-r8b and is being built on OSX 10.7.4 using command line (not eclipse)
Got the latest Avahi source from here:
http://www.linuxfromscratch.org/blfs/view/svn/basicnet/avahi.html
homebrewed all the necessary libs to get ./configure to run without errors.
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --disable-static --disable-mono --disable-monodoc --disable-gdbm --disable-libdaemon --disable-nls --disable-gtk --disable-gtk3 --disable-python --disable-qt3 --disable-qt4 --enable-core-docs --with-distro=none
./configure runs with no apparent red flags.
make results in this compile error:
socket.c: In function 'ipv6_pktinfo':
socket.c:271: warning: unused variable 'yes' [-Wunused-variable]
socket.c:270: warning: unused parameter 'fd' [-Wunused-parameter]
socket.c: In function 'avahi_send_dns_packet_ipv6':
socket.c:609: error: 'IPV6_PKTINFO' undeclared (first use in this function)
socket.c:609: error: (Each undeclared identifier is reported only once
socket.c:609: error: for each function it appears in.)
socket.c: In function 'avahi_recv_dns_packet_ipv6':
socket.c:869: error: 'IPV6_HOPLIMIT' undeclared (first use in this function)
socket.c:878: error: 'IPV6_PKTINFO' undeclared (first use in this function)
make[2]: *** [libavahi_core_la-socket.lo] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
Figured that it's not building against the android-ndk-r8b libs or finding ipv6.h or something.
Checked my .bash_profile.sh file:
export PATH=/Users/Muy01/Projects/Development/Android/android-sdks/tools/:$PATH
export PATH=/Users/Muy01/Projects/Development/Android/android-sdks/platform-tools/:$PATH
export PATH=/Users/Muy01/Projects/Development/Android/android-ndk-r8b/:$PATH
added --host=arm-linux-androideabi to the ./configure arguments list
resulting in this error:
checking host system type... Invalid configuration `arm-linux-androideabi': system `androideabi' not recognized
Couldn't figure out how to get a list of available host system types so changed direction and decided to try and build the static lib via Android.mk file.
Found this post on creating an appropriate Android.mk file:
can't compile avahi on android
Realized that I don't have Android.mk files within all the subdirectories.
Researched, downloaded, built, Androgenizer to try and convert all the Makefile.am files into Android.mk files.
http://cgit.collabora.com/git/user/derek/androgenizer.git/
Couldn't figure out or find info on how to do that though =/
Decided to try and create my own Android.mk file:
LOCAL_PATH := $(call my-dir)
ROOT_LOCAL_PATH :=$(call my-dir)
#Build avahi into a static lib
include $(CLEAR_VARS)
AVAHI_TOP := $(ROOT_LOCAL_PATH)/../avahi-0.6.31
MY_SOURCES := $(wildcard $(AVAHI_TOP)/avahi-core/*.c*)
MY_SOURCES += $(wildcard $(AVAHI_TOP)/avahi-common/*.c*)
LOCAL_C_INCLUDES := $(AVAHI_TOP)
LOCAL_SRC_FILES := $(MY_SOURCES:$(LOCAL_PATH)%=%)
LOCAL_MODULE := avahi
include $(BUILD_STATIC_LIBRARY)
Results in compile time errors for avahi-core/iface-linux.c:33:0:
/avahi-0.6.31/avahi-core/iface-linux.h:27:8: Redefinition of 'struct AvahiInterfaceMonitorOSDep'
/avahi-0.6.31/avahi-core/iface.h:46:16: Originally defined here
/avahi-0.6.31/avahi-core/iface-linux.h:33:9: Redeclaration of enumerator 'LIST_IFACE'
/avahi-0.6.31/avahi-core/iface.h:52:9: Previous definition of 'LIST_IFACE' was here
/avahi-0.6.31/avahi-core/iface-linux.h:34:9: Redeclaration of enumerator 'LIST_ADDR'
/avahi-0.6.31/avahi-core/iface.h:53:9: Previous definition of 'LIST_ADDR' was here
/avahi-0.6.31/avahi-core/iface-linux.h:35:9: Redeclaration of enumerator 'LIST_DONE'
/avahi-0.6.31/avahi-core/iface.h:54:9: Previous definition of 'LIST_DONE' was here
/jni//../avahi-0.6.31/avahi-core/iface-linux.c: In function 'netlink_callback':
And now I'm pretty much stuck.
I tried #if 0'ing out the iface-linux.c and h files resulting in a cascading slew of other errors, so prob a bad idea.
Thinking that it may be something I've done wrong with the ./configure command?
Perhaps an issue with my Android.mk file?
I figure this must be something that quite a few developers are dealing with so I'm probably missing something because I can't seem to find any good information via google.
Any help would be much appreciated!
I've sent this out to the avhi mailing list as well, if I get a response there I will post here for posterity.
Thanks,
Chris
I'll follow up here with the solution that worked for me.
My solution was to use JMDNS instead of Avahi.
There's not much traffic on the Avahi mailing list.
JMDNS has working examples available.
JMDNS took me about 4 hours to set up within my NDK environment and about a day to work out some "kinks."
tar avahi-0.6.31
patch -p1 < 0001-Add-Android-support.patch
patch -p1 < 0002-Add-uninstalled.pc.in-files.patch
cd avahi-0.6.31
./configure --sysconfdir=/etc --localstatedir=/var
make
cd the subdirectories: make Android.mk
then, you will see Android.mk in all the subdirectories.
ndk-build V=1 NDK_LOG=2 APP_ABI="armeabi armeabi-v7a"

Categories

Resources