Compiling Ceres Solver With Android and Eclipse - android

I am trying to use ceres solver with my android application, and there does not seem to be a lot of documentation about using them both together properly. I have followed the build instructions from the ceres solver website, as well as this helpful tutorial:
http://tech.sandyeggi.com/2013/10/using-ceres-solver-in-android-ndk.html
This has gotten me far and everything is linked properly, but when I try to compile the project I get an odd error:
/Users/Steven/Documents/ceres-solver-1.10.0/include/ceres/internal/port.h:39:35: fatal error: ceres/internal/config.h: No such file or directory
Sure enough that file does not exist. But the question is why? Is it something that is supposed to be auto-generated? or created my self?
I might be important, so here is my Android.mk:
LOCAL_PATH := $(call my-dir)
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
include $(CLEAR_VARS)
LOCAL_MODULE := ceres
LOCAL_SRC_FILES := libceres.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES += /Users/Steven/Documents/android-ndk-r10d/sources/cxx-stl/stlport/stlport
LOCAL_C_INCLUDES += /Users/Steven/Documents/eigen-eigen-36fd1ba04c12/eigen-eigen-36fd1ba04c12
LOCAL_C_INCLUDES += /Users/Steven/Documents/ceres-solver-1.10.0/include
LOCAL_C_INCLUDES += /Users/Steven/Documents/ceres-solver-1.10.0/internal/ceres/miniglog
LOCAL_MODULE := DrinkMateDeveloper
LOCAL_SRC_FILES := DrinkMateDeveloper.cpp
LOCAL_STATIC_LIBRARIES = ceres
include $(BUILD_SHARED_LIBRARY)

Questions like this are best asked on the ceres-solver mailinglist.
The config.h you are looking for exists in
ceres-solver-1.10.0/config/ceres/internal/config.h
as the documentation in that file indicates
Default (empty) configuration options for Ceres.
IMPORTANT: Most users of Ceres will not use this file, when compiling Ceres
with CMake, CMake will configure a new config.h with the currently
selected Ceres compile options and copy it into the source
directory before compilation. However, for some users of Ceres
who compile without CMake, this file ensures that Ceres will
compile, with the user either specifying manually the Ceres
compile options, or passing them directly through the compiler.
you are going to have to do your own compiler defines for the various variables that are defined in
https://ceres-solver.googlesource.com/ceres-solver/+/master/cmake/config.h.in?autodive=0%2F

Related

Android.mk PREBUILT_SHARED_LIBRARY how to generate LOCAL_SRC_FILES file from script?

I have an NDK project where I build the shared libraries using the cross-compiler and standard gnu make utils. That is done with a separate script. But for the purpose of using the libraries in my project, I would like my Android.mk process to call my script to generate the shared library if it hasn't already been built, and then have Android.mk wrap it using the PREBUILT_SHARED_LIBRARY process.
Currently, if I run my script offline to generate libmy_so.so, then the following makefile will work. However, if I don't run the script explicitly first, I get the following error:
Android NDK: ERROR:/path_to_project/Android.mk:my_module: LOCAL_SRC_FILES points to a missing file
and my script is never called, so the make process is failing before even trying to resolve the dependency.
include $(CLEAR_VARS)
LOCAL_MODULE := my_module
LOCAL_SRC_FILES := libmy_so.so
LOCAL_EXPORT_CFLAGS := # some stuff
LOCAL_EXPORT_LDLIBS := # some stuff
$(LOCAL_PATH)/libmy_so.so:
echo "generate file"
$(shell run_script_that_creates_libmy_so.so)
include $(PREBUILT_SHARED_LIBRARY)
Is there a clean solution to this? I am even ok with running the script automatically as a preprocessing step (I can always have my script quietly exit if the file exists already), but I have not found an incantation that allows the LOCAL_SRC_FILES variable to point to a non-existent file. I have considered placing a dummy libmy_so.so to start, but that is an ugly hack.
Found a hack -- better way?
I found a hack. The makefile prebuilt-library.mk in the NDK contains the following lines:
ifndef prebuilt
$(call __ndk_info,ERROR:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_SRC_FILES points to a missing file)
$(call __ndk_info,Check that $(prebuilt_path) exists, or that its path is correct)
$(call __ndk_error,Aborting)
#endif
I created a copy of this file (and prebuilt-shared-library.mk to which I reference my copy of prebuilt-library.mk) and commented those lines out to stop the error. Then the trick is to make some target that is evaluated first depend on the file I want to generate. After digging through the .mk scripts in the NDK, I found that libraries serves the purpose. By adding libraries: $(LOCAL_PATH)/libmy_so.so to Android.mk, it will finally do what I want.
include $(CLEAR_VARS)
LOCAL_MODULE := my_module
LOCAL_SRC_FILES := libmy_so.so
LOCAL_EXPORT_CFLAGS := # some stuff
LOCAL_EXPORT_LDLIBS := # some stuff
$(LOCAL_PATH)/libmy_so.so:
echo "generate file"
$(shell run_script_that_creates_libmy_so.so)
libraries: $(LOCAL_PATH)/libmy_so.so
include /path/to/my/mk/files/prebuilt-shared-library.mk
This is obviously less than ideal as I would like to make sure my makefiles mature with newer versions of the NDK, but it does the trick. Still interested in more elegant solutions.

