Hoe Makefiles de GCC-compilatie automatiseren en u tijd besparen

10

Het herhaaldelijk uittypen van lange gcc -opdrachten is pijnlijk. Het wordt nog erger als je voortdurend bibliotheken toevoegt of code aanpast. Makefiles repareren dit. Ze automatiseren het bouwproces, zodat u niet langer steeds dezelfde opdrachten hoeft te typen.

Hier is een eenvoudig Makefile-voorbeeld. Het vervangt een handmatige compilatiereeks.

Sla dit op in een bestand met de naam makefile. Voer make uit om het uitvoerbare bestand te bouwen. Er is één strikte regel. U moet vóór elke gcc -regel een tabteken gebruiken. Acht spaties zullen mislukken. De build-tool zal het afwijzen. Alle andere lijnen moeten aan de linkermarge beginnen.

Afhankelijkheden begrijpen

Een Makefile heeft twee soorten lijnen. Lijnen die links liggen zijn afhankelijkheidslijnen. Ze definiëren relaties tussen bestanden. Lijnen met tabbladen zijn uitvoerbare opdrachten. Dit kunnen alle geldige UNIX-opdrachten zijn.

Neem deze regel:
main.o: main.c util.h

Dit zegt dat main.o afhankelijk is van main.c en util.h. Als een van beide bronbestanden verandert, wordt de onderstaande opdracht uitgevoerd. Het herschept main.o.

De eerste regel in het bestand is speciaal. Het definieert het uiteindelijke doel. In dit geval is dat het uitvoerbare bestand ‘main’. Het vermeldt main.o en util.o als afhankelijkheden. Als deze objectbestanden nieuwer zijn dan de bron, bouwt Make ze opnieuw op. Vervolgens worden ze gekoppeld aan het uiteindelijke binaire bestand.

Deze opdracht wordt alleen uitgevoerd als de afhankelijkheden veranderen. Als er niets verandert, doet Make niets. Dat is het kernvoordeel. Het slaat werk over dat al gedaan is.

Waarom dit belangrijk is voor uw workflow

Grote programma’s hebben veel bibliotheken en bronbestanden. Het bijhouden welke bestanden handmatig zijn gewijzigd, is foutgevoelig. Een Makefile handelt dit automatisch af. Het hercompileert alleen wat nodig is. U wijzigt één headerbestand. Maak een herbouw van elk bronbestand dat het bevat. Je wijzigt een nutsfunctie. Maak alleen dat objectbestand opnieuw en koppel het uitvoerbare bestand opnieuw.

U hoeft niet op een UNIX-systeem te werken om deze logica te gebruiken. De meeste moderne compilers en IDE’s bevatten vergelijkbare functies. Controleer de documentatie van uw compiler. Zoek naar tools voor bouwautomatisering. Onder de motorkap werken ze op dezelfde manier.

Dit brengt ons terug bij headers als stdio.h. Je hebt ze in eerdere voorbeelden opgenomen zonder uit te leggen waarom. Het zijn standaardbibliotheken. Iemand heeft ze jaren geleden geschreven. Ze hebben ze beschikbaar gesteld om te voorkomen dat u basisfuncties opnieuw uitvindt. Makefiles en standaardbibliotheken maken deel uit van dezelfde filosofie. Ze laten je focussen op logica in plaats van standaard.

De tool is slechts zo goed als de regels ervan. Als uw afhankelijkheden verkeerd zijn, zal Make er niet in slagen om opnieuw op te bouwen wat het zou moeten doen. Of erger nog, het zal verouderde code bouwen. Controleer uw tabbladtekens. Controleer uw bestandsnamen. Zorg dat de syntaxis goed is en de compiler doet het zware werk.

Je vraagt ​​je misschien af ​​of handmatige compilatie ooit sneller is. Voor een enkel bestand misschien. Maar zodra u een header aanraakt in een project met meerdere bestanden, verliest de handmatige methode. Je begint opdrachten te kopiëren. Je begint typefouten te maken. Je begint je af te vragen waarom main.o niet is bijgewerkt.

De verschuiving van het typen van opdrachten naar het definiëren van regels is de echte winst. Jij definieert de staat. De tool dwingt de overgangen af. Het is een kleine verandering in gewoonte. Het loont de moeite bij elke volgende build.