How to pass a QMAKE variable from the command line? - linux

I am to trying cross-compile pile Qt from a Linux terminal. When I run qmake it applies the mkspecs qmake.conf in my context in such manner that the CROSS_COMPILE variable must be defined. For example, there is a critical conf line that looks like this:
QMAKE_CXX = $${CROSS_COMPILE}g++
Qmake returns an error though which clearly indicates $${CROSS_COMPILE} is not being resolved. It is simply using "g++" instead of the whole value which ought to be there.
I've tried to invoke qmake and define the variable from a bash script like this:
qmake qt.pro "CROSS_COMPILE=${CROSS_COMPILE}"
And like this :
qmake qt.pro -- "CROSS_COMPILE=${CROSS_COMPILE}"
And a few other such stabs at it. I've also tried hard coding the value in that command in case that had anything to do with it. I've tried defining this as an environmental variable too (just in case)...
Nothing works. Yet, I've seen piles of examples where this syntax seems to be valid. What am doing wrong? Could there be a character escape complication?

Your problem is that the shell already interpreted the ${} inside your string as a form of variable substitution.
Since you did not define the variable CROSS_COMPILE in the shell, it had no value and what qmake got were actually the 2 arguments between quotes "qt.pro" and "CROSS_COMPILE=", meaning that you have actually made qmake set CROSS_COMPILE to an empty value.
What you should try is:
qmake qt.pro "CROSS_COMPILE=\${CROSS_COMPILE}"
Note the backslash before the dollar sign, which escapes it to prevent it from having a special meaning to the shell and enables it to get passed on literally to qmake.
This question has also been already asked on Stackoverflow:
Define a string in qmake command line
More on the variable substitution of Bash:
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
EDIT:
Example:
I just tried myself with a fresh project file with the following contents:
SOME_OTHER_VAR=$${SOME_VAR}_something
message($${SOME_OTHER_VAR})
and doing
SOME_VAR=value
qmake qmake_variables.pro "SOME_VAR=${SOME_VAR}"
does work for me, printing:
Project MESSAGE: value_something

This is not the best answer, but I "solved" the problem by adding this to my qmake.conf:
CROSS_COMPILE=$$(CROSS_COMPILE)
That defined the variable in qmake by getting it from an environmental variable I set in my calling bash script.

Related

Link with -rpath=/usr/local/lib works, -rapth=$ORIGIN does not

I am working on an embedded Linux target, gcc 9.2. If I link with -rpath=/usr/local/lib, the readelf utility shows me the RPATH entry, as expected. If I link with -rpath=$ORIGIN, readelf shows no RAPTH, and nothing involving ORIGIN. The link command appears to be correct: x86_64-poky-linux-g++ ... -Xlinker -rpath=$ORIGIN .... Any ideas?
Simply typing $ORIGN was causing your shell to expand the variable before the value was passed to the linker. Since you likely had no ORIGIN environment variable, you were getting nothing.
You need to prevent shell expansion so that $ORIGIN literally is passed to the linker - to do that, one uses single quotes. Double quotes won't work because variables are interpolated in double quotes.

Linux unexpected things with shell and cmake etc

I am facing a strange issue with cd command and cmake.
cd command is not working with the paths which contain '-' minus sign in it. (unless used by tab expansion which is not desireable as path will be provided by ENV variable)
cmake issue
export $SOME_VAR=Some_value_for_this_variable
Now using this in cmake as
set (SOME_OTHER_VAR "$ENV{SOME_VAR}/SUFFIX")
above should give the output as SOME_OTHER_VAR=Some_value_for_this_variable/SUFFIX but instead it is replacing the env variable from starting and giving the output as SOME_OTHER_VAR=SUFFIXalue_for_this_variable means Some_v is replaced from starting with SUFFIX which is not expected.
Please help as i am not getting whats happening.
You're having some sort of character set issue. There are two different minus signs. The hyphen - (ASCII 45, U+002D), and the real minus sign − (U+2212). It's possible that the filename itself got the non-ASCII minus sign, which you can't easily type with your keyboard. The easiest fix would be to rename the file to the normal hyphen. Otherwise, you have to convince CMake to understand your Unicode filename. I have no idea if that's easy or hard.
I think your second problem is similar. The environment variable likely one or more non-printing characters in it, messing up the CMake variables, or at least the display. Try this: from the Linux command prompt, inspect the actual contents of the string.
echo $SOME_VAR | od -t c
For ASCII representation of everything, and/or
echo $SOME_VAR | od -t d1
for the byte contents

Read environment variable in make file