Android: How to link my own static libraries correctly?

I have an Android project written in C++ and have a problem in linking phase. The code is put in some static libraries which should be linked together.
I have found a lot of questions and answers on the net about this topic and most of them suggest to put my libraries to LOCAL_STATIC_LIBRARIES in the Android.mk file. But, if I do this, I found the content of LOCAL_STATIC_LIBRARIES is simply ignored: my libraries are not linked, and adding any dummy text here does not generate any error or warning message.
I tried it this way:
LOCAL_STATIC_LIBRARIES := MyLib.a
or with full path:
LOCAL_STATIC_LIBRARIES := $(LOCAL_PATH)/MyLib.a
none of them worked.
If I put my static libraries to LOCAL_LDLIBS then it is linked, but I got a warning message about non-system libraries are used, and probably the build will be wrong.
The content of my Android.mk file is:
LOCAL_LDLIBS := $(LOCAL_PATH)/MyLib.a ...
and I got this message:
Android NDK: WARNING:jni/Android.mk:myapp: non-system libraries in linker flags: jni/MyLib.a
Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK: current module
I could not find how to use LOCAL_STATIC_LIBRARIES right way, please help me!
I have android-ndk-r9 and android-sdk_r22.2.1 on a OpenSuSE x86 and using target=android-18
See JBL's answer here.
The LOCAL_STATIC_LIBRARIES variable does not work that way. First you need a section that defines the library you want to include:
include $(CLEAR_VARS)
LOCAL_PATH = .
LOCAL_MODULE := curl
LOCAL_EXPORT_C_INCLUDES := ../curl/include
LOCAL_SRC_FILES := ../curl/lib/libcurl.a
include $(PREBUILT_STATIC_LIBRARY)
THEN, you can include it using
include $(CLEAR_VARS)
LOCAL_MODULE = mylib
CFLAGS = ...
...
LOCAL_STATIC_LIBRARIES = curl
include $(BUILD_STATIC_LIBRARY)
Most probably the problem lies in that you are giving the extension of the library:
LOCAL_STATIC_LIBRARIES := MyLib.a
I think, it should be written as:
LOCAL_STATIC_LIBRARIES := MyLib

Android library project with native code packages library twice in the APK

I have two Android projects, one is a shared library and one is my application's project. Both projects contain some Java and some native code. When I try and run my APK I receive the following error:
Error generating final archive: Found duplicate file for APK: lib/armeabi/libOEShared.so
My shared library is marked as a library project (Properties->Android->'Is Library') so that I am able to use it's Java code. This presumably copies libOEShared.so for me once.
In order to link my Applications native code with libOEShared I use the NDK Prebuilds feature. Here is my Android.mk:
#include shared library
include $(CLEAR_VARS)
LOCAL_MODULE := OEShared
LOCAL_SRC_FILES := ../../../Shared/OEShared/libs/armeabi/libOEShared.so
include $(PREBUILT_SHARED_LIBRARY)
#build App library
include $(CLEAR_VARS)
LOCAL_MODULE := OEApp
LOCAL_SRC_FILES := OEApp.cpp
LOCAL_LDLIBS := -llog -lGLESv2 -lz
LOCAL_SHARED_LIBRARIES := OEShared
include $(BUILD_SHARED_LIBRARY)
However, the NDK also copies libOEShared into my Application project's lib folder, resulting in two copies being present in the final APK.
How can I link my Application's native code to libOEShared without it being automatically duplicated?
Thank you for you time, this has caused me a lot of frustration so far.
Only linking is required here, instead of build. Linking can be done by using LOCAL_LD_LIBS flag. You can try this.
LOCAL_LDLIBS := -L$(LOCAL_PATH)/../../../Shared/OEShared/libs/$(TARGET_ARCH_ABI)/ \
-lOEShared

Build issue when using prebuilt libraries with the Android NDK

