How can I set an Android Makefile to copy/rename files? - android

According to the Android online docs there's currently no way to specify multiple/mixed file extensions for the gcc compiler in an Android makefile. The source I'm using, a public project, has multiple extensions and in order to get it to compile I need to rename the files with the other extensions .cpp before build.
I set up a project subfolder I can copy these files into and rename them and then just link to them from there but I'd like to make this step a part of the build process so that any time those files are modified I can be certain this build will reflect those changes.
I'm not sure how to tell the Android.mk file to copy the files and rename them. I tried this but it doesn't work:
cp '$(LOCAL_PATH)/$(SOURCE_ROOT)/Sprite.mm' '$(LOCAL_PATH)/$(MM_RENAMES)/Sprite.cpp'
I receive the following error:
Anhdroid.mk:10 * missing separator. Stop.
Thanks,
Update
Alternatively, if someone knows a way to embed a call to execute a shell/Perl script in the beginning of the makefile would work too.

Ok, got it, this worked to copy files:
$(shell cp -fr $(LOCAL_PATH)/$(SOURCE_ROOT)/Sprite.mm $(LOCAL_PATH)/$(MM_RENAMES)/Sprite.cpp)
And this also works to run an outside script:
$(perl scripts/foo.pl)

Related

Generate include files with ndk-build?

