带引号的有问题的构建脚本

带引号的有问题的构建脚本

您好,我正在尝试创建一个执行这些命令的构建脚本:

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

它看起来像这样:

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

问题是, echo 命令显示了我想要的确切配置命令,但是在运行配置时它并不是正确的。 after CFLAGS=-mtunecore2,当 configure 尝试使用 -flto (被引用!!)作为参数时,出现了严重错误。

我究竟做错了什么?

谢谢!

PS:我正在运行MSYS,而不是真实的*尼克斯...

答案1

这里有一些纯粹的 Unixoid-shell 问题,我希望 MSYS 不会增加额外的问题。

进行多层引用可能很棘手。如果可能的话,我通常更愿意避免它们。

下面的修改使用$@参数来存储和检索将嵌入空格的参数。如果您需要多个这样的带有嵌入空格的参数列表,并且您的 shell 有数组参数,您可以使用这些参数(因为只有一个$@)。

# 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


对于您所声明的要求,您可以只使用这一级别的保护,但如果您需要多层引用(例如,如果BUILD_CORES包含空格,您将处理多层引用:makeopts/中的一层引用BUILD_LFLAGS和两层引用中的引用CONFIG_OPTS)。在这种情况下,我可能会求助于使用printfwith%qeval。格式%q说明符在大多数(但不是全部)shell 中可用(,巴什,桀骜)。它引用了它的值,以便以后可以正确评估它。

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

在这种特殊情况下,您还需要注意从LFLAGSconfigure获取的任何内容都知道如何“读取”shell生成的引用值。如果脚本是用 shell 语言编写的,其中%q生成系统上的默认 shell(即/bin/sh)不理解的构造(例如有时会产生$'blah'构造,但有些 shell 不知道如何解析它们)。

答案2

请注意,您没有在脚本中定义 PREFIX,因此需要在其他地方定义它才能正常工作,但我认为您想要(警告:我没有对此进行测试。):

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

请注意,当您使用双引号时,变量将在字符串内扩展(通常称为变量插值)。另外,我相信您的原始脚本中的引号不匹配,这也可能会给您带来问题。

相关内容