InglesPransesEspanyol

Ad


OnWorks favicon

makepp_cookbook - Online sa Cloud

Patakbuhin ang makepp_cookbook sa OnWorks na libreng hosting provider sa Ubuntu Online, Fedora Online, Windows online emulator o MAC OS online emulator

Ito ang command na makepp_cookbook na maaaring patakbuhin sa OnWorks na libreng hosting provider gamit ang isa sa aming maramihang libreng online na workstation gaya ng Ubuntu Online, Fedora Online, Windows online emulator o MAC OS online emulator

PROGRAMA:

NAME


makepp_cookbook -- Ang pinakamahusay na paraan upang mag-set up ng mga makefile para sa iba't ibang sitwasyon

DESCRIPTION


Natuklasan ko na halos walang nagbabasa ng manwal para sa isang tool sa paggawa, dahil sa totoo lang
walang talagang interesado sa mismong proseso ng paggawa--kami ay interesado lamang sa mga resulta.
Kaya ang cookbook na ito ay pinagsama-sama sa pag-asang makukuha ng mga tao ang kanilang kailangan
mabilis mula sa mga halimbawa nang walang paglusong sa manwal. Ipinapakita nito kung paano mag-type
mga tanong, samantalang ang mga tagubilin sa pag-install at mga hadlang ay makikita sa
mga madalas itanong.

gusali aklatan
Do ikaw Talaga kailangan a aklatan?

Nakakita ako ng maraming malalaking programa na binubuo ng malaking bilang ng mga module, bawat isa
na nakatira sa sarili nitong direktoryo. Karaniwan, ang bawat direktoryo ay inilalagay sa sarili nitong aklatan,
at pagkatapos ay ang panghuling programa ay nag-uugnay sa lahat ng mga aklatan.

Sa maraming mga kaso, sa tingin ko sa halip na gumamit ng isang silid-aklatan, mayroong isang mas mahusay na diskarte. Mga aklatan
ay hindi talaga ang tamang solusyon kung ang bawat modyul ay hindi maaaring o hindi na muling magagamit sa alinmang iba pa
program, dahil makukuha mo ang lahat ng mga kakulangan ng mga aklatan at wala sa mga
mga pakinabang. Ang mga aklatan ay kapaki-pakinabang sa mga sumusunod na kaso:

1. Kapag mayroon kang isang grupo ng mga subroutine na kailangang iugnay sa ilang iba't ibang
mga programa, at walang programa ang aktwal na gumagamit ng 100% ng mga subroutine--bawat programa ay gumagamit ng a
ibang subset. Sa kasong ito, marahil ay isang magandang ideya na gumamit ng isang static na library (a
.a file, o isang archive file).

2. Kapag mayroon kang isang module na dapat na maiugnay sa iba't ibang mga programa, at ikaw
gustong i-load ito nang pabago-bago upang ang bawat programa ay hindi kailangang magkaroon ng hiwalay na kopya ng
ang aklatan. Ang mga dynamic na aklatan ay maaaring makatipid ng executable na espasyo ng file at kung minsan ay mapahusay
pagganap ng system dahil mayroon lamang isang kopya ng library na na-load para sa lahat ng
iba't ibang mga programa na gumagamit nito.

3. Kapag ang oras ng iyong pag-link ay napakatagal, gamit ang mga shared library para sa malalaking piraso ng
ang programa ay maaaring makabuluhang mapabilis ang link.

Ang paggamit ng mga static na aklatan ay may isang pangunahing kawalan: sa ilang mga sistema (hal. Linux), ang pagkakasunud-sunod
kung saan ini-link mo ang mga aklatan ay napakahalaga. Pinoproseso ng linker ang mga aklatan
sa pagkakasunud-sunod na tinukoy sa command line nito. Kinukuha nito ang lahat ng iniisip nitong kailangan nito
bawat aklatan, pagkatapos ay lumipat sa susunod na aklatan. Kung ang ilang kasunod na aklatan ay tumutukoy sa a
simbolo na hindi pa naisasama mula sa isang nakaraang aklatan, ang linker ay hindi
alam na bumalik at kunin ito mula sa nakaraang aklatan. Bilang resulta, maaaring kailanganin ito
upang ilista ang library nang maraming beses sa command line ng linker. (Nagtrabaho ako sa isang proyekto
kung saan kailangan naming ulitin ang buong listahan ng mga aklatan ng tatlong beses. Ang proyektong ito ang ginawa
mas gusto ko ang alternatibong diskarte na iminungkahi sa ibaba, ang incremental linking.)

Ang paggamit ng mga dynamic na aklatan ay may ilang mga disadvantages. Una, ang iyong programa ay maaaring bahagyang
mas mabagal na magsimula kung ang library ay hindi pa ginagamit ng ibang program, dahil
kailangan itong hanapin at i-load. Pangalawa, maaari itong maging isang tunay na abala upang makuha ang lahat ng pabago-bago
mga aklatan na naka-install sa tamang mga lokasyon; hindi mo maaring kopyahin lang ang program na maipapatupad,
kailangan mo ring tiyakin na kopyahin mo ang lahat ng mga aklatan nito. Pangatlo, sa ilang mga sistema, ito
mahirap i-debug ang code sa loob ng mga shared library dahil hindi sinusuportahan ng mga debugger
mabuti sila.

Kung ang iyong module ay hindi kailanman gagamitin sa anumang iba pang programa, kung gayon mayroong maliit na dahilan upang gamitin
isang library: makukuha mo ang lahat ng disadvantages ng paggamit ng mga library at wala sa mga pakinabang.
Ang pamamaraan na gusto ko ay ang paggamit ng incremental linking, kung saan ito ay magagamit.

Narito kung paano mo ito magagawa sa Linux:

my_module.o : $(filter_out my_module.o, $(wildcard *.o))
ld -r -o $(output) $(inputs)

Ang gagawin nito ay lumikha ng isa pa .o tinawag ang file my_module.o, na bubuuin ng
ang lahat ng mga .o mga file sa subdirectory na ito. Ang linker ay lulutasin ng marami sa
mga sanggunian hangga't maaari, at iiwan ang natitirang mga sanggunian upang malutas sa a
kasunod na yugto ng pag-uugnay. Sa pinakamataas na antas, kapag sa wakas ay binuo mo na ang iyong programa,
sa halip na mag-link sa libmy_module.a or libmy_module.so, magli-link ka lang sa
my_module.o. Kapag na-link mo .o file, wala kang problema sa order-dependency sa
linker command line.

Pagpapaalam makepp malaman Palabas alin aklatan module ay kailangan

