Why can I not create variables in a GNU make 'define' directive - android

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

Related

Trouble with sed: "bad pattern"

I'm working on a script to run on Android (hence the weird shebang path). It involves using sed to comment out certain blocks of code from specified files. Currently, I'm trying to pass an entire sed command to a function, but I'm having a lot of trouble doing so.
This is the script:
#!/system/bin/sh
REM_RCTD=$1
REM_CCMD=$2
REM_TRITON=$3
DEVICE_CODE=$4
COLOR_GRN_PRE="<font color='#00ff00'>"
COLOR_YEL_PRE="<font color='#ffff00'>"
COLOR_POS="</font>"
YELLOW=0
GREEN=1
echoAndExec() {
CMD="$2"
if [ "$1" = ${YELLOW} ]; then
echo "$COLOR_YEL_PRE $CMD $COLOR_POS"
elif [ "$1" = ${GREEN} ]; then
echo "$COLOR_GRN_PRE $CMD $COLOR_POS"
fi
${CMD} || exit 1
}
if [ "$REM_RCTD" = "true" ]
then
CMD="sed -ir -e \_^# LG RCT(Rooting Check Tool)$_,/^$/{/^(#\|$)/!s/^/#/} init.lge.rc"
echoAndExec ${YELLOW} "${CMD}"
fi
if [ "$REM_CCMD" = "true" ]
then
CMD="sed -ir -e \_^service ccmd /system/bin/ccmd$_,/^$/{/^(#\|$)/!s/^/#/} init.lge.rc"
echoAndExec ${YELLOW} "${CMD}"
fi
if [ "$REM_TRITON" = "true" ]
then
CMD="sed -ir -e /# triton service/,\_chmod 644 /sys/devices/system/cpu/triton/enable_s/^/# / init.${DEVICE_CODE}.power.rc"
echoAndExec ${YELLOW} "${CMD}"
fi
Every command sent to the echoAndExec() function works fine, except for sed, which returns
sed: bad pattern '\_^##1 (\)
For the third sed command, it has the same issue with the /.
I've tried a bunch of combinations of quotes, with and without the usage of variables, with different syntax for the pattern beginnings (/#, _), but I'm really lost. As is probably obvious from my script, I'm pretty much a beginner in shell scripting.
Is there maybe a POSIX alternative to sed I could use that might work better? Or is there some combination of quotes and escapes that'll make this work? I just can't figure it out.
If anyone needs any more details, I'll be happy to provide them; I just don't know what would be relevant.
TL;DR: You can use eval in the function and include correct internal quotation marks in the command you pass, which for complex commands is cumbersome and may make code that uses your function very hard to read, but which has some advantages. Or you can pass the commands as multiple arguments to your shell function, after the initial color argument, shift off the color argument after storing or otherwise using it, and run the command as "$#". See below for full details. (There are also likely methods not covered here at all; perhaps others will write answers about them.)
The Problem
The ${CMD} in ${CMD} || exit 1 in not quoted, so word splitting and globbing are performed. That only does what you actually want in the very simplest of cases. Each of your sed commands contains text that you intend to be passed to sed as a single argument, but which contains spaces. The spaces cause it to split into multiple words, each of which is passed to sed as a separate command-line argument.
Consider the simplified situation where the command you want to run is:
printf '%s\n' 'foo bar' 'baz quux'
When you run printf with %s\n as its first argument, it prints each of its subsequent arguments on a line by itself. This is a convenient way to check the effects of word splitting and globbing. The output of that particular command is:
foo bar
baz quux
If you assign the whole command to CMD without internal quotes, the simplicity of this particular command makes the problem immediately obvious: there is no way for the shell to know where you do and do not intend for it to perform word splitting.
$ CMD="printf %s\n foo bar baz quux"
$ $CMD
foo
bar
baz
quux
But this is exactly the situation you have with each of your sed commands. Some of the spaces in your sed commands are intended to separate arguments, while others are not, and the shell has no way to know what you want.
Embedding internal quotation marks into the value of CMD will not solve the problem. Not by itself, anyway. Since they are themselves quoted, their special meaning is suppressed. Quote removal does not occur in this situation, so they will simply remain at the edges of the words where you put them. Furthermore, the whitespace you intended for them to quote still causes word splitting:
$ CMD="printf %s\n 'foo bar' 'baz quux'"
$ $CMD
'foo
bar'
'baz
quux'
You can, of course, expand $CMD inside double quotes ("$CMD"). But that prevents all word splitting, and attempts to run a program whose name is your entire command, spaces and all. That is not what you want:
$ "$CMD"
printf %s\n 'foo bar' 'baz quux': command not found
There are multiple ways to solve this problem. I'll show two.
Way 1: You can make the function run the command with eval
One solution is to expand $CMD in double quotes to prevent word splitting, but instead of running that, pass it as an argument to the eval shell builtin. That causes the shell to parse the contents of CMD the same way it does when those contents actually appear as a line in a script. Note that, since the actual text stored in CMD is not quoted, you must include internal quotes for everything that requires quoting. In simple cases, you can get away with using " " for either the inner quotes or the outer quotes:
$ CMD='printf "%s\n" "foo bar" "baz quux"'
$ eval "$CMD"
foo bar
baz quux
$ CMD="printf '%s\n' 'foo bar' 'baz quux'"
$ eval "$CMD"
foo bar
baz quux
However, for commands that contain characters like $ that may be treated specially if expanded inside double quotes -- like what you are doing with sed -- it is often necessary to use single quotes for both. To achieve this, you can end quoting for just long enough to write a single quote that is itself quoted with \, then resume quoting again. That is, you can write a single quote "inside" single quotes as '\''.
$ CMD='printf '\''%s\n'\'' '\''foo bar'\'' '\''baz quux'\'''
$ eval "$CMD"
foo bar
baz quux
This approach has the major disadvantage that it can be hard to quote your commands correctly to pass them to your shell function, and extremely hard for you (or someone else) to verify they are correct by inspection. However, it has the advantage that the function has a string that can be run, exactly as written, as your command. Normally this is unimportant, but in your case it may be important, because you are showing the user what the command was. If you want the user to see a command that can be run, verbatim -- that is, you want to show proper quoting to the user, not just run the command correctly -- then this eval-based approach is probably the simplest way to achieve that.
Here's a modified version of your shell function. It takes the color attribute value that goes in your start tag, rather than a number, as the first argument. I actually suggest you do that, as there's no reason $YELLOW and $GREEN cannot just be #ffff00 and #00ff00, respectively. But however you choose to write it, this should demonstrate how you can use eval in it.
echoAndExec() {
printf '<font color='\''%s'\''> %s </font>\n' "$1" "$2"
eval "$2" || exit 1
}
As you can see, I've also replaced echo with printf, since some echo implementations expand escape sequences, which you probably don't want here. (Some can also treat the first argument you pass as though it were an option, but that's not an issue here, since your first argument starts with <, never -.) Finally, I have made the variables lower-case. I suggest using lower-case names for your shell variables, unless you plan to export them as environment variables. It is common both for environment variables and for variables treated specially by shells (e.g., PS1) to be named in upper case, and using lower case helps avoid conflicts. You can use upper case if you want to, though.
Here's how you might call that function:
$ green='#00ff00'
$ cmd='printf '\''%s\n'\'' '\''foo bar'\'' '\''baz quux'\'''
$ echoAndExec "$green" "$cmd"
<font color='#00ff00'> printf '%s\n' 'foo bar' 'baz quux' </font>
foo bar
baz quux
Or just:
$ green='#00ff00'
$ echoAndExec "$green" 'printf '\''%s\n'\'' '\''foo bar'\'' '\''baz quux'\'''
<font color='#00ff00'> printf '%s\n' 'foo bar' 'baz quux' </font>
foo bar
baz quux
Of course, whether or not you assign the command to a variable first, you do not have to redefine green each time.
Way 2: You can pass the command as multiple arguments to the function
Normally, when you perform parameter expansion in double quotes, word splitting is suppressed entirely. However, the # parameter is special. * and # both contain the text of all your positional parameters, one after the other, but they behave differently when expanded in double quotes. With "$*", you get no word splitting--the positional parameters are joined, with single spaces (or whatever is the first character of $IFS) between them.
In contrast, with "$#", word splitting is performed between the positional parameters, but not within them. This is to say that each positional parameter becomes its own word, but a positional parameter that contains whitespace still won't be split any further (as it would be with $* or $# outside " ").
This provides exactly the functionality you need to pass a command to your function, in a way that allows you to write the command in a readable manner, and have the function run it correctly. Here's how you might write your function, if you want to take this approach:
echoAndExec() {
printf '<font color='\''%s'\''> ' "$1"
shift
printf '%s </font>\n' "$*"
"$#" || exit 1
}
Running "$#" initially would not do what you want, because it would have included the first positional parameter at the beginning. To remove the first positional parameter while shifting each of the others down by one (or you may prefer to think of it as shifting them left by one), I used the shift builtin.
That code is somewhat less readable than it could be, because I have avoided introducing any variables in the shell function. The reason I have done this is that the declare and local builtins are not actually required by POSIX, and I am not sure if your shell--and other shells on which you might need to run this script--support them. Without them, assigning to a variable in a shell function causes them to be set for the caller as well. For the particular script you've shown, that doesn't seem like it would be a problem, but I don't know if (or how) you might end up extending the script or what variable names you might use in it later.
Some of the changes shown above, compared to your version of the function, are specific neither to this approach of expanding "$#" nor to the preceding approach of using eval. I have explained those changes in the preceding section. You do not have to write your function exactly this way, though you can; the purpose of the above code is to serve as an example.
It's important to remember that you must call this function in a different way from the way you would call the function you wrote originally (and also differently from the eval-based version shown above). Don't store your commands in a variable first. Just pass each word of the command to the shell function:
$ green='#00ff00'
$ echoAndExec "$green" printf '%s\n' 'foo bar' 'baz quux'
<font color='#00ff00'> printf %s\n foo bar baz quux </font>
foo bar
baz quux
You will notice that this is much, much easier to call, because you don't have to use any quoting beyond what you would use just to run the command directly. In fact, you must not use such additional quoting. It is enormously easier to use this function and to understand what you have written and verify that it is correct.
However, this does have the disadvantage that it is no longer trivial to print the command that was passed in with its original quoting. The shell removes those quotes when the function is called. The function does not have access to them.
You might not care about this, but if you do, then you can make your shell function insert quotes around each argument. They won't necessarily be the same quotes that were used originally, and they might not even be correct if the arguments themselves contained single quotes. But they should typically indicate, in a reasonably unambiguous way, what arguments were passed:
echoAndExec() {
printf '<font color='\''%s'\''> ' "$1"
shift
printf \''%s'\'' ' "$#"
printf '</font>\n'
"$#" || exit 1
}
You would use that function the same way. It will look like this:
$ green='#00ff00'
$ echoAndExec "$green" printf '%s\n' 'foo bar' 'baz quux'
<font color='#00ff00'> 'printf' '%s\n' 'foo bar' 'baz quux' </font>
foo bar
baz quux
(As mentioned above, you don't have to redefine green each time. I've just done so, so that it's clear what green means in the versions of the shell function that I have written, and so that it is clear how to test this easily.)
Although you can do that, I underscore that the command it shows will not always be possible to run as shown, because it does not handle internal single quotes correctly. The command shown to the user is pretty good for humans, but not so great for computers. Therefore, although you can use this modified method, it is probably better to go with the eval-based way shown above, if you need to show the user a command with original (or otherwise proper) quoting.
Of course, it is also possible to process the arguments in a more sophisticated way that, for example, properly converts internal occurrences of ' into '\''.
Further Reading
Even though the shell being used here is probably not Bash, I nonetheless recommend the Bash reference manual for its clear, relatively accessible explanations of the important concepts in Bourne-style shell scripting.
For a more official source for such shells in general, links to specific topics within the Shell Command Language chapter of POSIX are included directly in the text above.
To see some of the information included here presented in another form, my chat with the OP about the question can be consulted.

Making sense of symbol table entry (when header function is not present)

I have a JNI function in a C++ library.
When I create the library using cmake (but forget to put function declaration) in the header file, the library is created successfully.
When I look for function name in library symbol table I get following output
nm libuserlibrary.so | grep printxx
00506e60 T _Z60Java_com_example_user_myapplication_userlibrary_printxxP7JNIEnv_P8_jobject
But when I give function declaration in the header file, I get following output
nm libuserlibrary.so | grep printxx
00506e50 T Java_com_example_user_myapplication_userlibrary_printxx
Why is there this difference between these two symbol table entries? What is the purpose of _Z60 and P7JNIEnv_P8_jobject around the function name?
I also noticed that in the first case, I cannot call the JNI funciton from Android java code (it says unsatisfied-linker-error, implementation not found).
C++ allows function overloads and namespaces like Java does. So, it annotated the function name with parameter information so the linker can bind to the correct overload.
JNI was designed for C which does not allow function overloads or namespaces. So it invented it's own annotation system and provides the javah tool to help you use it. The header can be used in C++ too. C++ was designed to allow some functions to be called as if they written in C. The header has code that indicates that to the compiler. So, put it all together and you can write Java-callable functions in C++.

Feature comparison: V8 vs. iOS JavaScriptCore

Without using any non-deafult switches (i.e. no --harmony), are there language features, global properties, etc. that exist in V8 (at 69a0664) but not in JSC (at f27bfeb) and vice versa?
I'm doing Android/iOS work and want to make sure the same scripts will work on both.
In terms of ECMAScript 5 features, going by this table, both have attempted to implement everything.
test262 failures for Mobile Safari (iOS 6.1.3):
10.4.2_1.1 eval within global execution context
10.4.2_1.2 eval within global execution context
15.5.4.9_3 Tests that String.prototype.localeCompare treats a missing "that" argument, undefined and "undefined" as equivalent
15.5.4.9_CE Tests that String.prototype.localeCompare returns 0 when comparing Strings that are considered canonically equivalent by the Unicode standard.
15.9.3.1_5 multi-argument Date construction
test262 failures for Chrome 28:
11.2.3-3_3 Call arguments are not evaluated before the check is made to see if the object is actually callable (undefined member)
15.5.4.9_6 Checking String.prototype.localeCompare.prototype
15.5.4.9_7 Checking if creating the String.prototype.localeCompare object fails
15.8.2.8_6 Checking if Math.exp is approximately equals to its mathematical values on the set of 64 argument values; all the sample values is calculated with LibC
15.9.3.1_5 multi-argument Date construction
Caveat: these aren't necessarily the corresponding versions, but are just what I have to hand.

What's the difference in GCC between -std=gnu++0x and -std=c++0x and which one should be used?

I'm having troubles with <stdint.h> when using -std=c++0x in GCC 4.4.3 (for Android):
// using -std=c++0x
#include <stdint.h>
uint64_t value; // error: 'uint64_t' does not name a type
But using -std=gnu++0x works:
// using -std=gnu++0x
#include <stdint.h>
uint64_t value; // OK
Is <stdint.h> incompatible with C++0x?
So far as I can tell, I think this could be argued an implementation bug (or actually, since C++0x isn't published, not a bug per se but an incomplete implementation of the current state of the upcoming standard).
Here's why, referring to n3225 for the expected behavior of -std=c++0x:
D.7 says
Every C header, each of which has a
name of the form name.h, behaves as if
each name placed in the standard
library namespace by the corresponding
cname header is placed within the
global namespace scope
OK, so far so easy. What does <cstdint> place in the standard library namespace?
18.4.1:
typedef unsigned integer type uint64_t; // optional
How optional? 18.4.1/2:
The header defines all functions,
types, and macros the same as 7.18 in
the C standard
Drat. What does the C standard say? Taking out n1256, 7.18.1.1/3:
These types are optional. However,
if an implementation provides integer
types with widths of 8, 16, 32, or 64
bits, no padding bits, and (for the
signed types) that have a
two's complement representation, it
shall define the corresponding typedef
names
But hang on, surely on Android with -std=c++0x GCC does provide a 64 bit unsigned type with no padding bits: unsigned long long. So <cstdint> is required to provide std::uint64_t and hence stdint.h is required to provide uint64_t in the global namespace.
Go on, someone tell me why I'm wrong :-) One possibility is that C++0x refers to "ISO/IEC 9899:1999 Programming languages — C" without specifying a version. Can it really be that (a) 7.18.1.1/3 was added in one of the TCs, and also (b) C++0x intends to reference the original standard as of 1999, not the amendments since then? I doubt either of these is the case, but I don't have the original C99 on hand to check (a) and I'm not even sure how to check (b).
Edit: oh, as for which one should be used -std=c++0x isn't really a strict standards-compliant mode yet, since there isn't a strict standard yet. And even if there was a standard, gcc 4.4.3 certainly isn't a finished implementation of it. So I see no great need to use it if -std=gnu++0x is actually more complete, at least in this respect for your combination of gcc version and platform.
However, gnu++0x will enable other GNU extensions, that you might not want your code to use. If you're aiming to write portable C++0x, then eventually you'd want to switch to -std=c++0x. But I don't think GCC 4.4 or any other C++0x implementation-in-progress is complete enough yet for it to be practical to write code from the (draft) standard, such that you could say with a straight face "I'm programming C++0x, and it's only 2011!". So I'd say, use whichever one works, and understand that whichever one you use now, you'll probably be switching to -std=c++11 eventually anyway.

better way to do Debug only assert code

I am writing my first Android application and I am liberally using asserts() from junit.framework.Assert
I would like to find a way to ensure that the asserts are only compiled into the debug build, not in the release build.
I know how to query the android:debuggable attribute from the manifest so I could create a variable and accomplish this in the following fashon:
static final boolean mDebug = ...
if (mDebug)
Assert.assertNotNull(view);
Is there a better way to do this? i.e. I would prefer not to use an if() with each assert.
thanks
I think the Java language's assert keyword is likely what you want. Under the covers, the assert keyword essentially compiles into Dalvik byte code that does two things:
Checks whether the static variable assertionsDisabled (set in the class' static constructor via a call to java.lang.Class.desiredAssertionStatus()) is != 0 and if so, does nothing
If it is 0, then it checks the assertion expression and throws a java.lang.AssertionError if the expression resolves to false, effectively terminating your application.
The Dalvik runtime by default has assertions turned off, and therefore desiredAssertionStatus always returns 1 (or more precisely, some non-zero value). This is akin to running in "retail" mode. In order to turn on "debug" mode, you can run the following command against the emulator or the device:
adb shell setprop debug.assert 1
and this should do the trick (should work on the emulator or any rooted debugging-ready device).
Note however that the aforementioned Dalvik code that checks the value of assertionsDisabled and throws an AssertionError if the expression is false is always included in your byte code and liberal sprinkling of asserts in your code may lead to byte code bloat.
Please see this for a bit more detail: Can I use assert on Android devices?
If you're concerned about shipping code with the JUnit asserts in (or any other class path), you can use the ProGuard config option 'assumenosideeffects', which will strip out a class path on the assumption that removing it does nothing to the code.
Eg.
-assumenosideeffects class junit.framework.Assert {
*;
}
I have a common debug library I put all my testing methods in, and then use this option to strip it from my released apps.
This also removes the hard to spot problem of strings being manipulated that are never used in release code. For example if you write a debug log method, and in that method you check for debug mode before logging the string, you are still constructing the string, allocating memory, calling the method, but then opting to do nothing. Stripping the class out then removes the calls entirely, meaning as long as your string is constructed inside the method call, it goes away as well.
Make sure it is genuinely safe to just strip the lines out however, as it is done with no checking on ProGuard's part. Removing any void returning method will be fine, however if you are taking any return values from whatever you are removing, make sure you aren't using them for actual operational logic.
I mean if you were using a language feature, like assert(), the compiler should be able to strip that out. But this is an actual class and if a class is referenced by executable code it will be included or assumed included in the final product by the compiler.
However there is nothing stopping you from creating a script that removes all the references to the Assert class in all of your code base before compilation.
Another approach would be to make a test project that targets your application and within JUnit tests actually calls the Assert on the areas which you want to make sure work. I personally like this approach because it is a nice and clean separation of test and application.
If you are just worried about the having an if-statement everywhere, then just wrap Assert with your own class, DebuggableAssert which does that check before each call to Assert.X. It will be sort of less performant because of the method entry/exit and the conditionals but if you can maintain your code better then it might be worth it.

Categories

Resources