How did make decide what to do? Let's go over the previous execution in more detail to find out.
First make notices that the command line contains no targets so it decides to make the default goal, count_words . It checks for prerequisites and sees three: count_words.o , lexer.o , and -lfl . make now considers how to build count_words.o and sees a rule for it. Again, it checks the prerequisites, notices that count_words.c has no rules but that the file exists, so make executes the commands to transform count_words.c into count_words.o by executing the command:
gcc -c count_words.c
This "chaining" of targets to prerequisites to targets to prerequisites is typical of how make analyzes a makefile to decide the commands to be performed.
The next prerequisite make considers is lexer.o . Again the chain of rules leads to lexer.c but this time the file does not exist. make finds the rule for generating lexer.c from lexer.l so it runs the flex program. Now that lexer.c exists it can run the gcc command.
Finally, make examines -lfl . The -l option to gcc indicates a system library that must be linked into the application. The actual library name indicated by "fl" is libfl.a . GNU make includes special support for this syntax. When a prerequisite of the form -l<NAME> is seen, make searches for a file of the form libNAME.so ; if no match is found, it then searches for libNAME.a . Here make finds /usr/lib/libfl.a and proceeds with the final action, linking.