Eclipse define build variable in pre-build - linux

I created simple shell script file in /tmp/test.sh
#!/bin/sh
echo 'aaaa'
In Eclipse->C/C++ Build->Setting->Build Step -> Pre-build steps->Command , I added TEST =/tmp/test.sh
Than in C/C++ Build->Setting->Tool Settings->Cross GCC Compiler ->Command line pattern , I tried to used this variable like -D ${TEST} so it pass -D aaaa (the output of shell script)
But in build console I didn't see that -D aaaa have been passed to gcc , In fact I didn't see -D at all
why is that? I want to set variable in pre-build that will be the output of shell script and use it with gcc command line pattern
How can I do that ?

Apparently the CDT managed build does not allow running external commands for assigning environment variables, build variables or command line flags, thus executing the script at that stage doesn't work.
Not a direct answer to the question on how to do that with the gcc command line pattern, but if you really only want to pass defines to the preprocessor with results you got from the script, you may use the script instead to update or create a header file that is included somewhere, e.g.:
#!/bin/sh
echo "#ifndef __MYVARHEADER__" > ../include/myvarheader.h
echo "#define __MYVARHEADER__" >> ../include/myvarheader.h
echo "#define aaaa" >> ../include/myvarheader.h
echo "#endif" >> ../include/myvarheader.h
In Eclipse->C/C++ Build->Setting->Build Step -> Pre-build steps->Command, just execute /tmp/test.sh

Related

Cmake add command line argument to binary

I create a binary myBinary via cmake/CMakeLists.txt.
I would like to "include" default options on my binary.
In other words, I want my binary to be called with myBinary --option myopt even when I just run ./myBinary
How can I do that?
CMake does not have built-in support for you you want to do.
One solution is to do as #Youka said - change the source code of your program.
Another solution that I have used sometimes is to autogenerate a script that executes an executable:
# Create startup script
MACRO(GEN_START_SCRIPT binName)
# Generate content
SET(fileContent
"#!/bin/bash\n"
"\n"
"# This startup script is auto generated - do not modify!\n"
"\n"
"${binName} -a 23 -b 34 -c 976\n"
"\n"
)
# Write to file
SET(fileName ${CMAKE_CURRENT_BINARY_DIR}/${binName}.sh)
FILE(WRITE ${fileName} ${fileContent})
ENDMACRO()
Then call the macro after defining your executable:
ADD_EXECUTABLE(myBinary file1.c file.2)
GEN_START_SCRIPT(myBinary)
You can of course add other stuff to the script, like environment variables etc.
If you're in control of the sources and you want different default behavior... change the sources!
This is in no way a build system issue (CMake or otherwise).

Internal Variable PIPESTATUS

