0

I'm trying to build Emacs from sources. When configure options were listed without an array Emacs configured properly. When I added a Bash array to add optional options it broke configure. Here is the broken array:

BUILD_OPTS=('--with-xml2' '--without-x' '--without-sound' '--without-xpm'
    '--without-jpeg' '--without-tiff' '--without-gif' '--without-png'
    '--without-rsvg' '--without-imagemagick' '--without-xft' '--without-libotf'
    '--without-m17n-flt' '--without-xaw3d' '--without-toolkit-scroll-bars' 
    '--without-gpm' '--without-dbus' '--without-gconf' '--without-gsettings'
    '--without-makeinfo' '--without-compress-install')

if [[ ! -e "/usr/include/selinux/context.h" ]] &&
   [[ ! -e "/usr/local/include/selinux/context.h" ]]; then
    BUILD_OPTS+=('--without-selinux')
fi

    PKG_CONFIG_PATH="${BUILD_PKGCONFIG[*]}" \
    CPPFLAGS="${BUILD_CPPFLAGS[*]}" \
    CFLAGS="${BUILD_CFLAGS[*]}" CXXFLAGS="${BUILD_CXXFLAGS[*]}" \
    LDFLAGS="${BUILD_LDFLAGS[*]}" LIBS="${BUILD_LIBS[*]}" \
./configure --prefix="$INSTALL_PREFIX" --libdir="$INSTALL_LIBDIR" \
    "${BUILD_OPTS[*]}"

When configuring with the array it results in:

configure: error: invlaid package name: xml2 --without-x --without-sound --without-xpm --without-jpeg --without-tiff --without-gif ...

I've been through 10.2. Array variables but I don't see what I am doing wrong. Changing to double quote and no quote did not help.

What is the problem and how do I fix it?

2 Answers2

3

From man bash:

   Any element of an array may  be  referenced  using  ${name[subscript]}.
   The braces are required to avoid conflicts with pathname expansion.  If
   subscript is @ or *, the word expands to all members  of  name.   These
   subscripts  differ only when the word appears within double quotes.  If
   the word is double-quoted, ${name[*]} expands to a single word with the
   value  of each array member separated by the first character of the IFS
   special variable, and ${name[@]} expands each element of name to a sep‐
   arate  word.

TL/DR: use "${BUILD_PKGCONFIG[@]}" in place of "${BUILD_PKGCONFIG[*]}"

To illustrate:

$ arr=('foo' 'bar baz')
$ printf '%s\n' "${arr[*]}"
foo bar baz
$ 
$ printf '%s\n' "${arr[@]}"
foo
bar baz
steeldriver
  • 81,074
  • Thanks @steeldriver. I am using single quotes, not double quotes. The behavior does not make sense, given "These subscripts differ only when the word appears within double quotes." Since double quotes are not being used, * and @ behave the same way. Or am I missing something? –  Jan 04 '18 at 02:09
  • @jww he passage is referring to the quotes around the expansion i.e. "${BUILD_PKGCONFIG[@]}" - the quoting of the elements during array creation is not the issue here (nevertheless I've changed them in my example, to avoid confusion) – steeldriver Jan 04 '18 at 02:10
  • Your answer is not too confusing, but the explicit action helped. The documents are very confusing. Why would the docs refer to the "array name" as a "word"? The "words" are the arrays elements, not the array name. They should switch to "array name" and "array element" to avoid all confusion. But that would probably make too much sense. Why remove confusion after 30 years... Awful docs... –  Jan 04 '18 at 02:22
  • It is not just the array name. It is the array name together with the ${ and the [*]} around it. Switching to array name will not make it clearer, in my opinion. – Weijun Zhou Jan 04 '18 at 03:29
2

You're expanding all elements of your arrays, concatenated together with spaces in between, as a SINGLE argument.

Use "${arrayname[@]}" rather than "${arrayname[*]}" and you should get the result you expect.

See LESS='+/^[[:space:]]*Arrays' man bash for further reading.

Wildcard
  • 36,499