Kahit na mayroon kang isang tunay na library, kung saan ang isang naibigay na programa ay nangangailangan lamang ng ilang mga file mula dito
(sa halip na bawat solong module), maaaring malaman ng makepp kung aling mga module ang
kailangan mula sa aklatan at isama lamang ang mga nasa build. Makakatipid ito ng compilation
time if you are develop the library along with a program, kasi hindi ka nag-abala
mag-compile ng mga module ng library na hindi kailangan para sa partikular na program na iyong ginagawa.

Kung mahigpit na sinusunod ng iyong library ang convention kung saan idineklara ang lahat ng function o klase
isang file xyz.h ay ganap na ipinatupad sa isang source file na nag-compile sa xyz.o (ibig sabihin, ikaw
huwag hatiin ang pagpapatupad sa xyz1.o at xyz2.o), pagkatapos ay maaari mong gamitin ang
Ang function na "$(infer_objects)" ay para sabihin sa makepp na i-pull out lang ang mga nauugnay na module mula sa
aklatan. Maaari itong gumana nang mahusay para sa mga aklatan na may kahit dose-dosenang mga file na kasama.
Karaniwan, sinusuri ng "$(infer_objects)" ang listahan ng .h mga file na kasama, at hitsura
para sa katumbas .o mga file. Kung mabilis kang gumagawa ng isang library at isang programa
magkasama, makakatipid ito ng oras ng compilation, dahil hindi ka kailanman mag-abala sa pag-compile ng mga module ng
ang aklatan na hindi ginagamit ng programa.

Narito ang isang halimbawa ng paraan ng paggamit ko nito:

