Înțelegerea sintaxei Makefile: probleme comune și soluții (inclusiv „Operator lipsă” și „Punctul de intrare nu a fost găsit”)

Intelegerea Sintaxei Makefile Probleme Comune Si Solutii Inclusiv Operator Lipsa Si Punctul De Intrare Nu A Fost Gasit



La fel cum un fișier de cod conține una sau mai multe linii de cod ca conținut pentru a-l face util, fișierul de bază este construit folosind variabile, reguli și ținte. În afară de asta, există și alți factori care sunt necesari pentru a face un makefile complet fără probleme. În acest ghid, vom discuta despre sintaxa de bază makefile și problemele comune în timpul scrierii unui makefile și vom oferi soluții pentru a rezolva aceste probleme.

Înțelegerea sintaxei de bază Makefile

Pentru a începe cu crearea unui makefile, explicăm proprietățile de bază ale unui makefile prin exemplul de cod makefile. Este necesar să includeți următoarele proprietăți de sintaxă în conținutul makefile pentru a obține un fișier executabil:







Variabil s: O bază de date care stochează obiecte care sunt necesare pentru a fi utilizate în fișierul make. Aceste variabile sunt utilizate pentru a specifica un compilator, steaguri, fișiere sursă, fișiere obiect și fișiere țintă. În următorul exemplu de fișier make, există un total de cinci variabile care sunt CXX (pentru a seta un compilator C++), CXXFLAGSc (steaguri compilatorului), TARGET (pentru a seta un nume de fișier executabil țintă), SRCS (pentru a seta un fișier cu cod sursă) , OBJS (pentru a conține fișierele obiect care sunt generate prin fișierul codului sursă).



Ținte: O ieșire așteptată de construit din sursă. Poate fi un fișier țintă sau orice nume simbolic: „toate” este ținta implicită care ar trebui construită prin variabila „TARGET”, „$TARGET” depinde de variabilele „OBJS”, iar ținta „curată” elimină ținta și fișiere obiect din directorul de lucru.



Reguli și comenzi de construcție: Set de instrucțiuni de bază care trebuie executate pentru a crea o țintă din fișierul sursă sau dependențe. De exemplu, regula „%.o: %.cpp” arată că fișierul cu extensia „cpp” este folosit pentru a crea un fișier obiect cu extensia „o”, în timp ce ambele fișiere conțin același nume. Pe de altă parte, comanda build $(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) este utilizat pentru a lega un fișier obiect și un fișier țintă nou împreună. În același mod, comanda build $(CXX) $(CXXFLAGS) -c $< -o $@ compilează fișierul sursă într-un fișier obiect.





Dependente: Dependențe sunt întotdeauna acolo când doriți să creați un makefile. De exemplu, ținta „toate” depinde de variabila „TARGET”, în timp ce „TARGET” depinde de variabila „OBJS”. În același timp, variabila „OBJS” depinde de fișierul sursă prin variabila „SRCS”.

Comentarii: Instrucțiunile pe înțelesul uman sunt de obicei folosite pentru a explica scopul liniei de cod în cazul în care utilizați un fișier după o lungă perioadă de timp. În următorul makefile, folosim comentariile care încep cu semnul „#” pentru a explica fiecare linie.



CXX = g++
CXXFLAGS = -std =c++ unsprezece -Perete
ȚINTĂ = Nou
SRCS = main.cpp
OBJS = $ ( SRCS:.cpp=.o )
toate: $ ( ŢINTĂ )
$ ( ŢINTĂ ) : $ ( OBJS )
$ ( CXX ) $ ( CXXFLAGS ) -O $ ( ŢINTĂ ) $ ( OBJS )
% .O: % .cpp
$ ( CXX ) $ ( CXXFLAGS ) -c $ < -O $ @
curat:
rm -f $ ( ŢINTĂ ) $ ( OBJS )

Probleme comune și soluții

Când scrieți orice makefile, este necesar să luați în considerare fiecare detaliu minor pentru a obține rezultatul dorit la sfârșit. Unele probleme comune sunt întâlnite frecvent de utilizatori în timpul creării unui makefile. În această secțiune, vom discuta aceste probleme și vom sugera soluții posibile, după cum urmează:

1: Nu se utilizează variabile

Utilizarea variabilelor într-un makefile este o necesitate, deoarece este necesară pentru a seta compilatoare, țintă, fișiere sursă etc. Cea mai frecventă problemă care poate fi întâlnită este să nu folosiți nicio variabilă într-un makefile. Prin urmare, asigurați-vă că utilizați variabilele esențiale, cum ar fi CXX, CXXFLAGSc (steaguri compilatorului), TARGET, SRCS și OBJS în exemplul de fișier anterior.

