how to make g++ count errors on compilation - linux

I am use to using VC++ and like the feature when you compile the program it tells you how many warnings and errors there are so at a quick glance you can tell if you made a positive change.
I am now working in Linux so have to use g++ and am getting tired of having a massive stream of errors that I have to scroll through and guess at how many there are.
is there a way I can make g++ count the errors and warnings like VC++ does ?

{ g++ 2>&1 | tee /proc/self/fd/3 | grep Error | wc -l } 3>&1

Related

Standard error file when there is no error

I'm new to Linux & shell and I'm struggling with checking if the compilation is successful.
g++ code.cpp -o code.o 2>error.txt
if [ ! -e error.txt ]
then
do something
else
echo "Failed to compile"
I guess an error file is created even if the compilation is successful. What is the content of the error file when there is no error? I need to change the if condition to check if the compilation is successful.
It's just the order of things. What happens when the shell parses the string g++ code.cpp -o code.o 2>error.txt is:
The shell creates error.txt, truncating the file if that name already exists.
g++ is called with its error output redirected to the new file.
If g++ does not write any data, then the file remains as it was (empty) at the end of step 1.
You probably aren't so much interested in the error file as you are the return value. You probably ought to just do:
if g++ code.cpp -o code; then : do something; done
or even just:
g++ code .cpp -o code && : do something
but if really want to do something else with the errors, you can do:
if g++ code.cpp -o code.o 2> error.txt; then
rm error.txt
: do something
else
echo >&2 Failed to compile code.cpp.\ See "$(pwd)"/error.txt for details.
fi
Make sure you escape at least one of the spaces after the . so that you get 2 spaces after the period (or just quote the whole argument to echo). Although it's become fashionable lately to claim that you only need one space, all of those arguments rely on the use of variable width fonts and any command line tool worth using will be used most often in an environment where fixed width fonts are still dominant. This last point is totally unrelated to your question, but is worth remembering.

How to determine the configuration of gcc from a bash script?

