How to change the information printed by Shake during a build - shake-build-system

Currently when building Shake outputs lines such as:
# gcc (for debugBuild)
But that is not informative for our application, so we'd like to print something like:
objectFileName.o[configurationFlavour]
How can you do that in Shake?

The easiest thing is to play with the Verbosity field of shakeVerbosity, or with --verbose. At Normal I get:
# ghc (for output/self/General/Intern.o output/self/General/Intern.hi)
And at Verbose I get:
ghc -c src\Development/Shake/Classes.hs -isrc -main-is Run.main -odir=output/self -hidir=output/self -i=output/self -DPORTABLE -fwarn-unused-imports
If that's not enough you can remove the output from cmd with quietly and print your own messages with putNormal:
putNormal "I'm running objectFileName.o in configuration"
quietly $ cmd "gcc -c objectFileName.o"

Related

How to compile and run in one line on linux terminal?

Everytime I compile and run c file, I have to type:
gcc filename.c
a.out
I don't want to do this in two lines, How to compile and run in one line on linux terminal?
Try
gcc filename.c && a.out
It only runs the second command if the first was successful. See https://askubuntu.com/questions/334994/which-one-is-better-using-or-to-execute-multiple-commands-in-one-line
You can separate commands with a ;. So for example:
gcc filename.c; ./a.out
However, you probably only want to run a.out if the compile was successful. For this you can use &&:
gcc filename.c && ./a.out
The Quick and Dirty Solution is Wrong
The quick and dirty solution is a very bad idea in C:
gcc myfile.c && ./a.out
This will not run the executable if the compilation fails, but when compilation succeeds the code will automatically run even if warnings are issued; in C you should always at least inspect warnings before attempting to run code. For the most part you should just never run code that compiles with warnings. Often running code with warnings will mean that code has some undefined behavior; you should not be running such blindly. Of course, with warnings at a minimum as in the above code, there may not be a lot of warnings, when there should be, anyway. At the absolute minimum, one should use:
gcc myfile.c -Wall -Wextra -Werror && ./a.out
Using -Wall -Wextra will issue warnings for a lot of silly mistakes that bring the undefined behavior, and -Werror keeps code compiled with warnings from automatically running.
A Better Solution
To solve this problem, and type less, I used to use this bash script saved as crepl in my search path:
#!/bin/bash
gcc -std=c99 -Wall -Wextra -Wpedantic -Werror $1 -o tempout &&\
./tempout && rm tempout
When I wanted to quickly test some source code saved in, e.g., myfile.c, I could enter at the command-line:
crepl myfile.c
The code will not run if compilation fails, and it will not run if it compiles with warnings thanks to -Werror. If compilation is successful, the program runs, and the temporary executable is removed after running.
Improvements
Since originally writing this answer I have evolved my solution into a slightly fancier bash script that accepts optional further arguments to the compiler, linking libraries, etc.
#!/usr/bin/env bash
# crun
#
# A script to invoke gcc, build the executable, execute the binary,
# and cleanup after. The script will exit without running the executable
# if there are any compiler errors or warnings.
#
# This script uses -std=c18, but it could probably be modified so that
# the version is taken from a command-line parameter, defaulting to c18.
#
# Any commands following the crun invocation are appended to CMD.
CMD="gcc -std=c18 -Wall -Wextra -Wpedantic -Werror"
TEMPFILE="tempfile$$"
for ARG in "$#"
do
CMD+=" $ARG"
done
CMD+=" -o ${TEMPFILE} && ./${TEMPFILE} && rm ${TEMPFILE}"
eval $CMD
Now if I need to link in, e.g., the math library:
crun myfile.c -lm
does the trick, failing if there are any errors or warnings (which are turned up to reasonable levels), and cleaning up after itself.
Explanation:
A ; B – Run A and then B, regardless of the success or failure of A
A && B – Run B only if A succeeded
A || B – Run B only if A failed
You wanted how to compile and run.
I give you how to write, compile and run.
cat << EOF > temp.c && gcc temp.c ; ./a.out ; rm temp.c a.out
#include <stdio.h>
int main(){ printf("%s\n", "Hello World!"); return 0; }
EOF
If you use such a thing fairly regularly you might also be interested in this:
#!/bin/sh
# GCC in the streams
temp="temp.c"
sgcc() {
(
rm "$temp" # just to be sure
# append every line from shell to the temp file
while read -r l; do printf "%s\n" "$l" >>"$temp"; done
cat "$temp"
gcc "$temp"
exitcode=$?
./a.out
rm "$temp" a.out
exit $exitcode
)
}
Which you can call like below:
sgcc << EOF
#include <stdio.h>
int main(){ printf("%s\n", "Hello World!"); return 0; }
EOF

