Script for compiling C++ - bash

I want to make a script that would make compiling things quicker to write. I want to compile a XYZ.cpp file and the I want the output to be XYZ.out.
Here's my script:
#!/bin/bash
# getting the part before .cpp
var1=`echo "$1" | cut -d"." -f1`
# compile
g++ -std=c++11 -Wall -pedantic -Wno-long-long "$1" -o "$var1.out" -lm
I run it: ccc program.cpp
The script runs but the output still is a.out. What am I doing wrong?

Just use one of bash's built-in parameter expansion features to remove any trailing portion of $1 that matches ".cpp":
#!/bin/bash
g++ -std=c++11 -Wall -pedantic -Wno-long-long -o "${1%%.cpp}.out" -lm "$1"
I've also moved the source file to be the last parameter to g++, so that it's clear where the options are (and end).

Related

Shell script not running through all files of certain extensions

I wrote a shell script that searches the directory that it is in for files that match any suffixes in the env var SUFFIXES.
#!/bin/bash
SUFFIXES=$(SUFFIXES:-'.c .cpp .cc'}
CC=${CC:-gcc}
CFLAGS=${CFLAGS:-"-Wall -Werror"}
VERBOSE=${VERBOSE:-1}
for i in *$SUFFIXES
do
$CC $CLAGS -o ${i%$SUFFIXES} $i 2> /dev/null
if [ $VERBOSE == 1 ]
then
echo "$CC $CLAGS -o ${i%$SUFFIXES} $i"
fi
done
Say I have a directory with hello.c, hey.c, howdy.cc, and hallo.cpp. Whenever the script is ran without changing the environment variables in the terminal, I get the following output:
gcc -Wall -Werror -o hello.c hello.c
gcc -Wall -Werror -o hey.c hey.c
gcc -Wall -Werror -o .cc .cc
gcc -Wall -Werror -o .cpp .cpp
The output that I am trying to get is:
gcc -Wall -Werror -o hello hello.c
gcc -Wall -Werror -o hey hey.c
gcc -Wall -Werror -o howdy howdy.cc
gcc -Wall -Werror -o hallo hallo.cpp
How would I go about fixing this?
Except for a few typos in your code that probably occurred here, you have some mistake in your loop
i in *$SUFFIXES means that *.c .cpp .cc, so it won't work on file.cpp or file .cc
${i%$SUFFIXES} try to cut all suffixes that you defined, from end of file name, while you have one of them in each file name
maybe an inner loop will helpful
for i in $SUFFIXES
do
for j in *$i
do
$CC $CFLAGS -o ${j%$i} $j 2> /dev/null
if [ $VERBOSE == 1 ]
then
echo "$CC $CFLAGS -o ${j%$i} $j"
fi
done
done

How to hide print information of Makefile?

when Makefile execute some tasks, il will print many information in console, can we choose to hide them? when I have many .o to generate, these information will be too many to see and they are just meaningless if we don't read them.
The following code
$(obj)environment.o: $(src)environment.c
$(CC) $(AFLAGS) -Wa, --no-warn \
-DENV_CRC=$(shell $(obj)../tools/envcrc) \
-c -o $# $(src)environment.c
will print heavy information like
arm-linux-gcc -g -Os -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float
-D__KERNEL__ -DTEXT_BASE=0x01000000
-I/home/mingzhao/Documents/bootloader/u-boot-1.2.0/include
-fno-builtin -ffreestanding -nostdinc -isystem
/home/mingzhao/Documents/bootloader/arm/4.3.2/bin/../lib/
gcc/arm-none-linux-gnueabi/4.3.2/include -pipe -DCONFIG_ARM
-D__ARM__ -march=armv4 -mabi=apcs-gnu -Wall -Wstrict-prototypes
-c -o environment.o environment.c
The "right" way to handle this (IMO) is to add this to your makefile:
$(VERBOSE).SILENT:
Then in your rules where you don't ever want the command printed (for example, an echo statement as in Beta's answer below) you prefix it with #. For all other commands, you don't prefix it with #.
What this does is enable "silent" mode by default (because the variable VERBOSE is not set and so this resolves to the .SILENT pseudo-target).
Then if you want to see everything, you add a VERBOSE=1 (actually you can set it to any non-empty value, so VERBOSE=true if you prefer). When you do that it turns off "silent" mode because the above line expands to 1.SILENT: (or true.SILENT: or whatever) which is meaningless to make.
You can use the option make --silent which will suppress output for all targets. If you want to suppress output for some commands, you can prefix them by #
I like something like this:
$(obj)environment.o: $(src)environment.c
#echo building $#
#$(CC) $(AFLAGS) -Wa, --no-warn \
-DENV_CRC=$(shell $(obj)../tools/envcrc) \
-c -o $# $(src)environment.c
The #echo ... gives a minimal status message, the '#' in front of the $(CC) suppresses standard output (but still allows error messages).
You can use this syntax : #$(CC) $(AFLAGS) -Wa, --no-warn \...

