Matt Clarkson
Matt Clarkson

Reputation: 14426

Makefile - Copy header files from multiple folders into one include folder with dependecies

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

UPDATE:

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

Answers (2)

user346034
user346034

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:

  1. The first line defines all your features, that is security, this and that. I simpy called tham a, b and c.
  2. The header names are derived from your feature names. E. g. feature a becomes header include/a_feature.h.
  3. The default target requires all the headers
  4. The line $(HEADERS): include/%_feature.h: % lets all header files depend on their base feature names, i. e. it replaces *include/SOMETHING_feature.h* with SOMETHING.
  5. The last target copies the header files from the directory of the location to the target directory within the project.

Unfortunately, it doesn't check timestamps of the header files in the ../FEATURE directory.

Cheers,

Martin.

Upvotes: 0

Beta
Beta

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

Related Questions