If you look at the code of GNU make, except on Microsoft platforms
$(<D) is an alias for $(patsubst %/,%,$(dir $<))
$(<F) is an alias for $(notdir $<)
$(dir) and $(notdir) take one argument, which is taken as a space separated list of file paths and they respectively expand to a space separated list of their dirname and basename.
If you have a:
target: dir/A\ B dir2/C
: $(dir $<)
: $(notdir $<)
recipe, $< expands to dir/A B so it's the same as
target: dir/A\ B dir2/C
: $(dir dir/A B)
: $(notdir dir/A B)
So, $(dir dir/A B) expands to the dirname of dir/A (dir/) a space and the dirname of B (./), so dir/ ./ and similarly A B for notdir (not the basename of dir/A B, but the basename of dir/A, a space and the basename of B).
Even if you made it : $(dir dir/A\ B), that would still be the dirname of dir/A\, followed by the dirname of B, there is no handling of backslash in there.
In your case $(dir /home/jidanni/Downloads/DreamHost Web Panel _ Mail _ Message Filters.html) results in /home/jidanni/Downloads/ ./ ./ ./ ./ ./ ./ ./ which becomes /home/jidanni/Downloads . . . . . . . after $(patsubst %/,%,...) is applied to it for $(<D).
In any case, make ultimately runs commands not directly by passing them a list of arguments, but via a shell, to which it passes a single command line string.
It has no such thing as array variables; the way it achieves some form of list is by joining and splitting strings on spaces.
So it should become obvious that you can't really reliably deal with file paths containing spaces.
And as ultimately the contents of make variables are expanded into the shell code, any character that is special in the syntax of the shell would also be a problem.
With make you should only use very tame file names as is typically the case in the source distribution of software it is used to build.
Here, doing:
target:
printf '<%s>\n' "$$(dirname -- '$(FILE)')" "$$(basename -- '$(FILE)')"
And using it in:
$ make target FILE='-dir-/a * b'
printf '<%s>\n' "$(dirname -- '-dir-/a * b')" "$(basename -- '-dir-/a * b')"
<-dir->
<a * b>
Would work. Pay close attention to the shell code that is interpreted and in particular what kind of quotes are used in there: '...' which in POSIX shells are the strong quotes inside which no character is special, and "..." which allows expansions including command substitutions and prevents split+glob on them, and of course the usual -- to avoid problems with arguments starting with -.
But even that does not work in:
$ make target FILE="dir/a'b"
printf '<%s>\n' "$(dirname -- 'dir/a'b')" "$(basename -- 'dir/a'b')"
<dir/ab)" "$(basename -- dir>
(the ' within $FILE ends up being taken as closing quote in the shell syntax. It would be worse with FILE="'\$(reboot)'" for instance).
Nor:
$ make target FILE=' dir/a b'
printf '<%s>\n' "$(dirname -- 'dir/a b')" "$(basename -- 'dir/a b')"
<dir>
<a b>
(leading spaces removed from the start of $FILE somehow).
Nor:
$ make target FILE=$'a\nb'
printf '<%s>\n' "$(dirname -- 'a
/bin/sh: 1: Syntax error: Unterminated quoted string
make: *** [Makefile:2: target] Error 2
That was broken into several shell invocations as you can confirm with:
$ make target FILE=$'a\nb' SHELL=echo
printf '<%s>\n' "$(dirname -- 'a
-c printf '<%s>\n' "$(dirname -- 'a
b')" "$(basename -- 'a
-c b')" "$(basename -- 'a
b')"
-c b')"
Nor:
$ make target FILE='$(SHELL)'
printf '<%s>\n' "$(dirname -- '/bin/sh')" "$(basename -- '/bin/sh')"
</bin>
<sh>
That particular case can be addressed by using $(value FILE) in place of $(FILE).
And of course that $(FILE) cannot be used in any sort of pseudo-list.