如何为基于 autotool 的项目启用特定于 Xcode 的构建标志



我正在尝试为iOS构建Google protobuf项目,但目前尚不清楚如何使用autotool启用iOS特定的标志,例如-fembed-bitcodeBITCODE_GENERATION_MODE=bitcode。我尝试使用以下脚本:

#!/bin/bash
## Environments
ScriptDir="$( cd "$( dirname "$0" )" && pwd )"
cd - &> /dev/null
# Exit the build pass if any command returns a non-zero value
#set -o errexit

# Echo commands
set -x
# 13.4.0 - Mavericks
# 14.0.0 - Yosemite
# 15.0.0 - El Capitan
# 16.0.0 - Sierra
DARWIN=darwin`uname -r`
MIN_SDK_VERSION=8.0
IPHONEOS_SYSROOT=`xcrun --sdk iphoneos --show-sdk-path`
IPHONESIMULATOR_SYSROOT=`xcrun --sdk iphonesimulator --show-sdk-path`
# Verbose clang output
#CLANG_VERBOSE="--verbose"
CC=clang
CXX=clang
SILENCED_WARNINGS="-Wno-unused-local-typedef -Wno-unused-function"
# NOTE: Google Protobuf does not currently build if you specify 'libstdc++'
# instead of `libc++` here.
STDLIB=libc++
CFLAGS="${CLANG_VERBOSE} ${SILENCED_WARNINGS} -DNDEBUG -g -O0 -pipe -fPIC -fcxx-exceptions"
CXXFLAGS="${CFLAGS} -std=c++11 -stdlib=${STDLIB}"
LDFLAGS="-stdlib=${STDLIB}"
LIBS="-lc++ -lc++abi"
PROTOC=`which protoc`
PROTOBUF_SOURCE_DIR="$ScriptDir"
PREFIX="$ScriptDir"/_build
if [ -d ${PREFIX} ]
then
rm -rf "${PREFIX}"
fi
mkdir -p "${PREFIX}/platform" &> /dev/null
## Functions
build-arch() {
HOST=$1
ARCH=$2
PLATFORM_CFLAGS=$3
PLATFORM_NAME=${ARCH}
SYSROOT=${IPHONEOS_SYSROOT}
make distclean
./configure 
--build=x86_64-apple-${DARWIN} 
--host=${HOST} 
--with-protoc=${PROTOC} 
--disable-shared 
--prefix=${PREFIX} 
--exec-prefix=${PREFIX}/platform/${PLATFORM_NAME} 
"CC=${CC}" 
"CFLAGS=${CFLAGS} -miphoneos-version-min=${MIN_SDK_VERSION} -arch ${ARCH} -isysroot ${SYSROOT} ${PLATFORM_CFLAGS}" 
"CXX=${CXX}" 
"CXXFLAGS=${CXXFLAGS} -miphoneos-version-min=${MIN_SDK_VERSION} -arch ${ARCH} -isysroot ${SYSROOT}" 
LDFLAGS="-arch ${ARCH} -miphoneos-version-min=${MIN_SDK_VERSION} ${LDFLAGS}" 
"LIBS=${LIBS}"
make -j8
make install
}
build-i386-simulator() {
ARCH=i386
HOST=${ARCH}-apple-${DARWIN}
PLATFORM_NAME=${ARCH}-simulator
SYSROOT=${IPHONESIMULATOR_SYSROOT}
make distclean
./configure 
--build=x86_64-apple-${DARWIN} 
--host=${HOST} 
--with-protoc=${PROTOC} 
--disable-shared 
--prefix=${PREFIX} 
--exec-prefix=${PREFIX}/platform/${PLATFORM_NAME} 
"CC=${CC}" 
"CFLAGS=${CFLAGS} -mios-simulator-version-min=${MIN_SDK_VERSION} -arch ${ARCH} -isysroot ${SYSROOT}" 
"CXX=${CXX}" 
"CXXFLAGS=${CXXFLAGS} -mios-simulator-version-min=${MIN_SDK_VERSION} -arch ${ARCH} -isysroot ${SYSROOT}" 
LDFLAGS="-arch ${ARCH} -mios-simulator-version-min=${MIN_SDK_VERSION} ${LDFLAGS}" 
"LIBS=${LIBS}"
make -j8
make install
}
build-x86_64-simulator() {
ARCH=x86_64
PLATFORM_NAME=${ARCH}-simulator
SYSROOT=${IPHONESIMULATOR_SYSROOT}
make distclean
./configure --prefix=${PREFIX} 
--exec-prefix=${PREFIX}/platform/${PLATFORM_NAME} 
--with-sysroot=${SYSROOT} 
--with-protoc=`which protoc` 
--enable-static 
--disable-shared
make -j8
make install
}
build-fat-lib() {
OUT=${PREFIX}/universal
mkdir -p ${OUT}
PLATFORM_ROOT=${PREFIX}/platform
LIPO=lipo
LIB=libprotobuf.a
${LIPO} ${PLATFORM_ROOT}/arm64/lib/${LIB} 
${PLATFORM_ROOT}/armv7/lib/${LIB} 
${PLATFORM_ROOT}/x86_64-simulator/lib/${LIB} 
${PLATFORM_ROOT}/i386-simulator/lib/${LIB} 
-create 
-output ${OUT}/${LIB}
LIB_LITE=libprotobuf-lite.a
${LIPO} ${PLATFORM_ROOT}/arm64/lib/${LIB_LITE} 
${PLATFORM_ROOT}/armv7/lib/${LIB_LITE} 
${PLATFORM_ROOT}/x86_64-simulator/lib/${LIB_LITE} 
${PLATFORM_ROOT}/i386-simulator/lib/${LIB_LITE} 
-create 
-output ${OUT}/${LIB_LITE}
}
## Build pass
cd ${PROTOBUF_SOURCE_DIR}
./autogen.sh
build-x86_64-simulator
build-i386-simulator
build-arch arm arm64 "BITCODE_GENERATION_MODE=bitcode -fembed-bitcode"
build-arch armv7-apple-${DARWIN} armv7 -fembed-bitcode
build-fat-lib
echo DONE!