2: Problemă cu separatorul lipsă

În timp ce scrieți un fișier make, este necesar să luați în considerare foarte atent regulile de indentare, deoarece utilizarea spațiilor în loc de file vă va duce la o problemă de „separator lipsă” în timpul execuției instrucțiunii „make”. De exemplu, adăugăm spațiul la începutul unei reguli la linia 13 și eliminăm fila.

$ ( ŢINTĂ ) : $ ( OBJS )
$ ( CXX ) $ ( CXXFLAGS ) -O $ ( ŢINTĂ ) $ ( OBJS )

La executarea interogării „make”, obținem o eroare „lipsing separator” la linia 13, iar fișierul se oprește. Pentru a evita această problemă, asigurați-vă că utilizați „tab” în loc de spații.

face

Pentru a evita această problemă, asigurați-vă că utilizați „tab” în loc de spații, așa cum este prezentat în următoarea imagine:

$ ( ŢINTĂ ) : $ ( OBJS )
$ ( CXX ) $ ( CXXFLAGS ) -O $ ( ŢINTĂ ) $ ( OBJS )

3: Problemă „Punctul de intrare nu a fost găsit”.

Această eroare apare în principal din cauza fișierului sursă și nu din cauza fișierului make, cum ar fi atunci când ratați utilizarea funcției „main()” în fișierul codului sursă. De exemplu, înlocuim definiția funcției main() cu o declarație simplă de funcție definită de utilizator.

#include
int show ( ) {
char v;
std::cout << 'Introduceți o valoare: ' ;
std::cin >> în;
std::cout << în << std::endl;
întoarcere 0 ;
}

La executarea instrucțiunii „make” din promptul de comandă din Windows, întâlnim „referința nedefinită la „WinMain””. Acest lucru se datorează faptului că compilatorul nu găsește niciun punct de intrare pentru a începe executarea fișierului C++. Pentru a rezolva acest lucru, înlocuiți „show” cu „principal”.

4: Utilizarea extensiilor incorecte

Uneori, un utilizator poate folosi în mod neintenționat extensiile greșite pentru un fișier sursă care urmează să fie utilizat în fișierul make. Folosirea unei extensii greșite va duce la erori de rulare, adică nicio regulă pentru a face o țintă. Creăm un makefile pentru a construi fișierul executabil și obiect pentru fișierul C++. În a șaptea linie, oferim fișierului sursă extensia „c”.

CXX := g++
CXXFLAGS := -std =c++ unsprezece -Perete
ȚINTĂ = nou
SRCS = principal.c
OBJS = $ ( SRCS:.cpp=.o )
Toate: $ ( ŢINTĂ )
$ ( ŢINTĂ ) : $ ( OBJS )

Rularea instrucțiunii „make” ne duce la eroarea „Fără regulă pentru a face ținta „main.c””. Pentru a evita această problemă, asigurați-vă că utilizați extensia corectă a fișierului sursă.

face

5: Lipsesc dependențe

În timp ce scrieți un fișier make, ar trebui să includeți toate dependențele pentru un fișier sursă pentru a obține rezultatul dorit. De exemplu, fișierul nostru de cod C++ folosește fișierul „myheader.h” ca dependență. Prin urmare, îl menționăm în fișierul de cod C++ după cum urmează:

#include
#include „myheader.h”
int show ( ) {
char v;
std::cout << 'Introduceți o valoare: ' ;
std::cin >> în;
std::cout << în << std::endl;
întoarcere 0 ;
}

În cadrul makefile, ignorăm în mod intenționat utilizarea fișierului „myheader.h” în cadrul regulii de compilare care este scrisă la linia 9.

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

Acum, în timp ce folosim instrucțiunea „make”, întâlnim eroarea „Nimic de făcut pentru „toți””.

face

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

Pentru a evita problema menționată și a rula codul sursă cu succes, menționați numele fișierului „myheader.h” la a noua linie a fișierului make, așa cum este descris în următoarele:

Concluzie

În acest ghid, am explicat în detaliu sintaxa makefile folosind conținutul necesar, cum ar fi variabile, comenzi de compilare, reguli etc. Exemplul de cod este inclus pentru a elabora sintaxa mai clar. La final, am discutat câteva probleme obișnuite și soluțiile acestora pe care un utilizator le poate întâlni în timpul creării unui makefile.