Johdanto

C-ohjelmointi, ohjelma on usein jaettu useita lähdetiedostoja ja otsikko tiedostoja parantaa organisaatiota, uudelleenkäytettävyyttä, ja koostenopeus. Kuitenkin, tämä modulaarisuus tuo haaste: kun otsikko tiedosto muuttuu, jokainen lähdekoodi tiedosto, joka sisältää sen on koodattava. Tämän tekeminen käsin on virhe-altis ja aikaa vievä. Makefiles, jonka ohjaa []make[] rakentaa automaatiotyökalu, ratkaista tämän ongelman koodaamalla riippuvuussuhteet ja automatisoimalla rakennusprosessi. Makefiles on riitti kulkua tahansa vakava C kehittäjä, mutta monet uudet tulokkaat kohtelevat niitä mustat laatikot. Tämä artikkeli selittää, miten riippuvuus toimii Makefiles, miten luoda ne automaattisesti, ja miten rakentaa Makefile luotettavuutta ja nopeutta.

Mitä Makefiles on?

Makefile on helppo tekstitiedosto, joka määrittelee joukon sääntöjä projektin rakentamiseen. [make[ apuohjelma lukee nämä säännöt, tarkistaa tiedoston aikaleimat ja suorittaa vain tarvittavat komennot hankkeen saattamiseksi ajan tasalle. Perusidea on yksinkertainen: jokaisella säännöllä on [tavoite[ (tiedosto, jota on tarkoitus tuottaa), ]-vaatimukset [] (tiedostot, joita tarvitaan kohteen rakentamiseen) ja -määräykset[] (hellin komentoja). Nauhoittamalla ne tiedostot, jotka riippuvat -muodossa]-muodossa olevasta aineistosta [] voidaan rakentaa uudelleen vain ne osat, jotka ovat muuttuneet.

Makefiles on ollut osa Unix 1970-luvulta lähtien, ja GNU Make on de facto standardi Linux ja MacOS. Syntaksi on tiivis, mutta voi olla hienovarainen; saada riippuvuussuhteita oikea on ensisijainen taito C kehittäjä tarvitsee.

Riippuvuussuhteiden ymmärtäminen

C-projektissa riippuvuussuhteet eivät rajoitu [-tiedostoihin. Jokaiseen lähdetiedostoon sisältyy yksi tai useampi otsikkotiedosto (esim. ). Jos otsikkoa muutetaan, kaikki -tiedostot, jotka sisältävät sen, on koottava uudelleen. Vastaavasti objektitiedostot riippuvat vastaavista tiedostoista ja lopullinen suoritustiedosto riippuu kaikista objektitiedostoista.

Eksplicit vs Implisiittiset riippuvuudet

Alkuaikojen Makefile-tiedostoissa ohjelmoijat listasivat kaikki ehdot manuaalisesti. Tämä lähestymistapa on hauras: otsikon unohtaminen tarkoittaa hiljaa rakentumista, samalla kun liian monet niistä laukaisee tarpeettomia rekomplikaatioita. Vielä pahempaa on, että projektin kasvaessa manuaalilistat eivät enää ole ylläpidettävissä. Modernin ratkaisuna on, että kääntäjä luo riippuvuussuhteet automaattisesti, jolloin ne muuttuvat implisiittisiksi, konetarkistetuiksi ennakko-olosuhteiksi.

Hyvin suunniteltu Makefile käsittelee riippuvuuksia ensiluokkaisena huolenaiheena. Tavoitteena ei ole koskaan rakentaa uudelleen mitään sellaista, mikä ei tarvitse jälleenrakentamista, ja rakentaa aina uudelleen kaikki, mikä tekee. Tämä on korjaus [] ja [] tehokkuus[]] olemus lisärakentamisessa.

Makefile-tiedoston perusrakenne

Tyypillinen Makefile sisältää vaihtelevia määritelmiä, sääntöjä ja väärennettyjä tavoitteita. Tässä on minimaalinen mutta toimiva esimerkki projektista, jossa ja :

CC = gcc
CFLAGS = -Wall -Wextra -O2

main: main.o utils.o
 $(CC) $(CFLAGS) -o main main.o utils.o

main.o: main.c
 $(CC) $(CFLAGS) -c main.c

utils.o: utils.c
 $(CC) $(CFLAGS) -c utils.c

clean:
 rm -f main main.o utils.o

Tällä Makefile-tiedostolla on neljä tavoitetta: (toteutettava tiedosto), kaksi objektitiedostoa ja valekohde . Riippuvuuslinjat paksusuolen jälkeen kertovat []make[], jotka tiedostot on tarkistettava ennen kuin päätetään rakentaa kohde uudelleen.

Valekohteet

tai eivät edusta tiedostoja. Jotta []make[] ei sekoittaisi niitä tiedostonimiin, ne olisi ilmoitettava [] fonyyiksi[[]]:

.PHONY: clean all

Jos -niminen tiedosto olisi olemassa, make[ pitäisi sitä ajan tasalla ja jättäisi reseptin väliin.

Riippuvuussuhteiden hallinta tehokkaasti

Manuaalinen Makefile-tiedosto on vakava vika: n riippuvuus :sta on oikea, mutta entä otsikot? Jos :n muutokset []: (joka sisältää sen) on rakennettava uudelleen, kuitenkin sääntö sanoo sen riippuvan vain :sta. Korjauksena on antaa kääntäjän tuottaa todellinen riippuvuusluettelo.

Automaattinen riippuvuus Generation GCC

GCC (ja Clang) voi tuottaa riippuvuutta koskevia tietoja käyttäen lippuperhettä. Käytännöllisin yhdistelmä useimmissa hankkeissa on :

  • [[] ......................................................................................................................................................................................................................................
  • [[ ] .] .
  • [[] . . . lisää valekohteet jokaiselle otsikolle, jolloin vältetään virheet, kun otsikko poistetaan.

Tässä... Miten liittää automaattinen riippuvuus seuranta Makefile:

CC = gcc
CFLAGS = -Wall -Wextra -O2 -MMD -MP
SRCDIR = src
OBJDIR = obj
SRCS = $(wildcard $(SRCDIR)/*.c)
OBJS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SRCS))
DEPS = $(OBJS:.o=.d)

all: myprogram

myprogram: $(OBJS)
 $(CC) $(CFLAGS) -o $@ $^

$(OBJDIR)/%.o: $(SRCDIR)/%.c
 @mkdir -p $(OBJDIR)
 $(CC) $(CFLAGS) -c $< -o $@

-include $(DEPS)

.PHONY: all clean
clean:
 rm -rf $(OBJDIR) myprogram

Selitys:

  • kerää kaikki ] lähdehakemistoon sisältyvät tiedostot.
  • muuttaa ne objektitiedostopoluksi.
  • luetellaan huoltotodisteet (esim. ).
  • -sääntö kokoaa jokaisen -tiedoston ja -säännön vuoksi luo -tiedoston sivuvaikutuksena.
  • Linja lukee luodut tiedostot, jotka muuttavat ne todellisiksi Makefile-edellytyksiksi. Viiva () estää virheet, kun -tiedostoja ei vielä ole (esim. ensimmäisessä rakennuksessa).

Jos on muutettu, n seuraava kutsumus on automaattisesti , koska -tiedosto sisältää :n ennakkoedellytyksenä.

Kehittyneet tekniikat

Luotujen riippuvuuksien käsittely turvallisesti

Kun otsikko poistetaan, -tiedosto voi silti viitata siihen, jolloin []make[[]] epäonnistuu puuttuvassa tavoitevirheessä. []-lippu osoittaa tämän lisäämällä tyhjät väärennetyt säännöt jokaiselle huolto-otsikkoriville. Jos otsikko on poissa, [-merkki yksinkertaisesti toimii väärällä säännöllä (mikä ei tee mitään) ja jatkuu.

Sisältää riippuvuustiedostot lähdekoodin muutosten jälkeen

Yksi hienovaraisuus: jos lähdetiedosto lisää tai poistaa , vastaava ] tiedosto on regeneroitava. Koska [] tiedosto on itse objektitiedoston ennakkoehto, []make[] Huomaa muuttunut aikaleima ja rekomplikaatio, joka uudistaa -tiedoston. Tämä rekursio toimii automaattisesti, kun ensimmäinen rakennus on valmis.

Tilauksen käyttäminen - vain ennakkoopinnot

Joskus tarvitaan hakemisto, joka on olemassa ennen rakentamista, mutta et halua sen aikaleiman laukaisevan uudelleenrakentamista. Se on [-tilaus-vain edellytykset[] (erillinen []). Yllä olevassa kaavasäännössä käytimme [] sisällä reseptiä; vaihtoehto on:

$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
 $(CC) $(CFLAGS) -c $< -o $@

$(OBJDIR):
 mkdir -p $@

Tämä varmistaa hakemiston luomisen ennen mitään kokoelmaa, mutta itse hakemiston muuttaminen (esim. uusi tiedosto sisällä) ei käynnistä uudelleenkommentointia.

Parhaat käytännöt riippuvuuden hallintaan

  1. Käytä automaattista riippuvuus sukupolven päivästä alkaen.[] Jopa yhden tiedoston projektin se on hyvä tapa. Se ei maksa mitään ja estää tulevia virheitä.
  2. Pidä riippuvuustiedostot erillään lähdetiedostoista.[] Laita ne tai []-hakemistoon. Tämä helpottaa puhdistusta ja välttää lähdepuun sotkemista.
  3. ] Sisältää luodut tiedostot niiden muodostavien sääntöjen jälkeen.[[] ] direktiivi on hyvä, mutta sen asettaminen kaavasäännön jälkeen varmistaa, että [make[] tietää ensin, miten objektitiedostoja rakennetaan ennen kuin -tiedostojen lukemista.
  4. ]Käytä vääriä siivouskohteita.[ , , ja ovat yleisiä.
  5. Vahvimuuttujat kääntäjän liput, lähdehakemistot ja luettelot tiedostoja.[ Tämä tekee Makefile uudelleenkäytettäväksi eri projekteissa ja helpompi muokata.
  6. Testaa Makefileesi tarkoituksellisella otsikon muutoksella.[[] Muokkaa otsikkoa, suorita [] ja vahvista vain ne kohdetiedostot, joihin asia vaikuttaa, on koottu uudelleen. Jos täydellinen uudelleenrakennettu tapahtuu, riippuvuusseurannassa on jotain vikaa.
  7. Keep the Makefile simple but not simple than necessary.[] Yli-insinöörin kanssa kehittyneet toiminnot kuten ] voi tehdä vianetsintä tuskallista. Aloita kuviosta tässä artikkelissa; se asteikot hyvin kymmeniä tiedostoja.

Ulkoiset resurssit

Syventääksesi ymmärrystäsi, tutustu näihin arvovaltaisiin viitetietoihin:

Päätelmä

C-ohjelman riippuvuuden hallinta Makefiles-tiedostoilla ei ole ylellisyyttä vaan välttämättömyys kaikille hankkeille, jotka ylittävät yhden tiedoston. Yhdistämällä kuviosäännöt, automaattinen riippuvuustuotanto [], ja huolellisesti luotujen []-tiedostojen sisällyttäminen, voit luoda sekä nopean että oikean rakennusjärjestelmän. Tässä esitetyt tekniikat poistavat manuaalisen seurannan, vähentävät rakennusaikoja ja estävät stalt-tiedostojen aiheuttamia hienovaraisia vikoja. Kun olet sisäistänyt nämä mallit, et koskaan kirjoita manuaalista riippuvuuslistaa. Sijoitukset oppimiseen kun oikea riippuvuus hallinta maksaa pois joka kerta kun juoksu ja katselet vain muutettujen tiedostojen kokoamista.