Makefile-syntaxis begrijpen: veelvoorkomende problemen en oplossingen (waaronder ‘Ontbrekende operator’ en ‘Ingangspunt niet gevonden’)

Makefile Syntaxis Begrijpen Veelvoorkomende Problemen En Oplossingen Waaronder Ontbrekende Operator En Ingangspunt Niet Gevonden



Net zoals een codebestand een of meer regels code als inhoud bevat om het de moeite waard te maken, wordt het basismakefile opgebouwd met behulp van variabelen, regels en doelen. Daarnaast zijn er nog andere factoren die nodig zijn om zonder problemen een compleet makefile te maken. In deze handleiding bespreken we de basissyntaxis van makefile en de veelvoorkomende problemen bij het schrijven van een makefile en bieden we oplossingen om deze problemen op te lossen.

De Makefile Basic-syntaxis begrijpen

Om aan de slag te gaan met het maken van een makefile, leggen we de basiseigenschappen van een makefile uit via het makefile-codevoorbeeld. Het is noodzakelijk om de volgende syntaxiseigenschappen in de makefile-inhoud op te nemen om een ​​uitvoerbaar bestand te krijgen:







Variabel s: Basisgegevens waarin objecten worden opgeslagen die nodig zijn om in het makefile te worden gebruikt. Deze variabelen worden gebruikt om een ​​compiler, vlaggen, bronbestanden, objectbestanden en doelbestanden te specificeren. Binnen het volgende voorbeeld van een makefile zijn er in totaal vijf variabelen: CXX (om een ​​C++-compiler in te stellen), CXXFLAGSc (compilervlaggen), TARGET (om de naam van een uitvoerbaar doelbestand in te stellen), SRCS (om een ​​broncodebestand in te stellen) , OBJS (om de objectbestanden te bevatten die zijn gegenereerd via het broncodebestand).



Doelstellingen: Een verwachte uitvoer die vanuit de bron moet worden opgebouwd. Het kan een doelbestand zijn of een willekeurige symbolische naam: “all” is het standaarddoel dat moet worden gebouwd via de “TARGET”-variabele, “$TARGET” hangt af van de “OBJS”-variabelen, en “clean” target verwijdert het doel en objectbestanden uit de werkmap.



Regels en build-opdrachten: Set basisinstructies die moeten worden uitgevoerd om een ​​doel te maken op basis van het bronbestand of de afhankelijkheden. De regel “%.o: %.cpp” geeft bijvoorbeeld aan dat het bestand met de extensie “cpp” wordt gebruikt om een ​​objectbestand met de extensie “o” te maken, terwijl beide bestanden dezelfde naam hebben. Aan de andere kant het build-commando $(CXX) $(CXXFLAGS) -o $(DOEL) $(OBJS) wordt gebruikt om een ​​objectbestand en een nieuw doelbestand aan elkaar te koppelen. Op dezelfde manier, het build-commando $(CXX) $(CXXFLAGS) -c $< -o $@ compileert het bronbestand in een objectbestand.





Afhankelijkheden: Afhankelijkheden zijn er altijd als u een makefile wilt maken. Het doel “all” is bijvoorbeeld afhankelijk van de variabele “TARGET”, terwijl het doel “TARGET” afhangt van de variabele “OBJS”. Tegelijkertijd is de variabele “OBJS” via de variabele “SRCS” afhankelijk van het bronbestand.

Opmerkingen: Voor mensen begrijpelijke instructies worden meestal gebruikt om het doel van de coderegel uit te leggen voor het geval u een bestand na lange tijd gebruikt. In het volgende makefile gebruiken we het commentaar dat begint met het “#”-teken om elke regel uit te leggen.



CXX = g++
CXXFLAGS = -soa =c++ elf -Muur
DOEL = Nieuw
SRCS = hoofd.cpp
OBJS = $ ( SRCS:.cpp=.o )
alles: $ ( DOEL )
$ ( DOEL ) : $ ( OBJS )
$ ( CXX ) $ ( CXXVLAGS ) -O $ ( DOEL ) $ ( OBJS )
% .O: % .cpp
$ ( CXX ) $ ( CXXVLAGS ) -C $ < -O $ @
schoon:
rm -F $ ( DOEL ) $ ( OBJS )

Veelvoorkomende problemen en oplossingen

Bij het schrijven van een makefile is het noodzakelijk om elk klein detail in overweging te nemen om uiteindelijk de gewenste uitvoer te krijgen. Een aantal veelvoorkomende problemen komen gebruikers vaak tegen bij het maken van een makefile. In dit gedeelte zullen we deze problemen bespreken en de mogelijke oplossingen als volgt voorstellen:

1: Geen variabelen gebruiken

Het gebruik van de variabelen in een makefile is een must-have omdat het vereist is om de compilers, het doel, de bronbestanden, enz. in te stellen. Het meest voorkomende probleem dat kan optreden is het niet gebruiken van een variabele in een makefile. Zorg er daarom voor dat u de essentiële variabelen zoals CXX, CXXFLAGSc (compilervlaggen), TARGET, SRCS en OBJS gebruikt in het vorige voorbeeld van een makefile.

