7

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?

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953

6 Answers6

7

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
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • An alternative using only bourne shell utilities can be realized with the help of echo, awk and printf: `echo "$( awk 'BEGIN{ printf "%c{libdir}/something" }, 0x24 }' )" > /path/to/my/file` – PeterErnsthaft Apr 20 '17 at 07:40
2

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.

iksajotien
  • 991
  • 18
  • 24
  • 1
    So, there is *no* way to do it with the shell variant? I have rather a lot of other code which is going to be annoying to have to convert into Python. – paxdiablo Jun 10 '16 at 14:18
2

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
}
bluelightning
  • 461
  • 3
  • 5
  • Pretty close. Unfortunately, this appears to cause problems to whatever parser is being used - it *does* put `${prefix}` into the file but it also puts in the redirection and the rest of the function verbatim, or possibly just up to the second (of two) lines needing this trick. Still, it's a good pointer to start with in that the solution probably needs me to put in the `$` in a way it's not recognised (such as an octal code. I'll follow that line for now. – paxdiablo Jun 13 '16 at 02:20
1

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.

Kaz
  • 55,781
  • 9
  • 100
  • 149
0

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

RzR
  • 3,068
  • 29
  • 26
0

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.