Redirecting input separated with spaces

Hi I've a question about feeding inputs to this simple bash script I wrote. All it does is add a set of flags to my compile operation to save me having to write them in myself every time. I can run it by using echo myprogram.c -o myprogram -llibrary | ./Compile.
But I can't find a way to run it in the way I expected to be able to, ./Compile < myprogram.c -o myprogram -llibrary
I've tried a few combinations of quotes and brackets to no avail, can anyone tell me how to feed the same input as produced by echo using the redirect input command.
#!/bin/bash
# File name Compile
#Shortcut to compile with all the required flags, name defaulting to
#first input ending in .c
echo "Enter inputs: "
read inputs
gcc -Wall -W -pedantic -std=c89 -g -O $inputs
exit 0
Just change your shell to:
#!/bin/bash
gcc -Wall -W -pedantic -std=c89 -g -O "$#"
Then you can only write(no redirection needed):
./Compile myprogram.c -o myprogram -llibrary
BTW, don't explicitly write exit 0 at end of this shell. It is redundant when gcc succeeds, and is wrong when gcc fails(exit code 1 will be overwritten).
You can use process substitution:
./Compile < <( echo myprogram.c -o myprogram -llibrary )
the above line produces the same result as your original command:
echo myprogram.c -o myprogram -llibrary | ./Compile

Have bash echo the final form of executed command, can I?

I have a small bash script build1c.sh .
if [ "$1" = "" ]; then
echo "You must give a .c file to compile."
exit 1
fi
cfile=$1
stem=${cfile%.*}
set -o verbose
gcc -c -g -Wall $cfile
gcc -o $stem $stem.o common.o reentrant.o -lssl -lcrypto
set +o verbose # optional here
The intention is to only echo the gcc commands being executed. I work to some extend. When I call build1c.sh client2.c , I see output
gcc -c -g -Wall $cfile
gcc -o $stem $stem.o common.o reentrant.o -lssl -lcrypto
set +o verbose # optional here
Still wacky, right? Those var reference($cfile, $stem) do not get their final form, so the echoing becomes pretty useless.
You know, what I like to see is
gcc -c -g -Wall client2.c
gcc -o client2 client2.o common.o reentrant.o -lssl -lcrypto
Is there correct and concise way to address this?
BTW: Minor request: Can I suppress the echoing of set +o verbose itself?
Replace set -o verbose with set -x
function echo_and_execute {
echo "$#"
"$#"
}
echo_and_execute gcc -c -g -Wall $cfile
echo_and_execute gcc -o $stem $stem.o common.o reentrant.o -lssl -lcrypto

How can i print the compilation options on making several C files using GCC and make

I want to print my whole file compilation options on make in my console on build.
For example on compiling test1.c test2.c test3.c using make
should print like
cc -g -O1 -Wall test1.c
cc -g -O1 -Wall test2.c
cc -g -O1 -Wall test3.c
make -n will show the commands make would execute without running them. Is that what you mean?
Use make -B -n to see all the build commands without actually building anything.

Resources