2: Probleem met ontbrekend scheidingsteken

Bij het schrijven van een makefile is het noodzakelijk om zeer aandachtig te letten op de inspringingsregels, omdat het gebruik van spaties in plaats van tabs ertoe kan leiden dat u tijdens de uitvoering van de make-instructie een “ontbrekend scheidingsteken” krijgt. We voegen bijvoorbeeld de spatie aan het begin van een regel toe op regel 13 en verwijderen het tabblad.

$ ( DOEL ) : $ ( OBJS )
$ ( CXX ) $ ( CXXVLAGS ) -O $ ( DOEL ) $ ( OBJS )

Bij het uitvoeren van de “make”-query krijgen we een “missing separator”-fout op regel 13 en stopt het bestand met draaien. Om dit probleem te voorkomen, moet u 'tab' gebruiken in plaats van spaties.

maken

Om dit probleem te voorkomen, zorg ervoor dat u “tab” gebruikt in plaats van spaties, zoals weergegeven in de volgende afbeelding:

$ ( DOEL ) : $ ( OBJS )
$ ( CXX ) $ ( CXXVLAGS ) -O $ ( DOEL ) $ ( OBJS )

3: Probleem “Ingangspunt niet gevonden”.

Deze fout treedt meestal op vanwege het bronbestand en niet vanwege het makefile, zoals wanneer u het gebruik van de functie “main()” in het broncodebestand mist. We vervangen bijvoorbeeld de functiedefinitie main() door een eenvoudige, door de gebruiker gedefinieerde functiedeclaratie.

#include
int tonen ( ) {
teken v;
std::uit << 'Voer een waarde in: ' ;
std::cin >> in;
std::uit << in << std::endl;
opbrengst 0 ;
}

Bij het uitvoeren van de ‘make’-instructie op de opdrachtprompt van Windows komen we de ‘ongedefinieerde verwijzing naar ‘WinMain’ tegen. Dit komt omdat de compiler geen enkel startpunt vindt om het C++-bestand uit te voeren. Om dit op te lossen, vervangt u “show” door “main”.

4: Gebruik van onjuiste extensies

Soms kan een gebruiker onbedoeld de verkeerde extensies gebruiken voor een bronbestand dat in het makefile moet worden gebruikt. Het gebruik van de verkeerde extensie zal leiden tot runtimefouten, d.w.z. geen regel om een ​​doel te maken. We maken een makefile om het uitvoerbare bestand en het objectbestand voor het C++-bestand te bouwen. In de zevende regel geven we het bronbestand de extensie “c”.

CXX := g++
CXXVLAGS := -soa =c++ elf -Muur
DOEL = nieuw
SRCS = hoofd.c
OBJS = $ ( SRCS:.cpp=.o )
Alles: $ ( DOEL )
$ ( DOEL ) : $ ( OBJS )

Het uitvoeren van de “make” -instructie leidt ons naar de fout “Geen regel om doel ‘main.c’ te maken”. Om dit probleem te voorkomen, moet u ervoor zorgen dat u de juiste bronbestandsextensie gebruikt.

maken

5: Ontbrekende afhankelijkheden

Terwijl u een makefile schrijft, moet u alle afhankelijkheden voor een bronbestand opnemen om de gewenste uitvoer te krijgen. Ons C++-codebestand gebruikt bijvoorbeeld het bestand “myheader.h” als afhankelijkheid. Daarom vermelden we het als volgt in het C++-codebestand:

#include
#include “mijnheader.h”
int tonen ( ) {
teken v;
std::uit << 'Voer een waarde in: ' ;
std::cin >> in;
std::uit << in << std::endl;
opbrengst 0 ;
}

Binnen de makefile negeren we opzettelijk het gebruik van het bestand “myheader.h” binnen de build-regel die op regel 9 is geschreven.

% .O: % .cpp
$ ( CXX ) $ ( CXXVLAGS ) -C $ < -O $ @

Nu we de instructie ‘make’ gebruiken, komen we de fout ‘Niets te doen voor ‘alles’ tegen.

maken

% .O: % .cpp mijnheader.h
$ ( CXX ) $ ( CXXVLAGS ) -C $ < -O $ @

Om het genoemde probleem te voorkomen en de broncode succesvol uit te voeren, vermeldt u de bestandsnaam “myheader.h” op de negende regel van het makefile, zoals hieronder weergegeven:

Conclusie

In deze handleiding hebben we de syntaxis van makefile grondig uitgelegd met behulp van de noodzakelijke inhoud zoals variabelen, build-opdrachten, regels, enz. Het codevoorbeeld is opgenomen om de syntaxis duidelijker uit te werken. Uiteindelijk hebben we enkele reguliere problemen en hun oplossingen besproken die een gebruiker kan tegenkomen tijdens het maken van een makefile.