Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Oct 2013 12:03:32 +0200
From:      Johan Kuuse <kuuse@redantigua.com>
To:        freebsd-questions@freebsd.org
Subject:   Re: FreeBSD Make question
Message-ID:  <CAGUU1d1jxXREw7e+XPRu8H3y12gP4BB-L3RVyCW0GFOEhH-3PQ@mail.gmail.com>
In-Reply-To: <20131018070903.7ef5f8a8.freebsd@edvax.de>
References:  <CAGUU1d2T5QMWF619KXgoMwtAG1iA4zcL3KFuCcg-tdOZBrXSGg@mail.gmail.com> <20131018070903.7ef5f8a8.freebsd@edvax.de>

Next in thread | Previous in thread | Raw E-Mail | Index | Archive | Help
--089e01160f56043fb104e9010c1b
Content-Type: text/plain; charset=ISO-8859-1

Hi again,

Thanks for all input (especially David Wheeler's articles are very
informative).
I have to stress that the whitespace problem I have applies to the Makefile
*target names*.
It is not about how to escape whitespaces in the shell commands.
I attach the Makefile I use for testing.

As you can see, I have tried four different types of escaping (actually I
have tried a lot more combinations, to be honest), but  I can't make it
work using BSD Make.
Both BSD Make and GNU Make treats a directory names containing spaces as a
list of targets (logical), but when trying to escape target names, the
differences starts to notice between the Make flavors.
GNU Make terminates with error when single or double quotes are used in
target names, while BSD Make interpretes quoted targets as a list of
target. Using a backslash (\) to escape whitespaces works with GNU Make
(the target is interpreted as a single target name, not as a list), while
BSD Make adds a literal '\' to the target name.
The problem gets really serious when using two or more targets, as shown in
the Makefile.

I haven't dived into the BSD Make source code, so I cannot tell the $IFS
variable is honored when dealing with whitespaces in names. Anyhow,
manipulating the $IFS environment variable, I had no success neither.
And yes, I limit this problem to the whitespace character, no control
charaters. :-)

Once again, any help appreciated.

Best Regards,
Johan


Makefile.freebsd-questions
--------
# MY_TARGET=/home/joe/directory name with spaces/hello.c
# MY_SECOND_TARGET=/home/joe/directory name with spaces/world.c

# MY_TARGET='/home/joe/directory name with spaces/hello.c'
# MY_SECOND_TARGET='/home/joe/directory name with spaces/world.c'

# MY_TARGET="/home/joe/directory name with spaces/hello.c"
# MY_SECOND_TARGET="/home/joe/directory name with spaces/world.c"

MY_TARGET=/home/joe/directory\ name\ with\ spaces/hello.c
MY_SECOND_TARGET=/home/joe/directory\ name\ with\ spaces/world.c

all: ${MY_TARGET} ${MY_SECOND_TARGET}
@echo This is Make version $(MAKE_VERSION)

${MY_TARGET}:
@echo $@

${MY_SECOND_TARGET}:
@echo $@
--------


BSD Make doesn't work as expected:
make -f Makefile.freebsd-questions
--------
"Makefile.freebsd-questions", line 20: warning: duplicate script for target
"/home/joe/directory\" ignored
"Makefile.freebsd-questions", line 20: warning: duplicate script for target
"name\" ignored
"Makefile.freebsd-questions", line 20: warning: duplicate script for target
"with\" ignored
/home/joe/directory\
name\
with\
spaces/hello.c
spaces/world.c
This is Make version 9201120530
--------

GNU Make works OK:
gmake -f Makefile.freebsd-questions
--------
/home/joe/directory name with spaces/hello.c
/home/joe/directory name with spaces/world.c
This is Make version 3.82
--------



On Fri, Oct 18, 2013 at 7:09 AM, Polytropon <freebsd@edvax.de> wrote:

