A Makefile szintaxis megértése: Gyakori problémák és megoldások (beleértve a „Hiányzó operátort” és a „Nem található belépési pontot”)

A Makefile Szintaxis Megertese Gyakori Problemak Es Megoldasok Beleertve A Hianyzo Operatort Es A Nem Talalhato Belepesi Pontot



Csakúgy, mint egy kódfájl egy vagy több kódsort tartalmaz, hogy érdemes legyen, az alap makefile változók, szabályok és célok felhasználásával készül. Ezen kívül vannak más tényezők is, amelyek szükségesek egy teljes makefile problémamentes elkészítéséhez. Ebben az útmutatóban megvitatjuk az alapvető makefile szintaxist és a makefile írása során felmerülő gyakori problémákat, és megoldásokat kínálunk ezekre a problémákra.

A Makefile alapvető szintaxisának megértése

A makefile létrehozásának megkezdéséhez elmagyarázzuk a makefile alapvető tulajdonságait a makefile kód példáján keresztül. A következő szintaktikai tulajdonságokat kell tartalmaznia a makefile tartalomban, hogy végrehajtható fájlt kapjon:







Változó s: A makefile-ban való használathoz szükséges objektumokat tároló alapadatok. Ezeket a változókat a fordító, a zászlók, a forrásfájlok, az objektumfájlok és a célfájlok megadására használják. A következő makefile-mintán belül összesen öt változó található, ezek a CXX (C++ fordító beállításához), CXXFLAGSc (fordító jelzők), TARGET (a cél végrehajtható fájlnév beállításához), SRCS (forráskódfájl beállításához). , OBJS (a forráskódfájlon keresztül generált objektumfájlok tárolására).



Célok: A forrásból felépítendő várható kimenet. Lehet célfájl vagy bármilyen szimbolikus név: az „all” az alapértelmezett cél, amelyet a „TARGET” változón keresztül kell létrehozni, a „$TARGET” az „OBJS” változóktól függ, a „clean” target pedig eltávolítja a célt és objektumfájlokat a munkakönyvtárból.



Szabályok és építési parancsok: A forrásfájlból vagy a függőségekből történő cél létrehozásához végrehajtandó alapvető utasítások készlete. Például a „%.o: %.cpp” szabály azt jelzi, hogy a „cpp” kiterjesztésű fájl egy „o” kiterjesztésű objektumfájl létrehozására szolgál, miközben mindkét fájl ugyanazt a nevet tartalmazza. Másrészt a build parancs $(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) egy objektumfájl és egy új célfájl összekapcsolására szolgál. Ugyanígy a build parancs $(CXX) $(CXXFLAGS) -c $< -o $@ a forrásfájlt objektumfájlba fordítja.





Függőségek: A függőségek mindig jelen vannak, amikor makefile-t szeretne létrehozni. Például az „összes” cél a „TARGET” változótól, míg a „TARGET” az „OBJS” változótól függ. Ugyanakkor az „OBJS” változó az „SRCS” változón keresztül a forrásfájltól függ.

Hozzászólások: Az ember számára érthető utasítások általában a kódsor céljának magyarázatára szolgálnak arra az esetre, ha egy fájlt hosszú idő után használ. A következő makefile-ben a „#” jellel kezdődő megjegyzéseket használjuk az egyes sorok magyarázatára.



CXX = g++
CXXFLAGS = -std =c++ tizenegy -Fal
TARGET = Új
SRCS = main.cpp
OBJS = $ ( SRCS:.cpp=.o )
mind: $ ( CÉL )
$ ( CÉL ) : $ ( OBJS )
$ ( évi CXX ) $ ( CXXFLAGS ) -O $ ( CÉL ) $ ( OBJS )
% .O: % .cpp
$ ( évi CXX ) $ ( CXXFLAGS ) -c $ < -O $ @
tiszta:
rm -f $ ( CÉL ) $ ( OBJS )

Gyakori problémák és megoldások

Bármilyen makefile írásakor minden apró részletet figyelembe kell venni, hogy a végén megkapjuk a kívánt kimenetet. Néhány gyakori problémával gyakran találkoznak a felhasználók makefile létrehozásakor. Ebben a részben megvitatjuk ezeket a problémákat, és javaslatokat teszünk a lehetséges megoldásokra az alábbiak szerint:

1: Nem használ változókat

A makefile-ban a változók használata kötelező, mivel ez szükséges a fordítók, a cél-, a forrásfájlok stb. beállításához. A leggyakoribb probléma, amivel találkozhatunk, az, hogy nem használunk változókat egy makefile-ban. Ezért ügyeljen arra, hogy az előző makefile-ben olyan alapvető változókat használjon, mint a CXX, CXXFLAGSc (fordítójelzők), TARGET, SRCS és OBJS.

