make
utility by making a "Hello, world"
program.
Make the directory for the hello-excercise
mkdir --parents ~/public_html/numeric/hello
and do the exercise in this directory.
(6 points) Hello, world
Create a project with the corresponding makefile with the following targets:
The (default) target "A" the prerequisite of which is a text
file, say out.A.txt (eventually with the text
"hello, your_username"):
A : out.A.txt
The file out.A.txt should be built by redirecting the
output from a program—say hellouser—which prints
"hello, your_username" on the standard output:
out.A.txt : hellouser
./hellouser > out.A.txt
The hellouser program should be built from a
hellouser.c using make's built-in recipe
hellouser : hellouser.c
The hellouser.c file should look like this,
#include<stdio.h>
int main(){
printf("hello, user\n");
return 0;
}
The interpreted languages, like python, would rather run the program via the interpreter,
out.A.txt : hellouser.py
python hellouser.py > out.A.txt
where the hellouser.py file should look like this,
print("hello, user")
Target "cleanA" (without prerequisites) that removes all generated files leaving only the essential files:
cleanA :
rm -f hellouser out.A.txt
Make sure commands make A and make cleanA
work as intended.
Comment an arbitrary line in the makefile explaining its purpose.
Hints:
~/.nanorc file with the content
syntax "makefile" "[Mm]akefile"
color white,magenta " "
(or whatever colors you prefer) where there is the tabulator
sign (obtained by pressing the tabulator-key on the keyboard)
between the quotes in the second line.
N.B.: It seems that the default value of the TERM
environment variable (which specifies the type of the terminal you are
using) is vt100 which is colorless. In order to have colors
you have to change the value of this variable to xterm:
On lifa
place the following line in your ~/.login file (where
~/ is the alias for your home directory)
setenv TERM xterm
On molveno place the following line in your
~/.profile file
export TERM=xterm
Another solution
is to use GNU Make version 3.82+ (which is installed on
molveno as /usr/local/bin/make and on lifa as
/usr/user/fedorov/bin/make) where the recipe prefix is
controlled by the variable .RECIPEPREFIX. You can then set
it to any character, for example ";" with the command
.RECIPEPREFIX := ;
(3 points) Linking several object-files
Here you will learn how to build a program out of several
functions---main, hello, and
world---which should be specified in separate files:
main.c, hello.c, and world.c.
Extend your makefile: now there must be a default target "all" (remember that default target is the first one) which depends on targets "A" and "B",
all: A B
The target B should depend on (that is, have as a prerequisite) another
file, say out.B.txt (eventually with the same string "hello,
user" in it).
B : out.B.txt
The file out.B.txt should be built by redirecting the
output from another program—say main—which also
prints "hello, your_username" on the standard output:
out.B.txt : main
./main > out.B.txt
The program main must be linked (with make's built-in recipe)
from three separate object-code files,
main : main.o hello.o user.o
main.o : main.c
hello.o : hello.c
user.o : user.c
where the last three lines can be omitted.
The files should contain the following functions,
hello.c should implement a function that prints "hello,
" to the stdout:
#include<stdio.h>
void hello(){ printf("hello, "); }
user.c should implement a function that prints
"username\n" to the stdout:
#include<stdio.h>
void user(){ printf("user\n"); }
main.c should implement the main function
which simply calls the two previous functions,
void hello(); void user(); int main(){ hello(); user(); return 0; }
For python, instead of compiling and linking, the main.py
file has to import the corresponding functions from the
hello.py and world.py files.
The cleanB target has to be created similar to
cleanA.
The general clean target should also be created,
clean: cleanA cleanB
(2 points) Check
Create a "checkA" and "checkB" targets that check whether the "A" and "B" targets have been built correctly. For example,
checkA: out.A.txt
@echo "checking target A ..."
@printf "hello, fedorov\n" > correct.txt
@diff --brief correct.txt out.A.txt
@echo "target A seems to be ok ..."
@rm -f correct.txt
(0 points) Backup
Create a "backup" target that builds an archive of the exercise and backs it up somehow, e.g. by mailing the archive to your NFIT mail account (or any other mail address suitable for backing up):
backup: hello.tgz
ssh $(shell whoami)@lifa.phys.au.dk \
'base64 $(shell pwd)/hello.tgz \
| mailx -s "hello backup" $(shell whoami)@phys.au.dk'
hello.tgz: makefile $(shell ls *.cc)
tar --create --gzip --file=hello.tgz makefile *.cc
tar --list --file=hello.tgz
You need to run mailx on lifa because all other servers are
behind the firewall.
The utility base64
performs encoding (and decoding) suitable for sending files as emails.