Script de construção problemático com aspas

1

Oi eu estou tentando criar um script de construção que executa esses comandos:

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 ..

Parece assim:

#!/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 ..

A coisa é, o comando echo mostra o comando de configuração exato que eu quero, mas ao executar o configure, não é a coisa certa. Algo vai terrivelmente errado, depois de CFLAGS=-mtunecore2 , quando o configure tenta usar -flto (que é citado !!) como um argumento.

O que estou fazendo de errado?

Obrigado!

PS: Estou executando MSYS, não real * nix ...

    
por rubenvb 15.09.2010 / 19:54

2 respostas

1

Há alguns problemas puramente de shell Unixoid aqui, espero que o MSYS não esteja adicionando problemas extras também.

Fazer vários níveis de cotação pode ser complicado. Eu geralmente prefiro evitá-los, se possível.

A modificação abaixo usa o parâmetro $@ para armazenar e recuperar os argumentos que terão espaço em branco incorporado. Se você precisar de várias dessas listas de argumentos com espaço em branco incorporado e seu shell tiver parâmetros de matriz, você poderá usá-los (já que existe apenas um dos $@ ).

# 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


Para seus requisitos declarados, você pode se safar com esse nível único de proteção, mas se precisar de vários níveis de cotação (por exemplo, se BUILD_CORES contivesse espaço em branco, estaria lidando com vários níveis de cotação: um nível de cotação em makeopts / BUILD_LFLAGS e dois níveis de cotação em CONFIG_OPTS ). Nesse caso, posso recorrer ao uso de printf com %q e eval . O especificador de formato %q está disponível na maioria dos shells, mas não em todos ( ksh , bash , zsh ). Ele cita seu valor para que possa ser avaliado mais tarde corretamente.

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

Neste caso em particular, você também precisa tomar cuidado para que qualquer coisa que obtenha LFLAGS do configure saiba como “ler” o valor citado que o shell produziu. Isso pode ser um problema se o script for escrito em uma linguagem shell em que %q produza uma construção que o shell padrão no sistema (ou seja, /bin/sh ) não entende (por exemplo, ksh às vezes produz $'blah' constrói, mas algumas conchas não sabem como analisá-las).

    
por 16.09.2010 / 10:58
0

Note que você não define PREFIX no seu script, então ele precisa ser definido em outro lugar para que isso funcione, mas eu acho que você quer ( Aviso: eu não fiz nenhum teste sobre isso. ) :

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}"

Observe que, quando você usa aspas duplas, a variável será expandida dentro da string (geralmente chamada de interpolação variável). Além disso, acredito que você tenha citações incompatíveis em seu script original que provavelmente também estavam causando problemas.

    
por 15.09.2010 / 21:27