I am trying to add more then one file created in different directories to a static library but apparently it does not work as expected.
My makefile structure is something like this:
./src/drv/platform/AVR/
- hal
- hw
--- spi
--- uart
- In
hal
I define a library name in$(LIB_TARGET)
namedlibHal
and all the*.o
files should be archived in that library. - In
hw
I define another library name in$(LIB_TARGET)
namedlibHw
and all*.o
files inhw/spi
andhw/uart
should go in that library: first the librarylibHw
is created with the object files inhw/spi
and they are never missed, then the objects inhw/uart
are created and should be added tolibHw
. - In each subdirectory a generic makefile with suffix rules is ran that creates the object files and then should add each
*.o
to the library. At the end of the run I should have in another library directory(as in another location) 2 libs,libHal
andlibHw
,libHal
contains everything inhal
,libHw
everything inhw
.
In this case the directory hw
does not have any source files and looks like this:
SUBDIRS:= spi uart
LIB_TARGET = libHw.a
.PHONY: $(SUBDIRS) clean all
default: all
$(SUBDIRS)::
$(MAKE) -C $@ $(MAKECMDGOALS)
all clean : $(SUBDIRS)
Each of the uart
and spi
subdirs hold something like this:
include $(TGT_BASE)/make/generic.mk
SRCS := uart.c
include $(TGT_BASE)/make/rules.mk
The file generic.mk
only holds generic platform definitions.
The code for the generic makefile rules.mk
with all the suffix rules.
.PHONY : all clean
OBJS = $(SRCS:.c=.o)
DEPS = $(OBJS:.o=.d)
LIB_TARGETT = $(LIB_DIR)/$(LIB_TARGET)
### Archive into a library file (.a)
$(LIB_DIR)/%.a: $(OBJS)
@echo $(MSG_L)
@echo 'Adding $^ to library $@'
$(AR) $(ARFLAGS) $@ $^
@echo $(MSG_L)
### rule for c files
%.o: %.c
@echo $(MSG_C)
$(CC) -c $(CFLAGS) $(MODULES_INC) $(TGT_LOCAL_INCLUDES) $< -o $@
@echo $(MSG_C)
### make dependencies
%.d: %.c
@echo $(MSG_D)
$(CC) -E -MM $(CFLAGS) $(MODULES_INC) $(TGT_LOCAL_INCLUDES) $(CURDIR)/$< > $@
@echo $(MSG_D)
all: $(DEPS) $(OBJS) $(LIB_TARGETT)
clean:
$(RM) -rf *.o *.d .depend
The makefile that exists in most
Now the problem is that sometimes some of the *.o
files in hw/uart
are not added to the library defined in hw
. Running make in debug reveals that make itself considers the prerequisites for the library to be older then the last access to the library so they are missed.
Found an implicit rule for 'F:/automata/tmp/remake//tmp/app/brick/lib/atmega328p/libHw.a'.
Pruning file 'uart.o'.
Finished prerequisites of target file 'F:/automata/tmp/remake//tmp/app/brick/lib/atmega328p/libHw.a'.
Prerequisite 'uart.o' is older than target 'F:/automata/tmp/remake//tmp/app/brick/lib/atmega328p/libHw.a'.
To explain better how this goes when it works here is an example
make[7]: Entering directory 'F:/automata/tmp/remake/src/drv/platform/AVR/hw/uart
'
-------- make c --------
avr-gcc -c -Wall -Werror -Os -mmcu=atmega328p -IF:/automata/tmp/remake//tmp/ap
p/brick -IF:/automata/tmp/remake/src/common/h -IF:/automata/tmp/remake/src/drv/p
latform/AVR/hw/spi -IF:/automata/tmp/remake/src/drv/platform/AVR/hw/uart -IF:/au
tomata/tmp/remake/src/modules/interface/cli -IF:/automata/tmp/remake/src/drv/pl
atform/AVR/hw/uart uart.c -o uart.o
-------- make c --------
------- make Lib -------
Adding uart.o to library F:/automata/tmp/remake//tmp/app/brick/lib/atmega328p/li
bHw.a
avr-ar rcs F:/automata/tmp/remake//tmp/app/brick/lib/atmega328p/libHw.a uart.o
------- make Lib -------
make[7]: Leaving directory 'F:/automata/tmp/remake/src/drv/platform/AVR/hw/uart'
And here is an example if it when it is not working
make[7]: Entering directory 'F:/automata/tmp/remake/src/drv/platform/AVR/hw/uart
'
-------- make c --------
avr-gcc -c -Wall -Werror -Os -mmcu=atmega328p -IF:/automata/tmp/remake//tmp/ap
p/brick -IF:/automata/tmp/remake/src/common/h -IF:/automata/tmp/remake/src/drv/p
latform/AVR/hw/spi -IF:/automata/tmp/remake/src/drv/platform/AVR/hw/uart -IF:/au
tomata/tmp/remake/src/modules/interface/cli -IF:/automata/tmp/remake/src/drv/pl
atform/AVR/hw/uart uart.c -o uart.o
-------- make c --------
make[7]: Leaving directory 'F:/automata/tmp/remake/src/drv/platform/AVR/hw/uart'
I am using make 3.82.90
and Windows 7
.
So any idea how I can force make to not miss those objects? Or to see their real time of creation and properly add them to the library? Remember, sometimes they are added, but sometimes they are not.
Thank you.