I have a program I am porting that links together multiple libraries when creating the executable. I have built all those libraries using the stand alone toolchain and using the standalone toolchain I am able to create an executable that works on an android device. So, it seems like the libraries I have built are functional. Now I am trying to incorporate those libraries with an app. So, in my android.mk I have something like this:
LOCAL_PATH := $(call my-dir)
ROOT_PATH := $(LOCAL_PATH)
include $(call all-subdir-makefiles)
include $(CLEAR_VARS)
LOCAL_PATH = $(ROOT_PATH)
LOCAL_MODULE := test-libs
LOCAL_STATIC_LIBRARIES := staticA
LOCAL_SHARED_LIBRARIES := sharedA sharedB sharedC sharedD
LOCAL_SRC_FILES := test-libs.c
include $(BUILD_SHARED_LIBRARY)
For each of the libraries, I have a Android.mk like this
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sharedA
LOCAL_SRC_FILES := sharedA.so
include $(PREBUILT_SHARED_LIBRARY)
When I then build my project (in eclipse), I get this:
C:/ndk/android-ndk-r7b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a(unwind-arm.o): In function `__gnu_unwind_pr_common':
/cygdrive/c/ndk/android-ndk-r7b/build/core/build-binary.mk:314: recipe for target `obj/local/armeabi/libtest-libs.so' failed
/tmp/ndk-digit/src/build/../gcc/gcc-4.4.3/libgcc/../gcc/config/arm/unwind-arm.c:1237: undefined reference to `__cxa_call_unexpected'
Any thoughts on what is going wrong?
Also, the static library and one of the shared libraries have no dependencies on anything and if I only include them all is cool. One of my shared libraries only had a dependency on the static library. If I only include those, but when I include the others, which have dependencies on other shared libraries, this problem occurs.
Update 1: Ok it appears to be because the APP_STL setting in my Application.mk was being ignored. All I have in my Application.mk is:
APP_STL := gnustl_shared
If I copy over the libgnustl_shared.so and treat it like another prebuilt shared lib, my problem is gone. Any idea why the APP_STL is not working properly. Note, I could have screwed something up. I just upgraded to using 7b. Using gnustl_shared used to work for me with other apps. Rolling back to 7 doesn't fix it. I think I have messed something up in Eclipse. I use Eclipse (windows) with sequoyah.
It looks like the linker is giving you an error. What you should do is the following:
Add a LOCAL_LDLIBS under your LOCAL_MODULE := test-libs. Here you need to include all the libraries you link against when you compile your pre-compiled libraries. So for example:
LOCAL_LDLIBS := -lgnustl_shared -lgcc -llog -landroid -lstdc++
Basically you need to identify what library contains the function __cxa_call_unexpected. A quick google shows that it's probably in libstdc++. Make sure that you also link with this library when creating your pre-compiled libraries.
I'm thinking it might have something to do with exceptions support.
Are you using exceptions in your code and if so are you compiling with a runtime library that supports exceptions? (and compiling with exceptions on)?.
There is more on this in the CPLUSPLUS-SUPPORT and STANDALONE-TOOLCHAIN files in the ndk docs.
I've observed a similar problem when one of my projects which contains only C source files (*.c) references another project that contains a c++ file(*.cpp). Application.mk files for both projects had APP_STL := gnustl_shared in them. The ndk version is ndk7e.
The solution was adding an empty C++ file (dummy.cpp) to the project that contained only .c files. Supposedly ndk understood that this project should be linked against the gnustl_shared and the build succeeded.

How to compile a static library using the Android NDK?

I'm trying to compile a static library to use on Android but I can't figure out how to compile it. The library uses standard libraries (stdio.h etc...) and libxml2.
I am trying to compile using arm-eabi-gcc but I get the following error:
/cygdrive/c/android-ndk-r4/build/platforms/android-8/arch-x86/usr/include/asm/posix_types.h:15:28: error: posix_types_64.h: No such file or directory
How do I get this to work?
As I understand it, the correct method is to use ndk-build and not invoking the compiler directly.
In Android.mk you need to specify a module for each static library you want to compile, and then specify that your shared library should use it.
Example of a modified Android.mk file of the hello-jni sample project:
LOCAL_PATH := $(call my-dir)
# Define vars for library that will be build statically.
include $(CLEAR_VARS)
LOCAL_MODULE := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES := <list_of_src_files>
# Optional compiler flags.
LOCAL_LDLIBS = -lz -lm
LOCAL_CFLAGS = -Wall -pedantic -std=c99 -g
include $(BUILD_STATIC_LIBRARY)
# First lib, which will be built statically.
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_STATIC_LIBRARIES := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
If you want control over which modules to compile when you run ndk-build you can create create a Application.mk file (in the same directory as Android.mk) and list all the modules as in the following example:
APP_MODULES := <module_name_1> <module_name_2> ... <module_name_n>
In response to
Can you generate a static library (.a file) without a shared library
that uses it?
(which really should have been its own question), the answer is yes.
By default, the NDK will only build executables and shared libraries (with their dependencies of course). You can, however, force the NDK to build a standalone static library by explicitly referencing it in your Application.mk.
Assuming your static library module is LOCAL_MODULE := libXYZ, add the following line to Application.mk (creating the file in the same folder as your Android.mk if it doesn't exist):
APP_MODULES := XYZ
Note the the APP_MODULES value does not include the lib prefix included in your static library module name.
Alternatively, if you don't want to create an Application.mk, you can specify the value on the command line: ndk-build APP_MODULES=XYZ
A cool trick: if you have an Android.mk file, you can change the build type from:
include $(BUILD_SHARED_LIBRARY)
to
include $(BUILD_STATIC_LIBRARY)
and .a libraries will be output to the obj/ folder into their respective architectures when you ndk-build the library.

Categories

Resources