I have a environment variable set with name $MY_ENV_VARIABLE.
How do I use this variable inside my makefile to (for example) include some source files?
LOCAL_SRC_FILES = $(MY_ENV_VARIABLE)/libDEMO.so
Something like above doesn't seem to work.
Note: in my case this is needed for building with the Android NDK but I guess this applies to make in general.
Just to add some information...
The syntax to access the environment variable in make is like other variables in make...
#export the variable. e.g. in the terminal,
export MY_ENV_VARIABLE="hello world"
...
#in the makefile (replace before call)
echo $(MY_ENV_VARIABLE)
This performs the substitution before executing the commmand. If you instead, want the substitution to happen during the command execution, you need to escape the $ (For example, echo $MY_ENV_VARIABLE is incorrect and will attempt to substitute the variable M in make, and append it to Y_ENV_VARIABLE)...
#in the makefile (replace during call)
echo $$MY_ENV_VARIABLE
Make sure you exported the variable from your shell. Running:
echo $MY_ENV_VARIABLE
shows you whether it's set in your shell. But to know whether you've exported it so that subshells and other sub-commands (like make) can see it try running:
env | grep MY_ENV_VARIABLE
If it's not there, be sure to run export MY_ENV_VARIABLE before running make.
That's all you need to do: make automatically imports all environment variables as make variables when it starts up.
I just had a similar issue (under Cygwin):
Running echo $OSTYPE on the shell prints the value, but
running env | grep OSTYPE doesn't give any output.
As I can't guarantee that this variable is exported on all machines I want to run that makefile on, I used the following to get the variable from within the makefile:
OSTYPE = $(shell echo $$OSTYPE)
Which of course can also be used within a condition like the following:
ifeq ($(shell echo $$OSTYPE),cygwin)
# ...do something...
else
# ...do something else...
endif
EDIT:
Some things I found after experimenting with the info from jozxyqk's answer, all from within the makefile:
If I run #echo $$OSTYPE or #echo "$$OSTYPE" in a recipe, the variable is successfully expanded into cygwin.
However, using that in a condition like ifeq ($$OSTYPE,cygwin) or ifeq ("$$OSTYPE","cygwin") doesn't expand it.
Thus it is logical that first setting a variable like TEST = "$$OSTYPE" will lead to echo $(TEST) printing cygwin (the expansion is done by the echo call) but that doesn't work in a condition - ifeq ($(TEST),cygwin) is false.

What's wrong with this shell script syntax?

I'm trying to run the Apache startup script, /etc/init.d/httpd. Environment variable definitions like this one give an error:
CONF_FILE=$(APACHE_HOME)/conf/httpd.conf
It says "/etc/init.d/httpd: line 15: APACHE_HOME: command not found"
So, I replaced the parentheses with curly brackets, and the script worked swimmingly. What gives? I'm really just asking this question because I want to understand why it's wrong, not how to fix it. The shebang is there, and it's unmodified from the original shell script, so why's it misinterpreting things?
In unix systems:
$SOMETHING /* variable */
$(SOMETHINGELSE) /* command */
${FOO} */ variable substitution */
$(...) executes its contents in a subshell, it doesn't get the value of a variable. You can use just plain $APACHE_HOME or ${APACHE_HOME}, which it sounds like you switched to.
$(something) tells the shell to execute command something and substitute the command's output.1
You want to substitute a variable's output, so you just need a $ in front of the variable, like so: CONF_FILE=$APACHE_HOME/conf/httpd.conf
Alternatively, you could use CONF_FILE=${APACHE_HOME}/conf/httpd.conf (note the curly braces instead of parenthesis), but it's not really necessary for your situation.
1This is useful when you want to assign a command's output to a variable. For example:
MY_VAR="$(egrep 'someline' somefile.txt)"

Shell script takes variable as a command

I'm coding an extremely simple shell script and it doesn't really work as it should. Here are the contents:
# Defining base project directory
BASE_DIR=/path/to/proj;
PRODUCTION_DIR = $BASE_DIR/out/production/dir;
# Generating headers
javah -classpath $PRODUCTION_DIR -d $BASE_DIR/jni/include com.my.class.Name
# Building native libs
ndk-build
Paths are correct, it works if I remove $PRODUCTION_DIR, if I'll run it like this, it says:
line 3: PRODUCTION_DIR: command not found
...
Does any one know what's wrong?
Remove whitespace,
PRODUCTION_DIR=$BASE_DIR/out/production/dir
Otherwise you're trying to run PRODUCTION_DIR with parameters = and $BASE_DIR/out/production/dir
Also, remove the ;'s at end of line, they're redundant

Resources