How to exclude certain char from being used as a variable name in production build? - rollup

After build, one of my variables is getting renamed to $ char. I use built code in Jquery project and this variable called $ causes errors. How can I exclude $ sign from being used as variable in the production files?
This is how the production code looke like even though I use nowhere $ sign:
function $(e,t){e.value=t==null?"":t}
How can exclude $ sign from being used as variable or function name?

Related

Cmake fails on username with '#'

I am working with a CMake (version 2.8.12) script (CMakeLists.txt) that worked on a previous computer (and probably still does). The problem seems to be that my username on my newer computer now contains a #. The CMake script now fails with this report:
"add_custom_command called with OUTPUT containing a '#'. This character is not allowed."
The parameter ${CMAKE_CURRENT_BINARY_DIR} contained in this line:
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/DBSTYPEDEFS.F77 COMMAND ${MKDBSTYPEDEFS_EXE} DEPENDS {MKDBSTYPEDEFS_EXE})
expands out to include my user-name as part of the full pathname.
Q: Is there a way to solve this problem?
If you cannot simply change your username on the machine, try moving the repository to another location on the machine.
If you current have the repository repo1 in your home directory, you'll get an expansion to something like this:
add_custom_command(OUTPUT /home/don#robinson/repo1/generated_files/DBSTYPEDEFS.F77 COMMAND ${MKDBSTYPEDEFS_EXE} DEPENDS {MKDBSTYPEDEFS_EXE})
which was causing your error. Moving the code to somewhere else, say /usr/local/repo1, the expansion in add_custom_command now looks like this:
add_custom_command(OUTPUT /usr/local/repo1/generated_files/DBSTYPEDEFS.F77 COMMAND ${MKDBSTYPEDEFS_EXE} DEPENDS {MKDBSTYPEDEFS_EXE})
which should remove the error.
Your script likely will fail when ran on any directory whose full path contains the hash symbol. Similarly, for the less-than and greater-than sign.
Since your username contains the hash symbol, you either have to change your username or to move the directory to a location whose path does not contain the hash symbol. See https://cmake.org/cmake/help/latest/policy/CMP0053.html for other disallowed characters. This is CMP0053.
If you want to keep your hashtagged username, the process will be more complicated, but it is something in the lines of
set(varname "otherwise & disallowed $ characters")
message("${${varname}}")

How do I escape a "$" in bitbake/yocto?

One of my recipes in Yocto need to create a file containing a very specific line, something like:
${libdir}/something
To do this, I have the recipe task:
do_install() {
echo '${libdir}/something' >/path/to/my/file
}
Keeping in mind that I want that string exactly as shown, I can't figure out how to escape it to prevent bitbake from substituting in its own value of libdir.
I originally thought the echo command with single quotes would do the trick (as it does in the bash shell) but bitbake must be interpreting the line before passing it to the shell. I've also tried escaping it both with $$ and \$ to no avail.
I can find nothing in the bitbake doco about preventing variable expansion, just stuff to do with immediate, deferred and Python expansions.
What do I need to do to get that string into the file as is?
Bitbake seems to have particular issues in preventing expansion from taking place. Regardless of whether you use single or double quotes, it appears that the variables will be expanded before being passed to the shell.
Hence, if you want them to not be expanded, you need to effectively hide them from BitBake, and this can be done with something like:
echo -e '\x24{libdir}/something' >/path/to/my/file
This uses the hexadecimal version of $ so that BitBake does not recognise it as a variable to be expanded.
You do need to ensure you're running the correct echo command however. Under some distros (like Ubuntu), it might run the sh-internal echo which does not recognise the -e option. In order to get around that, you may have to run the variant of echo that lives on the file system (and that does recognise that option):
/bin/echo -e '\x24{libdir}/something' >/path/to/my/file
By default this task will be executed as shell function via /bin/sh, but it depends on your system what it will be as you can have a symlink named /bin/sh pointing to bash. The BitBake's manual prevents from using bashism syntax though.
You can consider just adding this task in your recipe as python function:
python do_install () {
with open('/path/to/your/file', 'a') as file:
file.write('${libdir}/something')
}
'a' stands for append.
This should eliminate the problem with variable expansion.
There is no standard way to escape these sorts of expressions that I am aware of, other than to try to break up the expression - accordingly this should work:
do_install() {
echo '$''{libdir}/something' >/path/to/my/file
}
The best solution is simply this:
bitbake_function() {
command $libdir/whatever
}
Bitbake will only expand ${libdir}; $libdir is passed through verbatim.
We don't have to worry about dollar signs that are not followed by {, and in this case, there is no need for libdir to be wrapped in braces.
The only time we run into a problem with just $foo is if we have something like ${foo}bar where the braces are required as delimiters so that bar isn't included into the variable name. In that situation, there are other solutions, such as for instance generating the shell syntax "$foo"bar. This is less cryptic than resorting to \x24.
If you need to use $ in variable assignment, remember that bitbake won't evaluate $whatever so you have to escape it for the underlying shell.
For instance I set gcc/ld Rpath option to use $ORIGIN keyword this way:
TARGET_LDFLAGS_append = " -Wl,-rpath-link=\\$$ORIGIN"
https://lists.yoctoproject.org/pipermail/yocto/2017-September/037820.html
You can define a variable to be a literal dollar sign.
DOLLAR = "$"
do_install() {
echo '${DOLLAR}{libdir}/something' >/path/to/my/file
}
no extra quoting required.

preserve whitespace in preprocessor macro value taken from environment variable

In an Objective-C project I am attempting to take a file path from an environment variable and set it as a location to write generated files. This is used to run test code using xcodebuild in an automated testing environment where the file path is not determined until xcodebuild is called.
In attempt to do this I am entering a preprocessor macro in the Build Settings that references the variable:
BUILDSERVER_WORKSPACE=\#\"$(WORKSPACE)\"
and then setting the value of a string using that macro
NSString *workspaceLocation = BUILDSERVER_WORKSPACE;
in cases where the (string value of) the path for $WORKSPACE does not contain spaces it works fine but in cases where the path has spaces, the macro preprocessor sees the whitespaces as a macro separator and attempts to process them as separate macro definitions.
for example:
$WORKSPACE=/foo/bar/thudblat
will set the value of workspacelocation as #"/foo/bar/thudblat"
but
$WORKSPACE="/foo/bar/thud blat"
ends up creating multiple preprocessor definitions:
#define BUILDSERVER_WORKSPACE #"/foo/bar/thud
#define blat"
I have attempted to stringify the path, but since the presence or absence of whitespace only happens when i call xcodebuild to build and then run and so I cannot get that to work.
In the end, what I want is to simply take the path at $WORKSPACE and set its value to the NSString *workspaceLocation
so that workspaceLocation could potentially be "\foo\bar\thud blat"
I thought I had tried every scheme of quoting and escaping but, the one thing I had not tried was quoting the entire thing as suggested by #nielsbot
BUILDSERVER_WORKSPACE="\#\"$(WORKSPACE)\""
with an unescaped quote at the beginning and end of the entire value statement. Thad did the trick and gave me the string: #"/foo/bar/thud blat" when calling xcodebuild.
You can achieve that with double stringize trick:
#define STRINGIZE_NX(A) #A
#define STRINGIZE(A) STRINGIZE_NX(A)
static NSString *kWorkspace = #( STRINGIZE(BUILDSERVER_WORKSPACE) );
The way it works is very well explained in here: https://stackoverflow.com/a/2751891/351305
If you wish to really read the environment variable at runtime then you can simply obtain it from NSProcessInfo:
NSString *workspaceLocation = NSProcessInfo.processInfo.environment[#"WORKSPACE"];
That will give you the current value of the environment variables, spaces and all.
HTH

An alias that just prints the named directory?

I'm kind of just realizing how powerful the terminal can be. My question is essentially if I can create an alias that just prints the name of a directory. For example, I could easily make an alias such as "alias sitename="cd ~/sites/path/to/my/site/". But what I want is an alias that only prints the directory name so that I can use it for several things. So that, for example, if I wanted I could just say cd "alias", or mv from-dir "alias".
Is there a way to do this? I've tried and it seems to recognize the alias if I just type it in: it will report "alias" is a directory. But if I try to couple it with another command, it fails.
You don't want to use alias, what you are after is an environment variable
$ export SITENAME="~/sites/path/to/my/site/"
$ cd $SITENAME
Bash is quite picky over syntax - note the lack of spaces in the export and the $ when you use it.
Use a variable, simply
d=/path/to/some/directory
echo $d
cd $d
mv somedir $d/
You don't need to use an alias here, a variable is sufficient.
It sounds like you want to set a variable, not an alias. Such as,
sitename=/home/jimbo/. Then, cd $sitename would put you at /home/jimbo/.
If you want this variable to have permanence (i.e. you don't have to set it every time you open a new session), then you can make it an environmental variable using the export command or add it to your .bashrc file (typically located at $HOME/.bashrc) using the line: sitename=/home/jimbo/.
FYI, $HOME is another environmental variable that's equivalent to ~/.
Using a variable is the simplest solution. You could get fancy and use an array:
mydir() { echo "/my/directory"; }
To display the value
mydir
To use the value, you need some extra puncuation
cd $(mydir)
cd `mydir`

make targets depend on variables

I want (GNU) make to rebuild when variables change. How can I achieve this?
For example,
$ make project
[...]
$ make project
make: `project' is up to date.
...like it should, but then I'd prefer
$ make project IMPORTANTVARIABLE=foobar
make: `project' is up to date.
to rebuild some or all of project.
Make wasn't designed to refer to variable content but Reinier's approach shows us the workaround. Unfortunately, using variable value as a file name is both insecure and error-prone. Hopefully, Unix tools can help us to properly encode the value. So
IMPORTANTVARIABLE = a trouble
# GUARD is a function which calculates md5 sum for its
# argument variable name. Note, that both cut and md5sum are
# members of coreutils package so they should be available on
# nearly all systems.
GUARD = $(1)_GUARD_$(shell echo $($(1)) | md5sum | cut -d ' ' -f 1)
foo: bar $(call GUARD,IMPORTANTVARIABLE)
#echo "Rebuilding foo with $(IMPORTANTVARIABLE)"
#touch $#
$(call GUARD,IMPORTANTVARIABLE):
rm -rf IMPORTANTVARIABLE*
touch $#
Here you virtually depend your target on a special file named $(NAME)_GUARD_$(VALUEMD5) which is safe to refer to and has (almost) 1-to-1 correspondence with variable's value. Note that call and shell are GNU Make extensions.
You could use empty files to record the last value of your variable by using something like this:
someTarget: IMPORTANTVARIABLE.$(IMPORTANTVARIABLE)
#echo Remaking $# because IMPORTANTVARIABLE has changed
touch $#
IMPORTANTVARIABLE.$(IMPORTANTVARIABLE):
#rm -f IMPORTANTVARIABLE.*
touch $#
After your make run, there will be an empty file in your directory whose name starts with IMPORTANTVARIABLE. and has the value of your variable appended. This basically contains the information about what the last value of the variable IMPORTANTVARIABLE was.
You can add more variables with this approach and make it more sophisticated using pattern rules -- but this example gives you the gist of it.
You probably want to use ifdef or ifeq depending on what the final goal is. See the manual here for examples.
I might be late with an answer, but here is another way of doing such a dependency with Make conditional syntax (works on GNU Make 4.1, GNU bash, Bash on Ubuntu on Windows version 4.3.48(1)-release (x86_64-pc-linux-gnu)):
1 ifneq ($(shell cat config.sig 2>/dev/null),prefix $(CONFIG))
2 .PHONY: config.sig
3 config.sig:
4 #(echo 'prefix $(CONFIG)' >config.sig &)
5 endif
In the above sample we track the $(CONFIG) variable, writing it's value down to a signature file, by means of the self-titled target which is generated under condition when the signature file's record value is different with that of $(CONFIG) variable. Please, note the prefix on lines 1 and 4: it is needed to distinct the case, when signature file doesn't exist yet.
Of course, consumer targets specify config.sig as a prerequisite.