Reputation: 35
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
hal
I define a library name in $(LIB_TARGET)
named libHal
and all the *.o
files should be archived in that library.hw
I define another library name in $(LIB_TARGET)
named libHw
and all *.o
files in hw/spi
and hw/uart
should go in that library: first the library libHw
is created with the object files in hw/spi
and they are never missed, then the objects in hw/uart
are created and should be added to libHw
.*.o
to the library. At the end of the run I should have in another library directory(as in another location) 2 libs, libHal
and libHw
, libHal
contains everything in hal
, libHw
everything in hw
.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.
Upvotes: 0
Views: 1450
Reputation: 100876
When you say it always works when you run it with make all --debug=a
it always works: which part of that matters? If you run make all
does it always work? Or if you run make --debug=a
does it always work? Or do you have to use both to make it always work?
Since you're not showing all the makefile, we can't say much. For example, how are you setting the value of OBJS
? Where and how do you define the rules that build object files (or are you using make's built-in rules for that)? That information is critical. It looks like what's happening is that make is asking you to build one file but your rules build a different file, so make sees that the file it expects was not actually updated and doesn't do anything.
Also, it's very confusing that in your overview you talk about things like dir1
, dir2
, dir2.1
, etc. but then in the error output you provide completely different paths. We can't determine how the "real" pathnames in your example match up with the pseudo-paths in your overview.
Please either use real paths everywhere, or edit your example output to use the pseudo-paths, so we can see which paths are doing what.
Upvotes: 1