如何在我的iPhone应用程序中包含libxslt?

时间:2010-09-04 04:24:34

标签: iphone xcode libxml2 libxslt

我听说包含libxslt.dylib是让您的应用被拒绝的理由。我不知道那是多么准确。

尽管如此,我想包含最新版本的libxslt。我想对libxml2以及将来的其他库做同样的事情。

在我的应用中包含这样的代码库的正确方法是什么?

5 个答案:

答案 0 :(得分:3)

我终于得到libxslt来构建Xcode,链接到我的应用程序,并避开app store rejectionbot。

基本上你必须静态构建libxslt并更改符号名称,使它们与Apple寻找的名称不匹配。所有符号xsltFoo()必须更改为zsltFoo()。此外,库本身的名称必须从libxslt.a更改为libzslt.a

以下是10个简单步骤的方法:)

  1. 创建一个libxslt子目录并将libxslt-1.1.26.tar.gz放入其中。
  2. 右键点击目标 - > YourApp并选择添加 - >新建阶段 - >新运行脚本构建阶段
  3. 复制下面的构建脚本
  4. 将构建阶段从“运行脚本”重命名为“构建libxslt”并将其首先列入列表中
  5. 构建您的项目,这将导致在libxslt
  6. 中配置和构建并安装libxslt/dist
  7. 右键单击Frameworks并选择Add - >现有文件...然后选择libxslt/dist/lib/libzslt.a
  8. 转到项目 - >编辑项目设置 - >构建
  9. 在“搜索路径”下,修改标题搜索路径并添加libxslt/dist/include
  10. 通常
  11. #include <libxslt/whatever.h>添加到您的代码中
  12. 在代码中的任何地方使用zsltFoo代替xsltFoo
  13. 以下是步骤3中引用的libxslt构建脚本:

    #!/bin/sh
    
    # Setup
    LIBXSLT_VERSION="1.1.26"
    LIBXSLT_SHA1_CHECKSUM="69f74df8228b504a87e2b257c2d5238281c65154"
    GCC_VERSION="4.2.1"
    ARCH="arm-apple-darwin10"
    
    # Bail on any error
    set -e
    
    # Function that patches a file using sed(1).
    # First argument is filename, subsequent arguments are passed to sed(1).
    sed_patch_file()
    {
        FILE="${1}"
        shift
        sed ${1+"$@"} < "${FILE}" > "${FILE}".new
        if ! diff -q "${FILE}" "${FILE}".new >/dev/null; then
            cat "${FILE}".new > "${FILE}"
        fi
        rm "${FILE}".new
    }
    
    # Function that displays the command and then executes it
    show_cmd()
    {
        echo ${1+"$@"}
        ${1+"$@"}
    }
    
    # Dump environment variables
    #echo '***************************************************'
    #env | sort
    #echo '***************************************************'
    
    # Files
    SRCBALL="${SOURCE_ROOT}/libxslt/libxslt-${LIBXSLT_VERSION}.tar.gz"
    SRCDIR="${SOURCE_ROOT}/libxslt/libxslt-${LIBXSLT_VERSION}"
    DISTDIR="${SOURCE_ROOT}/libxslt/dist"
    
    # Verify source is installed
    if ! [ -f "${SRCBALL}" ]; then
        echo "ERROR: please download and install ${SRCBALL}" 2>&1
        echo "The SHA1 checksum should be: ${LIBXSLT_SHA1_CHECKSUM}" 2>&1
        exit 1
    fi
    
    # Unpack the archive if necessary
    if ! [ -e "${SRCDIR}" ]; then
    
        # Unpack archive
        echo "*** Unpacking archive ${SRCBALL}"
        tar zxf "${SRCBALL}" -C libxslt
    
        # Rename all symbols xsltFoobar -> zsltFoobar to avoid broken app store link analyzer
        echo "*** Changing symbol names"
        find libxslt/libxslt-"${LIBXSLT_VERSION}" -name '*.[ch]' -print | while read FILE; do
            sed_patch_file "${FILE}" -E 's%([^[:alnum:]_/"]|^)xslt([A-Z])%\1zslt\2%g'
        done
    
        # Disable build of xsltproc which fails to link
        sed_patch_file libxslt/libxslt-"${LIBXSLT_VERSION}"/Makefile.in -E '/^[[:space:]]xsltproc \\$/d'
    fi
    
    # Build and install
    if ! [ -e "${DISTDIR}" ]; then
    
        # Set up autoconf environment variables
        export CPP="${PLATFORM_DEVELOPER_BIN_DIR}/${ARCH}-gcc-${GCC_VERSION} -E"
        export  CC="${PLATFORM_DEVELOPER_BIN_DIR}/${ARCH}-gcc-${GCC_VERSION}"
        export CXX="${PLATFORM_DEVELOPER_BIN_DIR}/${ARCH}-g++-${GCC_VERSION}"
        export CPPFLAGS="-I${SDKROOT}/usr/lib/gcc/${ARCH}/${GCC_VERSION}/include -I${SDKROOT}/usr/include"
        export LDFLAGS="--sysroot=${SDKROOT}"
        export CFLAGS="-Os -pipe ${CPPFLAGS} ${LDFLAGS}"
        export CXXFLAGS="${CFLAGS}"
        export ARCH
    
        # Configure libxslt
        echo "*** Configuring libxslt-${LIBXSLT_VERSION}"
        ( cd "${SRCDIR}" && show_cmd ./configure \
          --prefix="${DISTDIR}" \
          --build=i386-apple-darwin10 \
          --host="${ARCH}" \
          --enable-static \
          --disable-shared \
          --with-libxml-include-prefix="${SDKROOT}"/usr/include \
          --with-libxml-libs-prefix="${SDKROOT}"/usr/lib \
          --without-python )
    
        # Build it
        echo "*** Building libxslt-${LIBXSLT_VERSION}"
        ( cd "${SRCDIR}" && show_cmd make )
    
        # Install it
        echo "*** Installing libxslt-${LIBXSLT_VERSION}"
        ( cd "${SRCDIR}" && show_cmd make install )
    
        # Change library name to avoid dynamic linking to the iPhone's shared libxslt library
        ln libxslt/dist/lib/lib{x,z}slt.a
    fi
    

