How to tell autoconf about broken cross HOST functions? - android

I am trying to cross-build an autotools enabled package for an unusual embedded system with a very incomplete libc. (If it is relevant: The package is CPython 3.4.2 and the "embedded system" is the command line shell on Android 4.4.)
AFAIK there's no way that configure running on my build machine can determine which functions on the host are broken. (configure can, and does, compile and link test programs on the build machine, but it has no access to running the program on the host.) So, for example, the wcsftime() function is declared in the host's <wchar.h> header and defined in the host's libc, but the implementation is incorrect.
For this package configure builds a config.h file with a C macro HAS_WCSFTIME, which is defined if configure believes the host has a working wcsftime() and is undef'd otherwise. And the package's source code is correctly ifdefed so that if wcsftime() is missing, strftime() is used instead, with proper conversions back and forth between 7-bit ascii and UCS-4.
I can't just run configure with:
CPPFLAGS=-UHAS_WCSFTIME configure --build=... --host=... ...
because the config.h file just redefines it anyway.
The options I've come up with so far are:
add a ac_cv_broken_host_wcsftime variable to the configure.ac file
add ifdefs for a HAS_BROKEN_WCSFTIME macro to the sources
fix the host's libc
create a patch for config.h that flips HAS_WCSFTIME from defined to undefined, and remember to run patch every time after I run configure
I've already implemented option (4) and it is ... unsatisfying. I can do (1) or (2) and contribute it back to the package developers, but then it will be months before the changes get incorporated. I'm working on option (3), but that will take years to get deployed to the majority of my user's phones and tablets.
What's the right way to deal with this problem? (I expect it to come up a lot since I've got a lot of different packages that I want to get working, and there are dozens of broken functions in libc.)
Is there some command line option to configure that will let me control which CPP macros do and do not get defined?

Is there some command line option to configure that will let me control which CPP macros do and do not get defined?
No.
Your best bet is to talk with the package maintainers. They can help you put an acceptable patch together for their package. You can then apply this patch until it gets pushed with the following method.
As an alternative to 4), you could also patch configure itself, especially if there's a bootstrap script that is invoked to create configure. Doing actions in the bootstrap script to fix up configure or libtool, etc. is one of the ways I've solved this problem in the past.
If in 3) you mean Bionic as libc, I'd think that "never" is probably a more accurate timetable than "takes years" to get wide character functions into it.
AFAIK there's no way that configure running on my build machine can determine which functions on the host are broken. (configure can, and does, compile and link test programs on the build machine, but it has no access to running the program on the host.)
Mostly true. Scratchbox2 will allow you to do runtime configure tests on the host, but it doesn't support Android, unfortunately.

Related

Android NDK API list?

