What is the most reliable way of using GNUMake with filenames containing spaces?

前端 未结 6 1406
深忆病人
深忆病人 2021-01-12 11:11

I want to use GNUMake to run a rule-based makefile which builds a set of C files in a directory structure (on a Windows file system).

The root directory, some sub-di

相关标签:
6条回答
  • 2021-01-12 11:46

    The easiest thing is indeed to fix the file names.

    Failing that, though, write your commands to put double quotes around the file names. The easiest and safest thing is to put all the file names into macros; the trick there is that you have to escape the double quotes, which Make is otherwise going to want to eat up itself.

    So: FN="\"C:\My Documents\myfiles.c\"" FN2="C:\My Documents\myfile2.c"

    or use $(CC) $(CFLAGS) "$(FN2)"

    The trick here is to echo your command line with echo

    echo $(CC) $(CFLAGS) "$(FN2)"
    

    or use make -d to get all the details of what make is trying to do.

    You may need to hack about with this a bit, in particular, you may need to double up the escapes

    0 讨论(0)
  • 2021-01-12 11:47

    If the spaces are only in the "root" part of the pathname, you can mount that directory on a path without blanks. There are multiple ways of doing this: from the command line ("net use" or "subst") or from Explorer (Tools > Map Network Drive). So C:\Documents and Settings\\My Documents\Test Dir" might become X:\BuildMe.c

    However, if there are blanks in the file names, or in directories below the "root" build directory, then there probably aren't any perfect solutions. I've used the other suggestions you mentioned (8.3 names, replacing blanks with a different character) and these work but they have their own problems.

    0 讨论(0)
  • 2021-01-12 11:49

    I simply add 'single quotes' around the offending string:- '$(TARGET_DIR)'

    Example: (this helped me get erlang.mk to work correctly on windows!)

    app:: $(C_SRC_ENV)
        @mkdir -p priv/
        $(c_src_verbose) $(CC) $(CFLAGS) $(C_SRC_DIR)/*.c -fPIC -shared -o $(C_SRC_OUTPUT) \
            -I '$(ERTS_INCLUDE_DIR)' $(C_SRC_OPTS)
    

    '$(ERTS_INCLUDE_DIR)' now correctly expands to 'c:/Program Files/erl7.0/erts-7.0/include/'

    using make -d also helps reveal invalid paths

    0 讨论(0)
  • 2021-01-12 12:02

    You may be able to escape the spaces in your makefile, i.e.:

    $(CC) $(CFLAGS) 'C:\Documents\ and\ Settings\<username>\My\ Documents\Test\ Dir\Build Me.c'
    

    I've added the single quotes just in case, but I don't know if this works if you're using the windows terminal (rather than cygwin etc).

    0 讨论(0)
  • 2021-01-12 12:03

    I found a great inspiration at http://www.mail-archive.com/help-make@gnu.org/msg05201.html which got me going. My own test application consists of a directory of WW2-era Jazz FLV files downloaded from YouTube and an audio subdirectory into which I'd like to store the OGA audio versions of each one. And, of course, the file names contain spaces. I would then like to run ffmpeg2theora to

    Here is the GNUMake Makefile that I've hacked together to work. Thanks to all of the hints on this site and also the referenced site above!

    sq = $(subst $(sp),?,$1)
    qs = $(subst ?,$(sp),$1)
    
    e :=
    sp := $(e) $(e)
    
    FLVS := $(foreach file,var,$(call sq,$(wildcard *.flv)))
    FLVS := $(subst .flv?,.flv ,$(FLVS))
    
    AUDIOS := $(patsubst %.flv,audio/%.oga,$(FLVS))
    
    .PHONY: audios show
    
    audios: $(AUDIOS)
    
    $(AUDIOS) : $(FLVS)
        ffmpeg2theora --novideo -o "$(call qs,$@)" "$(call qs,$(notdir $(patsubst %.oga,audio/%.flv,$@)))"
    
    show:
        echo $(FLVS)
        echo $(AUDIOS)
    
    0 讨论(0)
  • 2021-01-12 12:08

    I've typically used what is sort of a combination of Dana the Sane's answer and Brian Yoder's answer.

    You just use the $(subst) function to replace all occurances of spaces with escaped spaces. EG:

    empty := 
    space := $(empty) $(empty)
    program_files := $(subst $(space),\$(space),$(ProgramFiles))
    

    (Note that with some older versions of make on Windows you would also need to use another $(subst) to change path backslashes to slashes)

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