答案 1 :(得分:2)

我的应用被Apple拒绝接受以下消息。


XYZ app无法发布到App Store,因为它使用私有或未记录的API:

私人符号引用 xsltApplyStylesheet xsltCleanupGlobals xsltFreeStylesheet xsltInit xsltParseStylesheetFile xsltSaveResultToString

如您所知,正如iPhone开发人员计划许可协议第3.3.1节所述,不允许使用非公共API。在应用审核小组审核您的申请之前,请解决此问题并将新二进制文件上传到iTunes Connect。


据我了解,libxslt和libxml2库实际上存在于设备上,可通过Xcode中的下拉菜单获得。我动态地链接这两个库的链接,我的应用程序在设备上运行得很漂亮。因此,库必须在设备上。为什么我需要从头开始构建这些库作为静态库并增加我的应用程序的大小?

除了不使用xml和xslt之外,我找不到任何明确的解决方法。这毫无意义!

希尔顿,您是否已成功向iTunes提交使用xslt的应用程序?

答案 2 :(得分:2)

Hey Hilton,您有机会告诉我们您是如何将LIBXSLT库静态链接到您的应用中的吗?

我和其他几个人有完全相同的问题,但至少目前,我不知道如何将动态库转变为静态库。

感谢。

编辑:查看此Version of XSLT in iPhone

我的应用程序因使用LibXSLT而被拒绝,所以我手动添加源代码并以此方式执行。我的应用程序几天前就被批准了。

答案 3 :(得分:1)

您只能动态链接到设备上已存在的库。

如果要链接到设备上不存在的外部库,则必须自己将其编译为静态库并进行链接。

答案 4 :(得分:0)

根据Archie的回答,这个脚本(使用XCode 5命令行工具)生成一个适合包含在项目中的多架构libzslt,兼容iOS 6和iOS 7项目(虽然我没有包含iOS 7 64位)。

此解决方案假定libxslt-1.1.28已解压缩并与脚本位于同一目录中。

