|    Variables are fine for storing values as a single line of text, but what if we have a multiline value such as a command script we would like to execute in several places? For instance, the following sequence of commands might be used to create a Java archive (or  jar  ) from Java class files:    echo Creating $@... $(RM) $(TMP_JAR_DIR) $(MKDIR) $(TMP_JAR_DIR) $(CP) -r $^ $(TMP_JAR_DIR) cd $(TMP_JAR_DIR) && $(JAR) $(JARFLAGS) $@ . $(JAR) -ufm $@ $(MANIFEST) $(RM) $(TMP_JAR_DIR)      At the beginning of long sequences such as this, I like to print a brief message. It can make reading  make  's output much easier. After the message, we collect our class files into a clean temporary directory. So we delete the temporary  jar  directory in case an old one is left lying about,  [2]  then we create a fresh temporary directory. Next we copy our prerequisite files (and all their subdirectories) into the temporary directory. Then we switch to our temporary directory and create the jar with the target filename. We add the manifest file to the jar and finally clean up. Clearly, we do not want to duplicate this sequence of commands in our  makefile  since that would be a maintenance problem in the future. We might consider packing all these commands into a recursive variable, but that is ugly to maintain and difficult to read when  make  echoes the command line (the whole sequence is echoed as one enormous line of text).      [2]  For best effect here, the  RM  variable should be defined to hold  rm -rf  . In fact, its default value is  rm -f  , safer but not quite as useful. Further,  MKDIR  should be defined as  mkdir -p  , and so on.      Instead, we can use a GNU  make  "canned sequence" as created by the  define  directive. The term "canned sequence" is a bit awkward , so we'll call this a  macro  . A macro is just another way of defining a variable in  make  , and one that can contain embedded newlines! The GNU  make  manual seems to use the words  variable  and  macro  interchangeably. In this book, we'll use the word  macro  specifically to mean variables defined using the  define  directive and  variable  only when assignment is used.    define create-jar  @echo Creating $@...  $(RM) $(TMP_JAR_DIR)  $(MKDIR) $(TMP_JAR_DIR)  $(CP) -r $^ $(TMP_JAR_DIR)  cd $(TMP_JAR_DIR) && $(JAR) $(JARFLAGS) $@ .  $(JAR) -ufm $@ $(MANIFEST)  $(RM) $(TMP_JAR_DIR) endef      The  define  directive is followed by the variable name and a newline. The body of the variable includes all the text up to the  endef  keyword, which must appear on a line by itself. A variable created with  define  is expanded pretty much like any other variable, except that when it is used in the context of a command script, each line of the macro has a tab prepended to the line. An example use is:    $(UI_JAR): $(UI_CLASSES)         $(create-jar)      Notice we've added an  @  character in front of our  echo  command. Command lines prefixed with an  @  character are not echoed by  make  when the command is executed. When we run  make  , therefore, it doesn't print the  echo  command, just the output of that command. If the  @  prefix is used within a macro, the prefix character applies to the individual lines on which it is used. However, if the prefix character is used on the macro reference, the entire macro body is hidden:    $(UI_JAR): $(UI_CLASSES)         @$(create-jar)      This displays only:    $  make  Creating ui.jar...      The use of  @  is covered in more detail in the Section 5.1.2 in Chapter 5.    |