my_program: $(infer_objects *.o, $(LIB1)/*.o $(LIB2)/*.o)
$(CXX) $(inputs) -o $(output) $(SYSTEM_LIBRARIES)

Ibinabalik ng function na "$(infer_objects )" ang unang argumento nito (pagkatapos gawin ang wildcard
pagpapalawak dito), at tinitingnan din ang listahan ng mga file sa pangalawang argumento nito, para sa
mga file na ang pangalan ay kapareho ng pangalan ng alinman .h mga file na kasama ng anumang file sa una nito
argumento. Kung ang anumang mga file na ito ay natagpuan, ang mga ito ay idinagdag sa listahan.

gusali a statik aklatan

Kung sigurado kang kailangan mo talaga ng library at hindi available ang incremental linking o
hindi ang gusto mong gawin, may ilang paraan para gawin ito. Una, narito ang isang halimbawa
kung saan ang lahat ng mga file ay tahasang nakalista:

LIBRARY_FILES = abcde

libmine.a: $(LIBRARY_FILES).o
&rm -f $(output)
$(AR) cr $(output) $(inputs)
ranlib $(output) # Maaaring hindi kinakailangan, depende sa iyong OS.

Ang &rm ay builtin na "rm" command ng makepp. Kung sanay ka na magsulat ng makefiles, maaring
medyo nagulat sa utos na ito; maaari kang sanay sa isang bagay na mas katulad nito:

libmine.a: $(LIBRARY_FILES).o
$(AR) ru $@ $? # Hindi inirerekomenda!!!!!!!
ranlib $(output)

saan $? (kilala rin bilang "$(changed_inputs)") ay isang awtomatikong variable na nangangahulugang anumang mga file
na nagbago mula noong huling beses na binuo ang library, at ang $@ ay halos pareho
bilang "$(output)".

Ang pamamaraang ito ay hindi inirerekomenda para sa maraming mga kadahilanan:

· Ipagpalagay na nag-alis ka ng source file mula sa kasalukuyang direktoryo. Ito ay nasa
library, dahil hindi mo muling itinayo ang library mula sa simula. Bilang resulta, kahit ano
na ang mga link sa library na ito ay magiging lipas .o file, at maaari nitong sirain ang iyong
nagtatayo. (Minsan akong nalito nang lubusan dito noong sinusubukan kong tanggalin ang patay na code
mula sa isang proyekto: Patuloy akong nagtanggal ng mga file at naka-link pa rin ito, kaya naisip ko na ang code ay
patay. Gayunpaman, kapag may ibang tao na itinayong muli ang proyekto mula sa simula, hindi ito nag-link ng anuman
higit pa! Ang problema ay ang matanda .o Ang mga file ay nasa archive pa rin.)

Gayundin, depende sa iyong mga opsyon sa "ar" at sa iyong pagpapatupad ng "ar" (hal, kung ikaw
gamitin ang opsyong "q" sa halip na "r"), maaari kang magkaroon ng ilang bersyon ng
pareho .o sa loob ng .a file. Kung ang iba't ibang mga bersyon ay tumutukoy sa iba't ibang mga global, ang
maaaring subukan ng linker na hilahin silang dalawa. Ito ay malamang na isang masamang bagay.

Ito ang dahilan kung bakit inalis muna namin ang file ng library, at ginagawa ito mula sa simula. Ito ay
bahagyang mas matagal kaysa sa pag-update lamang ng mga module sa isang library, ngunit hindi mas matagal; sa
isang modernong computer, ang dami ng oras na natupok ng ar program ay minuscule kumpara
sa kung ano ang kinukuha ng C compiler sa isang tipikal na build, kaya hindi ito nararapat na mag-alala
tungkol sa.

· Isa sa mga paraan na sinusubukan ng makepp na garantiya ang mga tamang build ay gagawin nito
awtomatikong muling buuin kung nagbago ang command line para bumuo ng isang partikular na target. Pero
gamit ang $? variable ay maaaring magdulot ng mga problema, dahil sa tuwing ina-update ang library,
iba ang build command. (Maaari mong pigilan ito gamit ang
":build_check ignore_action"; tingnan ang makepp_build_check para sa mga detalye.)

· Ang pag-update ng archive sa halip na muling pagtatayo nito ay magiging imposible para sa makepp na gawin
ilagay ang file nang maayos sa isang build cache (tingnan ang makepp_build_cache para sa mga detalye).

Minsan maaari mong makita na ang paglilista ng lahat ng mga file ay medyo masakit, lalo na kung a
proyekto ay sumasailalim sa mabilis na pag-unlad at ang listahan ng mga file ay patuloy na nagbabago. Ito
maaaring mas madaling buuin ang library gamit ang mga wildcard, tulad nito:

libmine.a: $(only_targets *.o)
&rm $(output)
$(AR) cr $(output) $(inputs)

Inilalagay nito ang lahat ng .o mga file sa kasalukuyang direktoryo sa library. Ang wildcard
tumutugma sa alinman .o file na umiiral o maaaring itayo, kaya gagana ito kahit na ang mga file ay hindi
umiiral pa.

Ang function na "only_targets" ay ginagamit upang ibukod .o mga file na walang katumbas
mga source file pa. Ipagpalagay na mayroon kang isang file na tinawag xyz.c na dati mong inilalagay sa iyong
aklatan. Nangangahulugan ito na mayroong isang xyz.o file na nakahiga sa paligid. Ngayon tanggalin mo xyz.c
laos na kasi, pero nakalimutan mong tanggalin xyz.o. Kung wala ang "only_targets"
function, xyz.o isasama pa rin sa listahan ng .o mga file na kasama sa library.

gusali a dynamic aklatan

Ang proseso ng pagbuo ng mga dynamic na aklatan ay ganap na nakadepende sa system. Gusto ko ng mataas
Inirerekomenda ang paggamit ng libtool upang bumuo ng isang dynamic na library (tingnan ang
<http://www.gnu.org/software/libtool/>), kaya hindi mo na kailangang malaman kung paano ito gagawin
iyong platform, at para patuloy na gumana ang iyong makefile kahit na lumipat ka sa a
magkaibang OS. Tingnan ang dokumentasyon ng libtool para sa mga detalye. Narito ang isang sample na Makefile:

LIBTOOL := libtool

libflick.la : $(only_targets *.lo)
$(LIBTOOL) --mode=link $(CC) $(inputs) -o $(output)

%.lo : %.c
$(LIBTOOL) --mode=compile $(CC) $(CFLAGS) $(KASAMA) -c $(input) -o $(output)

gusali on ilang iba machine or network
Ang isa sa mga pinaka nakakainis na problema sa makefiles ay halos hindi sila gumana kapag ikaw
lumipat sa ibang makina o ibang network. Kung ang iyong mga makefile ay kailangang gumana
bawat posibleng makina sa planeta, malamang na kailangan mo ng isang uri ng pag-configure
iskrip. Ngunit kung kailangan mo lamang magtrabaho sa ilang magkakaibang mga makina, mayroong ilang mga paraan
maaari mong lapitan ang problemang ito:

paggamit a iba isama file in lahat ang kapaligiran

Sa simula ng bawat makefile, maaari kang magsama ng linyang tulad nito:

isama ang system_defs.mk

Ang file system_defs.mk ay karaniwang matatagpuan sa ibang lugar para sa bawat isa
kapaligiran. Kung nais mong ang iyong mga direktoryo ng build ay magkapareho sa lahat ng mga makina, pagkatapos ay ilagay
system_defs.mk sa isang direktoryo sa itaas ng mga build na direktoryo, o kung hindi ay magbigay ng isang kasamang landas
sa makepp gamit ang "-I" command line na opsyon.

Ito ay karaniwang uri ng masakit na gawin, ngunit ito ay mahusay na gumagana kung mayroong isang malaking bilang ng mga
pagkakaiba.

paggamit if pahayag

Ito ang pinakapangit na paraan upang gawin ito, ngunit karaniwan itong gagana.

ifsys i386
CC := gcc
iba ifsys sun4u
CC:= cc
iba ifsys hpux11
CC = c89
endif

Kung ang kailangan mo lang gawin ay maghanap ng ilang mga programa o aklatan o magsama ng mga file sa iba't ibang paraan
mga lugar, maaaring may mas magagandang paraan (tingnan sa ibaba).

find_program, first_available, findfile

Ang mga function na ito ay maaaring maghanap sa iba't ibang mga direktoryo sa iyong system upang mahanap ang
naaangkop na mga file. Ito ay hindi kasing lakas ng isang script ng pag-configure, siyempre, ngunit nahanap ko ito
kapaki-pakinabang. Halimbawa, ginagawa ko ang sumusunod:

CXX ;= $(find_program g++ c++ pg++ cxx CC aCC)
# Pumili ng unang C++ compiler na available sa PATH.
# (Nagkataon, kung hindi mo tinukoy ang CXX, ito
# ang paraan kung paano ito tinukoy.)
TCL_INCLUDE ;= -I$(dir_noslash $(findfile tcl.h, \
/usr/local/stow/tcl-8.4.5-nothread/include \
/usr/include/tcl8.4 /usr/include/tcl \
/net/na1/tcl8.4a3/include /net/na1/tcl8.4a3/include))
# $(findfile ) ay naghahanap ng tcl.h sa bawat isa sa ipinahiwatig
# na direktoryo at ibinabalik ang buong landas. Ito ay pagkatapos
# na-convert sa isang pagpipilian sa compilation sa pamamagitan ng pagtanggal ng
# filename (umalis sa direktoryo) at prefixing na may -I.
%.o: %.cpp
$(CXX) $(CXXFLAGS) $(TCL_INCLUDE) $(input) -o $(output)

TCL_LIB ;= $((first_available
/usr/local/stow/tcl-8.4.5-nothread/lib/libtcl8.4.so
/usr/lib/libtcl8.4.so /usr/lib/libtcl.so
/net/na1/tcl8.4a3/lib/libtcl8.4.a
/net/na1/tcl8.4a3/lib/libtcl8.4.sl))
# Hanapin kung nasaan ang Tcl library. Ito ay pagkatapos ay tahasang
# na nakalista sa utos ng link:
my_program : *.o
$(CXX) $(CXXFLAGS) $(input) -o $(output) $(TCL_LIB)

Kumuha kalamangan of kay Perl config impormasyon

Ang mga pamamaraan sa itaas ay maaaring hindi sapat kung kailangan mo ng ilang karagdagang impormasyon tungkol sa
iyong system, tulad ng kung mayroong isang mahabang double, o kung ano ang byte order. gayunpaman,
Nakalkula na ng perl ang mga bagay na ito, kaya magagamit mo lang ang mga sagot nito.

Ginagawang available ng autoconfigure script ng Perl ang lahat ng impormasyon ng configuration nito sa pamamagitan ng
ang %Config hash. Walang syntax para ma-access ang isang Perl hash nang direkta sa makepp, ngunit magagawa mo
i-drop sa Perl at itakda ang mga scalar variable, na direktang naa-access mula sa makepp:

perl_begin
# Kunin ang mga halaga sa config hash.
gumamit ng Config;
$CC = $Config{'cc'}; # C compiler na ginamit ng perl;
$byteorder_flags = "-DBYTEORDER=$Config{'byteorder'}";
$longdouble_defined = $Config{'d_longdbl'} eq 'define';
$CFLAGS_for_shared_libs = $Config{'cccdlflags'};
$LDFLAGS_for_shared_libs = $Config{'ccdlflags'};
perl_end

Gayundin, kapag nagawa mo na ang 'use Config', maaari mong gamitin ang "$(perl )" na pahayag, tulad ng
ito:

SHARED_LIB_EXTENSION := $(perl $Config{'dlext'})

I-type ang "perldoc Config" para makita kung anong impormasyon ang available sa pamamagitan ng %Config hash.

Ang config ng Perl ay isang magandang lugar upang makakuha ng mga bagay tulad ng impormasyon tungkol sa mga uri ng integer, byte
order, at iba pang mga bagay na karaniwang nangangailangan ng isang hiwalay na config script upang mahanap. Ilan sa
ang impormasyon nito na nauugnay sa pagkakaroon ng mga bagay sa file system ay maaaring hindi
wasto. Halimbawa, ang $Config{'cc'} ay tumutukoy sa C compiler kung saan binuo ang perl,
na maaaring hindi ang parehong C compiler na gusto mong gamitin. Sa katunayan, maaaring hindi ito umiiral
sa iyong system, dahil malamang na na-install mo ang Perl sa pamamagitan ng isang binary package.

Tips para paggamit mga wildcard
Pagtutugma lahat file maliban a tiyak subset

Ang mga wildcard ng Makepp ay walang anumang paraan sa kasalukuyan upang tumugma sa lahat ng mga file maliban isang tiyak
set, ngunit magagawa mo ito sa isang kumbinasyon ng mga function.

Halimbawa, ipagpalagay na mayroon kang test program para sa bawat module sa isang library, ngunit wala ka
nais na isama ang mga programa sa pagsubok sa aklatan. Kung ang lahat ng mga pagsubok na programa ay nagsisimula sa
pagsusulit, pagkatapos ay maaari mong ibukod ang mga ito tulad nito:

libproduction.a: $(filter_out test*, $(wildcard *.o))

Ang mga function na "$(filter )" at "$(filter_out )" ay isang napakalakas na hanay ng mga filter na dapat gawin
lahat ng uri ng set intersection at difference operations. Halimbawa,

SUBDIRS ;= $(filter_out *test* *$(ARCH)*, $(shell find . -type d -print))
# Ibinabalik ang lahat ng mga subdirectory na wala
# "test" o $(ARCH) sa kanila.

$(filter $(patsubst test_dir/test_%.o, %.o, $(wildcard test_dir/*.o)), \
$(wildcard *.o))
# Nagbabalik ng listahan ng mga .o na file sa kasalukuyang
# na direktoryo kung saan mayroong katumbas
# test_*.o file sa test_dir subdirectory.
$(filter_out $(patsubst man/man3/%.3, %.o, $(wildcard man/man3/*.3)), \
$(wildcard *.o))
# Nagbabalik ng listahan ng mga .o na file sa kasalukuyang
# na direktoryo kung saan walang manu-manong pahina
# na may parehong filename sa man/man3 subdirectory.

paggamit ang "$(only_targets )" tungkulin sa alisin lipas na .o file

Ipagpalagay na ikaw ay gumagawa ng isang programa o isang library na may build command na tulad nito:

programa: *.o
$(CC) $(inputs) -o $(output)

Ipagpalagay na nagtanggal ka na ngayon ng isang source file. Kung nakalimutan mong tanggalin ang kaukulang .o file,
mali-link pa rin ito kahit na wala nang paraan para mabuo pa ito. Nasa
sa hinaharap, malamang na awtomatikong makikilala ng makepp ang sitwasyong ito at hindi ito isasama
ang listahan ng wildcard, ngunit sa kasalukuyan, kailangan mong sabihin dito na manual itong ibukod:

programa: $(only_targets *.o)
$(CC) $(inputs) -o $(outputs)

Hindi alam ng Makepp ang anumang paraan upang mabuo ang lipas .o file pa dahil ang source file nito ay
nawala, kaya ang function na "$(only_targets )" ay ibubukod ito sa listahan ng dependency.

Tips para maramihang mga direktoryo
Ang isa sa mga pangunahing dahilan sa pagsulat ng makepp ay upang gawing simple ang paghawak ng maramihang
mga direktoryo. Nagagawang pagsamahin ng Makepp ang mga build command mula sa maraming makefile, kaya magagawa nito
maayos na makitungo sa isang panuntunan sa isang makefile na nakasalalay sa isang file na binuo ng a
ibang makefile.

Ano sa do in lugar of recursive gumawa

Sinusuportahan ng Makepp ang recursive make para sa backward compatibility, ngunit lubos itong inirerekomenda
na ikaw hindi gamitin ito. Kung hindi mo alam kung ano ito, mabuti.

Tingnan ang "Mas mahusay na sistema para sa mga hierarchical build" sa makepp para sa mga detalye kung bakit ayaw mo
gumamit ng recursive make, o kaya'y maghanap sa web ng "recursive make na itinuturing na nakakapinsala."

Sa halip na gumawa ng isang recursive make upang gawin ang "lahat" na target sa bawat makefile, ito ay
karaniwang mas madaling hayaan ang makepp na malaman kung aling mga target ang talagang kailangang itayo.
Higit pa rito, kung ilalagay mo ang lahat ng iyong .o at mga file ng library sa parehong direktoryo ng
makefiles, pagkatapos ay awtomatikong malalaman ng makepp kung aling mga makefile ang kailangan din--ang
Ang kailangan lang ay ilista ng iyong pinakamataas na antas ang mga file na kailangan
para sa huling hakbang sa pag-uugnay. Tingnan ang mga halimbawa sa ibaba.

Isa makefile para bawat direktoryo: sa pahiwatig pagkarga

Ang pinakakaraniwang paraan upang mahawakan ang maramihang mga direktoryo ay ang paglalagay ng makefile sa bawat direktoryo
na naglalarawan kung paano buuin ang lahat sa loob o mula sa direktoryong iyon. Kung ilalagay mo .o mga file sa
ang parehong direktoryo tulad ng mga source file, pagkatapos ay implicit loading (tingnan ang "Implicit loading" sa
makepp_build_algorithm) ay awtomatikong mahahanap ang lahat ng mga makefile. Kung ilalagay mo ang iyong .o
mga file sa ibang direktoryo (hal., sa isang subdirectory na umaasa sa arkitektura), pagkatapos ay ikaw
malamang na kailangang i-load ang lahat ng nauugnay na makefile gamit ang "load_makefile" na pahayag.

Narito ang isang sample na top-level makefile para sa isang directory hierarchy na gumagamit ng implicit loading
upang bumuo ng isang programa na binubuo ng maraming nakabahaging aklatan (ngunit tingnan ang "Kailangan mo ba talaga ng a
library?" sa makepp_cookbook, dahil gumagawa ng program mula sa isang grupo ng mga shared library
ay hindi palaging isang magandang ideya):

# Nangungunang antas ng makefile:
program : main.o **/*.la # Link sa mga shared library mula sa lahat ng subdirectories.
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(inputs) -o $(output) $(LIBS)

Iyon lang ang kailangan mo sa top level na makefile. Sa bawat subdirectory, ikaw
malamang na gagawa ng ganito:

# Makefile sa bawat subdirectory:
isama ang standard_defs.mk # Mga Paghahanap ., .., ../.., atbp. hanggang dito
# hinahanap ang ipinahiwatig na file.
# override ang ilang variable na kahulugan dito
SPECIAL_FLAGS := -do_something_different

Ang bawat makefile ay maaaring halos pareho kung ang mga utos na bumuo ng mga target
ay medyo magkatulad.

Sa wakas, ilalagay mo ang sumusunod sa standard_defs.mk file (na dapat marahil
ay matatagpuan sa top-level na direktoryo):

# Mga karaniwang setting ng variable at bumuo ng mga panuntunan para sa lahat ng mga direktoryo.
CFLAGS := -g -O2
INCLUDE_DIR := $(kasama ang find_upwards)
# Paghahanap ., .., ../.., atbp. para sa isang file o
Kasama sa # directory na tinatawag, kaya kung ilalagay mo
# lahat ng iyong isama ang mga file doon, ito ay
# Hanapin sila.
KASAMA := -I$(INCLUDE_DIR)

%.lo : %.c
$(LIBTOOL) --mode=compile $(CC) $(CFLAGS) $(KASAMA) -c $(input) -o $(output)

lib$(relative_to ., ..).la: $(only_targets *.lo)
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) -o $(output) $(mga input)
# $(relative_to ., ..) ay nagbabalik ng pangalan ng kasalukuyang
# subdirectory na nauugnay sa itaas na antas
# subdirectory. Kaya kung ang makefile na ito ay xyz/Makefile,
# bubuo ang panuntunang ito ng xyz/libxyz.la.

