I have a large project that builds to all available target architectures (arm, arm7, x86).
This project includes some other modules, some of which cannot be built for x86 (it fails to compile when built for x86).
Can i "ignore" this architecture for the given modules somehow? (so they will not be built for this arch?)
Or what is the best way to overcome this issue?
Assuming you have a set of Android.mk files, you can check the current architecture with $(TARGET_ARCH) variable. You can use
ifneq ($(TARGET_ARCH),x86)
include $(BUILD_SHARED_LIBRARY)
endif
... and so on
The best way to handle different support for architectures is to create different APK for each type.
http://developer.android.com/google/play/publishing/multiple-apks.html
Related
Since Crosswalk is over 40mb. I have decide split my apk to reduce apk size...
I have know how to publish differenk apk on Google Play Store...I have readed documantations...
Documentation says:
Supporting multiple CPU architectures When using the Android NDK, you
can create a single APK that supports multiple CPU architectures by
declaring each of the desired architectures with the APP_ABI variable
in the Application.mk file.
For example, here's an Application.mk file that declares support for
three different CPU architectures:
APP_ABI := armeabi armeabi-v7a mips APP_PLATFORM := android-9
NDK Application Documantation says
The Application.mk file is really a tiny GNU Makefile fragment that
defines several variables for compilation. It usually resides under
$PROJECT/jni/, where $PROJECT points to your application's project
directory. Another alternative is to place it under a sub-directory of
the top-level $NDK/apps/ directory. For example:
$NDK/apps//Application.mk Here, is a short name used to
describe your app to the NDK build system. It doesn't actually go into
your generated shared libraries or your final packages
I have no experience for NDK...watched some videos...
In this question latest answer told
For arm you'd put this line in Application.mk :
APP_ABI := armeabi armeabi-v7a
And for intel x86 :
APP_ABI := x86
And you have to change AndroidManifest.xml to have a
different version for each platform (following the instructions in the
link you provided).
Be carefull, if you run cordova build android again, it will probably
replace all the content of platforms/android, and your changes will be
lost.
To build the project use
platforms\android\cordova\build.bat -release
So if I do integrate my app with NDK and puting APP_ABI variable will split apk cpu architecture?
is there a easy way for this? do I have to do additional steps?
Crosswalk library for single architecture will increase the APK size by 20M. If you find it's over 40M, the library maybe for both of x86 and ARM.
If you are using official packaging tools of Crosswalk, you can choose targeting architecture. If you are using Crosswalk as library reference, you can download the library for different architecture separately from official website.
The problem:
I have a native Android application that is compiled for x86 and arm, armv7a.
The app also links to a pre-shared library.
That pre-shared library is also compiled for x86, arm, and armv7a. So there are 3 lib.so files.
What must I do in the Android.mk/Application.mk to link to the appropriate *.so file given the architecture it is being compiled for?
That is, when the build system is compiling for arm, it should link to the libs/armeabi/lib.so.
Likewise, when the Build system is compiling for x86, it should use the libs/x86/lib.so file.
I believe the alternative might be a more complex build script but I'm shooting for the simple solution first, if it exists.
Thanks!
The answer
Unfortunately my query skills were not very good and shortly after posting, I found the question and answer already on SO:
How can i Link prebuilt shared Library to Android NDK project?
To summarize:
Prebuilt shared libraries, compiled for different platforms, should all be named the same and go under the jni/${ARCH}/ directory.
That is, the structure should appear as so:
jni/x86/libtest.so
jni/armeabi/libtest.so
jni/armeabi-v7a/libtest.so
You should use the $(TARGET_ARCH_ABI) flag, for example:
include $(CLEAR_VARS)
LOCAL_MODULE := mylib-prebuilt
LOCAL_SRC_FILES := ../path_to_prebuilt_folder/libs/$(TARGET_ARCH_ABI)/libmylib.so
include $(PREBUILT_SHARED_LIBRARY)
When using JNI in Android does the C code need to be compiled to adhere to all different types of ARM architectures? For instance if I compile ffmpeg for armeabi can I use it on all Android devices or do I need to compile it to different targets such as armeabi-v7a?
Having
APP_ABI := armeabi armeabi-v7a x86
inside your Application.mk will create 3 .so files which are bundled with your apk file. This should cover all relevant android devices out there. No extra work needed from us developers.
As to your question: if you compile for armeabi your app will work for both armeabi and armeabi-v7a. Thats because the latter is an extension of armeabi.
You can find a detailed explanation inside ndk.dir/docs/CPU-ARCH-ABIS.html.
I'm trying to build static FAT library for Android NDK which should contain armv6 and armv7 versions.
Tried libtool - doesn't help, cause on MacOS it is not compatible with Android ABI.
Tried ranlib that I found in my NDK folder also with no success.
As an option could someone explain how should I use Android.mk to specify an appropriate library for an architecture.
On Android you don't (at least currently) create fat binaries. Instead, your APK will contain 1:n binaries for the architectures you wish to support.
Your Application.mk (preferred) or Android.mk should define a APP_ABI variable for the architecture(s)
For example, to support ARM (generic) and ARMv7a:
APP_ABI := armeabi armeabi-v7a
See $(NDK)/docs/APPLICATION-MK.txt for more information.
I've downloaded a custom toolchain (linaro) to build ARM based Android apps. How do I tell the NDK to use it? Can I define or set something in Android.mk and Application.mk that would allow me to do that? Is there another way?
The NDK makefile system is quite extensible and you can indeed define a different toolchain. You'll need some understanding of how Make works.
Toolchains are discovered and initialized in build/core/init.mk line 261 (in NDKr6, the line # may change in future versions). The initialization code looks for files named config.mk under $(NDK_ROOT)/toolchains/*. So you'll need to add your toolchain in a subdirectory under the NDK toolchains directory, and add a config.mk and setup.mk to that subdirectory. Look at toolchains/x86-4.4.3 and toolchains/arm-linux-androideabi-4.4.3 for examples. You should be able to cut and paste the ARM toolchain config.mk and setup.mk if your toolchain has a standard layout.
Once you've defined a toolchain in the toolchain directory, you can switch to it by setting the NDK_TOOLCHAIN variable inside your Application.mk file.
As the other answer mentions, toolchains are discovered by ndk-build makefile system in $(NDK_ROOT)/toolchains/ and you can mirror ideas you see there. But there are a few extra concepts for supporting non-Android target platforms that are interesting although they may be soon outdated as ndk-build starts to explicitly support other platforms, such as mingw targeting win32 (or other gcc compilers targeting plain 'ol linux).
In config.mk:
TOOLCHAIN_ABIS := (list of ABIs that the toolchain supports)
This is an important definition, because you can use this name in your Application.mk to build using the toolchain for a particular ABI. One of the benefits of corrupting the usage of this definition, is that ndk-build can simultaneously build for multiple ABIs. It always assumes that the platform is Android, but if you want to target win32 using a mingw based toolchain, you can define an "ABI" as x86-win32, and then use this ABI in your Application.mk to select it as an additional target via APP_ABI:= x86-win32 Then in your Android.mk files you can use the TARGET_ARCH_ABI definition to select win32 specific sources and include paths, for example:
ifeq ($(TARGET_ARCH_ABI),x86-win32)
LOCAL_SRC_FILES += my_win32_file.c
LOCAL_CFLAGS += -DSOME_WIN32_SPECIFIC
endif
The final piece is that in setup.mk for your toolchain, it may be insufficient to look at other toolchains as examples, because what setup.mk for a particular toolchain really does is override build settings in default-build-commands.mk, so what you want to do is inspect that file, and redefine things in it that you don't like.
Following the previous example, mingw does not support the noexec flag in the binaries, and you can get rid of this feature by adding the following lines in your setup.mk:
# These flags are used to enforce the NX (no execute) security feature in the
# generated machine code. This adds a special section to the generated shared
# libraries that instruct the Linux kernel to disable code execution from
# the stack and the heap.
TARGET_NO_EXECUTE_CFLAGS := # our platform doesn't support this flag!
TARGET_NO_EXECUTE_LDFLAGS := # our platform doesn't support this flag!
# These flags disable the above security feature
TARGET_DISABLE_NO_EXECUTE_CFLAGS := # our platform doesn't support this flag!
TARGET_DISABLE_NO_EXECUTE_LDFLAGS := # our platform doesn't support this flag!
This is just one example of the many features in default-build-commands.mk that may need to be overridden, and of course it's important to provide TOOLCHAIN_NAME so that the toolchain can be selected via NDK_TOOLCHAIN variable inside your Application.mk file in addition to the ABI methodology I mention above.
well,you can simply add "NDK_TOOLCHAIN_VERSION = 4.9" in your Application.mk