在上面的脚本中,我尝试通过 CFLAGS 传递我想要的选项,但没有奏效:通过此脚本构建 protobuf 库通过,但与另一个 Xcode 项目链接输出通用库失败。所以很明显,位码不包括在内,即标志不起作用。

我想知道是否不可能单独使用自动工具实现我所做的事情。我应该为此创建一个真正的 Xcode 项目吗?

自动工具提供了一个用于构建和维护构建系统的框架。 它们确实提供了一些标准化,但在很大程度上,基于 Autotools 的构建系统的功能是特定于项目的。

但话虽如此,你的脚本不会通过CFLAGSCC或其他任何内容传递给configure。 这些是configure识别的环境变量,但您试图将它们作为参数传达。 如果您想在make步骤中注入这些参数,这是最好的方法,但默认情况下它根本不适用于configure。 shell 语法要求变量赋值位于命令名称之前,例如:

"CC=${CC}" 
"CFLAGS=${CFLAGS} -miphoneos-version-min=${MIN_SDK_VERSION} -arch ${ARCH} -isysroot ${SYSROOT} ${PLATFORM_CFLAGS}" 
"CXX=${CXX}" 
"CXXFLAGS=${CXXFLAGS} -miphoneos-version-min=${MIN_SDK_VERSION} -arch ${ARCH} -isysroot ${SYSROOT}" 
LDFLAGS="-arch ${ARCH} -miphoneos-version-min=${MIN_SDK_VERSION} ${LDFLAGS}" 
"LIBS=${LIBS}" 
./configure 
--build=x86_64-apple-${DARWIN} 
--host=${HOST} 
--with-protoc=${PROTOC} 
--disable-shared 
--prefix=${PREFIX} 
--exec-prefix=${PREFIX}/platform/${PLATFORM_NAME}

或者,您可以通过前面的一个或多个单独的configure命令设置和export这些变量。

此外,顺便说一句

,当没有makefile时,make distclean不会执行您想要的操作,在尚未配置的Autotools项目中就是这种情况。 您应该通过使该命令的执行以顶级 makefile 的存在为条件来防止那里的失败。

为了完整起见,我的原始脚本有引用错误,例如,

"CC=${CC}"应该CC="${CC}",等等。

否则,@JohnBollinger在./configure之前移动这些环境变量的建议将不起作用。

最新更新