RISCV dissassembly options numeric and no-aliases

I cloned the riscv-tools repository (master branch) and followed the build procedure. Everything went fine.
Then I tried compiling the hello world program for a RV32IM instruction set, doing this:
riscv64-unknown-elf-gcc -m32 -march=RV32IM -o hello hello.c -save-temps
I used options save-temps to keep the intermediate files. (hello.s, hello.i, hello.o)
Everything is OK so far, I can run the hello world program with:
spike pk hello
Hello world!
Now I wanted to take a look at the assembly code for this program. I did the following and I do get the assembly code into hello.dump
riscv64-unknown-elf-objdump -D -S -l -F hello.o > hello.o.dump
Now what I would be interested to see is the assembly code without pseudo instructions and with the non ABI-register names.
It appears to be possible to get that, when I do:
riscv64-unknown-elf-objdump --target-help
I get this:
The following RISC-V-specific disassembler options are supported for use
with the -M switch (multiple options should be separated by commas):
numeric Print numeric reigster names, rather than ABI names.
no-aliases Disassemble only into canonical instructions, rather
than into pseudoinstructions.
However when I try adding these options, it does not work.
riscv64-unknown-elf-objdump -D -S -l -F -Mno-aliases hello.o > hello.o.dump
Unrecognized disassembler option: no-aliases
riscv64-unknown-elf-objdump -D -S -l -F -Mnumeric hello.o > hello.o.dump
Unrecognized disassembler option: numeric
riscv64-unknown-elf-objdump -D -S -l -F -Mnumeric,no-aliases hello.o > hello.o.dump
Unrecognized disassembler option: numeric
Unrecognized disassembler option: no-aliases
Is it a command syntax error or is it just not supported yet by the disassembler?
I can reproduce this and get the same error message. However, riscv64-unknown-elf-objdump returns 0 and the output file does contain an assembler dump without pseudoinstructions and/or with numeric register names, as requested by the option. So it seems like this is working as expected, it just also outputs an irritating error message.
The riscv-tools repo has not been updated since Feb. I also tried this with a build of a more recent version of riscv-gnu-toolchain and here I don't get the error message. So I'd say this is a non-critical bug that already has been fixed in riscv-gnu-toolchain and thus it will be fixed in riscv-tools as soon as riscv-gnu-toolchain is updated there.
You are right, I do get the error message, but when I look at the assembler dump, the numeric register names and the non-pseudo instructions are visible in the file.
Thanks for pointing out that this is just an misleading error message beeing printed...

Details on Makefiles