# I-publish ang pampublikong isama ang mga file sa top-level na isama ang direktoryo:
$(INCLUDE_DIR)/public_%.h : public_%.h
:build_check symlnk
&ln -fr $(input) $(output)

Isa makefile para bawat direktoryo: malinaw pagkarga

Kung gusto mong ilagay ang lahat ng iyong .o mga file sa isang subdirectory na umaasa sa arkitektura, kung gayon
ang halimbawa sa itaas ay dapat mabago upang maging katulad nito:

# Nangungunang antas ng makefile:
MAKEFILES := $(wildcard **/Makeppfile) # Listahan ng lahat ng mga subdirectory sa
# kumuha ng makefiles mula sa.

load_makefile $(MAKEFILES) # I-load silang lahat.

isama ang standard_defs.mk # Kumuha ng compile command para sa main.o.

programa : $(ARCH)/main.o */**/$(ARCH)/*.la
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(inputs) -o $(output) $(LIBS)
Hindi kasama ng # */**/$(ARCH) ang subdirectory
# $(ARCH), kung saan hindi namin gustong bumuo
# isang shared library.

Ang bawat makefile ay magiging eksaktong kapareho ng dati:

# Makefile sa bawat subdirectory:
isama ang standard_defs.mk
# ... variable na override dito