该脚本创建一个包含头文件和lib文件的目录依赖项。您可以通过调整标头和链接器搜索路径将它们包含在Xcode项目中。



    #!/bin/sh
    # build.sh

    GLOBAL_OUTDIR="`pwd`/dependencies"
    LOCAL_OUTDIR="outdir"
    XSLT_LIB="`pwd`/libxslt-1.1.28"

    IOS_BASE_SDK="7.0"
    IOS_DEPLOY_TGT="6.0"

    sed_patch_file()
    {
        FILE="${1}"
        shift
        sed ${1+"$@"}  "${FILE}".new
        if ! diff -q "${FILE}" "${FILE}".new >/dev/null; then
            cat "${FILE}".new > "${FILE}"
        fi
        rm "${FILE}".new
    }

    patch_libxslt() {
        export LIBXSLT_VERSION=1.1.28
        echo "*** Changing symbol names"
        find libxslt-"${LIBXSLT_VERSION}" -name '*.[ch]' -print | while read FILE; do
                sed_patch_file "${FILE}" -E 's%([^[:alnum:]_/"]|^)xslt([A-Z])%\1zslt\2%g'
        done

            # Disable build of xsltproc which fails to link
        sed_patch_file libxslt-"${LIBXSLT_VERSION}"/Makefile.in -E '/^[[:space:]]xsltproc \\$/d'
    }

    setenv_all()
    {
        unset LIBRARIES
        export LIBRARIES=${SDKROOT}/usr/lib
        echo "*** LIBRARIES: ${LIBRARIES}"

        # Add internal libs
        export LDFLAGS="--sysroot=${SDKROOT} $LDFLAGS -L${LIBRARIES}"
        export CFLAGS="--sysroot=${SDKROOT} $CFLAGS -I${SDKROOT}/usr/lib/gcc/${ARCH}/${GCC_VERSION}/include -I${SDKROOT}/usr/include -arch ${ARCH} -Os -pipe ${CPPFLAGS}"

        export CXX="$PLATFORM_BIN_DIR/g++"
        export CC="$PLATFORM_BIN_DIR/gcc"

        export LD=$TOOLROOT/ld
        export AR=$TOOLROOT/ar
        export AS=$TOOLROOT/as
        export NM=$TOOLROOT/nm
        export RANLIB=$TOOLROOT/ranlib
        export CPPFLAGS=$CFLAGS
        export CXXFLAGS=$CFLAGS

        export CXXFLAGS="${CFLAGS}"
    }

    setenv_arm7()
    {
        unset LN DEVROOT SDKROOT CFLAGS CC LD CPP CXX AR AS NM CXXCPP RANLIB LDFLAGS CPPFLAGS CXXFLAGS DYLD_LIBRARY_PATH ARCH PLATFORM_BIN_DIR TOOLROOT DISTDIR

        export ARCH=armv7
        export DEVROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer
        export SDKROOT=$DEVROOT/SDKs/iPhoneOS$IOS_BASE_SDK.sdk
        export PLATFORM_BIN_DIR=/Applications/Xcode.app/Contents/Developer/usr/bin
        export TOOLROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin    

        export DYLD_LIBRARY_PATH="$SDKROOT/usr/lib"

        export CFLAGS="-arch armv7 -pipe -no-cpp-precomp -isysroot $SDKROOT -miphoneos-version-min=$IOS_DEPLOY_TGT -I$SDKROOT/usr/include/"

        setenv_all
    }

    setenv_arm7s()
    {
        unset LN DEVROOT SDKROOT CFLAGS CC LD CPP CXX AR AS NM CXXCPP RANLIB LDFLAGS CPPFLAGS CXXFLAGS DYLD_LIBRARY_PATH ARCH PLATFORM_BIN_DIR TOOLROOT DISTDIR

        export ARCH=armv7s
        export DEVROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer
        export SDKROOT=$DEVROOT/SDKs/iPhoneOS$IOS_BASE_SDK.sdk
        export PLATFORM_BIN_DIR=/Applications/Xcode.app/Contents/Developer/usr/bin
        export TOOLROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin    

        export DYLD_LIBRARY_PATH="$SDKROOT/usr/lib"

        export CFLAGS="-arch armv7s -pipe -no-cpp-precomp -isysroot $SDKROOT -miphoneos-version-min=$IOS_DEPLOY_TGT -I$SDKROOT/usr/include/"

        setenv_all
    }

    setenv_i386()
    {
        unset LN DEVROOT SDKROOT CFLAGS CC LD CPP CXX AR AS NM CXXCPP RANLIB LDFLAGS CPPFLAGS CXXFLAGS DYLD_LIBRARY_PATH ARCH PLATFORM_BIN_DIR TOOLROOT DISTDIR

        export ARCH=i386
        export DEVROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer
        export SDKROOT=$DEVROOT/SDKs/iPhoneSimulator$IOS_BASE_SDK.sdk
        export PLATFORM_BIN_DIR=$DEVROOT/usr/bin
        export TOOLROOT=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

        export CFLAGS="-arch i386 -pipe -no-cpp-precomp -isysroot $SDKROOT -miphoneos-version-min=$IOS_DEPLOY_TGT"

        setenv_all
    }

    create_outdir_lipo()
    {
        for lib_i386 in `find $LOCAL_OUTDIR/i386 -name "lib*\.a"`; do
            lib_arm7=`echo $lib_i386 | sed "s/i386/arm7/g"`
            lib_arm7s=`echo $lib_i386 | sed "s/i386/arm7s/g"`
            lib=`echo $lib_i386 | sed "s/i386\///g"`
            mkdir -p $(dirname $lib)
            cmd="xcrun -sdk iphoneos lipo -arch armv7 $lib_arm7 -arch i386 $lib_i386 -arch armv7s $lib_arm7s -create -output $lib"
            echo $cmd
            $cmd
        done
    }

    merge_libfiles()
    {
        DIR=$1
        LIBNAME=$2

        cd $DIR
        for i in `find . -name "lib*.a"`; do
            $AR -x $i
        done
        $AR -r $LIBNAME *.o
        rm -rf *.o __*
        cd -
    }

    #######################
    # libxslt
    #######################

    patch_libxslt

    cd $XSLT_LIB
    rm -rf $LOCAL_OUTDIR
    mkdir -p $LOCAL_OUTDIR/arm7 $LOCAL_OUTDIR/i386

    make clean 2> /dev/null
    setenv_i386

    export DISTDIR=`pwd`/$LOCAL_OUTDIR/i386

    ./configure --prefix="${DISTDIR}" \
    --enable-static \
    --disable-shared \
    --with-libxml-include-prefix="${SDKROOT}"/usr/include \
    --with-libxml-libs-prefix="${SDKROOT}"/usr/lib \
    --without-crypto \
    --without-python || exit
    make "CC=$CC" "CFLAGS=$CFLAGS" "AR=$AR"
    make install

    ln $LOCAL_OUTDIR/i386/lib/lib{x,z}slt.a 

    # find ./ -iname *.a | grep -v $LOCAL_OUTDIR | xargs -L 1 -I '{}' cp '{}' $LOCAL_OUTDIR/i386
    # cp -vf lib*.a $LOCAL_OUTDIR/i386

    make clean 2> /dev/null
    setenv_arm7

    export DISTDIR=`pwd`/$LOCAL_OUTDIR/arm7

    ./configure --prefix="${DISTDIR}" \
    --host=armv7-apple-darwin12.5.0 \
    --enable-static \
    --disable-shared \
    --with-libxml-include-prefix="${SDKROOT}"/usr/include \
    --with-libxml-libs-prefix="${SDKROOT}"/usr/lib \
    --without-crypto \
    --without-python || exit
    make -j4
    make install

    ln $LOCAL_OUTDIR/arm7/lib/lib{x,z}slt.a 

    # find ./ -iname *.a | grep -v $LOCAL_OUTDIR | xargs -L 1 -I '{}' cp '{}' $LOCAL_OUTDIR/arm7
    # cp -rvf lib*.a $LOCAL_OUTDIR/arm7

    make clean 2> /dev/null
    setenv_arm7s

    export DISTDIR=`pwd`/$LOCAL_OUTDIR/arm7s

    ./configure --prefix="${DISTDIR}" \
    --host=armv7s-apple-darwin12.5.0 \
    --enable-static \
    --disable-shared \
    --with-libxml-include-prefix="${SDKROOT}"/usr/include \
    --with-libxml-libs-prefix="${SDKROOT}"/usr/lib \
    --without-crypto \
    --without-python || exit
    make -j4
    make install

    ln $LOCAL_OUTDIR/arm7s/lib/lib{x,z}slt.a 

    # find ./ -iname *.a | grep -v $LOCAL_OUTDIR | xargs -L 1 -I '{}' cp '{}' $LOCAL_OUTDIR/arm7s
    # cp -rvf lib*.a $LOCAL_OUTDIR/arm7s

    create_outdir_lipo
    mkdir -p $GLOBAL_OUTDIR/lib && cp -rvf $LOCAL_OUTDIR/lib/lib*.a $GLOBAL_OUTDIR/lib
    mkdir -p $GLOBAL_OUTDIR/include && cp -rvf $LOCAL_OUTDIR/arm7/include/* $GLOBAL_OUTDIR/include

    cd ..

    echo "Finished!"