Why does NDK compiler not recognize a LOCAL_CFLAGS definition? - c++

I have some pre-existing code I'm trying to compile into an NDK library. There's a simply #ifndef I need to execute correctly, but in my Android.mk the var I've defined with LOCAL_CFLAGS is not recognized. It thinks it's a command line option
When I run ndk-build with the NDK_LOG option it all compiles fine until I see this:
[armeabi-v7a] Compile++ thumb: NDKImageProcessor <= NDKImageProcessor.cpp
arm-linux-androideabi-g++: error: unrecognized command line option '-WINONLY=1'
make: *** [obj/local/armeabi-v7a/objs/NDKImageProcessor/NDKImageProcessor.o] Error 1
I'm simply trying to get the following from being included in compilation:
#ifndef WINONLY
#import <CoreGraphics/CGGeometry.h>
#endif
Android.mk is pretty straightforward:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := NDKImageProcessor
LOCAL_SRC_FILES := NDKImageProcessor.cpp
LOCAL_SRC_FILES += ../../../../SharedSrc/Image.cpp
LOCAL_LDLIBS := -llog
LOCAL_CFLAGS := -WINONLY=1
include $(BUILD_SHARED_LIBRARY)
If I simply do not add that LOCAL_CFLAGS line the compiler tries to compile that iOS code, which is a no-go obviously.

From the GCC documentation (it should be the same if you use Clang):
-D name
Predefine name as a macro, with definition 1.
-D name=definition
The contents of definition are tokenized and processed as if they appeared during translation phase three in a ‘#define’ directive. In particular, the definition will be truncated by embedded newline characters.
So to define WINONLY with the value 1 you'd use:
LOCAL_CFLAGS := -DWINONLY=1
or simply
LOCAL_CFLAGS := -DWINONLY

Related

How to link libjingle_peerconnection_so.so to a project and call classes from it?

I try to build my jni class with a single line that tries to call webrtc audio processing.
webrtc::AudioProcessing* apm = webrtc::AudioProcessingBuilder().Create();
I also try to link the libjingle_peerconnection_so.so to my project so that I could use implementation of the audio processing from this common library. My Android.mk looks as follows:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libwebrtc
PATH_TO_WEBRTC := /home/artemy/dev/webrtc_src/src
LOCAL_SRC_FILES := $(LOCAL_PATH)/../../../../libs/$(TARGET_ARCH_ABI)/libjingle_peerconnection_so.so
LOCAL_EXPORT_C_INCLUDES := $(PATH_TO_WEBRTC) $(PATH_TO_WEBRTC)/third_party/abseil-cpp
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := audio_processing_jni
LOCAL_SRC_FILES := audio_proc_jni.cpp
LOCAL_C_INCLUDES := audio_proc_jni.h
LOCAL_LDLIBS := -llog
LOCAL_STATIC_LIBRARIES := libwebrtc
include $(BUILD_SHARED_LIBRARY)
However the project fails to link:
[armeabi-v7a] Compile++ thumb: audio_processing_jni <= audio_proc_jni.cpp
[armeabi-v7a] SharedLibrary : libaudio_processing_jni.so
ap/audio_proc_jni.cpp:11: error: undefined reference to 'webrtc::AudioProcessingBuilder::AudioProcessingBuilder()'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
Is that possible or I need to find another way to webrtc directly from my native code?
Please check how your library is built. I see that the prebuilt libraries e.g. https://github.com/signalapp/libwebrtc-android/tree/master/debug/libs only export the JNI functions:
% nm --dynamic libwebrtc-android/debug/libs/armeabi-v7a/libjingle_peerconnection_so.so | grep \ T\ | grep -v \ Java_
0017a680 T JNI_OnLoad
You must rebuild the library such that the functions that you need are not hidden by the linker.

Std in ndk with cpp - vector problems

I am trying to compile a large c++ code for ndk.
I get a bunch of errors. A lot of them related to vectors:
vector<int> myvector --> the '<' gives an error
::iterator cannot be declared
Any ideas on how to get full STL support? I use a lot of libraries, like vector, algorithm, iostream etc
Here is my Android.mk file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := native
LOCAL_SRC_FILES := vns.cpp note.cpp cscore.cpp hscorecf.cpp hscorecp.cpp scoreinfo.cpp cscore.cpp score.cpp randMusic.cpp input.cpp main.cpp
APP_STL := stlport_shared
#but I have tried system, stlport_static, stlport_shared, or gnustl_static.
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
Got it.
I needed to put APP_STL := stlport_shared in a separate Application.mk file!
Got it. I needed to put APP_STL := stlport_shared in a separate Application.mk file.
Seems like you forgot to #include <vector> header or using namespace std;