At sa wakas, standard_defs.mk ay naglalaman ng isang bagay tulad ng sumusunod:

# Mga karaniwang setting ng variable at bumuo ng mga panuntunan para sa lahat ng mga direktoryo.
ARCH ;= $(shell uname -s)-$(shell uname -m)-$(shell uname -r)
# Minsan ang mga tao ay gumagamit lamang ng $(shell uname -m), ngunit
# ito ay magiging pareho para sa FreeBSD at Linux sa
# isang x86. Ang -r ay hindi talagang kapaki-pakinabang sa Linux,
# ngunit mahalaga para sa iba pang mga OS: mga binary para sa
Ang # SunOS 5.8 ay karaniwang hindi tatakbo sa SunOS 5.7.
&mkdir -p $(ARCH) # Tiyaking umiiral ang direktoryo ng output.
CFLAGS := -g -O2
INCLUDE_DIR := $(kasama ang find_upwards)
# Paghahanap ., .., ../.., atbp. para sa isang file o
Kasama sa # directory na tinatawag, kaya kung ilalagay mo
# lahat ng iyong isama ang mga file doon, ito ay
# Hanapin sila.
KASAMA := -I$(INCLUDE_DIR)

$(ARCH)/%.lo : %.c
$(LIBTOOL) --mode=compile $(CC) $(CFLAGS) $(KASAMA) -c $(input) -o $(output)

$(ARCH)/ lib$(relative_to ., ..).la: $(only_targets *.lo)
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) -o $(output) $(mga input)
# $(relative_to ., ..) ay nagbabalik ng pangalan ng kasalukuyang
# subdirectory na nauugnay sa itaas na antas
# subdirectory. Kaya kung ang makefile na ito ay xyz/Makefile,
# bubuo ang panuntunang ito ng xyz/$(ARCH)/libxyz.la.

# Kopyahin ang pampublikong isama ang mga file sa nangungunang antas na isama ang direktoryo:
$(INCLUDE_DIR)/public_%.h : public_%.h
&cp $(input) $(output)

Awtomatikong paggawa ang makefiles

Kung ang iyong mga makefile ay lubos na magkatulad (tulad ng sa halimbawa sa itaas), maaari mong sabihin sa Makepp
upang awtomatikong buuin ang mga ito kung wala ang mga ito. Idagdag lang ang sumusunod sa iyong pinakamataas na antas
makefile:

