MakeFile හි .PHONY හි අරමුණ කුමක්ද?


1761

දේ කරන්නේ .PHONYයම් Makefile දී අදහස් කරන්නේ? මම හරහා ගොස් ඇති මෙම , නමුත් එය ද සංකීර්ණ බවට පත් වී තිබේ.

යමෙකුට එය සරල වචන වලින් මට පැහැදිලි කළ හැකිද?

Answers:


1972

පෙරනිමියෙන්, 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.


49
@eSKay: 'ඇයි එය' ව්‍යාජ 'ලෙස හඳුන්වන්නේ?' - එය සැබෑ ඉලක්කයක් නොවන නිසා. එනම්, ඉලක්කගත නම එම ඉලක්කයේ විධාන මඟින් නිපදවන ගොනුවක් නොවේ.
බර්නාඩ්

97
Az ලේසර්: ඔබ ස්වදේශීය ඉංග්‍රීසි කථිකයෙක් දැයි මම නොදනිමි. මම නැහැ. ෆෝනි යන වචනයෙන් අදහස් කරන්නේ කුමක්ද යන්න අදහස් නොවේ. en.wiktionary.org/wiki/phony පවසයි: වංචනික; ව්‍යාජ; නොමඟ යවන පෙනුමක් ඇති.
බබාර්

59
මෙම පිළිතුර හරියටම සම්පුර්ණ නැත - එය සම්බන්ධිත නිබන්ධනයේ ආමන්ත්‍රණය කළ හැකි වුවද. ඔබේ ඉලක්කය කුමක් වුවත් ස්ථානීය වර්ගීකරණයේ කොටසක් නම්, මේක්ෆයිල් එකක ලේබලයක් / ගොනුවක් තැනීමට PHONY බල කරයි. එනම්, ඔබට 'පිරිසිදු කිරීම:' ලේබලයක් ව්‍යාජ ලෙස සකසා ඇත්නම් සහ ඔබේ ස්ථාපන ලේබලය පිරිසිදු කිරීමක් ලෙස පූර්වාවශ්‍යතාවක් ලෙස අර්ථ දක්වා තිබේ නම් - එනම් 'ස්ථාපනය කරන්න: පිරිසිදු කිරීම' නම්, Makefile ගොඩනැගීමට උත්සාහ කරන විට පිරිසිදු කිරීම සැමවිටම ක්‍රියාත්මක වේ. 'ස්ථාපනය කරන්න'. ඒවා සාර්ථක නම් නොසලකා සෑම විටම ගැනීමට අවශ්‍ය පියවර සඳහා මෙය ප්‍රයෝජනවත් වේ - එය කාලරාමු නොසලකා හැර බල කරනු ඇත.
synthesizerpatel

10
ඔබට භාවිතා කිරීමට අවශ්‍ය නොවන බව සලකන්න .PHONY ඔබට කර්තව්‍යයට සමාන නමක් ඇති ගොනුවක් නොමැති තාක් කල්. කාර්යය සෑම විටම කෙසේ හෝ ක්‍රියාත්මක වන අතර Makefile වඩාත් කියවිය හැකි වනු ඇත.
බර්නාඩ්

18
"ව්‍යාජ ඉලක්කයක් යනු සැමවිටම යල්පැනගිය ඉලක්කයකි" - විශිෂ්ට පැහැදිලි කිරීමක්!
ඩැනීජෙල්

736

installMakefiles වල ඉතා සුලභ වන ඔබට ඉලක්කයක් ඇතැයි උපකල්පනය කරමු . ඔබ නම් නෑ නෑ භාවිතා .PHONY, හා නම් ගොනුව installමෙම Makefile ලෙස එම බහලුම තුල පවතී, එසේ නම් make installකරන්නේ කිසිම දෙයක් . මෙයට හේතුව install“ ගොනුව නම් කිරීම සඳහා එවැනි හා එවැනි වට්ටෝරුවක් ක්‍රියාත්මක කරන්න” යන්නෙහි අර්ථය Make විසින් අර්ථ නිරූපණය කිරීමයි . ගොනුව දැනටමත් ඇති බැවින් සහ එහි පරායත්තතාවයන් වෙනස් නොවූ හෙයින් කිසිවක් සිදු නොවේ.

කෙසේ වෙතත් ඔබ installඉලක්කය PHONY බවට පත් කරන්නේ නම් , එය ඉලක්කය ප්‍රබන්ධයක් බව සාදන මෙවලමට කියනු ඇති අතර එමඟින් එය සත්‍ය ගොනුව නිර්මාණය කරනු ඇතැයි අපේක්ෂා නොකළ යුතුය. එබැවින් එය installගොනුව තිබේදැයි පරීක්ෂා නොකරනු ඇත, අර්ථය: අ) ගොනුව පවතින්නේ නම් එහි හැසිරීම වෙනස් නොවන අතර ආ) අමතර stat()ලෙස හැඳින්වෙන්නේ නැත.

සාමාන්‍යයෙන් ඔබගේ Makefile හි ඉලක්කගත නමට සමාන නමක් සහිත ප්‍රතිදාන ගොනුවක් නිෂ්පාදනය නොකරන සියලුම ඉලක්ක PHONY විය යුතුය. මෙම සාමාන්යයෙන් ඇතුළත් all, install, clean, distclean, සහ මත එසේ.


