Download the list of files from the list of URLs as prerequisites in the makefile

I would like to have a make file to compile the project, and I need some files (binaries) to load if they are missing, since it is not recommended to track them with git.

I have a list of URLs and a list of names given to them (and I would like to be able to choose a name to save them, since I can not control the name of the URL and basically the names are pretty terrible, descriptive). Let's say that the files will always be the same or we don’t care if they change on the server (we do not need to download them again).

So my idea was to write something like this in my makefile:

files = one two three four

main : $(files)
  command to do when files are present

but I want each of them to be loaded if they are not already present, and each of its own URL, so I need something like iterating over the $ elements (files).

I will write an idea that I mean by mixing python code and what I know from make files. I know this is rubbish, but I don’t know another way to do it (the question is how to write it well, basically), and I think it is pretty easy to understand.

urls = url1 url2 url3 url4

for i in len(files):
    $(files)[i] :
        curl -Lo $(files)[i] $(urls)[i]

So the question is: how do I do this?

I have been looking at the make documentation for a while, and I cannot find the right way to do this without writing down the file name several times (which I think should be avoided, but variables should be used instead). Canned recipes maybe , but I don’t see how to do it.

+6
2

, . : , GNU make:

№1:

files := one two three four
urls := url1 url2 url3 url4

main: $(files)
    @echo 'command to do when files are present'

# $(1): file name
# $(2): url
define DOWNLOAD_rule
$(1):
    @echo 'curl -Lo $(1) $(2)'
endef
$(foreach f,$(files),\
  $(eval $(call DOWNLOAD_rule,$(f),$(firstword $(urls))))\
  $(eval urls := $(wordlist 2,$(words $(urls)),$(urls)))\
)

echos :

$ make -j
curl -Lo one url1
curl -Lo four url4
curl -Lo three url3
curl -Lo two url2
command to do when files are present

:

DOWNLOAD_rule , $(1) $(2) URL-.

$(1) $(2) DOWNLOAD_rule :

$(eval $(call DOWNLOAD_rule,one,url1))

, :

one:
    @echo 'curl -Lo one url1'

foreach . :

$(foreach f,$(files),$(eval $(call DOWNLOAD_rule,$(f),url1)))

... , URL- (url1) . , .

URL-, , eval foreach:

  • , URL- $(urls),
  • , $(urls) urls.

:=, . = ( ) .

$(wordlist 2,$(words $(urls)),$(urls)) , :

  • $(wordlist s,e,l) s e l ( 1 l)
  • $(words l) l

, $(urls) , , url2 url3 url4:

  • $(words $(urls)) 3
  • $(wordlist 2,$(words $(urls)),$(urls)) url3 url4, $(wordlist 2,3,url2 url3 url4)

№2:

eval DOWNLOAD_rule, : make . (url), , :

files := one two three four
urls := url1 url2 url3 url4

main: $(files)
    @echo 'command to do when files are present'

# $(1): file name
define DOWNLOAD_rule
$(1): url := $$(firstword $$(urls))
$(1):
    @echo 'curl -Lo $(1) $$(url)'
urls := $$(wordlist 2,$$(words $$(urls)),$$(urls))
endef
$(foreach f,$(files),$(eval $(call DOWNLOAD_rule,$(f))))

$$ DOWNLOAD_rule, , eval , make make. $$ - , , eval foreach:

one: url := $(firstword $(urls))
one:
    @echo 'curl -Lo one $(url)'
urls := $(wordlist 2,$(words $(urls)),$(urls))

two: url := $(firstword $(urls))
two:
    @echo 'curl -Lo two $(url)'
urls := $(wordlist 2,$(words $(urls)),$(urls))

three: url := $(firstword $(urls))
three:
    @echo 'curl -Lo three $(url)'
urls := $(wordlist 2,$(words $(urls)),$(urls))

four: url := $(firstword $(urls))
four:
    @echo 'curl -Lo four $(url)'
urls := $(wordlist 2,$(words $(urls)),$(urls))

, . $$ :

one: url := url1
one:
    @echo 'curl -Lo one '
urls := url2 url3 url4

two: url := url1
two:
    @echo 'curl -Lo two '
urls := url2 url3 url4

three: url := url1
three:
    @echo 'curl -Lo three '
urls := url2 url3 url4

four: url := url1
four:
    @echo 'curl -Lo four '
urls := url2 url3 url4

: eval $$ .

№ 3:

(<file>-url) URL- (files):

# Set file URL and update files' list
# Syntax: $(call set_url,<file>,<url>)
set_url = $(eval $(1)-url := $(2))$(eval files := $$(files) $(1))

$(call set_url,one,url1)
$(call set_url,two,url2)
$(call set_url,three,url3)
$(call set_url,four,url4)

main: $(files)
    @echo 'command to do when files are present'

# $(1): file name
define DOWNLOAD_rule
$(1):
    @echo 'curl -Lo $(1) $$($(1)-url)'
endef
$(foreach f,$(files),$(eval $(call DOWNLOAD_rule,$(f))))

№ 4:

, GNU Make Standard Library (gmsl) John Graham-Cumming , , №3. , , urls URL- :

include gmsl

$(call set,urls,one,url1)
$(call set,urls,two,url2)
$(call set,urls,three,url3)
$(call set,urls,four,url4)

files := $(call keys,urls)

main: $(files)
    @echo 'command to do when files are present'

# $(1): file name
define DOWNLOAD_rule
$(1):
    @echo 'curl -Lo $(1) $$(call get,urls,$(1))'
endef
$(foreach f,$(files),$(eval $(call DOWNLOAD_rule,$(f))))
+3
FILES := file1 file2 file3

main : $(FILES)
    command to do when files are present

file1: firstuglyurl
file2: seconduglyurl
file3: thirduglyurl

$(FILES):
    curl -Lo $@ $<

[] , , . :

FILES := file1 file2 file3

main : $(FILES)
    command to do when files are present

file1: URL:=firstuglyurl
file2: URL:=seconduglyurl
file3: URL:=thirduglyurl

$(FILES):
    curl -Lo $@ $(URL)

(URL = > ) , make , , .

, , , , URL ( , ...).

+1

All Articles