SUBDIRS := $(filter_out unwanted_dir1 unwanted_dir2, $(wildcard */**))
$(foreach)/Makeppfile: : foreach $(SUBDIRS)
&echo "isama ang standard_defs.mk" -o $(output)
&echo "_include additional_defs.mk" -o >>$(output)
# Kung umiiral ang file additional_defs.mk, kung gayon
# ito ay isasama, ngunit kung hindi ito umiiral,
# ang _include na pahayag ay hindi papansinin.

Ngayon ang mga makefile mismo ay awtomatikong itatayo.

Isa makefile lamang at ang tuktok antas

Kung ang lahat ng iyong makefile ay magkapareho, maaari mong itanong: bakit ako dapat magkaroon ng isang makefile sa bawat isa
antas? Bakit hindi ilagay ang lahat sa top-level na makefile?

Oo, magagawa ito. Ang pangunahing kawalan ay nagiging mas mahirap tukuyin
iba't ibang mga pagpipilian sa pagbuo para sa bawat subdirectory. Ang pangalawang kawalan ay ang iyong
Ang makefile ay malamang na maging mas mahirap basahin.

Narito ang isang halimbawa ng paggawa nito:

# Top-level makefile para sa directory hierarchy. Binubuo ang programa
# sa isang hanay ng mga nakabahaging aklatan bilang isang halimbawa. (Tingnan ang mga babala sa itaas
# kung bakit maaaring gusto mong gumamit ng incremental linking o iba pa
# diskarte sa halip na mga nakabahaging aklatan.)
makepp_percent_subdirs := 1 # Payagan ang % na tumugma sa maraming direktoryo.
SUBDIRS := $(filter_out *CVS* other-unwanted_dirs $(wildcard **))
CFLAGS := -g -O2
KASAMA := -Ikasama

%.lo: %.c
$(LIBTOOL) --mode=compile $(CC) $(KASAMA) $(CFLAGS) -c $(input) -o $(output)

$(foreach)/ lib$(notdir $(foreach)).la: $(foreach)/*.lo : foreach $(SUBDIRS)
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) -o $(output) $(mga input)
# Panuntunan upang gawin ang lahat ng mga aklatan.

programa : main.o **/*.la
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) -o $(output) $(mga input)

kasama ang/$(notdir $(foreach)): $(foreach) : foreach **/public_*.h
&cp $(input) $(output)
# Sample na panuntunan para sa pagkopya sa publiko
# naa-access na .h file sa tamang lugar.

A linisin target

Ang mga tradisyunal na makefile ay naglalaman ng isang malinis na target, na nagbibigay-daan sa pag-alis ng lahat ng dati
binuo. May tatlong dahilan kung bakit hindi mo dapat gawin ito sa makepp:

1. Nagsusumikap si Makepp para matiyak ang tamang build. Kaya ang desperado "Ayoko
alam kung ano ang mali", ang pagnanais na magsimula sa simula ay isang bagay ng nakaraan.

2. Kung minsan, sisikapin ng mga tao na makatipid ng oras sa pamamagitan ng paggawa ng dalawang magkasalungat na bagay nang sabay-sabay:
"linisin mo lahat". Maaari nitong malito ang smart wildcard system ng makepp, dahil gagawin nito
kunin muna ang mga katotohanan bago gumawa ng anuman. Pagkatapos ay darating ang malinis na aksyon, na ginagawa
huwag sabihin sa makepp kung ano ang ginagawa nito (talagang hindi nito magagawa, dahil binabawi nito ang isang bagay -- ang
salungat sa kung para saan ang build tool). Pagkatapos ay dumating ang "lahat", ngunit ang napapanahon na mga file,
na kung saan doon, ay misteryosong nawala.

3. Mayroong "makeppclean" na utos, na ginagawa ang parehong bagay, at mas mahusay.

Gayunpaman, pinanatili namin ang makasaysayang seksyong ito, dahil may sinasabi ito sa iyo tungkol sa
way makepp works: Ang huwad na target na tinatawag na "clean" ay pangalan lang para sa isang set ng mga command
alisin ang lahat ng mga file na nagreresulta mula sa proseso ng paggawa. Karaniwan ang isang malinis na target na hitsura
isang bagay na tulad nito:

$(huwad na malinis):
&rm -fm $(wildcard *.o .makepp_log)
Tinatanggal ng # -m at .makepp_log ang lahat ng basura ng makepp.

Sa halip na tahasang ilista ang mga file na gusto mong tanggalin, maaari mo ring sabihin kay makepp
alisin ang lahat ng alam nito kung paano bumuo, tulad nito:

$(huwad na malinis):
&rm -fm .makepp_log $(only_targets *)

Ito ay may kalamangan na kung alinman sa iyong mga source file ay maaaring itayo mula sa iba pang mga file,
tatanggalin din sila; sa kabilang banda, lipas na .o mga file (mga file na dating
buildable ngunit ang pinagmulang file ay tinanggal na) ay hindi matatanggal.

Kung mayroon kang isang build na nagsasangkot ng mga makefile sa iba't ibang mga direktoryo, ang iyong nangungunang
level makefile ay maaaring sumangguni sa "malinis" na target (o anumang iba pang huwad na target) sa ibang
makefile:

# Top-level makefile
SUBDIRS := sub1 sub2

# bumuo ng mga panuntunan dito

# Maglinis pagkatapos ng build:
$(phony clean): $(SUBDIRS)/clean
&rm -fm .makepp_log $(only_targets *)

Bilang kahalili, maaari mo lamang ilagay ang iyong "malinis" na target sa top-level na makefile, at magkaroon nito
iproseso ang lahat ng mga direktoryo, tulad nito:

$(huwad na malinis):
&rm -fm $(only_targets **/*)

paggamit Qt's kapangyarihan preprocessor
Ang halimbawang ito ay nagpapakita ng makefile para sa isang utility na gumagamit ng Qt GUI library ng Nokia (tingnan ang
<http://qt.nokia.com>). Ang tanging bagay na medyo hindi karaniwan tungkol dito ay ikaw
dapat magpatakbo ng preprocessor na tinatawag na "moc" sa karamihan ng ".h" na mga file na naglalaman ng mga kahulugan ng widget,
ngunit hindi mo gustong magpatakbo ng "moc" sa anumang ".h" na mga file na hindi gumagamit ng "Q_OBJECT" na macro.

Awtomatikong pagtukoy alin file kailangan kapangyarihan file

Maaari mong, siyempre, ilista lang ang lahat ng ".h" na file na kailangang magkaroon ng "moc" na tumakbo sa mga ito.
Kung mabilis kang gumagawa ng mga bagong widget, gayunpaman, maaaring nakakaistorbo ito
patuloy na i-update ang listahan sa makefile. Maaari mong libutin ang pangangailangan na ilista ang moc
tahasang mga module na may ganito:

MOC := $(QTDIR)/bin/moc
MODULE := kahit anong module ang mangyari na mayroon ka sa iyong programa
MOC_MODULES := $(patsubst %.h, moc_%, $(&grep -l /Q_OBJECT/ *.h))
# Ini-scan ang lahat ng .h file para sa Q_OBJECT macro.

my_program: $(MODULES).o $(MOC_MODULES).o
$(CXX) $(inputs) -o $(output)

moc_%.cxx: %.h # Ginagawa ang mga moc file mula sa mga .h na file.
$(MOC) $(input) -o $(output)

%.o: %.cxx
$(CXX) $(CXXFLAGS) -c $(input) -o $(output)

Sinusuri ng diskarteng ito ang bawat isa sa iyo .h file sa tuwing tatakbo ang makepp, hinahanap ang
"Q_OBJECT" macro. Mukhang mahal ito, ngunit malamang na hindi ito magtatagal. (Ang .h
Ang lahat ng mga file ay kailangang i-load mula sa disk sa pamamagitan ng proseso ng compilation, kaya gagawin nila
mai-cache.)

# isama ang .moc file

Ang isa pang diskarte ay ang "#include" ang output mula sa "moc" preprocessor sa iyong widget
file ng pagpapatupad. Nangangahulugan ito na kailangan mong tandaan na isulat ang "#include", ngunit mayroon ito
ang kalamangan na mayroong mas kaunting mga module upang i-compile, at sa gayon ay mas mabilis ang pagsasama-sama.
(Para sa karamihan ng C++ compilation, ang karamihan ng oras ay ginugugol sa pagbabasa ng mga file ng header, at
ang output mula sa preprocessor ay kailangang magsama ng halos kasing dami ng mga file gaya ng iyong widget
gayon pa man.) Halimbawa:

// my_widget.h
klase MyWidget : pampublikong QWidget {
Q_OBJECT
// ...
}

// my_widget.cpp

#include "my_widget.h"
#include "my_widget.moc" // my_widget.moc ay ang output mula sa
// moc preprocessor.
// Iba pang mga bagay sa pagpapatupad dito.
MyWidget::MyWidget(QWidget * parent, const char * name):
QWidget(magulang, pangalan)
{
// ...
}

Ngayon ay kailangan mong magkaroon ng panuntunan sa iyong makefile upang gawin ang lahat ng ".moc" na file, tulad nito:

MOC := $(QTDIR)/bin/moc
# Panuntunan para gumawa ng mga .moc file:
%.moc: %.h
$(MOC) $(input) -o $(output)

Ang Makepp ay sapat na matalino upang mapagtanto na kailangan nitong gawin ang "my_widget.moc" kung hindi
mayroon na, o kung ito ay luma na.

Ang pangalawang diskarte na ito ay ang karaniwang ginagamit ko dahil pinapabilis nito ang pagsasama-sama.

Pamalit para hindi na ginagamit gumawa idioms
MAKECMDGOALS

Minsan ang mga tao ay may mga panuntunan sa kanilang makefile depende sa kung anong target ang kanilang itinatayo,
gamit ang espesyal na variable na "MAKECMDGOALS". Halimbawa, minsan nakakakita ng mga bagay tulad ng
ito:

ifneq ($(paggawa ng filter, $(MAKECMDGOALS)),)
CFLAGS := -O2
iba
CFLAGS := -g
endif

Ito ay gagana nang maayos sa makepp. Gayunpaman, inirerekumenda kong huwag gumamit ng "MAKECMDGOALS" para dito
kaso (at gayundin ang GNU ay gumagawa ng manwal). Mas mahusay mong ilagay ang iyong na-optimize at
debug-compiled .o mga file sa magkakahiwalay na direktoryo, o pagbibigay sa kanila ng iba't ibang prefix o
mga suffix, o paggamit ng mga repository, upang panatilihing hiwalay ang mga ito.

Marahil ang tanging oras kung kailan mo gustong sumangguni sa "MAKECMDGOALS" ay kung ito
tumatagal ng mahabang oras upang mai-load ang iyong mga makefile, at hindi mo kailangan iyon para sa iyong "malinis" na target
(ngunit hindi mo kailangan ng malinis na target). Halimbawa,

ifneq ($(MAKECMDGOALS),malinis)
load_makefile $(wildcard **/Makeppfile)
iba
walang_implicit_load . # Pigilan ang awtomatikong paglo-load ng anumang iba pang mga makefile.
endif

$(huwad na malinis):
&rm -f $(wildcard **/*.o)

Pag-recursive gumawa sa magtayo in iba mga direktoryo

Tingnan ang "Mga tip para sa maraming direktoryo" sa makepp_cookbook.

Pag-recursive gumawa sa baguhin halaga of a nagbabago

Ang ilang mga makefile ay muling ginagamit ang kanilang mga sarili gamit ang ibang halaga ng isang variable, hal, ang debug
target sa sumusunod na makefile fragment

.PHONY: lahat ng debug

na-optimize:
$(MAKE) program na CFLAGS=-O2

debug:
$(MAKE) program na CFLAGS=-g

programa: ao bo
$(CC) $(CFLAGS) $^ -o $@

%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@

Kung nag-type ang user ng "make debug", bubuo ito ng program sa default mode na naka-enable ang debug
sa halip na may pag-optimize.

Ang isang mas mahusay na paraan upang gawin ito ay ang bumuo ng dalawang magkaibang mga programa, na may dalawang magkaibang hanay ng
object file, tulad nito:

CFLAGS := -O2
DEBUG_FLAGS := -g
MGA MODYUL := ab

programa: $(MODULES).o
$(CC) $(CFLAGS) $(input) -o $(output)

debug/program: debug/$(MODULES).o
$(CC) $(DEBUG_FLAGS) $(inputs) -o $(output)

%.o : %.c
$(CC) $(CFLAGS) -c $(input) -o $(output)

debug/%.o : %.c
$(CC) $(DEBUG_FLAGS) -c $(input) -o $(output)

$(phony debug): debug/program

Ang bentahe ng paggawa nito sa ganitong paraan ay (a) hindi mo kailangang itayo muli ang lahat kapag ikaw
lumipat mula sa debug patungo sa na-optimize at bumalik muli; (b)

Ang nasa itaas ay maaaring maisulat nang medyo mas maigsi gamit ang mga repositoryo. Ang mga sumusunod
Ang makefile ay eksaktong katumbas:

pag-debug ng repositoryo=. # Ginagawa ang debug subdirectory na parang kopya ng
# ang kasalukuyang subdirectory.
load_makefile debug CFLAGS=-g
# I-override ang CFLAGS kapag na-invoke sa debug subdirectory
CFLAGS := -O2 # Halaga ng CFLAGS kapag na-invoke sa subdirectory na ito

programa: ao bo
$(CC) $(CFLAGS) $^ -o $@

%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@

$(phony debug): debug/program
# Kung i-type ng user ang "makepp debug", bubuo
# debug/program sa halip na program.

sari-sari tip
Gaano do I magtayo isa bahagi naiiba m minsan?

Ginagawa itong mahirap gawin ng Makepp dahil ang resulta ay hindi naaayon sa mga tuntunin.
Ngunit may mga sitwasyon kung saan maaaring kailanganin mo ito, hal para mag-compile ng isang module lang
mabigat na impormasyon sa pag-debug. Maaari mong makamit ito sa dalawang hakbang sa pamamagitan ng unang pagbuo ng
dependency nang hiwalay, at pagkatapos ay ibubukod ito mula sa yugto ng link:

makepp DEBUG=3 buggy.o # Buuin ito gamit ang ibang opsyon.
makepp --dont-build=buggy.o buggy # Gamitin ito, sa kabila ng "maling" build na opsyon.

Gaano do I gumawa sigurado my output mga direktoryo umiiral?

Maaari mong tukuyin ang isang panuntunan upang buuin ang direktoryo ng output, pagkatapos ay siguraduhin na ang bawat file ay iyon
napupunta sa direktoryo ng output ay nakasalalay dito. Ngunit kadalasan ay mas madaling gawin ang isang bagay tulad nito
ito:

# Ang klasikal na paraan
dummy := $(shell test -d $(OUTPUT_DIRECTORY) || mkdir -p $(OUTPUT_DIRECTORY))
# Ito ay karaniwang mas madali kaysa sa pagpapaasa sa lahat ng mga file
# $(OUTPUT_DIRECTORY) at pagkakaroon ng panuntunan para gawin ito.
# Tandaan na dapat mong gamitin ang := sa halip na = upang pilitin ito
# execute kaagad.
# Isang alternatibong diskarte: gamit ang Perl code, OUTPUT_DIRECTORY local var
perl_begin
-d $OUTPUT_DIRECTORY o mkdir $OUTPUT_DIRECTORY;
perl_end
# Ang modernong paraan, walang ginagawa para sa mga kasalukuyang direktoryo
&mkdir -p $(OUTPUT_DIRECTORY)

Ang isa sa mga pahayag na ito ay dapat na malapit sa tuktok ng iyong makefile, upang maisakatuparan ang mga ito
bago ang anumang bagay na maaaring mangailangan ng direktoryo.

Gaano do I pilitin a utos sa isakatuparan on bawat bumuo?

Ang pinakamadaling paraan ay hindi ang paggamit ng mekanismo ng panuntunan sa lahat, ngunit simpleng upang maisagawa ito, tulad ng
ito:

dummy := $(petsa ng shell > last_build_timestamp)

O ilagay ito sa isang perl block, tulad nito:

perl_begin
system("utos na isakatuparan");
perl_end

Ang diskarte na ito ay may kawalan na ito ay isasagawa kahit na ang isang hindi nauugnay na target ay
pinapatakbo.

Ang pangalawang diskarte ay ang pagdeklara ng file bilang isang huwad na target, kahit na ito ay isang tunay na file.
Pipilitin nito ang makepp na muling isagawa ang utos na buuin ito sa bawat oras, ngunit kung ito lamang
lalabas sa listahan ng dependency ng ilang panuntunan.

Gaano do I paikliin ang ipinapakita magtayo mga utos?

Kadalasan mayroong napakaraming mga opsyon sa compilation command na kung ano ang ipinapakita sa
hindi nababasa ang screen. Maaari mong baguhin kung ano ang ipinapakita sa pamamagitan ng pagpigil sa pagpapakita ng
buong command, at pagkatapos ay tahasang i-print ang kawili-wiling bahagi ng command. ito ay
madaling i-print lamang ang nauugnay na bahagi ng command sa pamamagitan ng paggamit ng "$(filter_out )", tulad ng
ito:

ALL_CFLAGS = $(CFLAGS) $(KASAMA) $(ADDL_CXX_FLAGS) $(DEBUG_FLAGS)

%.o : %.c
@&echo $(notdir $(CC)) ... \
$(filter_out -I* $(ADDL_CXX_FLAGS), $(ALL_CFLAGS)) \
-c $(input)
@$(CC) $(ALL_CFLAGS) -c $(input) -o $(output)

(Ang "@" sa harap ng command ay pinipigilan ang pag-print ng command.)

Papayagan ka nitong makita ang karamihan sa mga kawili-wiling opsyon ngunit hindi ipapakita ang lahat ng
isama ang mga direktoryo (na kadalasan ay napakarami!). Kung ang bahagi ay interesado ka
in ay magkadikit sa iyong command, maaari mo ring gamitin ang function na "print" (na nagdaragdag ng a
newline, kaya hindi mo gusto ang ilan sa kanila):

target:
@... $(i-print ang kawili-wiling bahagi) ...

Gaano do I palitan a file sa dependencies?

Para sa ilang hindi malinaw na mga format ng file, hindi sulit na magpatupad ng scanner. Sa isang proyekto
mayroon kaming mga xml file, sabihin foobar.xml na naglalaman ng mga dependencies para sa foobar.out:


a
b
c


Nagpasya kaming sumunod sa simpleng layout na ito, kaya hindi namin kailangang i-parse ang xml. Kasama ang
builtin &sed, narito ang ginagawa namin sa tatlong simpleng pagpapalit para sa tatlong uri ng
mga linya:

%.d: %.xml
&sed 's! !$(stem).out: \\! || s! (.+) !$$1 \\! || s! !# Walang laman!' \
$(input) -o $(output)

isama ang foobar.d

Sinusubukang isama ito, gumagawa muna ng "foobar.d":

foobar.out: \
isang \
b \
c \
# Walang laman

Ang walang laman (komento lang o talagang walang laman) na linya ay iniiwasang mag-alala tungkol sa trailing
backslash. Ang isang alternatibo sa paggawa ng isang listahan ng multiline ay:

%.d: %.xml
&sed 's! !$(stem).out: \$$((! || s! !))! || s!<.+?>!!g' \
$(input) -o $(output)

isama ang foobar.d

Ito ay gumagawa ng katumbas:

foobar.out: $((
a
b
c
))

Kung mayroon kang mas kumplikadong muling pagsulat na dapat gawin, tukuyin ang isang function sa loob ng makefile o sa a
module na iyong kasama. Hal. ang hindi pagtukoy sa $_ ay lalaktawan ang mga linya ng pag-input:

sub myfilter {
ibalik ang undef $_ kung /
aking $stem = f_stem;
s! !$stem.out: \$((! || s! !))! || s!<.+?>!!g;
}

%.d: %.xml
&sed 's! !$(stem).out: \$$((! || s! !))! || s!<.+?>!!g' \
$(input) -o $(output)

isama ang foobar.d

Gumamit ng makepp_cookbook online gamit ang mga serbisyo ng onworks.net


Mga Libreng Server at Workstation

Mag-download ng Windows at Linux apps

Linux command

Ad