Reputation: 14426
I have multiple files in various folders that I need to copy to one include folder:
Before make
../security/security_features.h
../this/this_features.h
[etc]
../that/that_features.h
After make
./include/security_features.h
./include/this_features.h
[etc]
./include/that_features.h
The files in the ./include folder all need to be dependent on the files in the various folders.
Makefiles are a bit of a mystery to me, I have tried to read the manuals and understand how to make dependencies:
./include/security_features.h: ../security/security_features.h
@cp -av $< $@
But I'll have to do this for all my files - is there another more elegant way?
Ideally I'd just like to write a Makefile variable of the various files in the scattered folders and the makefile know to copy all the files in that variable to the include folder.
Any Makefile gurus out there?
Thanks,
Matt
I have managed to do the list of files as such:
INCLUDES_SRC := ../security/security_features.h ../this/this_features.h
INCLUDES_DST := $(addprefix ./include/,$(notdir $(INCLUDES_SRC)))
And can make one dependent on the other:
$(INCLUDES_DST): $(INCLUDES_SRC)
@cp -av $< $@
However this just copying the first prerequisite (../security/security_features.h
) both times to the two targets (./include/security_features.h
, ./include/this_features.h
):
'../security/security_features.h' -> './include/security_features.h'
'../security/security_features.h' -> './include/this_features.h'
So I now have a make variable list of src and destination locations for files - anyone know how to copy all the files in turn?
Thanks
Matt
Upvotes: 2
Views: 10576
Reputation:
that's a tricky one. Best solution I found is this:
FEATURES = a b c
HEADERS = $(foreach ftr,$(FEATURES),include/$(ftr)_feature.h)
default: $(HEADERS)
@echo "Headers: $^"
$(HEADERS): include/%_feature.h: %
$(FEATURES):
@echo "Copying $(subst DUMMY,$@,'../DUMMY/DUMMY_feature.h') to include/$@_feature.h"
@cp $(subst DUMMY,$@,../DUMMY/DUMMY_feature.h) include/$@_feature.h
.PHONY: $(FEATURES)
Update: Maybe I should explain a little bit what happens here:
include/a_feature.h
.$(HEADERS): include/%_feature.h: %
lets all header files depend on their base feature names, i. e. it replaces *include/SOMETHING_feature.h* with SOMETHING.Unfortunately, it doesn't check timestamps of the header files in the ../FEATURE directory.
Cheers,
Martin.
Upvotes: 0
Reputation: 99124
The trouble with your rule:
$(INCLUDES_DST): $(INCLUDES_SRC)
@cp -av $< $@
is that it makes every source header a prerequisite of every destination header, and copies only the first one (with $<
).
This will do it:
.PHONY: INCLUDES
INCLUDES: $(INCLUDES_DST)
include/%: %
cp $^ include
vpath %.h security this
Roughly translated, this means "to make include/something
, find something
and copy it to include/
, and when looking for a file of the form x.h
, look in security/
and this/
."
(Note that if you have two headers with the same name this will miss one of them, but in that case you couldn't get them both into include
anyway.)
If you have a lot of source directories and you don't want to type them all in, Make can keep track of them:
INCLUDE_PATHS := $(dir $(INCLUDES_SRC))
vpath %.h $(INCLUDE_PATHS)
Upvotes: 5