GNU make: Generating automatic dependencies with generated header files

后端 未结 4 669
死守一世寂寞
死守一世寂寞 2020-12-05 12:13

So I followed the Advanced Auto-Dependency Generation paper --

Makefile:

SRCS := main.c foo.c

main: main.o foo.o

%.o: %.c
    $(CC) -MMD -         


        
4条回答
  •  旧时难觅i
    2020-12-05 12:45

    The problem is that the *.d Makefile-fragments generation must be performed after all the header generation is complete. Putting it this way, one can use the make dependencies to force the right order:

    SRCS := main.c foo.c
    HDRS := foo.h
    
    main: main.o foo.o
    
    %.o: %.c | generated_headers
        $(CC) -MMD -MG -MT '$@ $*.d' -c $< -o $@
        cp $*.d $*.tmp
        sed -e 's;#.*;;' -e 's;^[^:]*: *;;' -e 's; *\\$$;;' \
            -e '/^$$/d' -e 's;$$; :;' < $*.tmp >> $*.d
        rm $*.tmp
    
    -include $(SRCS:.c=.d)
    
    $(HDRS):
        mk_header.sh $*
    
    generated_headers: $(HDRS)
    
    clean:
        -rm $(HDRS) *.o *.d main
    
    .PHONY: clean generated_headers
    

    Notes:

    1. I use an order-only dependency.

    2. This solution is fairly scalable: Each generate-header rule, needs only to be a prerequisite of the generated_headers .PHONY target. Assuming that the header generation rule is written properly, once it has been generated correctly, satisfying the generated_headers target should be a no-op.

    3. One can't compile a single object, even if that object does not require any generated headers, without generating all the generated headers of the project first. While this is technically sound, your developers will complain.

      So you should think about having a FAST_AND_LOOSE flag, that will turn this feature off:

      %.o: %.c | $(if $(FAST_AND_LOOSE),,generated_headers)
          ...
      

      Thus a developer may issue:

      make FAST_AND_LOOSE=1 main.o
      

提交回复
热议问题