Any possibility to get environment variable value inside Android.mk?
For example
#export MYBASEDIR=/home/whoami/base
And, inside Android.mk How to get MYBASEDIR value ?
Bear with me for very basic question.
All environment variables are imported by make as make macros automatically.
So, just use $(MYBASEDIR) in the makefile.
Related
I've successfully written a go mobile library and used it from an Android Java app.
I've also successfully called a c function from JNI. This one has the JNIEnv pointer.
I'd like to pass the context/JNIEnv from Java to Go.
Here's where it seems to get complicated:
Go Mobile does not seem to use JNIEnv at all.
LoadJNI.java does have a context object and claims to pass it to the Go side. But there it isn't visible.
I've been able to include jni.h using the "C" directive
I can transfer the JNIEnv from JNI/C or store it there as a global variable but that's an ugly kludge.
https://github.com/golang/go/issues/16876 talks about a proposal to do reverse binding but it's unclear what the status is.
https://godoc.org/golang.org/x/mobile/cmd/gobind also talks about it but the following code snippet
import "Java/java/lang/System"
t := System.CurrentTimeMillis()
returns
cannot find package "Java/java/lang/System" in any of:
/usr/local/go/src/Java/java/lang/System (from $GOROOT)
/Users/----/go/src/Java/java/lang/System (from $GOPATH)
In C I solved it with a compiler directive: #cgo CFLAGS: -I...
But I'm not sure how to do it for Java
In short, I'm now stuck and would appreciate help. Ideally, I'd just like to pass the object as a parameter, if possible. However, I'd settle for any reverse binding to call Java from Go.
I hate to answer my own question, but I'd hate someone to go through this as well too. I'll update this answer as I go along.
Basic Setup
Edit build.gradle and add GOPATH and GO to gobind (additions in bold):
gobind {
pkg = ".../reverse/reverse"
GOPATH = "/Users/johndoe/go"
GO = "/usr/local/go/bin"
}
How to develop
Start from the reverse example. Get it to compile and run.
Make one modification and recompile.
Missing gobind
It turns out the installation process neglected to build gobind. Run go install golang.org/x/mobile/cmd/gobind
I'm Stuck
Trying to modify the reverse project to do anything other than what it's already doing is failing. Even stuff like passing an object and calling toString will fail.
More to come...
I'm trying to build a GNU Make Canned Recipe, like so:
define this-will-fail
my_var=1
$(info your variable is $(my_var))
endef
$(this-will-fail)
This causes an error *** missing separator. Stop.
However, the following works as expected:
define why-does-this-work
$(eval my_var=1)
$(info your variable is $(my_var))
endef
$(why-does-this-work)
by printing your variable is 1.
I'm looking at AOSP's build system and frequently see usage of eval paired with define. What's the relationship between these two items, and why can I not create variables "normally" when using define?
The answer stems from a simple point with big ramifications - a makefile has two dialects, 1) the make language itself and 2) the shell language you use for stuff like invoking gcc.
A reminder of the normal make "rule" syntax:
targets : prerequisites
recipe
While the make target and prerequisites is in make
syntax, the stuff in the recipe is in the shell syntax, not make syntax.
This explains why you cannot do stuff like assign make variables as part of a recipe, as so:
all: the_dependencies_of_all
this_will_not_work := because_the_shell_does_not_know_what_this_line_means
In the shell syntax bits, make does three special text manipulations, and then the remaining string is passed verbatim to the shell. The three steps are
deal with escaped newlines (e.g. backslash followed by newline)
run any make functions (like $(filter ....) and $(eval ..)
expand any make target variables (like $#)
In the normal case, this 3-steps-then-shell processs happens once per recipe line, so each line of your makefile recipe is run in a different shell (hence why some calls to make will spawns many /bin/sh sub-processes).
Manipulation #2 above explains why you can use eval inside a recipe to add some make syntax to your recipe. Eval will turn into an empty string, which will cause no problems with the shell, but make will have evaluated the string inside your statement, so stuff like variable definitions is possible.
The precise moment this evaluation happens is a bit tricky to pin down - it seems to happen when the variable is first expanded, which itself depends upon where you reference that variable in your makefile. Perhaps someone can clarify this a bit more, since when this happens has been ramifications for invocations of make that use the -j flag to run multiple recipe lines in parallel
More Info:
https://www.gnu.org/software/make/manual/html_node/Rule-Introduction.html#Rule-Introduction
https://www.gnu.org/software/make/manual/html_node/Recipe-Syntax.html#Recipe-Syntax
https://www.gnu.org/software/make/manual/html_node/Splitting-Recipe-Lines.html#Splitting-Recipe-Lines
I am having a problem with a project in android studio.
I don't know which function is changing my variable value and I want to see what's responsible for changing it.
Is there any way to see which function/constructor does modify the variable ?
I have already added the variable to the Watches, but that only shows when the value changes. So is there any way to see the function that does change it specifically after it has another value ?
I have a library that I want to customize its work (I mean replacing the main of the library by my outside program so I can for example reorder the calls of the library's functions) and for that I had to change some static variable to extern variables so the library and my program can handle them both.
My program works fine when on run on my Linux desktop machine, however when I tried to port that to Android using NDK, I couldn't compile it because of the extern keyword .
So, I was wondering if there's a way concerning the Android.mk or alternative to the use of extern keyword, to make the things work.
You're getting an "undefined reference" because extern is not a variable definition, only a declaration. That means you must have an non-extern declation somewhere else in your code, otherwise the compiler doesn't allocate a symbol for your variable.
As for alternatives, no, an extern variable is the only way to have a global variable accross multiple object files in C.
If you only need a global variable in the same object file, you can use static so the symbol is not exported to other objects.
I would like to use self defined Environment variables in my source code. I use System.getenv() to do this and the code line looks like this. Log.d("MyTest","== MyEnv " + System.getenv("AP") + " ANDROID_ASSETS:" + System.getenv("ANDROID_ASSETS"));
before I execute my code I define my AP variable with export: export AP="12345" and the this is my output of set command
ANDROID_ASSETS=/system/app
ANDROID_BOOTLOGO=1
ANDROID_DATA=/data
ANDROID_PROPERTY_WORKSPACE=9,32768
ANDROID_ROOT=/system
AP=12345
...
Then I execute my code and I get this line from logcat
D/MyTest( 5363): == MyEnv null ANDROID_ASSETS:/system/app
The value for my defined Environment variable is null. Any suggestions on why it didn't work?
Export command works for one session only, not for a whole system. You can't set environment variables that way. getprop/setprop doesn't work neither.
I had similar problem and found that easiest way to pass some arguments from console is to do something like:
echo "12345" > /sdcard/myapp/args/AP
Then read this file from Java.