can't find libstdc++ when building external modual using gnustl_static

I am adding gnustl_static to a external Android module and when I build it I get the following error.
make: *** No rule to make target `prebuilt/ndk/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/libstdc++.a', needed by `out/target/product/msm8960/obj/SHARED_LIBRARIES/liballjoyn_intermediates/LINKED/liballjoyn.so'. Stop.
when I look under "prebuilt/ndk/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/" I can not find the libstdc++.a there is a fild libsupc++.a
the build system is getting this from the binary.mk file found in the "build/core" folder it states
# LOCAL_NDK_STL_VARIANT is gnustl_static
my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/libs/$(TARGET_CPU_ABI)/include \
$(my_ndk_source_root)/cxx-stl/gnu-libstdc++/include
my_ndk_stl_static_lib := $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/libs/$(TARGET_CPU_ABI)/libstdc++.a
problem is I don't know what to get past this error.
There are many copies of libstdc++ in the prebuilt folder but they are not found in the location listed. The are found in
prebuild/ndk/$(ANDRIOD_NDK_VERSION)/platforms/$(ANDROID_SDK_VERSION)/$(ARCHETECTURE_TYPE)/usr/lib/libstdc++.a
here is a shortened form of my Android.mk file:
LOCAL_PATH := $(call my-dir)
# Rules to build libabc.so
include $(CLEAR_VARS)
LOCAL_CPP_EXTENSION := .cc
LOCAL_SDK_VERSION := 8
LOCAL_NDK_VERSION := 7
LOCAL_NDK_STL_VARIANT := gnustl_static
LOCAL_CFLAGS += \
-std=gnu++0x
LOCAL_C_INCLUDES := \
external/abc/inc \
external/openssl/include
LOCAL_SRC_FILES := \
file1.cc \
file2.cc
LOCAL_SHARED_LIBRARIES := \
libcrypto \
libssl \
liblog
LOCAL_PRELINK_MODULE := false
LOCAL_REQUIRED_MODULES := \
external/openssl/crypto/libcrypto \
external/openssl/ssl/libssl
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libabc
include $(BUILD_SHARED_LIBRARY)
Anyone have any ideas how I can solve the "No rule to make target" build issue?
Solution found:
The simple answer is that I need to change the LOCAL_NDK_VERSION version from 7 to 5 or 6.
The complex answer is that the binary.mk file has not been updated to account for changes that were made when NDK-7 was released.
In NDK-5 and NDK-6 when using gnustl_static the library file that contained everything for STL was in libstdc++.a that was located in the location specified in the binary.mk file. When NDK-7 was released the library name was changed from libstdc++.a to libgnustl_static.a. It does not look like the binary.mk was updated to account for this change.
This is not that surprising since it appears that no projects use gnustl_static. I did a grep accross all of the code in the android repository and the only code I found that was using the LOCAL_NDK_VERSION set to gnustl_static was my own.
You shoudl not use LOCAL_NDK_STL_VARIANT to select STL variant.
You should use APP_STL := gnustl_static in Application.mk file.

Undefined reference to android_main (Android NDK - native_app_glue)

