הלינקייה: מגזין חודשי למפתחים

רוצה לשמוע על כל האירועים, המדריכים, הקורסים והמאמרים שנכתבו החודש ?
הלינקייה הינו מגזין חופשי בעברית שמשאיר אותך בעניינים.
בלי ספאם. בלי שטויות. פעם בחודש אצלך בתיבה.

Commands

#
# Using the \ character allows us to break long commands
# into lines. The make will remove any tab character in the 
# beginning of the line following the \ character.
# 
# The output of this block is therefore: 
#
# nospace
# nospace
# one space
# one space
#
 
all :
        @echo no\
space
        @echo no\
        space
        @echo one \
        space
        @echo one\
         space

Using make variables AND shell variables in the same command is a bit confusing, since both use the $ sign. In make, we can escape a $ sign by doubling it, so when we have a $$ in a command, that variable refers to a shell variable. Here's an example:

# Make expands all variables before running a recipe. In this example, we 
# are using the make variable LIST along with a shell variable i. 
# When running this recipe, make first expands LIST to its value. 
# Make ignores the i because it's dollar is escaped using another dollar. 
# Now, make runs the shell on the script, expanding $$i to $i.
#
LIST = one two three
all:
        for i in $(LIST); do \
            echo $$i; \
        done
all:
	@echo "foo"
 
define say-hello
  echo "Hello World"
endef
 
COUNTRIES = il us uk
 
	@echo Im out
 
hi:
	$(say-hello)
########################
# the ifdef, ifeq, ifndef and ifneq
# directives tell make which parts of the makefile
# to use, and which parts to ignore. 
# They can be used inside a command to condition
# its execution. 
# Note they do not have a 'tab' in the begining of the line
 
all:
	@echo "foo"
 
define say-hello
  echo "Hello World"
endef
 
define maybe-say-hello 
  ifeq "x" "y"
    echo "Hello World"
  endif
endef
 
COUNTRIES = il us uk
 
 
hi:
	$(maybe-say-hello)
#########################
# When dealing with really long lists
# We may not be able to print the entire list in
# one command (due to command line lenght limitation).
# So, a way out is using a loop
# 
# Can you find the bug in this implementation ? 
 
.INTERMEDIATE: file_list
 
file_list:
        for d in logic ui
        do
          echo $d/*.java
        done > $@
##########################
# We need to fix two things:
# 1. Using the \ character to escape newline
# 2. Using the ; character in the for
# Now, we have a one-line for loop to print all files
#
# Can you spot the bug this time ? 
 
.INTERMEDIATE: file_list
 
file_list:
        for d in logic ui;   \
        do                  \
          echo $$d/*.java;    \
        done > $@
COMPILATION_DIRS = logic ui
 
# Using a make function, we can achieve the same effect as the
# long for loop - with one difference.
# Command line has a length limit. So, if there are many files, you may
# end up failing to run this one due to command too long limitation
 
# When dealing with long list of files, stick with the loops
 
file_list:
        echo $(addsuffix /*.java,$(COMPILATION_DIRS)) > $@
# When using a command like this, rm may fail if the directory did not
# exist. The better way is to use
# rm -f
 
# In addition, mkdir may fail if trying to create a deep subtree.
# Using
# mkdir -p
# always works
 
all:
        rm tmp
        mkdir tmp
        ls -l > tmp/files
# When make executes a command, it adds three special environment
# variables to the shell environment.
# They are:
#  MAKEFLAGS - which includes command line options passed to make
#  MFLAGS    - mirrors MAKEFLAGS (here for historical reasons)
#  MAKELEVEL - number of nested make invocations
#
# We can also add our own variables using the export directive
 
# Let's see them in action
 
all: builtins custom
 
builtins:
        # Builtin MAKE variables
        echo $$MAKEFLAGS
        echo $$MFLAGS
        echo $$MAKELEVEL
 
USERNAME = Ynon
export PASSWORD = secret password
export USERNAME
 
custom:
        # Some Custom Variables
        echo $$USERNAME
        echo $$PASSWORD
course: