The Android build process generates(?) Java stubs for each of the classes in the android.jar, and stores them in the following directory:
./out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/
For example, the subdirectory java/lang/ of the above directory contains .java files corresponding to java.lang.* classes, and the subdirectory `android/app/' contains .java files corresponding to android.app.* classes. These .java files dont contain actual code, but just signatures with dummy bodies.
I am assuming that those .java files are generated from the actual source code using a tool. My question is, which is this tool, and is it usable outside of the Android build process?
I want to use that tool to generate stubs for non-Android Java classes.
The "stubs" here is the framework API stub generated by running javadoc tool.
In most cases, when we talk about stub file in Android, we mean the java file generated by aidl tool. For example see How to generate stub in android? - Stack Overflow
In particular, the Android build system contains a makefile called droiddoc.mk that can be used to generate documentation, java API stubs and API xml files, which actually calls javadoc.
droiddoc.mk is under build/core. In build/core/config.mk there is a variable named BUILD_DROIDDOC to make it easier to include the droiddoc.mk.
Look at the droiddoc.mk, it calls javadoc:
javadoc \
\#$(PRIVATE_SRC_LIST_FILE) \
-J-Xmx1280m \
$(PRIVATE_PROFILING_OPTIONS) \
-quiet \
-doclet com.google.doclava.Doclava \
-docletpath $(PRIVATE_DOCLETPATH) \
-templatedir $(PRIVATE_CUSTOM_TEMPLATE_DIR) \
$(PRIVATE_DROIDDOC_HTML_DIR) \
$(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH)) \
$(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
-sourcepath $(PRIVATE_SOURCE_PATH)$(addprefix :,$(PRIVATE_CLASSPATH)) \
-d $(PRIVATE_OUT_DIR) \
$(PRIVATE_CURRENT_BUILD) $(PRIVATE_CURRENT_TIME) \
$(PRIVATE_DROIDDOC_OPTIONS) \
&& touch -f $#
There is nothing about the stub right? Don't worry, notice that there is a PRIVATE_DROIDDOC_OPTIONS variable, and
PRIVATE_DROIDDOC_OPTIONS := $(LOCAL_DROIDDOC_OPTIONS)
Many Android.mk files in AOSP, for example the framework/base/Android.mk, contain the include $(BUILD_DROIDDOC) to generate docs. In framework/base/Android.mk, there is a piece of code:
LOCAL_DROIDDOC_OPTIONS:=\
$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
-stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_stubs_current_intermediates/src \
-api $(INTERNAL_PLATFORM_API_FILE) \
-nodocs
LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
LOCAL_UNINSTALLABLE_MODULE := true
include $(BUILD_DROIDDOC)
The LOCAL_DROIDDOC_OPTIONS contains a -stubs option. And it will finally put into the javadoc command used by droiddoc.mk.
However, we may notice that the javadoc doesn't contain any option like -stubs. The key is that you can customize the content and format of the Javadoc tool's output by using doclets. The Javadoc tool has a default "built-in" doclet, called the standard doclet, that generates HTML-formatted API documentation. You can modify or subclass the standard doclet, or write your own doclet to generate HTML, XML, MIF, RTF or whatever output format you'd like.
We can use the -doclet option to specify our customized doclet. And the javadoc command in droiddoc.mk use the -doclet com.google.doclava.Doclava. That doclet receives the -stubs option.
Look at the Doclava implementation under external/doclava/src/com/google/doclava/Doclava.java
else if (a[0].equals("-stubs")) {
stubsDir = a[1];
} else if (a[0].equals("-stubpackages")) {
stubPackages = new HashSet<String>();
for (String pkg : a[1].split(":")) {
stubPackages.add(pkg);
}
}
It receives the -stubs option. And here is how it process the stubsDir.
// Stubs
if (stubsDir != null || apiFile != null || proguardFile != null) {
Stubs.writeStubsAndApi(stubsDir, apiFile, proguardFile, stubPackages);
}
And trace the implementation of the Stubs.writeStubsAndApi, you can see why the content in the stub files are like that.
You can even write your own java files and generate your stubs like what the test cases under build/tools/droiddoc/test.
Related
I need to use the protobuf library in the c++ code of android ndk. In other words, let my auto-generated something.pb.h be happy when it wants to include files like #include <google/protobuf/port_def.inc>.
I do see some methods, but they all use the old Android.mk approach, while I need to use the new CMakeLists.txt approach (and there is completely no such thing as Android.mk in my project).
Therefore, what should I do? Thanks for any suggestions!
What I have tried:
Firstly brew install protobuf. Then, in CMakelists.txt
SET(PROTOBUF_INCLUDE_DIR "/usr/local/include/")
# have also tried this: find_package(Protobuf REQUIRED)
# have also tried this: find_package(protobuf CONFIG REQUIRED)
find_package(protobuf REQUIRED)
message(STATUS "Using Protocol Buffers ${Protobuf_VERSION}")
target_link_libraries(vision_utils
${PROTOBUF_LIBRARIES}
# have also tried this: protobuf::libprotobuf
)
but various errors with different attempts above:
CMake Error at CMakeLists.txt:25 (find_package):
Could not find a package configuration file provided by "protobuf" with any
of the following names:
or
CMake Error at CMakeLists.txt:107 (add_library):
Target "vision_utils" links to target "protobuf::libprotobuf" but the
target was not found. Perhaps a find_package() call is missing for an
IMPORTED target, or an ALIAS target is missing?
Try generating protobuf buildfiles manually with
cmake -G "MinGW Makefiles" \
-DCMAKE_TOOLCHAIN_FILE={NDK PATH}/build/cmake/android.toolchain.cmake \
-DCMAKE_MAKE_PROGRAM={NDK PATH}/prebuilt/{YOUR PLATFORM}/bin/make \
-Dprotobuf_BUILD_TESTS=OFF \
{PROTOBUF SOURCE PATH}/cmake
build
cmake --build . --target libprotobuf
then in CMakeLists.txt set
set(Protobuf_INCLUDE_DIR {{PROTOBUF SOURCE PATH}/src})
set(Protobuf_LIBRARIES {build files path})
Got this solution from here
I have just created a protobuf file (.pb file) for my own custom images using a TensorFlow tutorial.
But when I replaced the same file into the assets folder in tensorflow/examples/android/assets and try to build and generate an APK, the APK gets generated, but when I run the APK in an Android device, the APK crashes.
If I run the classify_image from Python, it gives me proper results.
Appreciate any help.
Since DecodeJpeg isn't supported as part of the core, you'll need to strip it out of the graph first.
bazel build tensorflow/python/tools:strip_unused && \
bazel-bin/tensorflow/python/tools/strip_unused \
--input_graph=your_retrained_graph.pb \
--output_graph=stripped_graph.pb \
--input_node_names=Mul \
--output_node_names=final_result \
--input_binary=true
Change few parameters in this file
/tensorflow/examples/android/src/org/tensorflow/demo/TensorFlowImageListener.java
The input sizes need to be 299, not 224. You'll also need to change the mean and std values both to 128.
INPUT_NAME to "Mul:0" ,
OUTPUT_NAME to "final_result:0"
after which you will be able to compile the apk.
Good Luck
I am having trouble to get up and running with Google test. I have read the suggested steps from Google, I also looked a previous post, and read some other examples, but it doesn't clear much things up.
To keep things simple, I am trying the suggested example from Google test that is available from the directory in the Android ndk - sample1:
// main.cpp
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include "gtest/gtest.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
testing::InitGoogleTest(&argc, argv);
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/factorial/main.qml"));
viewer.showExpanded();
return RUN_ALL_TESTS();
}
// sample1_unittest.cpp
#include <limits.h>
#include "sample1.h"
#include "gtest/gtest.h"
// Tests factorial of 0.
TEST(FactorialTest, Zero) {
EXPECT_EQ(1, Factorial(0));
}
The files sample1.h, sample1.cpp are also in the project, which contain the factorial function. Google test was equally informed to the project file - factorial.pro:
INCLUDEPATH +=
/opt/android-studio/ndk/sources/third_party/googletest/googletest/include
When I press [Build > Build Project "factorial"] it gets the following error:
main.cpp:8: error: undefined reference to 'testing::InitGoogleTest(int*, char**)'
sample1_unittest.cpp:17: error: undefined reference to 'testing::Test::Test()'
I am working with Ubuntu, QtCreator, Android and C++. Indeed I have spent already 3 days mocking around, but getting not much anywhere so far. Thus, I am posting here in hope some guru may give any hint on this. Any help will be mostly appreciated.
It seems you haven't built Google Test from what you describe. You need to compile the project into a library and then link against it. If you have CMake installed, then you have two options:
Use CMake's GUI (it's fairly intuitive) to generate the build system files, and then use those as usual (e.g. if you generate a Visual Studio solution, open the .sln file and build the project).
Use the command line to do the same thing; essentially you just create a new directory and do cmake <path-to-google-test> inside of it. The rest is the same.
You could also build the library by yourself. The distribution contains a folder named fused-src which should contain at least two files: gtest_main.cpp and gtest-all.cpp. Compile those files and you're done. You need to generate two libraries here: gtest out of gtest-all.cpp and gtest_main out of gtest_main.cpp.
Another alternative would be to get already built libraries. I've never searched for them, but they might be out there.
Try something like this:
$ g++ -I $GTEST_HOME/include -L $GTEST_HOME/lib -lgtest -lgtest_main -lpthread test.cpp
For more details:
How to setup googleTest as a shared library on Linux
If it still doesn't work, may find interesting to consider to use Makefile:
# A sample Makefile for building Google Test and using it in user
# tests. Please tweak it to suit your environment and project. You
# may want to move it to your project's root directory.
#
# SYNOPSIS:
#
# make [all] - makes everything.
# make TARGET - makes the given target.
# make clean - removes all files generated by make.
# Please tweak the following variable definitions as needed by your
# project, except GTEST_HEADERS, which you can use in your own targets
# but shouldn't modify.
# Points to the root of Google Test, relative to where this file is.
# Remember to tweak this if you move this file.
GTEST_DIR = ..
# Where to find user code.
USER_DIR = ../samples
# Flags passed to the preprocessor.
# Set Google Test's header directory as a system directory, such that
# the compiler doesn't generate warnings in Google Test headers.
CPPFLAGS += -isystem $(GTEST_DIR)/include
# Flags passed to the C++ compiler.
CXXFLAGS += -g -Wall -Wextra -pthread
# All tests produced by this Makefile. Remember to add new tests you
# created to the list.
TESTS = sample1_unittest
# All Google Test headers. Usually you shouldn't change this
# definition.
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
$(GTEST_DIR)/include/gtest/internal/*.h
# House-keeping build targets.
all : $(TESTS)
clean :
rm -f $(TESTS) gtest.a gtest_main.a *.o
# Builds gtest.a and gtest_main.a.
# Usually you shouldn't tweak such internal variables, indicated by a
# trailing _.
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
# For simplicity and to avoid depending on Google Test's
# implementation details, the dependencies specified below are
# conservative and not optimized. This is fine as Google Test
# compiles fast and for ordinary users its source rarely changes.
gtest-all.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest-all.cc
gtest_main.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest_main.cc
gtest.a : gtest-all.o
$(AR) $(ARFLAGS) $# $^
gtest_main.a : gtest-all.o gtest_main.o
$(AR) $(ARFLAGS) $# $^
# Builds a sample test. A test should link with either gtest.a or
# gtest_main.a, depending on whether it defines its own main()
# function.
sample1.o : $(USER_DIR)/sample1.cc $(USER_DIR)/sample1.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1.cc
sample1_unittest.o : $(USER_DIR)/sample1_unittest.cc \
$(USER_DIR)/sample1.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1_unittest.cc
sample1_unittest : sample1.o sample1_unittest.o gtest_main.a
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $#
If you have to use Makefile to get gtest working, you probably may need to adjust the given template for your case, as you intend to build it to use with Android.
I'm trying to edit an Android Makefile in the hopes of getting it to print out the directory (path) location of one the ZIP files it creates. Ideally, since the build process is long and does many things, I would like for it print out the pathway to the ZIP file to a text file in a different directory I can access later:
Pseudo-code idea:
# print the desired pathway to output file
print(getDirectoryOf(variable-name.zip)) > ~/Desktop/location_of_file.txt
The Makefile snippet where I would like to insert this new bit of code is shown below. I am interested in finding the directory of $(name).zip (that is specific file I want to locate):
# -----------------------------------------------------------------
# A zip of the directories that map to the target filesystem.
# This zip can be used to create an OTA package or filesystem image
# as a post-build step.
#
name := $(TARGET_PRODUCT)
ifeq ($(TARGET_BUILD_TYPE),debug)
name := $(name)_debug
endif
name := $(name)-target_files-$(FILE_NAME_TAG)
intermediates := $(call intermediates-dir-for,PACKAGING,target_files)
BUILT_TARGET_FILES_PACKAGE := $(intermediates)/$(name).zip
$(BUILT_TARGET_FILES_PACKAGE): intermediates := $(intermediates)
$(BUILT_TARGET_FILES_PACKAGE): \
zip_root := $(intermediates)/$(name)
# $(1): Directory to copy
# $(2): Location to copy it to
# The "ls -A" is to prevent "acp s/* d" from failing if s is empty.
define package_files-copy-root
if [ -d "$(strip $(1))" -a "$$(ls -A $(1))" ]; then \
mkdir -p $(2) && \
$(ACP) -rd $(strip $(1))/* $(2); \
fi
endef
As part of your rule's action (that is, as one of the lines indented by a tab, or as a command that follows a semicolon):
#echo $(dir $(variable-name).zip)
If output to a file is desired,
#echo $(dir $(variable-name).zip) >~/Desktop/location_of_file.txt
and you can make the > a >> if you prefer to append to the file rather than to overwrite.
UPDATE
What does it mean, "As part of your rule's action (that is, as one of the lines indented by a tab, or as a command that follows a semicolon)"?
Answer: It means that you can #echo like this:
file-to-be-built: dependencies
some-command
#echo foo
another-command
Or like this:
file-to-be-built: dependencies
#some-command; \
echo foo; \
another-command
(note the placement of the #). Or like this:
file-to-be-built: dependencies; #some-command; echo foo; another-command
But not like this:
#echo foo
file-to-be-built: dependencies
some-command
another-command
(Here is yet another parenthetical statement, which you can ignore if you like: The #, as you may know, suppresses Make's copying of the command itself to standard output. You can omit it, of course, but if you include it then you must put it before the specific command you don't want Make to copy. Formally, the versions without semicolons issue multiple, separate commands in their own, separate environments, using separate invocations of the shell; whereas the versions with semicolons only invoke the shell once, with a single environment, and leave it to the shell to separate and execute the commands. Does this make sense? Maybe not, if you just read it -- I can't make much sense of such tangled verbiage, either, even though I wrote it, myself -- but do try it with the # in the various spots indicated and it should soon start to make sense to you. The # is no big deal in any case, but it's there to use to keep Make's output clean if you understand how to use it.)
I am developing an Android app on windows, using eclipse.
I would like to use OpenSSL for my Android application. It needs to be used with C++ via NDK.
I tried to download fries' OpenSSL source code from https://github.com/fries/android-external-openssl and build it.
I read the README.android file, but I didn't understand what these instructions are for.
Do I need to download the OpenSSL source code in addition to the fries source code?
I have tried putting all the files from Fries' into my jni folder of the Android project. It complained about not finding e_os.h and openssl/crypto.h and others like that.
More specifically:
In file included from D:/Projects/Fatal/Android/OpenSSL/jni/ssl/s2_meth.c:59:
D:/Projects/Fatal/Android/OpenSSL/jni/ssl/ssl_locl.h:124:18: error: e_os.h: No such file or directory
D:/Projects/Fatal/Android/OpenSSL/jni/ssl/ssl_locl.h:126:28: error: openssl/buffer.h: No such file or directory
D:/Projects/Fatal/Android/OpenSSL/jni/ssl/ssl_locl.h:127:26: error: openssl/comp.h: No such file or directory
I am not sure why it doesn't find those files, I tried to add all sort of paths into LOCAL_C_INCLUDES in all sort of Android.mk files, but nothing worked.
I would like to know how to build OpenSSL for Android. Thank you.
I know this is old, but I kept coming across this when I was searching for this problem. In the case that you are building a standalone OpenSSL to go with your project and are getting this error, I found a solution as per this thread:
In openssl-android/crypto, openssl-android/ssl, and openssl-android/apps, you'll find a variable declaration for local_c_includes that is something like this:
local_c_includes := \
$(NDK_PROJECT_PATH) \
$(NDK_PROJECT_PATH)/crypto/asn1 \
$(NDK_PROJECT_PATH)/crypto/evp \
$(NDK_PROJECT_PATH)/include \
$(NDK_PROJECT_PATH)/include/openssl
If you've placed your openssl-android directory in your Android project in the project/jni directory, then these variables no longer point to the correct location. The way I solved it was to modify these paths to be relative to LOCAL_PATH:
local_c_includes := \
$(LOCAL_PATH)/.. \
$(LOCAL_PATH)/asn1 \
$(LOCAL_PATH)/evp \
$(LOCAL_PATH)/../include \
$(LOCAL_PATH)/../include/openssl
Remember, you'll have to do this for each of the directories you're trying to build (crypto, ssl, or apps).
I realized that the fries' github is just something to patch the source of OpenSSL, it's not a stand alone OpenSSL for android.
It is required because it provide Android.mk files which are required by ndk-build of ndk. You don't want to build it using standard gcc because you want to build it for Android.