FreeBSD Make question

Johan Kuuse kuuse at redantigua.com
Fri Oct 25 22:38:34 UTC 2013


Johan:
Sorry for cluttering up my last mail with "enhanced" Gmail RTF, here
we go again in plain text, and a couple of added comments.

Benjamin:
    >>>Simon: do we allow whitespace in target names in either fmake or bmake?
    >>>If so, what are the escaping rules?

Johan:
> Thanks Benjamin for the hints, I'll check out the -hackers list.

Simon:
   > Whether it is "allowed" or not, it isn't something I would consider
   >doing.


Johan:
>Hi Simon,
>I definitely agree that whitespaces shouldn't go into targets if it could be avoided.

Simon:
  >>This works fine - my dirdeps.mk uses absolute paths of directories (plus
  >>added attributes) as targets

Johan:
>The background is that I'm trying to create a system of nonrecursive Makefiles, where all paths must be absolute.
>This implies using absolute paths as target names. What if a path contains whitespaces? (God forbid!)

Simon:
You lose.  Ideally you throw an error.

.error "Sorry ${USER}, I cannot let you do that"

Alternatively you could try substituting the spaces with glob chars.
That may cause more trouble than it fixes.

fixing make to handle this would not be trivial.

Johan:
Can you give an example of such a (glob chars) substitution?
May it be similar to, or better than, my ugly hack (see below)?


Simon:
    >What is the problem we are trying to solve?

Johan:
Problem described above, below goes a sample Makefile, trying several
ways to escaping whitespaces in target names.

The Makefile:

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 $@
--------

The output:

FreeBSD Make fails:
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
--------


The only possible workaround I have found so far with FreeBSD Make, is
to substitute whitespaces with another character in the target
variables, for example '+', (i.e.
/home/joe/directory+name+with+spaces/hello.c) and using the modified
variable as the target name. In the target rule, the variable
substitution then has to be "reversed" to obtain the "real" target
name:

# MY_TARGET=/home/joe/directory name with spaces/hello.c
# MY_TARGET_PLUS != echo "$(MY_TARGET)" | sed -e 's/ /+/g'

${MY_TARGET_PLUS}:
    @echo "${@:C/\+/ /g}"


Using this ugly hack, the warnings disappears in the example above,
but it doesn't really resolve the problem, as MY_TARGET_PLUS will
always be a non-existing target. So using this hack, targets will
always be executed/rebuilt, even if MY_TARGET is up to date.

Please just confirm that there is no other, better glob char
substitution, to resolve this problem.
Then I can consider FreeBSD Make + target-name-with-whitespaces = dead end.

Best regards,
Johan Kuuse


More information about the freebsd-doc mailing list