I have a bash script that compiles a program as well on older versions of Ubuntu (14.04.x and 16.04.x) than on the last one (18.04.x) and on other distributions (Arch, CentOS, Debian, Fedora, etc.) and therefore... with different gcc settings.
Then, to obtain an executable that can be launched (among other ways) by a double click, I must compile this program without the "-no-pie" option with older versions of gcc setting (Ubuntu 14.04.x and 16.04.x) when I have to use this option "=no-pie" for the new version of the gcc 7.3 setting (on Ubuntu 18.04.x).
The problem is that on the last Ubuntu release (18.04.x) and its derivatives (Kubuntu, Xbuntu, etc. and maybe with other distributions) with the new configuration of gcc (7.3) having the option "--enable-default-pie", if I compile my program without the option "-no-pie", the result is that the file created is an executable which is of the "shared library" type which can not be launched by a double click.
My question is either:
a) Is there a command that allows me to determine from a bash script if gcc is configured with the "--enable-default-pie" setting?
b) if not, is there a command that allows me to determine from a bash script if the compiled file is of the "shared library" or "executable" type?
For this second option, a solution could be how to save the response of "gcc -v" in a .txt file and check if there is the "--enable-default-pie" string but I've absolutely no clue how to do it.
If I there is not an answer to my first option, the second option (it is true less elegant but just as effective) would allow me to compile my program first without the "-no-pie" option, then check the status of such a created executable and if the result is a "shared library", of restart this compilation this time using the option "-no-pie" for, in one case as in the other, get an executable that can be launched by a double click whatever the setting of gcc may be.
Thank you in advance for your time, ideas and suggestions.
Best regards.
The recommend way to check for PIE support is to compile C code like this
#if defined __PIC__ || defined __pic__ || defined PIC || defined pic
# error PIC is default.
#endif
with the requested compiler flags and check whether there is an error. If you need special treatment for PIE, this will recognize PIE if it has been specified through the CC or CFLAGS variables, even if is not immediately apparent there. For example, for technical reasons, Fedora hides the PIE flags behind a -specs argument.
Yes, you can check GCC build options with gcc -v or gcc -###
In order to have pretty print you can use:
gcc -### -E 2>&1 | grep "Configured with" | sed 's/--/\n--/g'
So bash oneliner to say you have pie or not may be:
if [[ -n "`gcc -v -E 2>&1 | grep 'Configured with' | sed 's/--/\n--/g' | grep enable-default-spie`" ]]; then echo "PIE DEFAULT"; else echo "PIE NOT DEFAULT"; fi
To check file type just use file command, eg.:
file /usr/bin/x86_64-linux-gnu-gcc-7
/usr/bin/x86_64-linux-gnu-gcc-7: ELF 64-bit LSB executable,
x86-64, version 1 (SYSV), dynamically linked, interpreter
/lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0,
BuildID[sha1]=02ac46ba938c15f55f6fab165133e0f527bc2197, stripped
file /usr/lib/libchm.so.1.0.0
/usr/lib/libchm.so.1.0.0: ELF 64-bit LSB shared object, x86-64,
version 1 (SYSV), dynamically linked,
BuildID[sha1]=7c603d9a0771b5bfd5b869b4446e2f78ef13802a, stripped
File type function
function whatfile { file $1 -i | grep application | sed 's/^.*application\/x-//g;s/,.*$//g'; }
Example output:
aaa#xxx:~ $ whatfile /boot/grub/grub.conf
aaa#xxx:~ $ whatfile /usr/lib/libnss3.so
sharedlib
aaa#xxx:~ $ whatfile /bin/zcat
executable
Unfortunately, comments don't allow CR+LF (to show pre-formatted text).
Below is my formatted translation of your gcc setting command:
check_gcc_setting()
{
if [ -n "`gcc -v -E 2>&1 | grep 'Configured with' | sed 's/--/\n--/g' | grep enable-default-pie`" ]
then
GCC_SETTING="1"
else
GCC_SETTING="0"
fi
read -p "The gcc setting is $GCC_SETTING " GCCRESULT
}
Below is the result:
whatfile { file $1 -i | grep application | sed 's/^.*application\/x-//g;s/,.*$//g'; }
-bash: syntax error near unexpected token `}'

byacc %defines syntax error when compiling with make command

I am trying to run Ymer tool in windows 10 platform. I have installed g++, gcc, yacc via cygwin. After configure command, When I am running make command to compile the application, it generates following error.
PS C:\ymer> make
/bin/sh ./ylwrap src/grammar.yy y.tab.c src/grammar.cc y.tab.h echo src/grammar.cc | sed -e s/cc$/hh/ -e s/cpp$/hpp/ -e s/cxx$/hxx/ -e s/c++$/h++/ -e s/c$/h/ y.output src/grammar.output -- byacc -d
byacc: e - line 514 of "/cygdrive/c/ymer/src/grammar.yy", syntax error
%defines
^
Makefile:2467: recipe for target 'src/grammar.cc' failed
make: *** [src/grammar.cc] Error 1
It seems the grammar.yy file causes the problem. Anyone knows how to solve this problem. BTW I am not familiar neither with yacc nor make files. I am just very new to cygwin as well.
Thank you,
The %defines declaration is bison-specific (not part of standard yacc). The file grammar.yy contains some bison features which byacc implements, but this is not one of those. (From the description in the manual page, it seems that this is equivalent to the standard command-line option -d, making it less than useful).

Only show first screenful of compile errors in Rust when building with Cargo?

Is there a way to get rustc to only output the first few errors when compiling with Cargo, or even better, to print the oldest errors last? It seems the default threshold for aborting the compile is set quite high:
error: aborting due to 25 previous errors
I don't have the patience to scroll through 6-10 pages of text to find the first error.
Normally I would handle this by compiling inside my editor (vim), but the vim configuration that ships with rust doesn't seem to be setting errorformat properly.
Piping to a pager is also failing for some reason:
cargo test | less
cargo test writes errors to stderr, so you have to redirect stderr to stdout like this:
cargo test --color always 2>&1 | less -r

make -j$TOTAL_PROCESSORS

what does "make -j$TOTAL_PROCESSORS" means?
Say if I have a two core processor, It will execute "make -j2". What exactly it does?
I am adding a small example below
For compiling my toolchain the script file uses -
pushd toolchaindir
export TARGET=powerpc-linux-gnu
export LINUX_ARCH=powerpc
TOTAL_PROCESSORS=$(grep processor /proc/cpuinfo | wc -l)
make -j$TOTAL_PROCESSORS
if [ "$?" = "0" ]; then
echo "built toolchain successfully"
else
echo "failed during build"
exit 1
fi
popd
exit 0
How it builds toolchain?
make -j2 tells make that it can run two shell commands at once. Make determines whether it can do this from your makefile, so you had better write your makefiles correctly!
Consider this noddy makefile:
1.o: 1.c
gcc -c 1.c -o 1.o
2.o: 2.c
gcc -c 2.c -o 2.o
prog: 1.o 2.o
gcc 1.o 2.o -o prog
If you say make -j2 prog, then make cleverly decides that the production of 1.o is entirely independent of 2.o. Thus it can run the two compiles at the same time without error. So it does. Make waits for both these compiles to finish before combining both object files into prog in the final link step.
Unspeakably clever, so long as you get your makefiles right (if they don't work under -jn then they are bad bad bad!).
In one word: yes
It authorizes make to start $TOTAL_PROCESSORS compilations in parallel.
It expands the environment variable TOTAL_PROCESSORS, presumably to a number which indicates how many CPUs/cores you have, and then runs make with this amount of parallel jobs.
You'll need to look at what sets TOTAL_PROCESSORS to a value.
It reads whatever you shell variable $TOTAL_PROCESSORS is and runs that many jobs. I'm guessing that variable is set to the number of processors or cores on your machine. You can echo it's value in a shell just to be sure.

Resources