Forståelse af Makefile-syntaks: Almindelige problemer og løsninger (herunder 'Manglende operatør' og 'Indgangspunkt ikke fundet')

Forstaelse Af Makefile Syntaks Almindelige Problemer Og Losninger Herunder Manglende Operator Og Indgangspunkt Ikke Fundet



Ligesom en kodefil indeholder en eller flere linjer kode som indhold for at gøre det umagen værd, er den grundlæggende make-fil konstrueret ved hjælp af variabler, regler og mål. Bortset fra det er der også andre faktorer, der er nødvendige for at lave en komplet makefil uden problemer. I denne vejledning vil vi diskutere den grundlæggende makefile-syntaks og de almindelige problemer, mens vi skriver en makefil og give løsninger til at løse disse problemer.

Forståelse af Makefiles grundlæggende syntaks

For at komme i gang med oprettelsen af ​​en makefil, forklarer vi de grundlæggende egenskaber for en makefil via makefile-kodeeksemplet. Det er nødvendigt at inkludere følgende syntaksegenskaber i makefilens indhold for at få en eksekverbar fil:







Variabel s: En grundlæggende data, der lagrer objekter, der er nødvendige for at blive brugt i makefilen. Disse variabler bruges til at specificere en compiler, flag, kildefiler, objektfiler og målfiler. Inden for følgende eksempelmakefil er der i alt fem variabler, som er CXX (for at indstille en C++ compiler), CXXFLAGSc (compiler flag), TARGET (for at indstille et eksekverbart målfilnavn), SRCS (for at indstille en kildekodefil) , OBJS (til at indeholde objektfilerne, der genereres via kildekodefilen).



Mål: Et forventet output at bygge fra kilden. Det kan være en målfil eller et hvilket som helst symbolsk navn: 'alle' er standardmålet, der skal bygges via 'TARGET'-variablen, '$TARGET' afhænger af 'OBJS'-variablerne, og 'clean' target fjerner målet og objektfiler fra arbejdsmappen.



Regler og byggekommandoer: Sæt med grundlæggende instruktioner, der skal udføres for at skabe et mål fra kildefilen eller afhængigheder. For eksempel viser reglen '%.o: %.cpp', at filen med filtypen 'cpp' bruges til at oprette en objektfil med filtypen 'o', mens begge filer indeholder det samme navn. På den anden side byg kommandoen $(CXX) $(CXXFLAGS) -o $(MÅL) $(OBJS) bruges til at linke en objektfil og en ny målfil sammen. På samme måde byg kommandoen $(CXX) $(CXXFLAGS) -c $< -o $@ kompilerer kildefilen til en objektfil.





Afhængigheder: Afhængigheder er der altid, når du vil oprette en make-fil. For eksempel afhænger 'alle'-målet af 'TARGET'-variablen, mens 'TARGET' afhænger af 'OBJS'-variablen. Samtidig er 'OBJS'-variablen afhængig af kildefilen via 'SRCS'-variablen.

Kommentarer: Menneskeforståelige instruktioner bruges normalt til at forklare formålet med kodelinjen, hvis du bruger en fil efter lang tid. I den følgende make-fil bruger vi kommentarerne, der starter med '#'-tegnet til at forklare hver linje.



CXX = g++
CXXFLAGS = -std =c++ elleve -Væg
MÅL = Nyt
SRCS = main.cpp
OBJS = $ ( SRCS:.cpp=.o )
alle: $ ( MÅL )
$ ( MÅL ) : $ ( OBJS )
$ ( CXX ) $ ( CXXFLAGS ) -O $ ( MÅL ) $ ( OBJS )
% .O: % .cpp
$ ( CXX ) $ ( CXXFLAG ) -c $ < -O $ @
ren:
rm -f $ ( MÅL ) $ ( OBJS )

Fælles problemer og løsninger

Mens du skriver enhver make-fil, er det nødvendigt at overveje alle små detaljer for at få det ønskede output til sidst. Nogle almindelige problemer støder ofte på af brugere, mens de opretter en make-fil. I dette afsnit vil vi diskutere disse problemer og foreslå de mulige løsninger som følger:

1: Bruger ikke variabler

