Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Hi I'm trying to create a build script that executes these commands:

cd libiconv
../../src/libiconv/configure --prefix=/home/ruben/mingw64/build/gcc-libs \
                             --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 \
                             CFLAGS="-mtune=core2 -flto -fomit-frame-pointer -momit-leaf-frame-pointer" LFLAGS="-flto -fwhopr=2"
make -j3 -s
make -s install
cd ..

It looks like this:

#!/bin/sh
HOST=x86_64-w64-mingw32
TARGET=x86_64-w64-mingw32
BUILD=x86_64-w64_mingw32
# options
BUILD_CORES=2 #used as argument for "make -j#"
# directories: SRC_DIR contains full source package.
GCC_LIBS_DIR=$BUILD_DIR/gcc-libs

# optimized for my system.
BUILD_CFLAGS="\"-mtune=core2 -flto -fomit-frame-pointer -momit-leaf-frame-pointer\""
BUILD_LFLAGS="\"-flto -fwhopr="${BUILD_CORES}"\""
CONFIG_OPTS="--prefix="${PREFIX}" --host="${HOST}" --build="${BUILD}" CFLAGS="${BUILD_CFLAGS}" LFLAGS="${BUILD_LFLAGS}  
makeopts="-s -j"${BUILD_CORES}

# libiconv
cd libiconv
echo "configuring libiconv: "${CONFIG_OPTS}
../../src/libiconv/configure "${CONFIG_OPTS}" > configure.log || exit 1
echo "building libiconv"
make $MAKEOPTS > build.log || exit 1
echo "installing libiconv"
make -s install > install.log || exit 1
cd ..

The thing is, the echo command shows the exact configure command I want, but when running configure it doesn't so the right thing. Something goes terribly wrong, after CFLAGS=-mtunecore2, when configure tries to use -flto (which is quoted!!) as an argument.

What am I doing wrong?

Thanks!

PS: I'm running MSYS, not real *nix...

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

There are some purely Unixoid-shell issues here, I hope MSYS is not adding extra problems, too.

Doing multiple levels of quoting can be tricky. I usually prefer to avoid them if possible.

The modification below uses the $@ parameter to store and retrieve the arguments that will have embedded whitespace. If you need multiple such lists of arguments with embedded whitespace and your shell has array parameters you could those (since there is only one of $@).

# assume BUILD_CORES is simple enough that it will not need extra quoting later...
BUILD_CFLAGS='-mtune=core2 -flto -fomit-frame-pointer -momit-leaf-frame-pointer'
BUILD_LFLAGS="-flto -fwhopr=$BUILD_CORES"
set -- --prefix="$PREFIX" --host="$HOST" --build="$BUILD" CFLAGS="$BUILD_CFLAGS" LFLAGS="$BUILD_LFLAGS"
makeopts="-s -j$BUILD_CORES"

# libiconv
cd libiconv
echo "configuring libiconv: $@"
../../src/libiconv/configure "$@" > configure.log || exit 1


For your stated requirements, you can get away with just this single level of protection, but if you needed multiple levels of quoting (e.g. if BUILD_CORES contained whitespace you would be dealing with multiple levels of quoting: one level of quoting in makeopts/BUILD_LFLAGS, and two levels of quoting in CONFIG_OPTS). In that case I might resort to using printf with %q and eval. The %q format specifier is available in most, but not all, shells (ksh, bash, zsh). It quotes its value so that it can later be evaluated correctly.

BUILD_CFLAGS='-mtune=core2 -flto -fomit-frame-pointer -momit-leaf-frame-pointer'
BUILD_LFLAGS=$(printf '%s-flto -fwhopr=%q' '' "$BUILD_CORES")
CONFIG_OPTS=$(printf \
  '%s--prefix=%q --host=%q --build=%q CFLAGS=%q LFLAGS=%q' '' \
  "$PREFIX" "$HOST" "$BUILD" "$BUILD_CFLAGS" "$BUILD_LFLAGS")
makeopts=$(printf '%s-s -j%q' '' "$BUILD_CORES")

# libiconv
cd libiconv
echo "configuring libiconv:" "$CONFIG_OPTS"
eval ../../src/libiconv/configure "$CONFIG_OPTS"
echo "building libiconv"
eval make "$MAKEOPTS" > build.log || exit 1

In this particular case you would also need to take care that anything that gets LFLAGS from configure will know how to “read” the quoted value that the shell produced. This could be a problem if the script is written in a shell language where %q produces a construct that the default shell on the system (i.e. /bin/sh) does not understand (e.g. ksh will sometimes produce $'blah' constructs, but some shells do not know how to parse them).

share|improve this answer
    
eval is exactly what was needed. I just used the BUILD_CFLAGS="\"...\"" ... CONFIG_OPTS="..$BUILD_CFLAGS" ... eval ../../src/libiconv/configure "$CONFIG_OPTS$"... version and it works as it should now. Thanks! –  rubenvb Sep 17 '10 at 17:07
    
@above: I meant "..."$CONFIG_OPTS" without the last $ –  rubenvb Sep 17 '10 at 17:37
add comment

Note that you don't define PREFIX in your script, so it needs to be defined elsewhere for this to work, but I think you want(Warning: I did no testing on this.):

BUILD_CFLAGS="\"-mtune=core2 -flto -fomit-frame-pointer -momit-leaf-frame-pointer\""
BUILD_LFLAGS="\"-flto -fwhopr=${BUILD_CORES}\""
CONFIG_OPTS="--prefix=${PREFIX} --host=${HOST} --build=${BUILD} CFLAGS=${BUILD_CFLAGS}  
LFLAGS=${BUILD_LFLAGS}"
MAKEOPTS="-s -j${BUILD_CORES}"

Notice that when you are using double-quotes that the variable will be expanded within the string (often called variable interpolation). Also, I believe you had mismatched quotes in your original script that were also likely causing you problems.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.