I am learning about Makefiles and when I first searched the web I did not get any response regarding my question(s).
What are the -o, -f, -c, -g, -Wall, -I, etc. actually called (like +, --, ||, && are called operators), so I can do a correct search on them in the future, and what do they do?
An example I found where this occurs in a Makefile is shown below:
helloworld : helloworld.c
gcc -o helloworld helloworld.c
hellomake: hellomake.c hellofunc.c
gcc -o hellomake hellomake.c hellofunc.c -I.
all: myprog.c
gcc -g -Wall -o myprog myprog.c
(Note: they are parts taken from other Makefiles examples just to show where the "-g", "-Wall", etc. were used
Those flags have nothing to do with make per se. Make is a program that exists to run other programs. Most commonly, but not solely, compilers.
Those flags are flags for your compiler (gcc in this case). So you should be looking at the documentation for your compiler to understand what they do.
Make just runs the commands you give it. You won't find compiler flags in the documentation for make any more than you would in the documentation for your shell, even though you can run the compiler from your shell.
You're conflating two different things. All a makefile does is define a set of commands you can use to shorten a command line call using the program Make. So, in your example, "make helloworld" will call "helloworld.c gcc -o helloworld helloworld.c" on the command line, where "make all" will call "myprog.c gcc -g -Wall -o myprog myprog.c". On the other hand, the program gcc has different command line arguments (such as -o) which tell the program to run a certain way. -Wall, for example, tells it to output all warnings, even trivial ones.
Those are command line flags. The flags you're referring to appear to be flags to gcc (your C compiler).
Much of a Makefile consists of what are essentially shell commands. The "gcc -g -Wall -o myprog myprog.c" is an example of this. You could type the same command in your shell (ie: in a terminal) to do the same thing. What make does is figure out the right time to execute these commands, and it also make it possible to come up with generalized rule (eg: "this is how I always compile .c files into .o files").
"-o", "-f", "-c", "-g", "-Wall", "-I",
Are all options of the Compiler, it's nothing to to with Make. Read the compiler man page.
man gcc

GCC and makefile: Only show errors and warnings

I have a makefile that compiles every .c file in my project. For each file, I get the whole compile command printed out to the shell, with all the options and flags. This is the example output for one file:
arm-none-eabi-gcc -c -mcpu=cortex-m3 -O0 -dM -g -gdwarf-2 -mthumb
-fomit-frame-pointer -fverbose-asm -Wa,-ahlms=src/sim/sim_configuration.lst -include ./lib/stm32core/stm32f2xx_conf.h -I . -I./lib/ARMStandardLibrary
-I./lib/LwIP -I./lib/LwIP/src/include -I./lib/LwIP/src/include -I./lib/LwIP/src/include/ipv4 -I./lib/LwIP/src/include/ipv6 -I./lib/FatFS -I./lib/stm32core -I./src -I./src/sim -I./src/sd -I./src/tftp src/sim/sim_configuration.c -o src/sim/sim_configuration.o
The problem is that various warnings get lost inside this whole mess of command outputs. Is there a way to only print the warnings and errors that appear (not the original command)?
Execute make with the -s option. From the man page.
-s, --silent, --quiet
Silent operation; do not print the commands as they are executed.
Just prepend the command with the # symbol.
If you rely on built-in implicit rules, you will have to make them explicit or, in your specific case, you could use:
.SILENT: *.o
for silencing all commands used for building to the %.o targets.
You could always filter all the output from stdout, which should leave you with all the errors on stderr:
make 1>/dev/null
Use # before a command to hide the it:
rule1:
#gcc someting

Change build output directory when building via terminal

Recently, I found a program that is kind of a mix between an IDE and a text editor. It supports the syntax of the language and it does formatting, but it does not build and run the program for you. I am running Mac OS X 10.6.8. I looked up how to build C code using the Terminal application. The format is:
gcc [file]
Pretty simple. The problem is that I cannot change the directory of where the built file is outputted, nor can I change the name. By default, every file compiled is outputted in the home directory by the name of 'a.out.' How can I specify the output directory and name?
Thanks!
gcc has a -o option to change the output name. You can specify the path there. E.g.:
$ ls
program.c
$ gcc program.c -o program
$ ls
program program.c
$ mkdir bin
$ gcc program.c -o bin/program
$ ls bin
program
$
You should probably also want to know about a few other common options:
-std=c99, -std=gnu99: Use the c99 standard / with gnu extensions.
-Wall, -Wextra, -pedantic: Enable extra warnings.
-O0 -ggdb: Compile with debugging symbols. Look up how to use gdb.
-O2: Compile with processor-independent optimizations. Not compatible with -O0.

Resources