makefile execute another target

前端 未结 2 973
我在风中等你
我在风中等你 2020-12-23 00:12

I have a makefile structured something like this:

all : 
    compile executable

clean :
    rm -f *.o $(EXEC)

I realized that I was consis

相关标签:
2条回答
  • 2020-12-23 00:36

    If you removed the make all line from your "fresh" target:

    fresh :
        rm -f *.o $(EXEC)
        clear
    

    You could simply run the command make fresh all, which will execute as make fresh; make all.

    Some might consider this as a second instance of make, but it's certainly not a sub-instance of make (a make inside of a make), which is what your attempt seemed to result in.

    0 讨论(0)
  • 2020-12-23 00:45

    Actually you are right: it runs another instance of make. A possible solution would be:

    .PHONY : clearscr fresh clean all
    
    all :
        compile executable
    
    clean :
        rm -f *.o $(EXEC)
    
    fresh : clean clearscr all
    
    clearscr:
        clear
    

    By calling make fresh you get first the clean target, then the clearscreen which runs clear and finally all which does the job.

    EDIT Aug 4

    What happens in the case of parallel builds with make’s -j option? There's a way of fixing the order. From the make manual, section 4.2:

    Occasionally, however, you have a situation where you want to impose a specific ordering on the rules to be invoked without forcing the target to be updated if one of those rules is executed. In that case, you want to define order-only prerequisites. Order-only prerequisites can be specified by placing a pipe symbol (|) in the prerequisites list: any prerequisites to the left of the pipe symbol are normal; any prerequisites to the right are order-only: targets : normal-prerequisites | order-only-prerequisites

    The normal prerequisites section may of course be empty. Also, you may still declare multiple lines of prerequisites for the same target: they are appended appropriately. Note that if you declare the same file to be both a normal and an order-only prerequisite, the normal prerequisite takes precedence (since they are a strict superset of the behavior of an order-only prerequisite).

    Hence the makefile becomes

    .PHONY : clearscr fresh clean all
    
    all :
        compile executable
    
    clean :
        rm -f *.o $(EXEC)
    
    fresh : | clean clearscr all
    
    clearscr:
        clear
    

    EDIT Dec 5

    It is not a big deal to run more than one makefile instance since each command inside the task will be a sub-shell anyways. But you can have reusable methods using the call function.

    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!")
    
    0 讨论(0)
提交回复
热议问题