I'm writing an Android App fully in C++. Using OpenGL E.S. 2, Android-NDK r7 (platform-9), OpenJDK, and Ubuntu 12.04.
The issue that I'm running into is that my main library which is supposed to make calls to the engine I'm developing is spitting out "undefined reference to android_main" errors. Why it is doing this I have no idea, but I'm almost positive it has some thing to do with my Android.mk. For whatever reason, I can't quite figure it out.
While the engine library builds perfectly fine, the main Android.mk which references the files used which make up the actual game isn't building in the way I'd like it to.
The Goal
-I'd like this to link up with -loptim so it may reference and call functions from the engine as a separate library. Because of this, I should be able to port this engine to various other projects and simply link it. This appears to have been done, though if someone else has a better way of accomplishing this I'm all ears.
-I'd also like to figure out why my android_main is not being referenced, and what can be done to fix it.
Main.cpp
#include "engine/stdafx.hpp"
#include "engine/AppData.hpp"
#include "engine/Engine.hpp"
#include "glm/glm.hpp"
using namespace optim;
void android_main( android_app* application )
{
AppData appData;
appData.mApplication = application;
appData.mGraphicsService = new GraphicsService( application );
Engine app( &appData );
}
Android.mk
MY_LOCAL_PATH := $(call my-dir)
LOCAL_PATH := $(MY_LOCAL_PATH)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/engine/Android.mk
include $(CLEAR_VARS)
LOCAL_PATH := $(MY_LOCAL_PATH)
LOCAL_CFLAGS := -I$(LOCAL_PATH)/glm -I$(ANDROID_NDK)/sources/cxx-stl/stlport/stlport -I$(LOCAL_PATH)/ -I$(LOCAL_PATH)/engine
LOCAL_MODULE := pongdroid
LOCAL_SRC_FILES := Main.cpp PongDroid.cpp
LOCAL_LDLIBS := -landroid -llog -lEGL -lGLESv2 -L$(PONGDROID_DEV)/obj/local/armeabi/ -loptim
LOCAL_STATIC_LIBRARIES := android_native_app_glue
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
Note that -loptim is the shared library of the engine I'm linking the main module to. The problem is that, while it appears to link perfectly fine, the library for this makefile in particular won't produce a shared_library. Everything else seems to compile just fine, however.
NDK-BUILD
**** Build of configuration Default for project pongdroid ****
ndk-build all
Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
Compile++ thumb : optim <= Engine.cpp
Compile++ thumb : optim <= Config.cpp
Compile++ thumb : optim <= GraphicsService.cpp
Compile thumb : android_native_app_glue <= android_native_app_glue.c
StaticLibrary : libandroid_native_app_glue.a
StaticLibrary : libstdc++.a
SharedLibrary : liboptim.so
./obj/local/armeabi/libandroid_native_app_glue.a(android_native_app_glue.o): In function `android_app_entry':
/home/amsterdam/Android/android-ndk/sources/android/native_app_glue/android_native_app_glue.c:234: undefined reference to `android_main'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/liboptim.so] Error 1
**** Build Finished ****
Update
So, I've narrowed down the problem a bit. The issue lies in the fact that the root Android.mk file for some reason seems to be ignoring its own library. What's even stranger is that when I comment out include $(LOCAL_PATH)/engine/Android.mk, the error output gets worse.
So, I'm posting my engine/Android.mk file for clarity to see if anyone can make sense of this mess...
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS := -I$(LOCAL_PATH)/
LOCAL_MODULE := optim
LOCAL_SRC_FILES := Engine.cpp Config.cpp GraphicsService.cpp
LOCAL_LDLIBS := -landroid -llog -lEGL -lGLESv2
LOCAL_STATIC_LIBRARIES := android_native_app_glue
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
Update 2
A call to ndk-build pongdroid from the shell.
ndk-build pongdroid
Compile++ thumb : pongdroid <= Main.cpp
Compile++ thumb : pongdroid <= PongDroid.cpp
SharedLibrary : liboptim.so
/home/amsterdam/Programming/Android/pongdroid/obj/local/armeabi/libandroid_native_app_glue.a(android_native_app_glue.o): In function `android_app_entry':
/home/amsterdam/Android/android-ndk/sources/android/native_app_glue/android_native_app_glue.c:234: undefined reference to `android_main'
collect2: ld returned 1 exit status
make: *** [/home/amsterdam/Programming/Android/pongdroid/obj/local/armeabi/liboptim.so] Error 1
Are you including "android_native_app_glue.h" header in Main.cpp or one of its included headers?

Using stl_tree.h on Android NDK results in "No such file or directory"

I'm porting a native library to a NDK application.
When I try to use the stl_tree.h #include, I got the following error.
error: stl_tree.h: No such file or directory
This is my Android.mk file.
LOCAL_PATH := $(call my-dir)
MY_PATH := $(LOCAL_PATH)
include $(call all-subdir-makefiles)
LOCAL_PATH := $(MY_PATH)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog -la -lb -lc -lstdc++ -lgcc #I try to explicit declare the stdc++ and gcc but still doesn't works.
LOCAL_MODULE := rmsdk
LOCAL_SRC_FILES := curlnetprovider.cpp RMServices.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include-all \
$(LOCAL_PATH)/include-all/openssl
LOCAL_STATIC_LIBRARIES := adept cryptopenssl curl dp expat fonts hobbes jpeg mschema png t3 xml zlib
include $(BUILD_SHARED_LIBRARY)
And this is my Application.mk
APP_MODULES := adept cryptopenssl curl dp expat fonts hobbes jpeg mschema png t3 xml zlib rmsdk
APP_STL := stlport_static
My actual problem is, when compiling I get a: '_Rb_tree_increment' is not a member of 'std'
This is why I try to include the stl_tree myself. It appears this lib don't get included.
I can only speak for C++, not for android, but why are you trying to include stl_tree.h directly? You should include either <map> or <set> to get the actual container you want to use. In g++ anyway stl_tree.h is just a private implementation used by map and set.
I solved it using the stlport from NDK 5.
The Android NDK doesn't have the STL (or at least, it didn't the last time I looked at the SDK, which was on Froyo).
The reason why it doesn't have the STL is that by default everything is compiled with exceptions disabled. So be very, very careful when using third-party STL ports; there's a good chance that if anything goes wrong it'll just crash.