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

How to enable Xcode-specific build flags for autotool-based projects

我正在尝试为 iOS 构建 Google protobuf 项目,但不清楚如何启用 iOS 特定的标志,例如 -fembed-bitcodeBITCODE_GENERATION_MODE=bitcode 与自动工具。我试过以下脚本:

#!/bin/bash

## Environments
ScriptDir="$( cd "$( dirname "[=11=]" )" && 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=
  ARCH=
  PLATFORM_CFLAGS=
  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项目失败。很明显,没有包含位码,即标志不起作用。

我想知道是否无法单独使用 autotool 来实现我所做的事情。我应该为此创建一个真正的 Xcode 项目吗?

Autotools 提供了构建和维护构建系统的框架。它们确实提供了一些标准化,但在很大程度上,基于 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 之前移动这些环境变量的建议将行不通。