I am new to linux and bash scripting and i have query about this internal variable PIPESTATUS which is an array and stores the exit status of individual commands in pipe.
On command line:
$ find /home | /bin/pax -dwx ustar | /bin/gzip -c > myfile.tar.gz
$ echo ${PIPESTATUS[*]}
$ 0 0 0
working fine on command line but when I am putting this code in a bash script it is showing only one exit status. My default SHELL on command line is bash only.
Somebody please help me to understand why this behaviour is changing? And what should I do to get this work in script?
#!/bin/bash
cmdfile=/var/tmp/cmd$$
backfile=/var/tmp/backup$$
find_fun() {
find /home
}
cmd1="find_fun | /bin/pax -dwx ustar"
cmd2="/bin/gzip -c"
eval "$cmd1 | $cmd2 > $backfile.tar.gz " 2>/dev/null
echo -e " find ${PIPESTATUS[0]} \npax ${PIPESTATUS[1]} \ncompress ${PIPESTATUS[2]} > $cmdfile
The problem you are having with your script is that you aren't running the same code as you ran on the command line. You are running different code. Namely the script has the addition of eval. If you were to wrap your command line test in eval you would see that it fails in a similar manner.
The reason the eval version fails (only gives you one value in PIPESTATUS) is because you aren't executing a pipeline anymore. You are executing eval on a string that contains a pipeline. This is similar to executing /bin/bash -c 'some | pipe | line'. The thing actually being run by the current shell is a single command so it has a single exit code.
You have two choices here:
Get rid of eval (which you should do anyway as eval is generally something to avoid) and stop using a string for a command (see Bash FAQ 050 for more on why doing this is a bad idea.
Move the echo "${PIPESTATUS[#]}" into the eval and then capture (and split/parse) the resulting output. (This is clearly a worse solution in just about every way.)
Instead of ${PIPESTATUS[0]} use ${PIPESTATUS[#]}
As with any array in bash PIPESTATUS[0] contains the first command exit status. If you want to get all of them you have to use PIPESTATUS[#] which returns all the contents of the array.
I'm not sure why it worked for you when you tried it in the command line. I tested it and I didn't get the same result as you.

Pass a full bash script line to another bash function to execute

in the BASH code below, the variable ECHO_ALL is a global and set to either 'yes' or 'no' based on input parsing of options.
--- begin of ~/scripts/util/util-optout.sh ---
########################################
# #param $#
# #return the return value from $#
# #brief A wrapper function to allow
# for OPTional OUTput of any
# command w/wo args
#######################################
optout()
{
if [ ${ECHO_ALL} = 'no' ]; then
"$#" 1>/dev/null 2>&1
return $?
else
"$#"
return $?
fi
}
--- end of file ---
in another bash file I source the above util-optout.sh file and use the optout() function to allow for conditional output.. essentially allow for conditional redirection of any commands output to /dev/null to make scripts silent.
for example in some other build script i have
source ~/scripts/util/util-optout.sh
optout pushd ${ZLIB_DIR}
optout rm -vf config.cache
optout CC=${BUILD_TOOL_CC} ./configure ${ZLIB_CONFIGURE_OPT} --prefix=${CURR_DIR}/${INSTALL_DIR}
# ^^^^^^^^^^^^^^^^^^^
# ^ this breaks my optout() command
# my optout() fails when there are prefixed bash env vars set like CC=${...} before ./configure
optout popd
optout make -C ${ZLIB_DIR} ${ZLIB_COMPILER_OPT} all
optout make -C ${ZLIB_DIR} install
for simple commands with any type of parameters after it like 'pushd' or 'rm'.. optout() works great.
even the optout make -C ones work fine.
but it gives me an error for commands that have prefix env-vars set like the optout CC=${...} ./configure ...
utils/util-optout.sh: line 33: CC=gcc: command not found
Is there a way to make my optout() function work for ANY possible valid bash script line.
i know it has something to do with the use of "$#" or "$*" in my optout() function, but i have studied the bash man pages in detail and I can't make it work for all possible bash line cases.
so far the only way to get past this limitation with my optout() is the following 3-line style; which is annoying.
export CC=${BUILD_TOOL_CC}
optout ./configure ${ZLIB_CONFIGURE_OPT} --prefix=${CURR_DIR}/${INSTALL_DIR}
unset CC
Any ideas on how to reduce it all back down to a single optout ... line
optout is a command like any other, and so must be preceded by any local modifications to the environment. The command that optout runs will inherit that environment.
CC=${BUILD_TOOL_CC} optout ./configure ${ZLIB_CONFIGURE_OPT} --prefix=${CURR_DIR}/${INSTALL_DIR}
By the way, this is just one of the problems you are likely to encounter with your optout function. You cannot run arbitrary command lines in that fashion, only a simple command followed by zero or more arguments (and I would expect there are some exceptions to even that restricted set, as well).

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.

Bash config file or command line parameters

If I am writing a bash script, and I choose to use a config file for parameters. Can I still pass in parameters for it via the command line? I guess I'm asking can I do both on the same command?
The watered down code:
#!/bin/bash
source builder.conf
function xmitBuildFile {
for IP in "{SERVER_LIST[#]}"
do
echo $1#$IP
done
}
xmitBuildFile
builder.conf:
SERVER_LIST=( 192.168.2.119 10.20.205.67 )
$bash> ./builder.sh myname
My expected output should be myname#192.168.2.119 and myname#10.20.205.67, but when I do an $ echo $#, I am getting 0, even when I passed in 'myname' on the command line.
Assuming the "config file" is just a piece of shell sourced into the main script (usually containing definitions of some variables), like this:
. /etc/script.conf
of course you can use the positional parameters anywhere (before or after ". /etc/..."):
echo "$#"
test -n "$1" && ...
you can even define them in the script or in the very same config file:
test $# = 0 && set -- a b c
Yes, you can. Furthemore, it depends on your architecture of script. You can overwrite parametrs with values from config and vice versa.
By the way shflags may be pretty useful in writing such script.

Resources