i'm new to makefile and i would like to perform several operations.
my current makefile is as follows:
OBJECTS=radio_listener.o radio_app_comm_func.o
TARGET_EXECUTABLE=radio_listener
# Default target
all: ${TARGET_EXECUTABLE}
# Compile all required .o files this way
%.o: %.c
@echo "Compiling $<"
@gcc -c -g -m32 $< -o $@
# Compile target exe by combining all objects
${TARGET_EXECUTABLE}: ${OBJECTS}
@echo "Linking $@"
@gcc ${OBJECTS} -g -m32 -o $@
# Cleanup rule
clean:
@echo "Cleaning up..."
@rm -f *.o ${TARGET_EXECUTABLE}
@echo "Done."
.PHONY: clean all
1. Say I execute 'make'. then change a MACRO define in radio_app_comm_types.h.
radio_app_comm_types.h is included in radio_app_comm_func.h.
after changing the MACRO, and executing 'make' again, i get "Nothing to be done for 'all'.
Obviously i somehow need to tell my Makefile, that radio_app_comm_func.h, is dependent on radio_app_comm_types.h.
How to do this?
2. The 2nd thing that interest me, is how to use the same Makefile, dor different executables.
Currently i have only radio_listener , but i plan on adding radio_control,radio_server, which their h files will also include radio_app_comm_func.h, and maybe some other h files (in order to use the relevant .c files of them.
How can i achieve this? I'm looking to implement a flow as follows:
a) Executing make, will compile all relevant files for each of the exe's, and in the end will create 3 different executables for me - radio_listener, radio_control, radio_server
b) Executing make server (for example), will compile all relevant files that are needed only for radio_server (including looking for changes, say, in radio_app_comm_types.h) and finally will create only 1 executable - radio_server for me
c) Executing make controller ...compile all needed for radio_control, etc (you get my meaning i guess)
I'm working on Ubuntu x64 system, if that's relevant.
Any help will be much appreciated.
Thank you.
Here's a version that uses the advanced auto-dependency rules, and allows for multiple targets to be built. Update the flags near the top and create new entries in TARGETS
and make a new xxx_SRC
variable to add new targets.
If you want the dependency files in the current directory you can change DEPDIR
to be just .
or else go through the makefile and delete references to it, either way.
TARGETS := exe1 exe2 exe3
DEPDIR = .d
exe1_SRC := foo.c bar.c
exe2_SRC := biz.c boz.c
exe3_SRC := bling.c blang.c
CC := gcc
CFLAGS := -g -O2
CPPFLAGS := -DXXX -I../include
LDFLAGS := -L../lib
LDLIBS := -lfoo -lbar
# ----- Nothing below here needs to be changed
.PHONY: all
all : $(TARGETS)
.SECONDEXPANSION:
# For each target, depend on the .o files for its sources
$(TARGETS): $$(patsubst %.c,%.o,$$($$@_SRC))
$(LINK.c) $^ $(LDLIBS) -o $@
ALLSRC := $(foreach T,$(TARGETS),$($T_SRC))
.PHONY: clean
clean:
rm -f $(TARGETS) *.o $(DEPDIR)/*.d
# -----
# Advanced auto-dependency, from:
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
$(shell mkdir -p $(DEPDIR) >/dev/null)
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
%.o : %.c
%.o : %.c $(DEPDIR)/%.d
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(ALLSRC)))