Escaping colons in filenames in a Makefile

后端 未结 6 1746
再見小時候
再見小時候 2020-12-03 20:59

Is there a way to get GNU make to work correctly with filenames that contain colons?

The specific problem I\'m running into happens to involve a pattern rule. Here\

相关标签:
6条回答
  • 2020-12-03 21:22

    The answers here all seemed too complex to be helpful. I finally found a solution here:

    colon := :
    $(colon) := :
    

    and then used the macro in the filename as:

    filename$(:)
    

    which successfully translated to "filename:" upon evaluation.

    0 讨论(0)
  • 2020-12-03 21:22

    The following hack worked for me, though it unfortunately relies on $(shell).

    # modify file names immediately
    PRE := $(shell rename : @COLON@ *)
    # example variables that I need
    XDLS = $(wildcard *.xdl)
    YYYS = $(patsubst %.xdl,%.yyy,$(XDLS))
    # restore file names later
    POST = $(shell rename @COLON@ : *)
    
    wrapper: $(YYYS)
        @# restore file names
        $(POST)
    
    $(YYYS):
        @# show file names after $(PRE) renaming but before $(POST) renaming
        @ls
    

    Because PRE is assigned with :=, its associated shell command is run before the XDLS variable is evaluated. The key is to then put the colons back in place after the fact by explicitly invoking $(POST).

    0 讨论(0)
  • 2020-12-03 21:25

    I doubt it's possible: see this discussion about colons in Makefiles. In summary, GNU make has never worked well with filenames that contain whitespace or colons. The maintainer, Paul D. Smith, says that adding support for escaping would tend to break existing makefiles. Furthermore, adding such support would require significant changes to the code.

    You might be able to work around with some sort of nasty temporary file arrangement.

    Good luck!

    0 讨论(0)
  • 2020-12-03 21:39

    I am not positivie this should work, but the reason it says "missing destination file" is simple:

    %.bar: ; cp $< $@
    

    That line says to copy the target from the first dependency. your a:b.bar does not have any dependency, so the cp fails. what did you want it to copy ? a:b.foo ? in that case, you would need:

    %.bar: %.foo ; cp $< $@
    
    0 讨论(0)
  • 2020-12-03 21:46

    There is another way i've found today when dealing with Makefile variables defining filenames (containing colons).

    # definition
    SOME_FNAME = $(NAME)__colon__$(VERSION)
    
    # usage in target
    foo:
        $(do_something) $(subst __colon__,:,$(SOME_FNAME))
    
    0 讨论(0)
  • 2020-12-03 21:46

    I could not get the answer posted by @navjotk to work, so I am just gonna cheat and do this;

    FILENAME:=foo:bar
    foo_bar:
        touch $(FILENAME)
    
    run:
        if [ ! -e "$(FILENAME)" ]; then $(MAKE) foo_bar; fi
    

    output:

    $ make run
    if [ ! -e "foo:bar" ]; then /Library/Developer/CommandLineTools/usr/bin/make foo_bar; fi
    touch foo:bar
    
    $ ls
    Makefile foo:bar
    

    Close enough for me.

    0 讨论(0)
提交回复
热议问题