views:

28

answers:

1

http://stackoverflow.com/questions/239004/need-a-makefile-dependency-rule-that-can-handle-missing-files gives some pointers on how to handle removed source files for generating .o files. I'm using gcc/g++, so adding the -MP option when generating dependencies works great for me, until I get to the link stage with my .a file...

What about updating archives/libraries when input sources go away? This works OK for me, but is there a cleaner way (ie, something as straightforward as the g++ -MP option)?

#BUILD_DIR is my target directory (includes Debug/Release and target arch)
#SRC_OUTS are my .o files    

LIBATLS_HAS = $(shell nm ${BUILD_DIR}/libatls.a | grep ${BUILD_DIR} | sed -e 's/.*(//' -e 's/).*://')
LIBATLS_REMOVE = $(filter-out $(notdir ${SRC_OUTS}), ${LIBATLS_HAS})

${BUILD_DIR}/libatls.a: ${BUILD_DIR}/libatls.a(${SRC_OUTS})
ifneq ($(strip ${LIBATLS_REMOVE}),)
    $(AR) -d $@ ${LIBATLS_REMOVE}
endif

Updated to the following after initial feedback:

LIBATLS_HAS := $(shell $(AR) t ${BUILD_DIR}/libatls.a)
LIBATLS_REMOVE := $(filter-out $(notdir ${SRC_OUTS}), $(filter %.o,${LIBATLS_HAS}))

.PHONY: clean_archive
clean_archive:
    $(AR) -d $(BUILD_DIR)/libatls.a $(LIBATLS_REMOVE)

.PHONY: $(LIBATLS_REMOVE)
$(LIBATLS_REMOVE): clean_archive

${BUILD_DIR}/libatls.a: % : %(${SRC_OUTS}) ${LIBATLS_REMOVE}
A: 

There are a few different ways to do this. One that's pretty clean is:

LIBATLS_HAS:=$(shell $(AR) t $(BUILD_DIR)/libatls.a)
LIBATLS_REMOVE:= $(filter-out $(SRC_OUTS),$(LIBATLS_HAS))
REMOVE_LIST = $(addprefix remove_,$(LIBATLS_REMOVE))

.PHONY: $(REMOVE_LIST)
$(REMOVE_LIST): remove_%
    $(AR) -d $(BUILD_DIR)/libatls.a $*

$(BUILD_DIR)/libatls.a: % : %($(SRC_OUTS)) $(REMOVE_LIST)

This is a little inefficient in that it runs a seperate $(AR) command for each member to be removed. I doubt that'll be a problem, but if it is you can get around it with a phony target:

# Note that this will run once at most.
.PHONY: clean_archive
clean_archive:
    $(AR) -d $(BUILD_DIR)/libatls.a $(LIBATLS_REMOVE)

.PHONY: $(REMOVE_LIST)
$(REMOVE_LIST): clean_archive
Beta
Thanks for the feedback. I still hope for a more direct way. :) It seems like it'd be a common issue.I like "$(AR) t" over the nm|grep|sed. I have to filter the archive's table of contents (filter %.o below).The second version should use LIBATLS_REMOVE, correct?Updating above with combined version.
b3nj1
@b3nj1: I don't think there is a more direct way that doesn't involve dangerous hacks. One can make a wish list of features that Make could have, but a Make that could handle this problem really cleanly would be a general-purpose language.
Beta