Looks like the canonical way to do this in bash is something like
unset args
while IFS= read -r line; do
args+=("$line")
done < file
cmd "${args[@]}"
or, if your version of bash has mapfile:
mapfile -t args < filename
cmd "${args[@]}"
The only difference I can find between the mapfile and the while-read loop versus the one-liner
(set -f; IFS=$'\n'; cmd $(<file))
is that the former will convert a blank line to an empty argument, while the one-liner will ignore a blank line. In this case the one-liner behavior is what I'd prefer anyway, so double bonus on it being compact.
I would use IFS=$'\n' cmd $(<file) but it doesn't work, because $(<file) is interpreted to form the command line before IFS=$'\n' takes effect.
Though it doesn't work in my case, I've now learned that a lot of tools support terminating lines with null (\000) instead of newline (\n) which does make a lot of this easier when dealing with, say, file names, which are common sources of these situations:
find / -name '*.config' -print0 | xargs -0 md5
feeds a list of fully-qualified file names as arguments to md5 without any globbing or interpolating or whatever. That leads to the non-built-in solution
tr "\n" "\000" <file | xargs -0 cmd
although this, too, ignores empty lines, though it does capture lines that have only whitespace.