Pre-build step in makefile

前端 未结 5 1031
广开言路
广开言路 2021-01-31 09:04

How can I run a script, which must execute before all other makefile commands? And it will be nice (but not mandatory) to the script is not executed if there is nothing to build

相关标签:
5条回答
  • 2021-01-31 09:32

    You could add a special target to your Makefile and have all your build rules depend on that:

    run-script:
        myscript
    
    .o.c: run-script
         $(CC) $(CFLAGS) -o $@ $<
    
    .o.S: run-script
         $(AS) $(AFLAGS) -o $@ $<
    

    Depending on what your script actually does, putting it to run once in a stage before the Makefile (configure stage in autoconf terms) could make even more sense (and be less work).

    0 讨论(0)
  • 2021-01-31 09:34

    Thank you for answers. ndim helped me much, asveikau. The final file is one binary executable, so I can use now something like this:

    run-script:
        myscript
    $(AXF_FILE): run-script $(OBJ_DIRS) $(OBJ_FILES)
        $(LINK) #......
    

    It will run myscript once. {AXF_FILE} value depends on myscript and I must run it before. And in this case myscript runs always, not only when rebuild is needed. After, The Simplest Answer came to my mind:

    all: run-script $(AXF_FILE)
    

    That's all ;) (Of course, any target can be used instead of "all")


    Edit: this method execute script after $(AXF_FILE) is calculated too. So it's possible to get wrong value of AXF_FILE. Now only the first answer by ndim works as I need.

    0 讨论(0)
  • 2021-01-31 09:35

    I propose two solutions. The first mimics what NetBeans IDE generates:

    CC=gcc
    
    .PHONY: all clean
    
    all: post-build
    
    pre-build:
        @echo PRE
    
    post-build: main-build
        @echo POST
    
    main-build: pre-build
        @$(MAKE) --no-print-directory target
    
    target: $(OBJS)
        $(CC) -o $@ $(OBJS)
    
    clean:
        rm -f $(OBJS) target
    

    The second one is inpired by what Eclipse IDE generates:

    CC=gcc
    
    .PHONY: all clean
    .SECONDARY: main-build
    
    all: pre-build main-build
    
    pre-build:
        @echo PRE
    
    post-build:
        @echo POST
    
    main-build: target
    
    target: $(OBJS)
        $(CC) -o $@ $(OBJS)
        @$(MAKE) --no-print-directory post-build
    
    clean:
        rm -f $(OBJS) target
    

    Note that in the first one, pre and post builds are always called regardless of whether the main build is determined to be up to date or not.

    In the second one, the post-build step is not executed if the state of the main build is up to date. While the pre-build step is always executed in both.

    0 讨论(0)
  • 2021-01-31 09:37

    What you are proposing seems a bit "un-make-like". Why not just run the command in whatever makefile target you need it to go before?

    Example, if you need it to run before linking foo:

    foo: ${OBJS}
        my-command-goes-here
        ${CC} -o $@ ${OBJS} ${LIBS}
    
    0 讨论(0)
  • 2021-01-31 09:39

    Depending on your make version, something like the following should at least avoid running dozens of times if CFLAGS and AFLAGS are evaluated dozens of times:

    CHEAT_ARG := $(shell myscript)
    

    Note the colon.

    This runs exactly once. Never more than once, but also never less than once. Choose your own tradeoffs.

    0 讨论(0)
提交回复
热议问题