6
InPineappleUndertheSea පිළිගත් පිළිතුර එහි මුලික වටිනාකමේ මට්ටමේ සිට සැලකිය යුතු ලෙස වැඩිදියුණු කර ඇති අතර දැන් එය මේ තරම්ම හොඳ ය. ඔබේ අදහස තේරුම් ගැනීමට මට එහි සංශෝධන ඉතිහාසය බැලීමට සිදු විය.
අමරි

2
මගේ කේත රචනයේ 'ස්ථාපනය කරන්න' හෝ ඒ හා සමාන ලිපිගොනු මා සතුව නොමැති බැවින් මෙය අර්ථ විරහිත බව පෙනේ. බොහෝ ලිපිගොනු වලට ගොනු දිගුවක් ලැබෙනු ඇති අතර, ගොනු දිගුවක් නොමැති ගොනු සාමාන්‍යයෙන් 'README' වැනි සියලුම කැප් වල ඇත. නැවතත්, ඔබට 'install.sh' වෙනුවට 'install' නමින් bash ස්ක්‍රිප්ට් එකක් තිබේ නම්, ඔබට නරක කාලයක් ලැබෙනු ඇත.
නියුක්ලියාර්ටයිඩ්

7
Ason ජේසන් ටූ මෙය අනිවාර්යයෙන්ම සත්‍ය නොවේ. මෙම පළමුෙවන් අත්ගුණය සම්මුතීන් ඔබ ඇසිය .shහෝ .bashඔවුන් ඔබ ඇතුලත් කල යුතු වේ (පුස්තකාල සඳහා දීර්ඝ එකතු ප්රධාන කාර්යය සහ සංචිත ඇති වගේ "වැඩසටහන්" සඳහා දීර්ඝ බව ලකුණු source mylib.sh). ඇත්ත වශයෙන්ම, මම මෙම SO ප්‍රශ්නයට යොමු වූයේ මගේ Makefile නමින් හැඳින්වෙන ඩිරෙක්ටරියේම පිටපතක් තිබීම නිසායinstall
Kyle

10
Yle කයිල් ඔව්, මගේ අතීත ආත්මයේ තේරුම කුමක්දැයි මට විශ්වාස නැත. මේ දිනවල මම නිතරම භාවිතා කරමි .PHONY...
නියුක්ලියාර්ටයිඩ්

2
@JasonTu මෙහි විසඳුම සරලයි: කාල යන්ත්‍රයක් සාදා ඔබේ අතීතය "ප්‍රතිස්ථාපනය කරන්න". ඔබ .PHONYඅනුවාදය බව කිසිවෙකු වටහා නොගන්නා ලෙස ඔබ සමඟ සවලක් රැගෙන යාමට මම නිර්දේශ කරමි .
මාටීන් උල්හාක්

122

සටහන : සාදන්න මෙවලම 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.

3
මෙය මා ධාවනය කරන විධානයන් අර්ථවත් කරනවා පමණක් නොව, මෙය makeසමස්තයක් වශයෙන් අර්ථවත් කරයි, මේ සියල්ලම ලිපිගොනු පිළිබඳ වේ! මෙම පිළිතුරට ස්තූතියි.
Kzqai

සරල රීතියක් ලෙස පෙනෙන්නේ මෙයයි: `` `ඉලක්කය: පරායත්තතා ... විධාන ...` `` Ref: gnu.org/software/make
VicX

81
.PHONY: install
  • "ස්ථාපනය" යන වචනය මෙම Makefile හි ගොනු නාමයක් නියෝජනය නොකරයි;
  • එකම ඩිරෙක්ටරියේ ඇති "install" නම් ගොනුවක් සමඟ Makefile කිසිදු සම්බන්ධයක් නැත.

45

එය ගොනු නාමයක් නොවන ගොඩනැගීමේ ඉලක්කයකි.


33

හොඳම පැහැදිලි කිරීම වන්නේ ග්නූ විසින් සාදන ලද අත්පොතයි: 4.6 ව්‍යාජ ඉලක්ක අංශය .

.PHONYයනු නිෂ්පාදනයේ විශේෂ නිමැවුම් ඉලක්ක නාම වලින් එකකි . ඔබ උනන්දු විය හැකි වෙනත් ඉලක්ක තිබේ, එබැවින් මෙම යොමු කිරීම් මඟ හැරීම වටී.

.PHONY ඉලක්කයක් සලකා බැලීමට කාලය පැමිණි විට, එම නම සහිත ගොනුවක් තිබේද යන්න හෝ එහි අවසන් වෙනස් කිරීමේ කාලය කුමක් වුවත්, සාදන්න එහි වට්ටෝරුව කොන්දේසි විරහිතව ක්‍රියාත්මක කරයි.

සහ වැනි සම්මත ඉලක්ක සඳහා ඔබ උනන්දු විය හැකිය .allclean


11

".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සෑම අවස්ථාවකදීම නැවත ගොඩනඟා නැත ලබා, නමුත් විට පමණක් රඳා ඉලක්ක ඕනෑම ගොනුවක් ලෙස එයට එරෙහිව මුලික වේ.


6

විශේෂ ඉලක්කය .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

විධාන කොටස් එකින් එක හැඳින්වේ.


3

සුපුරුදු ඉලක්කය වෙඩි තැබීම නොකිරීමට මම බොහෝ විට ඒවා භාවිතා කරමි.

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.