Answers:
පෙරනිමියෙන්, Makefile ඉලක්ක "ගොනු ඉලක්ක" වේ - ඒවා වෙනත් ලිපිගොනු වලින් ගොනු තැනීමට භාවිතා කරයි. Make එහි ඉලක්කය ගොනුවක් යැයි උපකල්පනය කරයි, මෙය Makefiles ලිවීම සාපේක්ෂව පහසු කරයි:
foo: bar
create_one_from_the_other foo bar
කෙසේ වෙතත්, සමහර විට ඔබේ Makefile ගොනු පද්ධතියේ භෞතික ලිපිගොනු නියෝජනය නොකරන විධාන ක්රියාත්මක කිරීමට ඔබට අවශ්යය. මේ සඳහා හොඳ උදාහරණ වන්නේ “පිරිසිදු” සහ “සියල්ල” යන පොදු ඉලක්ක ය. සමහර විට මෙය එසේ නොවේ, නමුත් ඔබේ ප්රධාන නාමාවලියෙහි නම් කර ඇති ගොනුවක් තිබිය හැකclean
. එවැනි අවස්ථාවකදී Make ව්යාකූල වනු ඇත, මන්දයත් පෙරනිමියෙන් clean
ඉලක්කය මෙම ගොනුව සමඟ සම්බන්ධ වන අතර Make එය ක්රියාත්මක කරන්නේ ගොනුව එහි යැපීම් සම්බන්ධයෙන් යාවත්කාලීනව නොපෙන්වන විට පමණි.
මෙම විශේෂ ඉලක්ක ව්යාජ ලෙස හැඳින්වෙන අතර ඒවා ගොනු සමඟ සම්බන්ධ නොවන බව ඔබට පැහැදිලිව පැවසිය හැකිය, උදා:
.PHONY: clean
clean:
rm -rf *.o
make clean
ඔබට නම් කළ ගොනුවක් තිබුණත් දැන් අපේක්ෂිත පරිදි ක්රියාත්මක clean
වේ.
Make සම්බන්ධයෙන් ගත් කල, ව්යාජ ඉලක්කයක් යනු සැමවිටම යල්පැනගිය ඉලක්කයකි, එබැවින් ඔබ ඉල්ලන සෑම විටම make <phony_target>
එය ගොනු පද්ධතියේ තත්වයෙන් ස්වාධීනව ක්රියාත්මක වේ. සමහර පොදු make
බොහෝ විට ව්යාජ බව ඉලක්ක කරන්නේ: all
, install
, clean
, distclean
, TAGS
, info
, check
.
install
Makefiles වල ඉතා සුලභ වන ඔබට ඉලක්කයක් ඇතැයි උපකල්පනය කරමු . ඔබ නම් නෑ නෑ භාවිතා .PHONY
, හා නම් ගොනුව install
මෙම Makefile ලෙස එම බහලුම තුල පවතී, එසේ නම් make install
කරන්නේ කිසිම දෙයක් . මෙයට හේතුව install
“ ගොනුව නම් කිරීම සඳහා එවැනි හා එවැනි වට්ටෝරුවක් ක්රියාත්මක කරන්න” යන්නෙහි අර්ථය Make විසින් අර්ථ නිරූපණය කිරීමයි . ගොනුව දැනටමත් ඇති බැවින් සහ එහි පරායත්තතාවයන් වෙනස් නොවූ හෙයින් කිසිවක් සිදු නොවේ.
කෙසේ වෙතත් ඔබ install
ඉලක්කය PHONY බවට පත් කරන්නේ නම් , එය ඉලක්කය ප්රබන්ධයක් බව සාදන මෙවලමට කියනු ඇති අතර එමඟින් එය සත්ය ගොනුව නිර්මාණය කරනු ඇතැයි අපේක්ෂා නොකළ යුතුය. එබැවින් එය install
ගොනුව තිබේදැයි පරීක්ෂා නොකරනු ඇත, අර්ථය: අ) ගොනුව පවතින්නේ නම් එහි හැසිරීම වෙනස් නොවන අතර ආ) අමතර stat()
ලෙස හැඳින්වෙන්නේ නැත.
සාමාන්යයෙන් ඔබගේ Makefile හි ඉලක්කගත නමට සමාන නමක් සහිත ප්රතිදාන ගොනුවක් නිෂ්පාදනය නොකරන සියලුම ඉලක්ක PHONY විය යුතුය. මෙම සාමාන්යයෙන් ඇතුළත් all
, install
, clean
, distclean
, සහ මත එසේ.
.sh
හෝ .bash
ඔවුන් ඔබ ඇතුලත් කල යුතු වේ (පුස්තකාල සඳහා දීර්ඝ එකතු ප්රධාන කාර්යය සහ සංචිත ඇති වගේ "වැඩසටහන්" සඳහා දීර්ඝ බව ලකුණු source mylib.sh
). ඇත්ත වශයෙන්ම, මම මෙම SO ප්රශ්නයට යොමු වූයේ මගේ Makefile නමින් හැඳින්වෙන ඩිරෙක්ටරියේම පිටපතක් තිබීම නිසායinstall
.PHONY
...
.PHONY
අනුවාදය බව කිසිවෙකු වටහා නොගන්නා ලෙස ඔබ සමඟ සවලක් රැගෙන යාමට මම නිර්දේශ කරමි .
සටහන : සාදන්න මෙවලම Makefile කියවන අතර රීතියක ':' සංකේතයේ දෙපස ඇති ගොනු වල වෙනස් කිරීමේ කාල මුද්දර පරීක්ෂා කරයි.
'පරීක්ෂණය' නාමාවලියක පහත ලිපිගොනු ඇත:
prerit@vvdn105:~/test$ ls
hello hello.c makefile
Makefile හි රීතියක් පහත පරිදි අර්ථ දැක්වේ:
hello:hello.c
cc hello.c -o hello
දැන් උපකල්පනය කරන්න 'හෙලෝ' ගොනුව කිසියම් දත්ත අඩංගු පෙළ ගොනුවක් වන අතර එය 'hello.c' ගොනුවෙන් පසුව නිර්මාණය කරන ලද්දකි. එබැවින් 'හෙලෝ' වෙනස් කිරීම (හෝ නිර්මාණය කිරීම) කාල මුද්දරය 'hello.c' ට වඩා අළුත් වනු ඇත. එබැවින් අපි විධාන රේඛාවෙන් 'හලෝ සාදන්න' යනුවෙන් ඉල්ලා සිටින විට, එය මෙසේ මුද්රණය වේ:
make: `hello' is up to date.
දැන් 'hello.c' ගොනුවට පිවිස එහි සුදු පැහැති අවකාශ කිහිපයක් තබන්න, එය කේත වාක්ය ඛණ්ඩයට හෝ තර්කනයට බලපාන්නේ නැති අතර පසුව ඉතිරි කර ඉවත් වන්න. දැන් hello.c හි වෙනස් කිරීමේ කාල මුද්දරය 'හෙලෝ' වලට වඩා අලුත් ය. දැන් ඔබ 'make hello' ලෙස ඉල්ලා සිටියහොත්, එය විධාන ක්රියාත්මක කරන්නේ:
cc hello.c -o hello
'හෙලෝ' (පෙළ ගොනුව) ගොනුව නව ද්විමය ගොනුවක් වන 'හෙලෝ' සමඟ නැවත ලියනු ලැබේ (ඉහත සම්පාදන විධානයේ ප්රති result ලය).
අපි පහත පරිදි makefile හි .PHONY භාවිතා කරන්නේ නම්:
.PHONY:hello
hello:hello.c
cc hello.c -o hello
ඉන්පසු 'make hello' යනුවෙන් ආයාචනා කරන්න, එය pwd 'test' හි ඇති ඕනෑම ගොනුවක් නොසලකා හරිමින් සෑම විටම විධානය ක්රියාත්මක කරයි.
දැන් සිතමු, එම 'හෙලෝ' ඉලක්කයට පරායත්තතා ප්රකාශ කර නැත:
hello:
cc hello.c -o hello
සහ 'හෙලෝ' ගොනුව දැනටමත් pwd 'test' හි ඇත, පසුව 'make hello' සැමවිටම පෙන්වන්නේ:
make: `hello' is up to date.
make
සමස්තයක් වශයෙන් අර්ථවත් කරයි, මේ සියල්ලම ලිපිගොනු පිළිබඳ වේ! මෙම පිළිතුරට ස්තූතියි.
.PHONY: install
හොඳම පැහැදිලි කිරීම වන්නේ ග්නූ විසින් සාදන ලද අත්පොතයි: 4.6 ව්යාජ ඉලක්ක අංශය .
.PHONY
යනු නිෂ්පාදනයේ විශේෂ නිමැවුම් ඉලක්ක නාම වලින් එකකි . ඔබ උනන්දු විය හැකි වෙනත් ඉලක්ක තිබේ, එබැවින් මෙම යොමු කිරීම් මඟ හැරීම වටී.
.PHONY ඉලක්කයක් සලකා බැලීමට කාලය පැමිණි විට, එම නම සහිත ගොනුවක් තිබේද යන්න හෝ එහි අවසන් වෙනස් කිරීමේ කාලය කුමක් වුවත්, සාදන්න එහි වට්ටෝරුව කොන්දේසි විරහිතව ක්රියාත්මක කරයි.
සහ වැනි සම්මත ඉලක්ක සඳහා ඔබ උනන්දු විය හැකිය .all
clean
".PHONY" හි එක් වැදගත් උපක්රමයක් ද ඇත - භෞතික ඉලක්කයක් වෙනත් භෞතික ඉලක්කයක් මත රඳා පවතින ව්යාජ ඉලක්කයක් මත රඳා පවතින විට:
TARGET1 -> PHONY_FORWARDER1 -> PHONY_FORWARDER2 -> TARGET2
ඔබ TARGET2 යාවත්කාලීන කළේ නම්, TARGET1 TARGET1 ට එරෙහිව පරණ එකක් ලෙස සැලකිය යුතුය, එබැවින් TARGET1 නැවත ගොඩනැඟිය යුතුය. එය සැබවින්ම මේ ආකාරයෙන් ක්රියා කරයි .
TARGET2 විට වෙනත් ඕනැම කොටසක් නොවේ TARGET1 එරෙහිව පැනීම - ඔබ TARGET1 නැවත නොකළ යුතු බව බලාපොරොත්තු විය යුතු අතර එසේ වුවහොත්.
මෙය පුදුම සහගත ලෙස ක්රියා නොකරන්නේ මන්ද: ව්යාජ ඉලක්කය කෙසේ හෝ ධාවනය කර ඇත (සාමාන්යයෙන් ව්යාජ ඉලක්ක මෙන්) , එයින් අදහස් කරන්නේ ව්යාජ ඉලක්කය යාවත්කාලීන යැයි සලකන බවයි. එම නිසා TARGET1 ව්යාජ ඉලක්කයට එරෙහිව පරණ යැයි සැලකේ .
සලකා බලන්න:
all: fileall
fileall: file2 filefwd
echo file2 file1 >fileall
file2: file2.src
echo file2.src >file2
file1: file1.src
echo file1.src >file1
echo file1.src >>file1
.PHONY: filefwd
.PHONY: filefwd2
filefwd: filefwd2
filefwd2: file1
@echo "Produced target file1"
prepare:
echo "Some text 1" >> file1.src
echo "Some text 2" >> file2.src
ඔබට මෙය සමඟ සෙල්ලම් කළ හැකිය:
ව්යාජ ඉලක්කයක් හරහා ෆයිල් 1 වක්රව ෆයිල් 1 මත රඳා පවතින බව ඔබට පෙනේ - නමුත් මෙම පරායත්තතාවය හේතුවෙන් එය සැමවිටම නැවත ගොඩනඟයි. ඔබ තුළ ඇති පරායත්ත වෙනස් කරන්නේ නම් fileall
වලින් filefwd
දක්වා file
, දැන් fileall
සෑම අවස්ථාවකදීම නැවත ගොඩනඟා නැත ලබා, නමුත් විට පමණක් රඳා ඉලක්ක ඕනෑම ගොනුවක් ලෙස එයට එරෙහිව මුලික වේ.
විශේෂ ඉලක්කය .PHONY:
ව්යාජ ඉලක්ක ප්රකාශ කිරීමට ඉඩ සලසයි, එම නිසා make
ඒවා සත්ය ගොනු නාමයන් ලෙස පරික්ෂා නොකරනු ඇත: එවැනි ලිපිගොනු තවමත් පැවතුනද එය සැමවිටම ක්රියාත්මක වේ.
ඔබට .PHONY:
ඔබේ කිහිපයක් තැබිය හැකිය Makefile
:
.PHONY: all
all : prog1 prog2
...
.PHONY: clean distclean
clean :
...
distclean :
...
ව්යාජ ඉලක්ක ප්රකාශ කිරීමට තවත් ක්රමයක් තිබේ: සරලව '::' දමන්න
all :: prog1 prog2
...
clean ::
...
distclean ::
...
මෙම '::' විශේෂ අර්ථයක් ඇත: ඉලක්ක ව්යාජ වේ ප්ලස් ඔවුන් කිහිප වතාවක් පෙනී හැක:
clean ::
rm file1
...
clean ::
rm file2
විධාන කොටස් එකින් එක හැඳින්වේ.
සුපුරුදු ඉලක්කය වෙඩි තැබීම නොකිරීමට මම බොහෝ විට ඒවා භාවිතා කරමි.
superclean: clean andsomethingelse
blah: superclean
clean:
@echo clean
%:
@echo catcher $@
.PHONY: superclean
ව්යාජ තොරව, make superclean
තමන් කටයුතු clean
, andsomethingelse
හා catcher superclean
, නමුත් PHONY සමඟ, make superclean
වෙඩි තියන්නේ නැහැ catcher superclean
.
clean
ඉලක්කය PHONY බවට පත් කිරීම ගැන අපට කරදර විය යුතු නැත , මන්ද එය සම්පූර්ණයෙන්ම ව්යාජ නොවේ. එය කිසි විටෙකත් පිරිසිදු ගොනුව නිපදවන්නේ නැතත්, එයට වෙඩි තැබීමට විධාන ඇත, එබැවින් එය අවසාන ඉලක්කයක් යැයි සිතනු ඇත.
කෙසේ වෙතත්, superclean
ඉලක්කය සැබවින්ම ව්යාජ ය, එබැවින් සාදන්න superclean
ඉලක්කය සඳහා ඩිප්ස් සපයන වෙනත් ඕනෑම දෙයක් සමඟ එය ගොඩගැසීමට උත්සාහ කරනු ඇත - මෙයට වෙනත් superclean
ඉලක්ක සහ %
ඉලක්කය ඇතුළත් වේ .
අප ගැන සියලු කිසිවක් කියන්නේ නැහැ සටහන andsomethingelse
හෝ blah
, ඒ නිසා ඔවුන් පැහැදිලිව ම ඩැහැගන්නා වෙත යන්න.
ප්රතිදානය මේ වගේ දෙයක්:
$ make clean
clean
$ make superclean
clean
catcher andsomethingelse
$ make blah
clean
catcher andsomethingelse
catcher blah