FreeBSD Make question

Johan Kuuse kuuse at redantigua.com
Fri Oct 18 10:03:35 UTC 2013


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 at 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, ...
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Makefile.freebsd-questions
Type: application/octet-stream
Size: 637 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-questions/attachments/20131018/c5a01e3e/attachment.obj>


More information about the freebsd-questions mailing list