Ik heb een makefile als volgt opgebouwd:
all :
compile executable
clean :
rm -f *.o $(EXEC)
Ik realiseerde me dat ik constant “make clean” uitvoerde gevolgd door “clear” in mijn terminal voordat ik “make all” uitvoerde. Ik heb graag een schone terminal voordat ik vervelende C++-compilatiefouten probeer te doorzoeken. Dus ik probeerde een derde doel toe te voegen:
fresh :
rm -f *.o $(EXEC)
clear
make all
Dit werkt, maar dit voert een tweede exemplaar van make uit (denk ik). Is er een juiste manier om dezelfde functionaliteit te krijgen zonder een tweede exemplaar van make uit te voeren?
Antwoord 1, autoriteit 100%
Eigenlijk heb je gelijk: het voert een ander exemplaar van make uit.
Een mogelijke oplossing zou zijn:
.PHONY : clearscr fresh clean all
all :
compile executable
clean :
rm -f *.o $(EXEC)
fresh : clean clearscr all
clearscr:
clear
Door make fresh
aan te roepen, krijg je eerst het doel clean
, dan het clearscreen
dat clear
uitvoert en tenslotte all
die het werk doen.
BEWERK 4 aug.
Wat gebeurt er in het geval van parallelle builds met de -j
optie van make?
Er is een manier om de bestelling vast te leggen. Uit de handleiding van het merk, sectie 4.2:
Soms heb je echter een situatie waarin je een specifieke volgorde wilt opleggen aan de regels die moeten worden aangeroepen zonder dat het doel moet worden bijgewerkt als een van die regels wordt uitgevoerd. In dat geval wilt u voorwaarden voor alleen bestellen definiëren. Vereisten voor alleen bestellen kunnen worden gespecificeerd door een pijpsymbool (|) in de lijst met vereisten te plaatsen: eventuele vereisten links van het pijpsymbool zijn normaal; alle vereisten aan de rechterkant zijn alleen bestellen: doelen: normale vereisten | alleen-bestellen-vereisten
Het normale gedeelte met vereisten kan natuurlijk leeg zijn. U kunt ook nog steeds meerdere regels met vereisten voor hetzelfde doel declareren: ze worden op de juiste manier toegevoegd. Houd er rekening mee dat als u hetzelfde bestand als zowel een normale als een alleen-bestel-vereiste aanduidt, de normale vereiste voorrang heeft (aangezien ze een strikte superset zijn van het gedrag van een alleen-bestellen-vereiste).
Daarom wordt de makefile
.PHONY : clearscr fresh clean all
all :
compile executable
clean :
rm -f *.o $(EXEC)
fresh : | clean clearscr all
clearscr:
clear
BEWERK 5 december
Het is niet erg om meer dan één makefile-instantie uit te voeren, aangezien elke opdracht in de taak een sub-shellsowieso. Maar u kunt herbruikbare methoden gebruiken met de aanroepfunctie.
log_success = (echo "\x1B[32m>> $1\x1B[39m")
log_error = (>&2 echo "\x1B[31m>> $1\x1B[39m" && exit 1)
install:
@[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
command1 # this line will be a subshell
command2 # this line will be another subshell
@command3 # Use `@` to hide the command line
$(call log_error, "It works, yey!")
uninstall:
@[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
....
$(call log_error, "Nuked!")
Antwoord 2, autoriteit 2%
Als u de regel make all
van uw “nieuwe” doel heeft verwijderd:
fresh :
rm -f *.o $(EXEC)
clear
Je zou gewoon het commando make fresh all
kunnen uitvoeren, dat zal worden uitgevoerd als make fresh; make all
.
Sommigen beschouwen dit misschien als een tweede exemplaar van make, maar het is zeker geen sub-exemplaar van make (een merk in een merk), waar uw poging in leek te resulteren.