I am developving a number of projects in Eclipse that share common files (such as peripheral drivers). Each project therefore pulls together source files from a number of folders.

Within my makefile I have concatenated together the names of all the source folders as can be summarised:

SOURCE = \
 $(SOURCE_FOLDER)/Source/Application/Bus_Link/modbus.c		\
 $(SOURCE_FOLDER)/Source/Application/Bus_Link/Mitsubishi.c	\
 $(SOURCE_FOLDER)/Source/Application/Bus_Link/DF1.c		\

COMMON_SOURCE = \
 $(COMMON_FOLDER)/Source/IOcommon.c 				\
 $(COMMON_FOLDER)/Source/DataLink/adc.c 			\
 $(COMMON_FOLDER)/Source/DataLink/dac.c 			\

# Concatentate all sources together.
SOURCE += $(COMMON_SOURCE)

I have then created the compile rule as follows:

define COMPILE_C_TEMPLATE
$(OUTPUT_FOLDER)/$(notdir $(basename $(1))).o : $(1)
	$(COMPILE) -c  $$(CFLAGS) $$< -o $$@
endef

$(foreach src, $(SOURCE), $(eval $(call COMPILE_C_TEMPLATE, $(src))))

This works, but obviously doesn't include any dependency rules, so if I change a header file I have to re-compile the entire project.

I have added rules to make dependency files as follows:

define DEPEND_C_TEMPLATE
$(OUTPUT_FOLDER)/$(notdir $(basename $(1))).d : $(1)
$(OUTPUT_FOLDER)/$(notdir $(basename $(1))).d : $(1)
	$(COMPILE) -MM $$(CFLAGS) $$< -o $$@
endef

$(foreach src, $(SOURCE), $(eval $(call DEPEND_C_TEMPLATE, $(src))))

This also works. and generates correctly-formatted dependency files into the designated output folder. However, I can't find a way of using them to compile the project.

I would appreciate any help

Can't you just put the common files in a library and include the library in each of the projects?

Thanks for the suggestion. I was convinced that there must be a way of doing it the way I wanted since Eclipse has the option to reference one project from another. After posting my query I continued searching the web for a solution and eventually came up with the following, which is very neat and works, even though I don't fully understand how!

all : $(PROJECT_NAME).s19

$(PROJECT_NAME).s19 : $(PROJECT_NAME).elf
	@echo -----------------------------------------
	@echo CREATING $(PROJECT_NAME).s19
	$(OBJCOPY) $(OUTPUT_FOLDER)/$(PROJECT_NAME).elf -O srec $(OUTPUT_FOLDER)/$(PROJECT_NAME).s19
	$(SIZE) $(OUTPUT_FOLDER)/$(PROJECT_NAME).s19

$(PROJECT_NAME).elf : $(OBJ_FILES_NO_PATH) makefile
	@echo -----------------------------------------
	@echo LINKING $(PROJECT_NAME).elf
	$(LINK) $(INCLUDE_FOLDERS) $(CFLAGS) $(OBJECT_FILES) $(LINKER_FLAGS) -o $(OUTPUT_FOLDER)/$@
	$(SIZE) $(OUTPUT_FOLDER)/$(PROJECT_NAME).elf
	@$(COMPILE) --version

-include $(OBJECT_FILES:.o=.d)

# rules for compiling C files
%.o : %.c
	@echo -----------------------------------------
	@echo COMPILING DEPENDENCY FILE FOR $@
	$(COMPILE) -MM $(INCLUDE_FOLDERS) $(CFLAGS) $< > $(OUTPUT_FOLDER)/$(addsuffix .d, $(notdir $(basename $@)))
	@echo -----------------------------------------
	@echo COMPILING OBJECT FILE $@
	$(COMPILE) -c $(INCLUDE_FOLDERS) $(CFLAGS) $< -o $(OUTPUT_FOLDER)/$@

The clue is in the line
-include $(OBJECT_FILES:.o=.d)
This apparently ensures that the rule for compiling C files uses the dependency file rather than simply comparing the timestamps of the .c and .o files as suggested by the lines that follow. You will also note that when it re-compiles the .c file it makes two passes, one with the -c switch to create the new .o object file and the other with the -MM switch to re-create the .d dependency file.

I hope this might be of help to others.

This article has been dead for over six months. Start a new discussion instead.