Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GNU-Make does not recompile when a header file changed

GNU-Make does not recompile when hdr.h file changed. As below printed lines, it did not try to recompile even main.d file is generated. Can you guide me why it happend?

hdr.h

#ifndef __HDR_H__  

#define LOOP_CNT 1000  

#endif /* __HDR_H__ */  

main.c

#include <stdio.h>  
#include "hdr.h"  

int main(void)  
{  
    int i, sum = 0;  
    for (i = 0; i < LOOP_CNT; i++) sum += i;  
    (void)printf("sum = %d\n", sum);  
    return 0;  
}  

Makefile

SUFFIXES += .d

.PHONY: clean  

OBJECTS = $(patsubst %.c,%.o,$(wildcard *.c))  
CC = armcc  
LD = armcc  
CFLAGS += 

# Default target  
all: sum  

sum : $(OBJECTS)  
    $(CC) $(CFLAGS) -o $@ $^  

$(OBJECTS) : %.o : %.c   
    $(CC) $(CFLAGS) -o $@ -c $<  

# Generating dependency files  
%.d : %.c  
    @$(CC) -M $< > $@  

# Include dependency file to have gcc recompile necessary sources  
include $(patsubst %.c,%.d,$(wildcard *.c))  
#$(info $(patsubst %.c,%.d,$(wildcard *.c)))

clean:  
    rm -f *.o *.d core $(EXEC_NAME)  

Here is printed line in second.

C:\project\dep>make all
Makefile:24: main.d: No such file or directory
armcc    -o main.o -c main.c
armcc    -o sum main.o

C:\project\dep>make all
make: Nothing to be done for `all'. 

main.d file is generated as below.

__image.axf: main.c
__image.axf: C:\Program Files\ARM\RVCT\Data\4.1\713\include\windows\stdio.h
__image.axf: hdr.h
like image 851
andwella Avatar asked May 17 '17 09:05

andwella


People also ask

How do I make changes to the header files without recompilation?

Make the changes in the header files. Use the command `make -t' to mark all the object files as up to date. The next time you run make, the changes in the header files do not cause any recompilation. If you have already changed the header file at a time when some files do need recompilation, it is too late to do this.

How do I re-recompile a header file?

Recompile the source files that need compilation for reasons independent of the particular header file, with `make -o header file'. If several header files are involved, use a separate `-o' option for each header file. Update all the object files with `make -t'.

How to recompile the source files that really need recompilation?

You need to follow this procedure − Use the command `make' to recompile the source files that really need recompilation. Make the changes in the header files. Use the command `make -t' to mark all the object files as up to date. The next time you run make, the changes in the header files do not cause any recompilation.

What happens if a C header file has changed?

If a header file has changed, each C source file that includes the header file must be recompiled to be safe. Each compilation produces an object file corresponding to the source file.


2 Answers

As a quick and dirty Makefile fix for rebuilding if headers change I just list all my header files and then add $(HEADERS) as a dependency in the part that builds the object files from the C src files. Its not as efficient as it could be but I find it to be good enough, i.e.

HEADERS = \
    my_header.h \
    my_other_header.h

$(BUILD_DIR)/%.o: %.c $(HEADERS)
    $(LINK.c) $< -c -o $@
like image 62
bph Avatar answered Oct 01 '22 18:10

bph


Generally speaking, if a source file needs to be compiled to create an object file, then its dependency file also needs to be rebuilt.

So, instead of having a separate target for the .d files, simple regenerate it when compiling. To achieve this, a simple approach is to replace

$(OBJECTS) : %.o : %.c   
    $(CC) $(CFLAGS) -o $@ -c $<  

# Generating dependency files  
%.d : %.c  
    @$(CC) -M $< > $@  

with

$(OBJECTS) : %.o : %.c   
    $(CC) $(CFLAGS) -o $@ -c $<  
    @$(CC) -M $< > $@  

Note that the dependency file will only be regnerated if compilation succeeds. If compilation fails, the object file will be deleted, so recompilation would be forced regardless of whether the dependency file is up to date.

like image 39
Peter Avatar answered Oct 01 '22 19:10

Peter