I've looked around at some questions about writing android.mk files and the "make: * No rule to make target .c needed by .o"** they all center around typos which I don't think that I have.
This is an SDL project that builds fine with my CMake build scripts but I just can't get android.mk to work for me.
Here's the project setup in cmake
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(blp)
#set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
FIND_PACKAGE(SDL2 REQUIRED)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIR})
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/source/core_math")
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/source/utils/time_utils")
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/source/utils/resource_utils")
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/source/ren_opengl")
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/source/core_engine")
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/source/components/renderable2d")
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/source/glm/vec3.hpp")
FIND_PACKAGE(SDL2 REQUIRED)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIR})
FIND_PACKAGE(SDL2_IMAGE)
INCLUDE_DIRECTORIES(${SDL2_IMAGE_INCLUDE_DIR})
ADD_SUBDIRECTORY(source)
ADD_SUBDIRECTORY(project)
SET(SRC_FILES main.c)
SET(EXTERNAL_TARGET_LIBS ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARY})
SET(COMPONENTS renderable2d)
SET(INTERNAL_TARGET_LIBS core_math time_utils resource_utils ren_opengl)
SET(TARGET_LIBS ${INTERNAL_TARGET_LIBS} ${EXTERNAL_TARGET_LIBS} ${COMPONENTS})
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/resources/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bin/resources/)
the project subfolder is where I can create different projects and reuse the source dynamic libs that I create.
inside the source, you can see I have a bunch of dynamic libs that are created. At the end there's the dynamic libs and one .h and .c class that imports all of them, then I import that one .h file inside my project to use the libs.
Now onto my android.mk file, it's not very complete yet but this is where I am running into trouble.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main
SDL_PATH := ../SDL
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include/
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/utils/time_utils/
# Add your application source files here...
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \
utils/time_utils.c \
//removing the above line, core_engine.c throws an import error
//adding the above line I get the error listed at the bottom
core_engine/core_engine.c \
project.c
LOCAL_SHARED_LIBRARIES := SDL2
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog
include $(BUILD_SHARED_LIBRARY)
make: *** No rule to make target `/Users/blubee/SDL/android-project/jni/src/time_utils/time_utils.c', needed by `/Users/blubee/SDL/android-project/obj/local/armeabi/objs/main/time_utils/time_utils.o'. Stop.
each lib is under it's own folder int he project source tree like this
source/components/renderable2d/renderable2d.c /.h
source/core_engine/core_engine.c /.h
source/core_math/mat4_scalar/mat4_scalar.c /.h
source/core_math/vec3_scalar/vec3_scalar.c /.h
source/..
etc...
It could be a build oder or the order in which I am defining the sources files in the android.mk folder, I am not sure. Any suggestions? I also made sure that there's no typos or extra spaces in my environment variables or the source file for the android.mk
It seems that android.mk is a lot more sensitive to header include order more so than cmake.
I simplified my project just to a main.c with a #include "SDL.h" and that builds just fine.
I will go from there and learn android.mk, while it's similar to cmake it's a lot more picky.
Related
I have an existing android application that I'd like to build inside AOSP (android source tree) using Android.mk. The app uses constraint layout which is not included in AOSP source tree (AFAIK).
How can I satisfy this dependency? Other support libs are included such as recyclerview, v4 etc but not contraint layout.
Should I download the lib aar and if yes , how do I add/include it?
Or should I get the source (where to download?) and build it somewhere in the source tree?
Thanks in advance for any help.
There are several ways to resolve your issue.
1. Add a prebuilt .apk
You don't have to put your source code to the AOSP tree.
You can just add your .apk file, put it either in packages/apps/YourApp, or vendor/yourname/packages/apps/YourApp, or even your_dir_name/packages/apps/YourApp, and create an Android.mk file for build system to determine your application.
Android.mk will look like:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := YourApplication # your .apk name
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
include $(BUILD_PREBUILT)
Pros: you can build your project with gradle.
2. Add source code to AOSP
If you still want to place your source code to packages/apps and build it there, you can put a ConstrainsLayout to your project's libs/ directory and add to your Android.mk something like:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# List of static libraries to include in the package
LOCAL_STATIC_JAVA_LIBRARIES := constraint-layout
# Build all java files in the java subdirectory
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Name of the APK
LOCAL_PACKAGE_NAME := YourApplication
# Tell it to build an APK
include $(BUILD_PACKAGE)
In case you will not get it work (I haven't met this issue, but he did):
LOCAL_STATIC_JAVA_LIBRARIES := libconstraint-layout
include $(BUILD_PACKAGE)
Other stuff, and finally
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := libconstraint-layout:libs/constraint-layout.aar
Cons: You will have to build your code either with make by mma or mm -B, or to have a gradle as your second build system for development. The second option will work, but to establish a full build and to have your .apk built in out/ directory you will have to build it with make.
3. Adding a ConstraintLayout
In case you want to have several applications, which use a constraint layout, you can add it as a new library module as precompiled .aar.
Can be somewhere in 'vendor/yourname/libs' or 'your_dir_name/libs' respectively.
It is similar to adding a prebuilt .apk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := constraint-layout
LOCAL_SRC_FILES := $(LOCAL_MODULE).aar
LOCAL_MODULE_SUFFIX := .aar
include $(BUILD_PREBUILT)
After that, in your application's Android.mk you will have to add:
LOCAL_STATIC_JAVA_LIBRARIES := constraint-layout
Alternatively, you can add a ConstraintLayout's .aar to the prebuilds/ as it eventually will be there someday.
There is a good topic about Android.mk: https://wladimir-tm4pda.github.io/porting/build_cookbook.html
https://stackoverflow.com/a/46414919/9237859 is right, except LOCAL_STATIC_JAVA_AAR_LIBRARIES should be used instead of LOCAL_STATIC_JAVA_LIBRARIES, since constraint-layout is a aar file.
From Android 9.0, there is no need of adding .aar and .jar separately in the project for constraint-layout. We can use constraint-layout library built in to AOSP.
We need to add one extra line in Android.mk:
LOCAL_USE_AAPT2 := true
Then, we need to add:
LOCAL_AAPT_FLAGS := \
--auto-add-overlay \
--extra-packages android.support.constraint
LOCAL_STATIC_ANDROID_LIBRARIES += android-support-constraint-layout
LOCAL_STATIC_JAVA_LIBRARIES += android-support-constraint-layout-solver
For more detailed answer: How to use constraint-layout during AOSP build without including external .aar and .jar
This can be done as follows:
Download constraint-layout.aar and constraint-layout-solve.jar and put these files in lib folder.
Add the following to your Android.mk file
LOCAL_STATIC_JAVA_AAR_LIBRARIES += constraint-layout
LOCAL_STATIC_JAVA_LIBRARIES += constraint-layout-solver
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := constraint-layout:libs/constraint-layout.aar
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := constraint-layput-solver:libs/constraint-layout-solver.jar
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.
I'm trying to use Google's Protocol buffer on a C++ project. I can build it just fine for say... an iOS framework target. However, I can't seem to get the compiler to find any of the google/protobuf files. I already have the static library file (not sure if this one works on my architecture? i used: https://gist.github.com/BennettSmith/9487468ae3375d0db0cc)
in the output of the proto file, let's say blah.pb.h, i have a reference to protobuf:
#include <google/protobuf/stubs/common.h>
the compiler can't find that ^ reference.
I've tried to ndk-build with something like this:
include $(CLEAR_VARS)
LOCAL_MODULE := libprotobuf
LOCAL_SRC_FILES := src/lib/libprotobuf.a
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_SRC_FILES:=$(shell find src/lib -name '*.cpp')
LOCAL_MODULE := mymodule
LOCAL_C_INCLUDES += ./src/lib
LOCAL_STATIC_LIBRARIES := libprotobuf
include $(BUILD_SHARED_LIBRARY)
but it doesn't seem to help at all. what's going on? how do i include lib protobuf when i have the .a file? do i have to compile it from source?
turns out i have to multiple things:
i have to duplicate the entire protobuf include folder (the one with all the headers) to my project. and then include them in my LOCAL_EXPORT_C_INCLUDES
also, the command that i was using to do ndk-build is also not fully correct. it was missing a ton of stl stuff, like missing "string" or vector or map. so i used this instead:
ndk-build V=1 NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk APP_STL=stlport_static
NDK - Android Java with native (JNI) C++ code build issue
I tried to build the ndk and get error
/android-ndk-r9/build/core/prebuilt-library.mk:68: *** target pattern contains no '%'. Stop.****
my Android.mk code is :
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_CAMERA_MODULES := on
OPENCV_INSTALL_MODULES := on
#OPENCV_LIB_TYPE:=SHARED
include D:/Books/Java/winx86_01Jan12/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk
LOCAL_SRC_FILES := F_jni.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_LDLIBS += -llog -ldl
LOCAL_MODULE := f
include $(BUILD_SHARED_LIBRARY)
please help Until I resolve my problem.I'm really confused.I tried several ways and I could not solve my issue.
ndk-build invokes make which does not handle the : character in targets well. If your project resides on disk D:, too, then you can refer to OpenCV without the drive letter,
include /Books/Java/winx86_01Jan12/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk
Otherwise you can try
include //D/Books/Java/winx86_01Jan12/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk
include //localhost/D$/Books/Java/winx86_01Jan12/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk
If nothing helps, copy your OpenCV SDK such that you can use a relative path, e.g.
include ../../OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk
PS The source of your troubles is probably cygwin somewhere on the PATH. Since November 2011, NDK r7, ndk-build does not need cygwin. OpenCV made the reciprocate step short afterwards. Unfortunately, many developers still need cygwin for their daily work; furthermore, until recently, you still needed cygwin to run ndk-dgb (you have ndk-gdb-py.cmd now!). So my advice is to remove cygwin\bin directory from your PATH before you run ndk-build.cmd. You can easily do it in Project build properties if you use Ecliplse/ADT to build your native code.
I have an Android.mk file that compiles my NDK C code just fine:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := galib
LOCAL_SRC_FILES := galib.c tables-lr35-contam.c tables-lr35-perf.c
LOCAL_CFLAGS := -DTARGET_ANDROID=1
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
I'd like to call the first source galib.cpp instead of .c because that's the name I need it to be when compiling it in the WPF environment. It really is just C code but to make a DLL I have to name it .cpp for it to handle the __declspec(dllexport) stuff properly.
However, when I rename it galib.cpp and change the .mk file to say the same and try to build it for Android, I get the error:
$ ndk-build
make: *** No rule to make target `/cygdrive/c/apk/adev/android/etold/jni/galib.c',
...needed by `/cygdrive/c/apk/adev/android/etold/obj/local/armeabi/objs/galib/galib.o'. Stop.
as though it still wants a .c file for some reason. I also tried "ndk-build -B" in case there's something left over from the .c build, but that results in the same error. Any idea why? Thanks!
I know that you asked that long time ago. But anyway - for other people like me:
I tackled into this problem too just now.
For some reason clean build doesn't do the job even when you change the sources list at LOCAL_SRC_FILES.
I had to navigate to \obj\local\armeabi\objs\ within the project and clean .o files manually.
After that it compiled fine.