2: Hiányzó elválasztó probléma

A makefile írásakor nagyon figyelmesen kell átgondolni a behúzási szabályokat, mert a tabulátorok helyett szóközök használata „hiányzó elválasztó” problémához vezet a „make” utasítás végrehajtása során. Például hozzáadjuk a szóközt egy szabály elejéhez a 13. sorban, és eltávolítjuk a tabulátort.

$ ( CÉL ) : $ ( OBJS )
$ ( évi CXX ) $ ( CXXFLAGS ) -O $ ( CÉL ) $ ( OBJS )

A „make” lekérdezés végrehajtásakor a 13. sorban „hiányzó elválasztó” hibát kapunk, és a fájl futása leáll. A probléma elkerülése érdekében ügyeljen arra, hogy a szóköz helyett a „tabulátort” használja.

készítsenek

A probléma elkerülése érdekében ügyeljen arra, hogy a szóközök helyett a „tabulátort” használja, ahogy az a következő képen látható:

$ ( CÉL ) : $ ( OBJS )
$ ( évi CXX ) $ ( CXXFLAGS ) -O $ ( CÉL ) $ ( OBJS )

3: „Belépési pont nem található” probléma

Ez a hiba többnyire a forrásfájl miatt következik be, nem pedig a makefile miatt, például amikor kihagyja a „main()” függvény használatát a forráskódfájlban. Például a main() függvénydefiníciót egy egyszerű, felhasználó által definiált függvénydeklarációra cseréljük.

#include
int show ( ) {
char v;
std::cout << 'Adjon meg egy értéket:' ;
std::cin >> ban ben;
std::cout << ban ben << std::endl;
Visszatérés 0 ;
}

A Windows parancssorában a „make” utasítás végrehajtása során a „WinMain definiálatlan hivatkozásával” találkozunk. Ennek az az oka, hogy a fordító nem talál belépési pontot a C++ fájl végrehajtásának megkezdéséhez. Ennek megoldásához cserélje ki a „show” szót „fő” szóra.

4: Helytelen kiterjesztések használata

Előfordulhat, hogy a felhasználó akaratlanul is rossz kiterjesztést használ a makefile-ban használandó forrásfájlhoz. A nem megfelelő kiterjesztés használata futási hibákhoz vezet, azaz nincs szabály a cél létrehozásához. Létrehozunk egy makefile-t a C++ fájl végrehajtható és objektumfájljának felépítéséhez. A hetedik sorban a forrásfájlt adjuk meg „c” kiterjesztéssel.

CXX := g++
CXXFLAGS := -std =c++ tizenegy -Fal
CÉL = új
SRCS = fő.c
OBJS = $ ( SRCS:.cpp=.o )
Mind: $ ( CÉL )
$ ( CÉL ) : $ ( OBJS )

A „make” utasítás futtatása a „No rule to make target „main.c” hibaüzenethez vezet. A probléma elkerülése érdekében ügyeljen arra, hogy a megfelelő forrásfájl-kiterjesztést használja.

készítsenek

5: Hiányzó függőségek

Makefile írása közben a kívánt kimenet eléréséhez a forrásfájl összes függőségét bele kell foglalnia. Például a C++ kódfájlunk a „myheader.h” fájlt használja függőségeként. Ezért a C++ kódfájlban a következőképpen említjük:

#include
#include „myheader.h”
int show ( ) {
char v;
std::cout << 'Adjon meg egy értéket:' ;
std::cin >> ban ben;
std::cout << ban ben << std::endl;
Visszatérés 0 ;
}

A makefile-n belül szándékosan figyelmen kívül hagyjuk a „myheader.h” fájl használatát a 9. sorban írt buildszabályon belül.

% .O: % .cpp
$ ( évi CXX ) $ ( CXXFLAGS ) -c $ < -O $ @

Most, amikor a „make” utasítást használjuk, a „Nothing to be do for all” hibaüzenettel találkozunk.

készítsenek

% .O: % .cpp myheader.h
$ ( évi CXX ) $ ( CXXFLAGS ) -c $ < -O $ @

Az említett probléma elkerülése és a forráskód sikeres futtatása érdekében említse meg a „myheader.h” fájlnevet a makefile kilencedik sorában, ahogyan az alábbiakban látható:

Következtetés

Ebben az útmutatóban alaposan elmagyaráztuk a makefile szintaxisát, felhasználva a szükséges tartalmakat, például változókat, build parancsokat, szabályokat stb. A kódpélda a szintaxis egyértelműbb kidolgozása érdekében szerepel. A végén megvitattunk néhány szokásos problémát és azok megoldásait, amelyekkel a felhasználó találkozhat makefile létrehozásakor.