When using a normal build system like Makefiles, issuing make install will, for most open source libs out there, produce two directories in the --prefix=: lib/ and include/.
ndk-build -h is not helpful, neither is the android developers page. I've seen somewhere that specifying
ndk-build NDK_LIBS_OUT=/my/path/to/lib
provides the desired lib directory with the .sos in it.
Is there an equivalent for the includes?
(Specifically, i'm trying to compile SDL_ttf for android but it needs SDL.h, whereas the SDL build only provides the libs.)

Libogg compiled with standalone toolchain (generated by NDK script) tries to load itself from incorrect file - libogg.so.0 instead of libogg.so

I'm trying to add libogg to my android NDK project.
I'm using project template that comes with SDL library.
I'm on Windows, so all following scripts were executed under MSYS, a linux terminal emulator.
First, I generated a standalone toolchain.
android-ndk/build/tools/make-standalone-toolchain.sh --platform=android-12 --system=windows-x86_64 --toolchain=arm-linux-androideabi-4.9 --install-dir=Y:/gcc_android_androideabi-4.9_api12/
Then I built the library.
make clean
configure CC="/y/gcc_android_androideabi-4.9_api12/bin/arm-linux-androideabi-gcc" LIBS="-lgnustl_shared" CFLAGS="-mthumb" --host=arm-linux-androideabi
make
Then I copied resulting libogg.so to my project folder and added following to my jni/src/Android.mk:
...
include $(CLEAR_VARS)
LOCAL_MODULE := ogg-prebuilt
LOCAL_SRC_FILES := ../../prebuilt-libs/$(TARGET_ARCH_ABI)/libogg.so
include $(PREBUILT_SHARED_LIBRARY)
...
LOCAL_SHARED_LIBRARIES := ... ogg-prebuilt ...
...
Similar code works fine for another libraries that I use.
ndk-build successfully finds my libraries and adds them to the .apk.
The problem arises when I call System.loadLibrary("ogg"); at runtime. Dynamic linker gives me error message saying something like
Can't find library "libogg.so.0".
I'm sure that my library loading code is ok because it works for other libraries that I have.
Error from the dynamic linker is interesting because make not just generated single libogg.so. It generated 3 completely same files with different names: libogg.so, libogg.so.0 and libogg.so.0.8.2.
I tried to replace libogg.so with libogg.so.0 and adjusted Android.mk properly, but NDK build script yelled at me, saying that prebuilt shared libraries must have .so extension. I tried to just copy libogg.so.0 to libs/ folder, but NDK build script ignored it when building .apk.
Then I opened libogg.so in a hex editor and searched for libogg. I found only one occurence: libogg.so.0[NUL]. I replaced .0 with 2 [NUL]s, so it became libogg.so[NUL][NUL][NUL] and now library loads perfectly.
I can reproduce this error with all toolchains I use: arm-linux-androideabi-gcc-4.9, i686-linux-android-gcc-4.9 and mipsel-linux-android-gcc-4.9. They all are generated using similar scripts.
The error persists if I rename libogg.so.0 or libogg.so.0.8.2 to libogg.so and use it instead of original one. As I said, all three files have same content.
While I can make a sed script to automatically fix library name in .so files when necessary, I wonder if there is a better solution to this problem.
Maybe I have to add some flags to configure?
My slightly less hacky fix for this is to remove the version information from the build system of libogg.
In the directory where you have the libogg source code, open the file src/Makefile.am and change this line:
libogg_la_LDFLAGS = -no-undefined -version-info #LIB_CURRENT#:#LIB_REVISION#:#LIB_AGE#
to
libogg_la_LDFLAGS = -avoid-version
If you don't have automake installed then you can change the generated Makefile after running ./configure. Find the libogg_la_LDFLAGS and make a similar change to the one detailed above. On Linux a sed one-liner like this does the job:
sed -i 's/^libogg_la_LDFLAGS.*/libogg_la_LDFLAGS = -avoid-version/g' src/Makefile

Android NDK mangles relative path on windows

I am trying to create an Android Studio wrapper around C code and am running into a problem with the NDK. Because the C code is from a 3rd party project, I am trying to not move the code location and have the project in a subdirectory of the repository and as such have to not use the build in call to the NDK and its autogenerated make file. The NDK call works correctly, but I get the following error:
make.exe: *** No rule to make target `C:/some_relative_path/jni/../../../../core.c', needed by `C:/some_relative_path/obj/local/armeabi/objs/my_module/C_/some_relative_path/jni/__/__/__/__/core.o'. Stop.
As you can see, the object path has been mangled such that : and .. have been turned into underscores.
I had to add a jni folder to my project and place the Android.mk and Application.mk files in it to satisfy the path appending of the NDK Gradle plugin. As a result the jni folder had no source files in it. Since I found several links on google talking about needing more than one source file, I added two dummy source files to the jni directory.
Among other things, my Android.mk file contains the following:
LOCAL_SRC_FILES := \
$(LOCAL_PATH)/NDKBug1.c \
$(LOCAL_PATH)/NDKBug2.c \
$(LOCAL_PATH)/../../../../core.c \
I'm looking to see if anyone can help me with either this path issue directly, or perhaps suggest an alternative way of setting things up.
The file names in LOCAL_SRC_FILES are supposed to be relative to the local directory, so you need to remove the $(LOCAL_PATH)/ prefix - then it should work.
I haven't heard about a bug requiring to have source files in the local dir though, so I think you can get rid of them.

Android.mk rules to make a file.o from many files.txt then link it with other files.o produced from files.cpp

I'm porting a modem connection manager written in C++ from linux to gingerbread. This does not end up being an "app" with a "gui" that I would use a java wrapper with the NDK but a service that is called at boot from "init.rc". I found some not up to date docs related to android build system under build/core/. There you find some html files explaining the basics of Android build system and several "file.mk" which are some templates for common situation like creating a c++ executable, static libraries, shared library etc.
I place my tree with all the sources under external/myservice and it's meant to be compiled at the same time as Android itself. (I've already ported the kernel to my platform and it works, just the modem left to go)
In a subfolder in an Android.mk file, I have a bunch of ".cpp" files listed with the variable LOCAL_SRC_FILES := cppfile1.cpp cppfile2.cpp .... That will generate cppfile1.o cppfile2.o ...
I need to link those cppfile*.o with objfile.o to form a libfile.so. I found the rules on how to generate a libfile.so from a bunch of files.o.
Where things get complicated, is to port the "linux makefile" command to create objfile.o. Here is how it looks like
$(LD) $(LDFLAGS) -r -b binary -o QMIDB.o \
QMI/Entity.txt \
QMI/EnumEntry.txt \
QMI/Enum.txt \
QMI/Field.txt \
QMI/Struct.txt
Which means it is a linker job to merge a bunch of text file to make that objfile.o. That file is just a bunch of initialized data structure, there is no code to execute in it but it's pretty ugly to look at all files.txt with a text editor.
I have no clue how to integrate that in the Android.mk file. How can it be done? I'd even appreciate just a hint on where I can find more information. It is easy to find information on building Android applications but it's another story to find anything closer to Android/Kernel itself.
From the mk. file file you can easily get so file....
You need to use android Ndk setup and cygwin setup if you are using windows platform to genreate so file from your native code.
Firstly install and place ndk to a location...
Then install cygwin setup not default one check all features in the installation process (it a sort of linux terminal) as ndk-build command is recognized from linux terminal.
Now from your cygwin terminal get access to your project folder jni file.. or where mk is placed...
http://developer.android.com/sdk/ndk/index.html
Use the following referal how to run ndk-build command from cygwin terminal..
Now providing complete path of ndk we use the ndk-build command...
After that the complied code generates the .so file for our project...
Now what we are using System.loadlibrary command to use the so file i.e our native code can now be used.
Note to get so file form mk we need to complie using ndk setup.We can't directly copy paste so file to make our native code run.Also we we are using windows platfrom we will need to use cygwin setup to do that

NDK: Android.mk / GNU Make

The Android.mk for my NDK project contains several hundred CPP files from which I build about a dozen static libs and finally a single shared lib. Most of my developing experience so far is on Windows, so I'm not very familiar with Linux, GNU Make, and the like.
When I add a new CPP file to Android.mk (i.e. to LOCAL_SRC_FILES), issuing ndk-build rebuilds all of my files, apparently because Android.mk changed, and it refers to all of the CPP files. Is there a way to avoid this? Let's assume I make a separate file for each static lib, and each such file would add that lib's CPP files to LOCAL_SRC_FILES and be included by Android.mk. Should that result in rebuilding only the lib whose included file is modified? This was actually my first attempt, but I went seriously wrong somewhere, and had to start over as the build would no longer succeed (which is why I'm asking before trying again).
Assuming the above approach is reasonable, how does including a file relate to the scope/lifetime of variables set in the including/included files?
Still hoping someone can answer this...
Firstly try to split your project into multiple android.mk files, instead of just one. It would limit the recompilation step each time you change one of them.
Then try this ndk-build -o <your_android.mk>. For instance:
ndk-build -o jni/Android.mk
Ref: How to prevent Android native project full rebuild after changing Android.mk?

Categories

Resources