> On Thu, 17 Oct 2013 18:43:33 +0200, Johan Kuuse wrote:
> > Hi,
> >
> > I'm trying to write a Makefile for FreeBSD Make (not GNU Make), with
> target
> > names containg spaces.
> > Example:
> >
> > MY_TARGET=/home/joe/directory name with spaces/hello.c
> > ${MY_TARGET}:
> >     @echo ${.TARGET}
> >
> > The output is truncated to '/home/joe/directory'
>
> That is to be expected. :-)
>
> The space character is a _special_ character. It serves as
> a statement separator. (There are other special characters
> depending for example on the shell in use; other systems
> have different special characters that _could_ be valid in
> directory names or file names, but _should_ not be used
> because they could cause trouble when _improperly_ dealt
> with.)
>
>
>
> > Is there any possible way to escape this properly?
>
> There are, in fact, many possibilities.
>
> In an "O(n) manner" you can use the backslash \ to escape
> each of the spaces. They hereby lose their special meaning
> of being a statement separator:
>
> MY_TARGET=/home/joe/directory\ name\ with\ spaces/hello.c
>
> In an "O(1) manner" you can enclose the whole string in
> double quotes "...":
>
> MY_TARGET="/home/joe/directory name with spaces/hello.c"
>
> Single quotes '...' work similarly, with the exception that _if_
> your string contains variables, they would not be expanded,
> but in your example, this does not apply.
>
> MY_TARGET='/home/joe/directory name with spaces/hello.c'
>
> The so-called backticks `...` have a totally different meaning
> (subshell result) and will not be considered here. :-)
>
>
>
> > I have read all the documentation I could find, and tried several ways
> > solving this problem, using quotes, escapes, substitutions.
>
> Note that even if you get the above statement working, there
> could be further annoying trouble ahead! If you intend to use
> special characters in file names (and directory names), there
> are a lot things you have to pay attention to.
>
> I suggest having a read of the following articles:
>
> David A. Wheeler:
> Filenames and Pathnames in Shell:
> How to do it correctly
>
> http://www.dwheeler.com/essays/filenames-in-shell.html
>
> as well as
>
> David A. Wheeler:
> Fixing Unix/Linux/POSIX Filenames:
> Control Characters (such as Newline), Leading Dashes,
> and Other Problems
>
> http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html
>
>
>
> > The output is the same if as use sh, bash, or tcsh, so it isn't shell
> > related.
>
> The Makefile executes a shell (usually sh) for each command
> to be executed. It handles its own statements "internally"
> (declaring dependencies and such).
>
>
>
> > Are spaces simply not possible to use in target names?
>
> They are possible, but you should not use them. It's also
> possible to use ~, *, newline, ; or - in file names, but
> you really _really_ should not do this. :-)
>
>
>
>
>
> --
> Polytropon
> Magdeburg, Germany
> Happy FreeBSD user since 4.0
> Andra moi ennepe, Mousa, ...
>

--089e01160f56043fb104e9010c1b
Content-Type: application/octet-stream; name="Makefile.freebsd-questions"
Content-Disposition: attachment; filename="Makefile.freebsd-questions"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_hmx7f9wq0

IyBNWV9UQVJHRVQ9L2hvbWUvam9lL2RpcmVjdG9yeSBuYW1lIHdpdGggc3BhY2VzL2hlbGxvLmMK
IyBNWV9TRUNPTkRfVEFSR0VUPS9ob21lL2pvZS9kaXJlY3RvcnkgbmFtZSB3aXRoIHNwYWNlcy93
b3JsZC5jCgojIE1ZX1RBUkdFVD0nL2hvbWUvam9lL2RpcmVjdG9yeSBuYW1lIHdpdGggc3BhY2Vz
L2hlbGxvLmMnCiMgTVlfU0VDT05EX1RBUkdFVD0nL2hvbWUvam9lL2RpcmVjdG9yeSBuYW1lIHdp
dGggc3BhY2VzL3dvcmxkLmMnCgojIE1ZX1RBUkdFVD0iL2hvbWUvam9lL2RpcmVjdG9yeSBuYW1l
IHdpdGggc3BhY2VzL2hlbGxvLmMiCiMgTVlfU0VDT05EX1RBUkdFVD0iL2hvbWUvam9lL2RpcmVj
dG9yeSBuYW1lIHdpdGggc3BhY2VzL3dvcmxkLmMiCgpNWV9UQVJHRVQ9L2hvbWUvam9lL2RpcmVj
dG9yeVwgbmFtZVwgd2l0aFwgc3BhY2VzL2hlbGxvLmMKTVlfU0VDT05EX1RBUkdFVD0vaG9tZS9q
b2UvZGlyZWN0b3J5XCBuYW1lXCB3aXRoXCBzcGFjZXMvd29ybGQuYwoKYWxsOiAke01ZX1RBUkdF
VH0gJHtNWV9TRUNPTkRfVEFSR0VUfQoJQGVjaG8gVGhpcyBpcyBNYWtlIHZlcnNpb24gJChNQUtF
X1ZFUlNJT04pCgoke01ZX1RBUkdFVH06CglAZWNobyAkQAoKJHtNWV9TRUNPTkRfVEFSR0VUfToK
CUBlY2hvICRACg==
--089e01160f56043fb104e9010c1b--



Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?CAGUU1d1jxXREw7e+XPRu8H3y12gP4BB-L3RVyCW0GFOEhH-3PQ>