View
220
Download
0
Category
Preview:
Citation preview
8/20/2019 Dum Ka Biryani Make for Each Other
1/63
Dum Ka Biryani,
Make for each other
Version 1.0
February 2011
GNU Free Documentation License
Shakthi Kannan
shakthimaan@gmail.com
http://www.shakthimaan.com
() Dum Ka Biryani, Make for each other 1 / 1
http://find/http://goback/
8/20/2019 Dum Ka Biryani Make for Each Other
2/63
Dum Ka Biryani
() Dum Ka Biryani, Make for each other 2 / 1
http://find/http://goback/
8/20/2019 Dum Ka Biryani Make for Each Other
3/63
2.1 What a Rule Looks Like
Makefile
target : prerequisites ...
recipe
...
...
Tab before recipe!
() Dum Ka Biryani, Make for each other 3 / 1
http://find/http://goback/
8/20/2019 Dum Ka Biryani Make for Each Other
4/63
2.2 A Simple Makefile
Makefile
biryani : masala.o rice.o onion.o curd.o coriander.o meat.occ -o biryani masala.o rice.o onion.o curd.o coriander.o meat.o
masala.o : masala.c masala.h defs.hcc -c masala.c
rice.o : rice.c rice.h defs.hcc -c rice.c
onion.o : onion.c defs.hcc -c onion.c
curd.o : curd.c defs.hcc -c curd.c
coriander.o : coriander.c defs.hcc -c coriander.c
meat.o : meat.c defs.hcc -c meat.c
clean:rm biryani \
masala.o rice.o onion.o curd.o coriander.o meat.o
() Dum Ka Biryani, Make for each other 4 / 1
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
5/63
2.4 Variables Make Makefiles Simpler
Makefile
objects = masala.o rice.o onion.o curd.o coriander.o meat.o
biryani : $(objects)cc -o biryani $(objects)
masala.o : masala.c masala.h defs.hcc -c masala.c
rice.o : rice.c rice.h defs.h
cc -c rice.c
onion.o : onion.c defs.hcc -c onion.c
curd.o : curd.c defs.hcc -c curd.c
coriander.o : coriander.c defs.hcc -c coriander.c
meat.o : meat.c defs.hcc -c meat.c
clean:rm biryani $(objects)
() Dum Ka Biryani, Make for each other 5 / 1
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
6/63
2.5 Letting make Deduce the Recipes
Makefileobjects = masala.o rice.o onion.o curd.o coriander.o meat.o
biryani : $(objects)cc -o biryani $(objects)
masala.o : masala.h defs.h
rice.o : rice.h defs.h
onion.o : defs.h
curd.o : defs.h
coriander.o : defs.h
meat.o : defs.h
clean:rm biryani $(objects)
() Dum Ka Biryani, Make for each other 6 / 1
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
7/63
2.6 Another Style of Makefile
Makefileobjects = masala.o rice.o onion.o curd.o coriander.o meat.o
biryani : $(objects)
cc -o biryani $(objects)
$(objects) : defs.h
masala.o : masala.h
rice.o : rice.h
clean:
rm biryani $(objects)
() Dum Ka Biryani, Make for each other 7 / 1
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
8/63
2.7 Rules for Cleaning the Directory
Makefile
objects = masala.o rice.o onion.o curd.o coriander.o meat.o
biryani : $(objects)
cc -o biryani $(objects)
$(objects) : defs.h
masala.o : masala.h
rice.o : rice.h
.PHONY : clean
clean:
-rm biryani $(objects)
() Dum Ka Biryani, Make for each other 8 / 1
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
9/63
3.1 What Makefiles Contain
* Explicit ruleonion.o : onion.c defs.h
cc -c onion.c
* Implicit rulemasala.o : masala.h
* Variable definitionobjects = masala.o rice.o onion.o curd.o coriander.o meat.o
* Directiveifeq ($(CC), gcc)
libs=$(libs for gcc)else
libs=$(normal libs)
endif
* Comments# This is a comment
() Dum Ka Biryani, Make for each other 9 / 1
http://goforward/http://find/http://goback/
8/20/2019 Dum Ka Biryani Make for Each Other
10/63
3.2 What Name to Give Your Makefile
Default
* GNUMakefile
* makefile
* Makefile
() Dum Ka Biryani, Make for each other 10 / 1
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
11/63
3.2 What Name to Give Your Makefile
Default
* GNUMakefile
* makefile
* Makefile
$ make
$ make -f myMakefile
$ make --file=myMakefile
() Dum Ka Biryani, Make for each other 10 / 1
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
12/63
3.3 Including Other Makefiles
* Syntaxinclude filenames...
* Regex and variables allowedinclude foo *.mk $(bar)
* To ignore Makefile if not found-include filenames...
() Dum Ka Biryani, Make for each other 11 / 1
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
13/63
3.3 Including Other Makefiles
* Syntaxinclude filenames...
* Regex and variables allowedinclude foo *.mk $(bar)
* To ignore Makefile if not found-include filenames...
$ make
$ make -I
$ make --include-dir
() Dum Ka Biryani, Make for each other 11 / 1
O
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
14/63
3.6 Overriding Part of Another Makefile
GNUmakefile
meat:cc -c vegetables.c
%: force@$(MAKE) -f Makefile $@
force: ;
() Dum Ka Biryani, Make for each other 12 / 1
3 6 O idi P f A h M k fil
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
15/63
3.6 Overriding Part of Another Makefile
GNUmakefile
meat:cc -c vegetables.c
%: force@$(MAKE) -f Makefile $@
force: ;
$ make
$ make meat
() Dum Ka Biryani, Make for each other 12 / 1
3 7 H k R d M k fil
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
16/63
3.7 How make Reads a Makefile
First phase* Reads all makefiles
* Reads included makefiles
* Internalize variables, values, implicit and explicit rules
* Constructs dependency graph of targets and pre-requisites* immediate : expansion in phase one
Second phase
* Determines which targets need to be re-built
* Invokes the necessary rules* deferred : expansion in phase two
() Dum Ka Biryani, Make for each other 13 / 1
3 7 H k R d M k fil
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
17/63
3.7 How make Reads a Makefile
Variable assignment
* immediate = deferred
* immediate ?= deferred
* immediate := immediate
* immediate += deferred or immediate
immediate, if variable was previously set as a simple variable (:=)deferred, otherwise
Second phase
* Determines which targets need to be re-built
* Invokes the necessary rules
* deferred : expansion in phase two
() Dum Ka Biryani, Make for each other 14 / 1
3 7 Ho make Reads a Makefile
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
18/63
3.7 How make Reads a Makefile
Conditional Directives
* immediate
Rule Definition
Makefile
target : prerequisites ...
recipe
...
...
Makefileimmediate : immediate ; deferred
deferred
() Dum Ka Biryani, Make for each other 15 / 1
4 2 Rule Syntax
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
19/63
4.2 Rule Syntax
* First target as default, if not specified.
* A rule tells make two things: when the targets are out of date(prerequisites), and how to update them (recipe) when necessary.
Makefile
target : prerequisites ...
recipe...
...
Makefile
target : prerequisites ; recipe
recipe
...
...
() Dum Ka Biryani, Make for each other 16 / 1
4 4 Using Wildcard Characters in File Names
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
20/63
4.4 Using Wildcard Characters in File Names
Makefileclean :
rm -f *.o
Wildcard expansion does not happen in variable definition
Makefile
objects = *.o
Use Wildcard function!
Makefile
objects = $(wildcard *.o)
() Dum Ka Biryani, Make for each other 17 / 1
4 5 Searching Directories for Prerequisites
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
21/63
4.5 Searching Directories for Prerequisites
VPATH make variable
VPATH = src:../headersvpath Directive
Makefile
vpath pattern directories
vpath %.h ../headers
To clear search paths:
Makefile
vpath patternvpath %.h
vpath
() Dum Ka Biryani, Make for each other 18 / 1
4 5 4 Writing Recipes with Directory Search
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
22/63
4.5.4 Writing Recipes with Directory Search
Automatic variables$ˆ all prerequisites$@ target$< first prerequisite
Makefile
coriander.o : coriander.c
cc -c $(CFLAGS) $^ -o $@
Makefile
masala.o : masala.c masala.h defs.hcc -c $(CFLAGS) $< -o $@
() Dum Ka Biryani, Make for each other 19 / 1
4 6 Phony Targets
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
23/63
4.6 Phony Targets
Error in submake ignored:
Makefile
SUBDIRS = masala rice onion
subdirs :
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \
done
Makefile
SUBDIRS = masala rice onion
.PHONY : subdirs $(SUBDIRS)subdirs: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@
() Dum Ka Biryani, Make for each other 20 / 1
4 12 Static Pattern Rules
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
24/63
4.12 Static Pattern Rules
* Override implicit rule.
* No uncertainity.
Makefile
targets ... : target-pattern: prereq-patterns ...
recipe
...
Makefile
objects = curd.o coriander.o masala.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
() Dum Ka Biryani, Make for each other 21 / 1
5 1 Recipe Syntax
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
25/63
5.1 Recipe Syntax
* Follows shell syntax.* Backslash-newline pairs are preserved and passed to the shell.
Makefile
all :
@echo In a cooking vessel\
add a layer of semi-cooked Basmati rice
@echo Add meat on this\
rice layer@echo Add another layer \
of rice
@echo Sprinkle the ingredients with water and cook
() Dum Ka Biryani, Make for each other 22 / 1
5 1 Recipe Syntax
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
26/63
5.1 Recipe Syntax
* Follows shell syntax.* Backslash-newline pairs are preserved and passed to the shell.
Makefile
all :
@echo In a cooking vessel\
add a layer of semi-cooked Basmati rice
@echo Add meat on this\
rice layer@echo Add another layer \
of rice
@echo Sprinkle the ingredients with water and cook
$ makeIn a cooking vessel add a layer of semi-cooked Basmati rice
Add meat on this rice layer
Add another layer of rice
Sprinkle the ingredients with water and cook
() Dum Ka Biryani, Make for each other 22 / 1
5.1.2 Using Variables in Recipes
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
27/63
5.1.2 Using Variables in Recipes
MakefileLIST = masala rice onion
all:
for i in $(LIST); do \
echo $$i; \done
() Dum Ka Biryani, Make for each other 23 / 1
5.1.2 Using Variables in Recipes
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
28/63
5.1.2 Using Variables in Recipes
MakefileLIST = masala rice onion
all:
for i in $(LIST); do \
echo $$i; \done
$ make
masala
rice
onion
() Dum Ka Biryani, Make for each other 23 / 1
5.4 Parallel Execution
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
29/63
5.4 Parallel Execution
* -j number, number of recipies to execute in parallel.
* -l number, number (limit) of jobs to run in parallel.
() Dum Ka Biryani, Make for each other 24 / 1
5.4 Parallel Execution
http://goforward/http://find/http://goback/
8/20/2019 Dum Ka Biryani Make for Each Other
30/63
* -j number, number of recipies to execute in parallel.
* -l number, number (limit) of jobs to run in parallel.
$ make
$ make -j
$ make --jobs
$ make -l
$ make --max-load
() Dum Ka Biryani, Make for each other 24 / 1
5.5 Errors in Recipes
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
31/63
p
* Ignore errors in a recipe line.
Makefileclean :
-rm -f *.o
() Dum Ka Biryani, Make for each other 25 / 1
5.7 Recursive Use of make
http://goforward/http://find/http://goback/
8/20/2019 Dum Ka Biryani Make for Each Other
32/63
* Recursive make commands should always use the variable MAKE.
Makefile
subsystem :
cd subdir && $(MAKE)
Makefile
subsystem :
$(MAKE) -C subdir
() Dum Ka Biryani, Make for each other 26 / 1
5.7.2 Communicating Variables to Sub-make
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
33/63
g
Makefile
variable = value
export variable ...
unexport variable ...
Makefile
export variable = value
export variable := value
export variable += value
() Dum Ka Biryani, Make for each other 27 / 1
5.8 Defining Canned Recipes
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
34/63
Makefile
define mix-masala=@echo "Adding green chillies"@echo "Adding ginger garlic paste"@echo "Adding cinnamon, cardamom"@echo "Adding fried onions"@echo "Adding coriander and mint leaves"endef
mix:$(mix-masala)
() Dum Ka Biryani, Make for each other 28 / 1
5.8 Defining Canned Recipes
http://goforward/http://find/http://goback/
8/20/2019 Dum Ka Biryani Make for Each Other
35/63
Makefile
define mix-masala=@echo "Adding green chillies"@echo "Adding ginger garlic paste"@echo "Adding cinnamon, cardamom"@echo "Adding fried onions"@echo "Adding coriander and mint leaves"endef
mix:$(mix-masala)
$ make
$ make mixAdding green chillies
Adding ginger garlic pasteAdding cinnamon, cardamomAdding fried onionsAdding coriander and mint leaves
() Dum Ka Biryani, Make for each other 28 / 1
6.2 The Two Flavors of Variables
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
36/63
* Recursively Expanded variable
Makefile
spice = $(chillies)
chillies = $(both)
both = green chillies and red chillie powder
all: ; echo $(spice)
() Dum Ka Biryani, Make for each other 29 / 1
6.2 The Two Flavors of Variables
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
37/63
* Recursively Expanded variable
Makefile
spice = $(chillies)
chillies = $(both)
both = green chillies and red chillie powder
all: ; echo $(spice)
$ make
green chillies and red chillie powder
() Dum Ka Biryani, Make for each other 29 / 1
6.2 The Two Flavors of Variables
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
38/63
* Simply Expanded variable
Makefile
chillie := red chillie
spice := $(chillie) powder, green chillies
chillie := green chillies
all:
echo $(spice)
echo $(chillie)
() Dum Ka Biryani, Make for each other 30 / 1
6.2 The Two Flavors of Variables
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
39/63
* Simply Expanded variable
Makefile
chillie := red chillie
spice := $(chillie) powder, green chillies
chillie := green chillies
all:
echo $(spice)
echo $(chillie)
$ makered chillie powder, green chillies
green chillies
() Dum Ka Biryani, Make for each other 30 / 1
6.2 The Two Flavors of Variables
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
40/63
* Conditional Variable assignment operator
Makefile
ifeq ($(origin RICE), undefined)
RICE = Basmati riceendif
Makefile
RICE ?= Basmati rice
() Dum Ka Biryani, Make for each other 31 / 1
6.3.1 Substitution References
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
41/63
Makefile
masala := chillies.o onions.o garlic.o ginger.o
biryani := $(masala:.o=.c)
Makefile
masala := chillies.o onions.o garlic.o ginger.o
biryani := $(masala:%.o=%.c)
* ’biryani’ is set to ’chillies.c onions.c garlic.c ginger.c’
() Dum Ka Biryani, Make for each other 32 / 1
6.3.2 Computed Variable Names
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
42/63
Makefile
greeny = coriander
coriander = green coriander leaves
leaves := $($(greeny))
all:
@echo $(leaves)
() Dum Ka Biryani, Make for each other 33 / 1
6.3.2 Computed Variable Names
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
43/63
Makefile
greeny = coriander
coriander = green coriander leaves
leaves := $($(greeny))
all:
@echo $(leaves)
$ make
green coriander leaves
() Dum Ka Biryani, Make for each other 33 / 1
6.6 Appending More Text to Variables
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
44/63
Makefile
objects = masala.o rice.o onion.o curd.o
...
objects += coriander.o
Makefile
CFLAGS = $(includes) -O
...
CFLAGS += -pg
() Dum Ka Biryani, Make for each other 34 / 1
6.7 The override Directive
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
45/63
Makefile
override variable = value
override variable := value
override variable += more text
Makefile
override CFLAGS += -g
override define masala= more-masala
endef
() Dum Ka Biryani, Make for each other 35 / 1
6.9 Undefining Variables
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
46/63
Makefile
water := saffron water
leaves = mint leaves
undefine waterundefine leaves
Makefile
override undefine CFLAGS
() Dum Ka Biryani, Make for each other 36 / 1
6.11 Target-specific Variable Values
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
47/63
Makefile
target ... : variable-assignment
Makefile
prog : CFLAGS = -g
prog : masala.o rice.o onion.o
() Dum Ka Biryani, Make for each other 37 / 1
6.12 Pattern-specific Variable Values
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
48/63
Makefile
pattern ... : variable-assignment
Makefile
%.o : CFLAGS = -O
Makefile
%.o: %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
lib/%.o: CFLAGS := -fPIC -g%.o: CFLAGS := -g
all: rice.o lib/masala.o
() Dum Ka Biryani, Make for each other 38 / 1
7.1 Example of a Conditional
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
49/63
Makefile
libs for gcc = -lgnu
normal libs =
biryani : $(objects)ifeq ($(CC), gcc)
libs=$(libs for gcc)
else
libs=$(normal libs)
endif
() Dum Ka Biryani, Make for each other 39 / 1
7.2 Syntax of Conditionals
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
50/63
Makefile
conditional-directive
text-if-trueendif
Makefile
conditional-directivetext-if-true
elsetext-if-false endif
Makefile
conditional-directivetext-if-one-is-true
endif else conditional-directivetext-if-trueelsetext-if-false endif
() Dum Ka Biryani, Make for each other 40 / 1
7.2 Syntax of Conditionals
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
51/63
Four conditional directives:
* ifeqifeq ($(CC), gcc)
* ifneq
ifneq ($(STRIP), strip)
* ifdefifdef $(LIBS)
* ifndefifndef $(CFLAGS)
() Dum Ka Biryani, Make for each other 41 / 1
8.1 Function Call Syntax
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
52/63
Makefile
$(function arguments)
${function arguments}
Makefile
comma := ,
empty :=
space:= $(empty) $(empty)
masala:= chillies onion garlic ginger
list:= $(subst $(space),$(comma),$(masala))
’list’ is now ’chillies,onion,garlic,ginger’
() Dum Ka Biryani, Make for each other 42 / 1
8.2 Functions for String Substitution and Analysis
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
53/63
Makefile
$(subst from,to,text )
$(patsubst pattern,replacement,text )
$(strip string )
$(findstring find,in )
$(filter pattern...,text )
$(filter-out pattern...,text )
$(sort list )
$(word n, text )
() Dum Ka Biryani, Make for each other 43 / 1
8.3 Functions for File Names
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
54/63
Makefile
$(dir names... )
$(notdir names... )
$(suffix names... )
$(basename names... )
$(addsuffix suffix,names... )
$(addprefix prefix,names... )
$(join list1, list2 )
$(wildcard pattern )
() Dum Ka Biryani, Make for each other 44 / 1
8.4 Functions for Conditionals
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
55/63
Makefile
$(if condition,then-part[,else-part] )
$(or condition1[,condition2[,condition3...]] )
$(and condition1[,condition2[,condition3...]] )
() Dum Ka Biryani, Make for each other 45 / 1
8.5 The foreach Function
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
56/63
Makefile
$(foreach var,list,text )
Makefilefind files = $(wildcard $(dir)/*)
dirs := masala rice leaves
files := $(foreach dir, $(dirs), $(find files))
() Dum Ka Biryani, Make for each other 46 / 1
8.6 The call Function
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
57/63
Makefile
$(call variable,param,param,... )
Makefile
reverse = $(2) $(1)
make = $(call reverse,cook,mix)
’make’ contains ’mix cook’
() Dum Ka Biryani, Make for each other 47 / 1
8.7 The value Function
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
58/63
Makefile
$(value variable )
Makefile
LIST = $PATH
all:
@echo $(LIST)
@echo $(value LIST)
() Dum Ka Biryani, Make for each other 48 / 1
8.7 The value Function
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
59/63
Makefile
$(value variable )
Makefile
LIST = $PATH
all:
@echo $(LIST)
@echo $(value LIST)
$ make
ATH
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
() Dum Ka Biryani, Make for each other 48 / 1
8.9 The origin Function
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
60/63
Makefile
$(origin variable )
How the variable was defined:
* undefined
* default
* environment
* environment override
* file
* command line
* automatic
() Dum Ka Biryani, Make for each other 49 / 1
8.10 The flavor Function
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
61/63
Makefile
$(flavor variable )
Flavor of the variable:
* undefined
* recursively expanded variable
* simply expanded variable
() Dum Ka Biryani, Make for each other 50 / 1
8.11 The shell Function
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
62/63
Makefile
contents := $(shell cat onion.c)
Makefile
files := $(shell echo *.c)
() Dum Ka Biryani, Make for each other 51 / 1
References
http://find/
8/20/2019 Dum Ka Biryani Make for Each Other
63/63
GNU Make:http://www.gnu.org/software/make/
GNU Make Manual:http://www.gnu.org/software/make/manual/
Dum Ka Biryani, Make for each other (sources):http://www.shakthimaan.com/downloads.html#dum-ka-biryani-make-for-each-other
Symbols in LaTeX and HTML:http://newton.ex.ac.uk/research/qsystems/people/sque/symbols/
() Dum Ka Biryani, Make for each other 52 / 1
http://find/Recommended