I'm trying to cross-compile an Android executable (command line) that calls a method inside a proprietary android prebuilt shared object (.so aarch64)
I'm using an Ubuntu 20.04 x86_64 and I want cross-compile an executable for Android 10 aarch64.
The method is defined from the relative JNI in the following way:
public static native int getScore();
I build a simple C program:
#include <stdio.h>
extern int getScore();
int main(){
getScore();
return(1);
}
Then I develop an Android.mk file like the following:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mygame
LOCAL_SRC_FILES := libmygame.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := getscore
LOCAL_SRC_FILES := getscore.c
LOCAL_SHARED_LIBRARIES := mygame
include $(BUILD_EXECUTABLE)
Then I try to compile with:
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk
But I get the follwoing error:
./obj/local/arm64-v8a/objs/getscore/getscore.o: In function `main':
/tmp/cross-compile-test/./getscore.c:24: undefined reference to `getScore'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [/home/mark01/Android/Sdk/ndk/21.3.6528147/build/core/build-binary.mk:738: obj/local/arm64-v8a/getscore] Error 1
Related
I'm trying to use FFTW in my Android application. I have followed this tutorial and was able to buid fftw with floating point precision using this build.sh, on OSX:
INSTALL_DIR="`pwd`/jni/fftw3"
SRC_DIR="`pwd`/../fftw-3.3.3"
NDK_ROOT="/Users/awesomeUserName/Desktop/android-ndk-r9"
cd $SRC_DIR
export
PATH="$NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/:$PATH"
export SYS_ROOT="$NDK_ROOT/platforms/android-14/arch-arm/"
export CC="arm-linux-androideabi-gcc --sysroot=$SYS_ROOT"
export LD="arm-linux-androideabi-ld"
export AR="arm-linux-androideabi-ar"
export RANLIB="arm-linux-androideabi-ranlib"
export STRIP="arm-linux-androideabi-strip"
mkdir -p $INSTALL_DIR
./configure --host=arm-eabi --build=i386-apple-darwin10.8.0 --prefix=$INSTALL_DIR LIBS="-lc -lgcc" --enable-float
make
make install
exit 0
This generates the fftw3/lib and fftw3/include directories correctly and everything seems fine.
I then want to compile this .cpp file:
#include "./fftw3/include/fftw3.h"
extern "C" {
int FooPluginFunction ()
{
fftwf_complex *in, *out;
fftwf_plan p;
in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * 1024);
out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * 1024);
p = fftwf_plan_dft_1d(1024, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
fftwf_execute(p); /* repeat as needed */
fftwf_destroy_plan(p);
fftwf_free(in); fftwf_free(out);
return 42;
}
}
To generate a shared library, using the following Android.mk makefile:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := fftw3
LOCAL_SRC_FILES := fftw3/lib/libfftw3f.a
LOCAL_EXPORT_CPPFLAGS := fftw3/include
include $(PREBUILT_STATIC_LIBRARY)
# Here we give our module name and source file(s)
LOCAL_MODULE := FooPlugin
LOCAL_SRC_FILES := FooPlugin.cpp
LOCAL_SHARED_LIBRARIES := fftw3f
include $(BUILD_SHARED_LIBRARY)
When I run Android.mk, I get a few undefined reference errors like this one:
/Users/awesomeUsername/Desktop/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/FooPlugin/FooPlugin.o: in function FooPluginFunction:jni/FooPlugin.cpp:8: error: undefined reference to 'fftwf_malloc'
The structures fftwf_complex and fftwf_plan are fine because these are defined in fftw.h, but the functions fftwf_malloc, fftwf_free, fftwf_destroy, fftwf_plan_dft_1d, etc. are defined in fftw.f03, which doesn't seem to be found by the compiler.
How can I modify my makefile so that it finds and uses the .f03 files so that I can use fftw on Android?
I just removed the --build parameter and the error disapeared
I want to make a native c program with a dynamic link library, so I put these files in Android/development/hello/: hello.c, myprint.h,myprint.c, the main() is in hello.c, and the Android.mk is:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myprint
LOCAL_SRC_FILES := myprint.c
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := helloworld
LOCAL_SRC_FILES := hello.c
LOCAL_SHARED_LIBRARIES := myprint
include $(BUILD_EXECUTABLE)
Then I make helloworld, and the output info is that:
target thumb C: helloworld <= development/hello/hello.c
target thumb C: myprint <= development/hello/myprint.c
target SharedLib: myprint (out/target/product/generic/obj/SHARED_LIBRARIES/myprint_intermediates/LINKED/myprint.so)
target Symbolic: myprint (out/target/product/generic/symbols/system/lib/myprint.so)
target Strip: myprint (out/target/product/generic/obj/lib/myprint.so)
target Executable: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld)
/home/neil/dev/google_422/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin/../lib/gcc/arm-linux-androideabi/4.7/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lmyprint.so
development/hello/hello.c:5: error: undefined reference to 'myprint'
collect2: error: ld returned 1 exit status
Please help me...
And my native code is:
// hello.c
#include "myprint.h"
int main()
{
myprint();
return 0;
}
// myprint.h
void myprint();
// myprint.c
#include <stdio.h>
void myprint()
{
printf("myprint...\n");
}
This is happening because you might not be compiling both files so it is unable to locate/link the declaration of that function.
try this
gcc headerfile.c mainfile.c
i try to use freetype lib in my project with cocos2d-x. I built freetype and added to the project(like here http://en.wikibooks.org/wiki/OpenGL_Programming/Installation/Android_NDK#FreeType ). In xcode it builds without errors. Now I trying to use it on android. I made make file in freetype dir:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := freetype
LOCAL_SRC_FILES := lib/libfreetype.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/include/freetype2
include $(PREBUILT_STATIC_LIBRARY)
and added to main makefile
LOCAL_STATIC_LIBRARIES := freetype curl_static_prebuilt
...
$(call import-module,freetype)
during linking has the error: libfreetype.a: file format not recognized; treating as linker script
Prebuilt : libfreetype.a <=
/Users/user/Development/Slots/Slots_Android/lib/freetype/lib/
SharedLibrary : libgame.so
/Users/user/Development/android_ndk_r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6.x-google/../../../../arm-linux-androideabi/bin/ld:./obj/local/armeabi/libfreetype.a:
file format not recognized; treating as linker script
/Users/user/Development/android_ndk_r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6.x-google/../../../../arm-linux-androideabi/bin/ld:./obj/local/armeabi/libfreetype.a:1:
syntax error collect2: ld returned 1 exit status
How to fix it?
when I tried the NDK build command here is the error i got
D:\AndroidWorkSpace\cppTestProj>D:\android-ndk-r8b-windows\android-ndk-r8b\ndk-b
uild.cmd
Android NDK: WARNING: Unsupported source file extensions in jni/Android.mk for m
odule cppTestProj
Android NDK: LOCAL_SRC_FILES :=
"Compile++ thumb : cppTestProj <= maintestapp.cpp
jni/maintestapp.cpp:1:19: fatal error: iostream: No such file or directory
compilation terminated.
make: *** [obj/local/armeabi/objs/cppTestProj/maintestapp.o] Error 1
The JNI folder has the following files:
maintestapp.cpp
Test_array_type.cpp
Test_array_type.h
Could u pls let me know the issue. Im not using Cygwin for the same. Am I missing any files?
Here is the make file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := cppTestProj
LOCAL_SRC_FILES := LOCAL_SRC_FILES := maintestapp.cpp \
Test_array_type.cpp
include $(BUILD_SHARED_LIBRARY)
here is the cpp file
#include<iostream>
#include"Test_array_type.h"
#include<stdio.h>
#include<conio.h>
using namespace std;
int main()
{
Test_array_type test_array;
Test_array_type *ptest_array1;
test_array.AddToList(10);
test_array.AddToList(20);
test_array.AddToList("Basha");
test_array.PrintList();
ptest_array1 = test_array.clonelist();
test_array.DeleteFromList(3);
test_array.AddToList(10);
test_array.AddToList(20);
test_array.AddToList(30);
test_array.AddToList(40);
test_array.AddToList(true);
test_array.AddToList("Java Beon APP");
test_array.PrintList();
ptest_array1->PrintList();
getch();
return true;
}
you should not run the 'ndk-build' command from your projects jni folder. To execute the Android.mk file run ndk-bild command within your root directory of project.
Your Android.mk should be look like this
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := cppTestProj
LOCAL_SRC_FILES := maintestapp.cpp \
Test_array_type.cpp
include $(BUILD_SHARED_LIBRARY)
Then run your ndk-build command
You can see this link for sample Android.mk file
Update:
static {
System.loadLibrary("hello-jni");
}
for more information please refer HelloJni.java file of sample project.
Thanks
you need to add LOCAL_C_INCLUDES and include your visual C++ include folders, since you are obviuosly working with it.
I compiled simple file main.cpp using android-ndk-r8b:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
puts("!!!Hello World!!!");
return EXIT_SUCCESS;
}
I used command as follow:
.../android-ndk-r8b/ndk-build APP_ABI=x86
from the directory of main.cpp file
My Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -fPIC
LOCAL_MODULE := main
LOCAL_SRC_FILES := main.cpp
include $(BUILD_EXECUTABLE)
Then I tried to open this file on debian x86 and I have this information:
./main: No such file or directory
then I used command:
ld main
and had information:
ld: error in main(.eh_frame); no .eh_frame_hdr table will be created.
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048320
Is it possible to run file compiled via android-ndk on a common linux x86 distribution?
No, the Android run-time libraries are not compatible with desktop Linux.
Note that your ndk-build puts the main executable in ./libs/x86/