My server needs to keep building a large amount of Android projects. All of them are almost identical except for minor change on manifest.xml or any resource file (if it's better for the task) for each build. To reduce cost and improve efficiency, I try to implement incremental build. My planned procedures are:
after the first successful build, skip all the previous
procedures (aapt to generate R.java, adle to make java, etc.)
directly call aapt to make resource files, e.g., *.ap_
call apkbuilder to make classes.dex and usigned.apk
make signed.apk
So my question is whether the above solution is possible? And any clue about how to implement it?
This isn't necessarily a solution for your particular requirements but perhaps it will provide you with some useful pointers.
I have an Antlib that I use for building Android projects. You probably won't want to use it yourself as it has some drawbacks, but it should serve as an example of how to perform the various steps to build an Android app using Ant. In particular, it shows how to call the various Android SDK tools from Ant and how to use the Ant uptodate task and Ant's if and unless attributes to avoid processing files that haven't changed.
The source for the Android Ant macros is here (the Antlib documentation might help you to make sense of what it's doing).
Related
I'm using the Native Development Kit (NDK) in a project of mine, and I'm trying to automate the whole app build procedure with Python.
Whenever ndk-build is called, it copies the prebuilt shared libraries to libs/<abi>/, even if there's no changes in them or they already exist there. This causes problem when I call ant later on, as it detects changed files (the library timestamps are newer) and so rebuilds the apk without any need.
Is there a way to change the ndk-build behaviour so it checks for existing libraries in the libs/<abi>/ folder and if they need updating or some are missing, it will call ndk-build, otherwise, just proceed to the next build step?
I've tried using filecmp in Python, but as the timestamps are different between the prebuilt shared libraries and the installed ones, it doesn't work.
The OP probably doesn't need this any more, but I had the exact same problem, trying to set up a Makefile to build a project, so maybe this will be helpful to someone else in the future as well.
ndk-build is a wrapper around gnu make, that invokes a bunch of Makefiles in build/core directory of the ndk, so, while it's not universally applicable*, for your personal project you can modify those Makefiles to do whatever you want. I found a clean-installed-binaries target that a couple of build/install targets depended on, removing those dependencies fixed the issue with perpetual installs.
In whichever cases that clean target is necessary you can invoke it manually with:
ndk-build clean-installed-binaries.
*Given the time to come up with a clean opt-in solution you can submit a patch to ndk project, and if accepted it will eventually become universally applicable.
I have a library project that serves as the backend for a number of other projects. It does the web connection and parsing etc. Then I have other front end projects that build on this.
For development and server environments I wrote an ANT build script that replaces certain values in the code bases on the build type.
So I have two targets buildDev and buildProd.
Is there a way for me to have the values set correctly while building the dependent (non-library projects). E.g. if I do ant debug on the project it builds the backend with ant buildDev and if I do ant release it does it with ant buildProd.
I'm pretty sure that's not possible, so what are the alternatives.
For the curious, the custom builds just replaces a file that has static variables that are assigned different values based on the type of build. Nothing too complex.
In ant, there are a variety of different tasks that can be used to edit properties in a file.
I'm sure you're aware of property files, so if you use the documentation here:
http://ant.apache.org/manual/index.html
It could probably help you.
If you set your variables in an ant-style property file, then for certain builds you could have separate files for separate builds, and then therefore have the variables set correctly.
If you're talking about having variables set in your source, try the copy task:
http://ant.apache.org/manual/index.html
Filterchains on a copy task will allow you to replace certain lines of code out of a file. So if you have a variable named server_ip or something like that, you can use a filterchain to change that value and re-copy that source file back into your tree.
I hope this answers your questions. If not, be gentle. I'm kinda new at answering stuff and I got slightly chewed out on an Android post haha.
I found the solution. The default Android Ant build.xml passes the release name to the child library project script while calling it. The following lines and the code that follows details it.
<!-- figure out which target must be used to build the library projects.
If emma is enabled, then use 'instrument' otherwise, use 'debug' -->
<condition property="project.libraries.target" value="instrument" else="${build.target}">
<istrue value="${build.is.instrumented}" />
</condition>
Then it's just a matter of having the same targets in all the interdependent projects.
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.
i saw some info regarding this question in several threads but non suited my condition.
I have an android application which i now need to customized some resources and code.
For the time being i have some problems using android library so i have an ant build that copies base resources and Assets plus specific ones to my android project and than changes the package name in the manifest as needed. All my activity have constant path and non relative to the package name so that's not an issue.
The problem is with the R object in the gen folder that is generated in the aapt. aapt does have a parameter to not use the android manifest package but another one, but it's available only if i use the ant build file, the parameters for the ADT are hard coded in the plugin.
has anyone found solution to this ? i mean i can always use ant task to change all R references (imports) but it looks to me error prone. Any way except wrapper script that wont do it on windows to customize aapt ?
again... no answer for my question, i'll start thinking you guys got something against me.
in short, i see there's no solution, the things i can do:
use ant task that regexps all the import com....R; to the new package - disadvantage: even the smallest issue with the regexp i may mess something up in the code that will show only in runtime.
use wrapper script around aapt.exe or aapt binary that adds --custom-package my.package.name that even if i change the manifest package will keep the original R files, for both ant and eclipse - disadvantage, some: 1. on windows this needs to be an exec file as eclipse looks for one it took me a while to build one properly in C, on linux\mac this could be a script of any kind so we need 2 versions of it\ 2. every update to the SDK we need to install the wrapper all over again.
edit the ant tasks jar code to allow --custom-package and edit the adt source code to enable in the menu custom parameters - this is great feature that should be included! but the disadvantage is until the code is accepted (if it is accepted) and added to the SDK itself , i'll needs to merge my changes every new SDK emerges, unlike #2 this is a lot harder.
I chose option #2, for now i have executable for windows, and i'll check options for Linux and mac (probably simple bash script) once i'm there, and i'll create a python installation script and save it all in the svn along with my build project.
Good luck to everyone....
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.