Now its time to go into the useful stuff. This tutorial requires more files in order to understand how it works.
In this first example i demonstrate how to create folders and then compile into it.
This example will use the files from the previous tutorial.
#Another makefile.
CC = gcc
PROGRAM = prog
SRCS = $(wildcard ./*.c)
#simplified version of: $(patsubst %.c,%.o,$(SRCS))
OBJS = $(SRCS:%.c=%.o)
FOLDER = .objs
all: $(PROGRAM)
$(PROGRAM): $(OBJS)
$(CC) $^ -o $@
$(FOLDER)/%.o: %.c | $(FOLDER)
$(CC) $< -c -o $@
$(FOLDER):
mkdir $@
run: all
./$(PROGRAM)
clean:
rm $(OBJS)
One of the main differences is that i added | $(FOLDER) which will add a new dependency. This dependency type will only be revised if the object never was created. This is different from the normal dependency which checks for changes to the objects. The | is useful when adding folders since you probably only want to create the folder once, and not each time some file or folder within was changed.
First we need to create a new makefile containing this:
#Another makefile.
#This is a vector.
VECTOR = a b c d
#this is for testing the if-case
TEST_TRUE = something something
TEST_FALSE =
test1:
@$(foreach OBJ,$(VECTOR),echo "Hello $(OBJ)!";)
test2:
@$(if $(TEST_FALSE),echo "Hello TRUE",echo "HELLO FALSE")
#defines a function that will return error (usually will break the code)
LINE1 := a(){ return 1; }; a;
#define something to demonstrate how the minus (-) sign works at the start.
LINE2 := echo hello world!
test3:
$(LINE1)
$(LINE2)
test4:
-$(LINE1)
$(LINE2)
This example is more tricky. First we declare an array ARRAY <= {a,b,c,d} (array: ARRAY contains the values a, b, c and d).
We can step through each value of array with the foreach function. That is what im doing in this line: @$(foreach OBJ,$(ARRAY),echo "Hello $(OBJ)!";)
In this example i say that OBJ is the variable im using during the loop function. Then im saying that for each value in the array ARRAY lets print each value into echo "Hello $(OBJ)!";, that should finally give the line: echo "Hello a!"; echo "Hello b!"; echo "Hello c!"; echo "Hello d!";.
The @ (at) sign says that we should not print out the result from the line into stdout. So in this case it should only print out:
Hello a!
Hello b!
Hello c!
Hello d!
instead of:
echo "Hello a!"; echo "Hello b!"; echo "Hello c!"; echo "Hello d!";
Hello a!
Hello b!
Hello c!
Hello d!
If you now try to run make test2 then you probably will see HELLO TRUE that is because the first input parameter contained "something", if its only left with blank then it will return the last input parameter. You may try it out by changing $(TEST_TRUE) with TEST_FALSE or just blank ( )
As you can see with test3 & test4, im using a minus "-" sign at the start. The minus might be useful if you want to continue your recipies even if the current line fails (returns some sort of error)