Brug af variablerne i en make-fil er et must-have, da det er nødvendigt at indstille kompilatorer, mål, kildefiler osv. Det mest almindelige problem, der kan støde på, er ikke at bruge nogen variabel i en make-fil. Sørg derfor for at bruge de essentielle variabler som CXX, CXXFLAGSc(kompilatorflag), TARGET, SRCS og OBJS i den forrige eksempelmakefil.

2: Manglende separatorproblem

Mens du skriver en make-fil, er det nødvendigt at overveje indrykningsreglerne meget opmærksomt, fordi brug af mellemrum i stedet for tabulatorer vil føre dig til et 'manglende separator'-problem under udførelsen af ​​'make'-instruktionen. For eksempel tilføjer vi mellemrummet i starten af ​​en regel på linje 13 og fjerner fanen.

$ ( MÅL ) : $ ( OBJS )
$ ( CXX ) $ ( CXXFLAG ) -O $ ( MÅL ) $ ( OBJS )

Ved udførelse af 'make'-forespørgslen får vi en 'manglende separator'-fejl på linje 13, og filen stopper med at køre. For at undgå dette problem skal du sørge for at bruge 'tab' i stedet for mellemrum.

lave

For at undgå dette problem skal du sørge for at bruge 'tab' i stedet for mellemrum som vist på følgende billede:

$ ( MÅL ) : $ ( OBJS )
$ ( CXX ) $ ( CXXFLAG ) -O $ ( MÅL ) $ ( OBJS )

3: 'Entry Point Not Found'-problem

Denne fejl opstår for det meste på grund af kildefilen og ikke på grund af makefilen, som når du savner brugen af ​​'main()'-funktionen i kildekodefilen. For eksempel erstatter vi funktionsdefinitionen main() med en simpel brugerdefineret funktionserklæring.

#include
int show ( ) {
char v;
std::cout << 'Indtast en værdi: ' ;
std::cin >> i;
std::cout << i << std::endl;
Vend tilbage 0 ;
}

Når vi udfører 'make'-instruktionen på kommandoprompten i Windows, støder vi på den 'udefinerede reference til 'WinMain''. Dette skyldes, at compileren ikke finder noget indgangspunkt for at begynde at udføre C++-filen. For at løse dette skal du erstatte 'show' med 'main'.

4: Brug af forkerte udvidelser

Nogle gange kan en bruger utilsigtet bruge de forkerte udvidelser til en kildefil, der skal bruges i makefilen. Brug af den forkerte udvidelse vil føre til køretidsfejl, dvs. ingen regel for at lave et mål. Vi opretter en make-fil for at bygge den eksekverbare og objektfil til C++-filen. I den syvende linje giver vi kildefilen 'c'-udvidelsen.

CXX := g++
CXXFLAGS := -std =c++ elleve -Væg
MÅL = nyt
SRCS = hoved.c
OBJS = $ ( SRCS:.cpp=.o )
Alle: $ ( MÅL )
$ ( MÅL ) : $ ( OBJS )

Kørsel af 'make'-instruktionen fører os til fejlen 'Ingen regel for at lave mål 'main.c''. For at undgå dette problem skal du sørge for at bruge den korrekte kildefiltype.

lave

5: Manglende afhængigheder

Mens du skriver en make-fil, bør du inkludere alle afhængigheder for en kildefil for at få det ønskede output. For eksempel bruger vores C++ kodefil filen 'myheader.h' som sin afhængighed. Derfor nævner vi det i C++ kodefilen som følger:

#include
#include 'myheader.h'
int show ( ) {
char v;
std::cout << 'Indtast en værdi: ' ;
std::cin >> i;
std::cout << i << std::endl;
Vend tilbage 0 ;
}

Indenfor makefilen ignorerer vi med vilje brugen af ​​'myheader.h'-filen inden for build-reglen, der er skrevet på linje 9.

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

Nu, mens vi bruger 'make'-instruktionen, støder vi på fejlen 'Intet at gøre for 'alle''.

lave

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

For at undgå det nævnte problem og køre kildekoden med succes skal du nævne filnavnet 'myheader.h' på den niende linje i makefilen som afbildet i det følgende:

Konklusion

I denne vejledning forklarede vi grundigt syntaksen for makefil ved hjælp af dets nødvendige indhold som variabler, build-kommandoer, regler osv. Kodeeksemplet er inkluderet for at uddybe syntaksen mere tydeligt. Til sidst diskuterede vi nogle almindelige problemer og deres løsninger, som en bruger kan støde på, mens han opretter en make-fil.