zak
zak

Reputation: 104

compile headers dependencies with makefile

I am programming an UDP client server application in the C programming language; I want to automatically compile 2 sources files and 3 header files whenever the dependencies change so I decided to use the make utility.

The makefile target is called "edit" :

    edit : server_UDP.o  client_UDP.o \
            gcc -o edit server_UDP.o  client_UDP.o \


    client_UDP.o : client_UDP.c cliHeader_UDP.h  wrapHeader.h
            gcc -c client_UDP.c

    server_UDP.o : server_UDP.c servHeader_UDP.h  wrapHeader.h
            gcc -c  server_UDP.c

It doesn't trigger a recompile when I change a few lines of code in wrapHeader.h.

How do to I modify the edit makefile rule(s) when there is a change in wrapHeader.h to recompile server_UDP and client_UDP ?

**note : wrapHeader.h is the main header

cliHeader_UDP.h : include "wrapHeader.h"

servHeader_UDP.h : include "wrapHeader.h"

Upvotes: 4

Views: 8980

Answers (2)

Daniel
Daniel

Reputation: 500

You did not say that edit.c includes your two specific headers, but I guess it must, if it links to the objects.

This is exactly the scenario where makepp plays out one of its strengths: If you follow the convention that for every .o file you need to link there is an include statement of a corresponding name (in your case that would be client_UDP.h & server_UDP.h) then makepp will figure everything out itself, besides detecting the header files as dependencies.

This even works recursively, so if you had a wrapHeader.c (where there is no corresponding include statement in edit.c), that would get automatically compiled and linked.

So you don't need a makefile. But if you want to avoid calling makepp edit everytime, then you can create a one-liner

edit:

You will only need to learn make syntax, if you have more complex requirements. But if you do, there is no limit. Besides doing almost all that GNU make can, there are lots more useful things, and you can even extend your makefiles with some Perl programming.

Upvotes: 0

Dylan
Dylan

Reputation: 580

I think what you want are Make dependency files.

You can specify the compiler to generate a dependency file for you with the '-MMD -MP' arguments, which create a new file with the same name as the source file except with the extension *.d, in the same folder as your source.

The dependency file contains all the headers the code depends on, which will lead to GNU make compiling your source file if a header it uses is modified.

An example dependency file enabled makefile:

# Makefile

CC   := gcc
LD   := g++

# The output executable.
BIN   := program

# Toolchain arguments.
CFLAGS    := 
CXXFLAGS  := $(CFLAGS)
LDFLAGS   := 

# Project sources.
C_SOURCE_FILES := mysourcefile1.c src/myothersrc.c
C_OBJECT_FILES := $(patsubst %.c,%.o,$(C_SOURCE_FILES))

# The dependency file names.
DEPS := $(C_OBJECT_FILES:.o=.d)

all: $(BIN)

clean:
    $(RM) $(C_OBJECT_FILES) $(DEPS) $(BIN)

rebuild: clean all

$(BIN): $(C_OBJECT_FILES)
    $(LD) $(C_OBJECT_FILES) $(LDFLAGS) -o $@

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

# Let make read the dependency files and handle them.
-include $(DEPS)

This should work for your situation:

SOURCES := server_UDP.c client_UDP.c
OBJECTS := $(patsubst %.c,%.o,$(SOURCES))

DEPS := $(OBJECTS:.o=.d)

edit: $(OBJECTS)
    gcc -o edit $(OBJECTS)

%.o: %.c
    gcc -c $< -o $@

-include $(DEPS)

Upvotes: 2

Related Questions