Is there a way/tool to enumerate all the C function prototypes (not sure if that's the right term) from the .h files in the NDK folder subdirectories (i.e. C:\android-ndk-r8b\platforms\android-9\arch-arm\usr\include) and produce something like a javadoc? The reason I'm asking is because we have a developer on our end who is trying to port his Windows code over to the android platform and before he begins to go forward with such an effort, he needs to know what API calls are supported so he can begin changing his code base to make it Android-NDK compliant. I've run across the following links in my search for an answer:
http://mobilepearls.com/labs/native-android-api/#c++
C:/android-ndk-r8b/docs/STABLE-APIS.html
C:/android-ndk-r8b/docs/CPLUSPLUS-SUPPORT.html
The right way to check if the code is compliant is to compile it and see what breaks. Win32 API surely would - there's even no point in checking if an NDK counterpart exists. The C/C++ RTL is a little more tricky - some functions have counterparts, some don't. But enumerating them all and matching by hand is, frankly, a waste of time. A compiler will do the same much faster.
For starters, let the code be Linux compliant. The minute differences between Android libs and Linux can usually be resolved incrementally. Note that you have a moving target here: platform-14 supports much more Linux headers than 9.
http://www.tenouk.com/Module000linuxnm3.html
can you use libs instead of .h files?
the link explains using 'nm' to dump symbols from libs

Externalizing Android Linux kernel module

I don't know if what I'm trying to do is even possible, and while it may be undesirable I'd like to know whether I can make this work.
I have a Linux kernel compiled for an Android tablet and I need to make some changes to one of the built-in modules. (Compiling a new kernel from source is not, in this particular case, an option for me).
I've gotten as far as compiling using my modified source and compiling the .ko files I need. However, when compiling these modules, I get a list of errors that look like the following:
WARNING: "alarm_start_range" [/modules/p3_battery.ko] undefined!
It seems as though my Makefile isn't correctly linking this header:
#include <linux/power/p3_battery.h>
Anyway, I tried to load those modules on the device, and when I try to do insmod p3_battery.ko, I get a failure message (which I expected). Looking at dmesg, I see messages that tell me the following:
p3_battery: Unknown symbol alarm_start_range (err 0)
As mentioned above, those functions do exist in the kallsyms table.
I can provide more detail by supplying my Makefile if that will help, but I wanted to offer a concise formulation of the problem to see if what I'm doing here makes any sense.

Android.mk for LibXtract

Can somebody help me write Android.mk for LibXtract or point me in correct directoin?
Here is source for lib - https://github.com/jamiebullock/LibXtract.git
Or mayby there is a way to use linux generated shared objects in Android?
Especially for bigger established projects, crafting Android.mk files is quite an effort. More so, if you are not familiar with Android NDK build architecture whose understanding requires digging deep into the documentation and Android NDK make files. I would suggest trying to use existing make files by setting CC to point to your NDK tool chain, and CFLAGS += -sysroot $(SYSROOT) where SYSROOT=${NDK_INSTALL_DIR}/platforms/android-<level>/arch-<arch>/ (depending on targeted Android API version and architecture). Even without knowing about your library, I would bet you should have good chance of success this way. Android NDK documentation (${NDK_INSTALL_DIR}/doc/STANDALONE-TOOLCHAIN.html) details the use of independent tool chain and also instructs how to create a standalone tool chain that will not require the use of -sysroot argument to xxx-gcc.
If you decide to use Android.mk instead, you might check existing projects -CSipSimple comes to my mind (PJSIP converted from standard form GNU make files).
Important is to create the shared objects using Android tool chains. It is possible to build them outside of your application source tree, and then just copy the shared objects into the package source libs/<architecture>/ directory.
Integration with your build system depends on details that are not known (including how smooth you desire this whole integration to be e.g. because of other people working with the same project). If you are creating an application from command line, the easiest would be to have GNU make file or shell script in the package root directory ensure libXtract.so and your application package is up-to-date by calling libXtract make file and ant to build and pack your Java application. If you are using ant there should be a way to specify using make to take care of libXtract.so. I am not sure if eclipse is completely relying on ant for building an application to know if this would be enough for enabling complete build by clicking mouse buttons from within eclipse, too.
The answer to this question says you could use cmake script to build Android.mk files - I have not tried this approach.

How do I build the Android SDK with hidden and internal APIs available?

I want to rebuild the Android SDK (or rather only the android.jar) to include hidden and internal APIs.
I could not find any documentation or discussion doing on how to go about this. I have an Ubuntu CyanogenMod build environment already setup that is able to build cm7.
Now, I read that make SDK will build the SDK but I want to build an SDK that includes methods and fields that are marked as hidden using #hide. Is this possible?
What I want to do is make changes to an application that uses hidden API and in order to rebuild it I would like to use the modified SDK.
This is what I always do to use hidden api.
Build the repo or download jars from https://sites.google.com/site/hippunosource/home/android/androidnohide-apiwo-shi-yongsuru-rifurekushonha-wei-shi-yong
copy out out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar (better to rename it as something like framework_all.jar)
config your project build path-->libraries --> add this external jars. In Order and Export, move it up and before android.jar
I have done some investigating into this, and my conclusion is simply: This cannot be done without quite a bit of work. Read the rest of this answer for details on what I have found.
android.jar is actually comprised of the "public api" of framework.jar and core.jar which is found in system/frameworks/ on the device. android.jar is a kind of what I would call Java library header, all implementation in the actual byte code are just a throw new RuntimeException("stub");, this allows you to build against android.jar (e.g. in Eclipse), but execution has to be performed on a device or emulator.
The public API of the Android SDK is defined by classes/methods/fields that are not prefixed with the #{hide} javadoc annotation. I.e. everything that is not annotated is included in the SDK.
android.jar is built from the sources located in out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates which itself is generated by the tool DroidDoc located in build/tools/droiddoc.
DroidDoc is the tool (probably adapted from javadoc, or using javadoc) that generate the actual Android SDK documentation. As a side-effect, and probably because it is already parsing all the javadoc, it also spews out the android stubs which are then compiled into the android.jar which is distributed in the SDK.
So to include the stuff that is hidden you could, if you only want to include specific parts, just remove the #hide annotation and rebuild the SDK.
However if you want to include all the hidden parts things get a lot more complicated. You can modify DroidDoc (the relevant source is in build/tools/droiddoc/src/Stubs.java) such that nothing is detected as hidden. This is quite trivial and I have tried this, however the stubs that is then generated does not compile at all.
My conclusion by now is that this is simply not feasible. The stubs generated if you remove the part of DroidDoc that detect hidden annotations, is simply not compilable, and would require quite a bit of work to compile correctly.
So my answer to your questions is: No, this cannot be done, without doing a lot of work. Sorry.
A side note about the mkstubs tool. mkstubs are used when you build a SDK addon, i.e. the addons you can find in the Android SDK manager from vendors, e.g. Samsung providing you with an additional API for stuff specific to Samsung phones. mkstubs does much the same as the DroidDoc stubs generation process, however it does not use #hide annotations, it uses a .defs file describing which packages/classes/fields to include or exclude from your SDK addon.
However this is all irrelevant to the question, as the Android SDK build does not use the mkstubs tool. (Unfortunately.)
We could reconstruct the *.jar files from the Android platform.
First, connect ADB to your device. Then run:
adb pull /system/framework/core.jar .
adb pull /system/framework/framework.jar .
The core.jar contain the standard Java libraries (java.*) and the framework.jar contain the Android libraries (android.*). This is not usable yet, as the actual files are in DEX format, not JAR format.
We could convert these DEX-formatted *.jars into real JARs using tools such as dex2jar:
dex2jar core.jar
dex2jar framework.jar
Then pull in these jars using "Add External JARs..." (assuming you're using Eclipse ADT)
right click on Project → Properties → Java Build Path → Libraries → Add External JARs... → (Choose the core-dex2jar.jar and framework-dex2jar.jar from above).
This will enable you to use the internal and some Java 7 APIs. (The generated APK, as far as I can see, does not contain any actual code from the JARs.)
You can download the modified android.jar to be used as hidden APIs from this repository. Follow the instructions there.
For Lollipop the flow is little different:
Get /system/framework/arm/boot.oat from lollipop device
Use 'java -jar oat2dex.jar boot boot.oat'
You will get two folders: dex and odex. Go to dex and make 'java -jar dex2jar.jar framework.dex'
Rename resulting framework.jar to .zip, extract and find classes you need
Go to [sdk_path]/platforms/[target_platform] and extract android.jar (first rename it to zip).
Copy files from extracted framework to extracted android.jar. Then compress to zip and rename to .jar :)
ps: probably you need repeat steps 4-6 for 'framework_classes2.dex'
DroidCon 2011
Here Erik Hellman from Sony Ericson explains how to access the hidden Android API's:
http://vimeo.com/30180393
(Hmm link doesn't appear to work).
Goto the DroidCon webpage Day 2 scroll down to Using Hidden APIs 10:15 and you can watch it there.
Links are dieing!
I've found this one: http://skillsmatter.com/podcast/os-mobile-server/hidden-api I don't know, how long it'll be up.
The official APIs in the Android SDK is usually sufficient for most normal applications. However, there are sometimes situations where a developer needs access to the internal system services, APIs and resources that are not published in the official APIs. Fortunately, these APIs are still available through some clever tricks and can often be useful when developing new and innovative solution on top of Android. In this session you will learn how to access and use these hidden and protected APIs, the limitations of their usage and some tips'n'trick on how to use them in a safe and control manner across multiple vendors devices and Android versions. The audience will see several advanced demos that you normally cannot do with Android. Expect a fairly advanced session with lots of insights in the internals of the Android platform.
Try to look at this:
The ultimate target of these articles is to give developers the power of Internal and Hidden APIs without using reflection. If you complete all the steps described in next several parts you will be able to use Internal and Hidden APIs as if they were public open APIs. There will be no need for reflection.
But if you’re using these non-public APIs then you should be aware that your application is at great risk. Basically there are no guarantees that APIs will not be broken with next update to Android OS. There are even no guarantees about consistent behavior across devices from different vendors. You are completely on your own.
There are three scenarios you may want to follow:
Enable both internal and hidden APIs (scenario A)
Enable only hidden API (scenario B)
Enable only internal API (scenario C)
Scenario A is a sum of B and C. Scenario B is the easiest one (requires no eclipse ADT plugin modifications).
Scenario A: read parts 1, 2, 3, 4, 5
Scenario B: read parts 1, 2, 3, 5
Scenario C: read parts 1, 2, 3, 4, 5
I once wrote some Groovy scripts for extracting the java files from a repo checkout from http://source.android.com/ and then compiling them without the need for a full toolchain for compiling all the android sources, including the needed other steps (packaging, generating resources etc).
They can be found here:
https://github.com/thoutbeckers/CollectAndroid
But for sure this will need updating for anything after Gingerbread, mostly by setting the correct directories in "rootdirs" in the config file (CollectConfig.groovy).
At the time I regularly used this for development with all of the hidden API and sources (also problematic at the time) available.
As mentioned elsewhere com/android/internal/** will still be hidden in recent versions of ADT due to the access rule aded.
Long's answer worked for me, but I was still missing some classes I needed, in particular android.provider.Telephony. I was able to add it like this:
Extract the framework.jar file
mkdir /tmp/framework
cp framework.jar /tmp
cd /tmp/framework
jar xvf ../framework.jar
mv android classes
Build the Android repo, which will create the out/target/common/obj/JAVA_LIBRARIES directory
Find where the missing classes are
$ cd /path/to/out/target/common/obj/JAVA_LIBRARIES
$ find . | grep "/Telephony.class"
./telephony-common_intermediates/classes/android/provider/Telephony.class
./android_stubs_current_intermediates/classes/android/provider/Telephony.class
Add the new classes and rebuild the framework JAR file
cd /tmp/framework
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes .
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/classes .
cd classes
jar cvf ../framework.jar .
Or you can just be lazy and include all of the classes into one giant jar file:
cd /tmp/framework
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/*/classes .
cd classes
jar cvf ../framework.jar .
I can't comment but this is basically a comment to #KennyTM's (https://stackoverflow.com/a/13550030/2923406) excellent answer:
If you find yourself with the following error in Eclipse:
The type com.android.internal.util.Predicate cannot be resolved. It is indirectly referenced from required .class files
(that is, android.internal.* is not available)
Then one possible solution is to apply the same method for /system/framework/framework2.jar. Using the Android Emulator for SDK19 I have this extra jar. On my HTC One there is even a framework3.jar.

How to integrate Scala into core Android platform?

I am interested in integrating Scala (or some other non-Java JVM-language) into the android platform. I am not referring to writing an android application with Scala, that I did early early on, but actually hooking into the build process that builds the android platform source tree. I imagine this will be a matter of hooking into the makefiles and such. Does anyone have insight into this?
What I have so far:
The platform source treefrom git://android.git.kernel.org/platform/manifest.git built in its virgin form, guided by "[Download and build the Google Android][1]"
build/core/combo/scalac.mk # Configures scala compiler related variables, included by config.mk
Added definitions in build/core/definitions.mk for an all-subdir-scala-files and an all-scala-files-under
Added definition in definitions.mk to build scala files such that they are included in the package
What's left:
Include scala-library.jar
Ensure changes to -bootclasspath has not broken anything
Figure out how to handle case where scala classes depend on java classes and visa versa
Major cleanup of code
Testing!
Figure out what to do (other than just posting them here) with the changes I've made
Looks like I'm almost there!!!
Some notes from the past
Latest: I have found where the Java source files are compiled! In definitions.mk, see 'define transform-java-to-classes.jar'. The latest idea is to write a transform-scala-to-classes definition and then have it store those classes in the directly that gets packaged. I will call transform-scala-to-class right before this step in transform-java-to-classes.jar. Support for eclipse and cygwin will for now be dropped as it clutters up the code with workarounds and therefore increases my chances of failure.
The build process starts out by the root Makefile running build/core/main.mk
build/core/main.mk includes build/core/config.mk which includes build/core/combo/javac.mk which sets HOST_JAVAC, TARGET_JAVAC, and COMMON_JAVAC. COMMON_JAVAC is the "Java compiler command with common arguments," by the look of it the other two variables get these values by default, unless in a special environment (openjdk or eclipse). COMMON_JAVAC is not used outside this file. The other two are only used in build/core/definitions.mk.
build/core/java_library.mk (included by config.mk) seems to only be concerned with building jars. This is out of the scope of us caring. Any interaction with jars presupposes class files which presuppose that we were already successful in building our scala files.
There are checks in main.mk regarding the version of java. We will ignore these and assume that our version of scala is compatible. Right now (in combo/scalac.mk) I am using the same --target arg used in javac.mk. This should perhaps be stored in a variable.
main.mk also includes build/core/definitions.mk which in turns defines some useful functions. The one we care about here is all-java-files-under and all-subdir-java-files. The latter is used in Android.mk files to find java files. The former is used in the implementation of the latter. I will write Scala equivalents of them.
To figure out how the build process works, I am now running make with -n and others. I got this idea from the stackoverflow article "[Tool for debugging makefiles][2]". I am also investigating debugging with remake.
build/core/{config.mk, definitions.mk} gives us light as to which make files/commands are used to do what.
As a possible way of hacking in support on a per project bases, additional code could most likely be added to the project's Android.mk file. From platform/build/core/build-system.html we read "Android.mk is the standard name for the makefile fragments that control the building of a given module. Only the top directory should have a file named "Makefile"." You could create a new target like "scala-build" and run that (make PackageName scala-build) before the final make. One could perhaps also hide it sneakily in a variable assignment, mitigating the need for a target to be called explicitly.
Another way (far far more hackish) is to hijack the command being used for javac. This is set in build/core/combo/javac.mk. Your project's Android.mk will have to include *.scala files in LOCAL_SRC_FILES along with the *.java files.
Guys on reddit say, there's a tutorial on integration Scala into Android with ant here.

Categories

Resources