如何将第三方库(如 fftw3 和 sndfile)链接到 Xcode 中的 iPhone 项目?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3588904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 19:40:54  来源:igfitidea点击:

How do I link third party libraries like fftw3 and sndfile to an iPhone project in Xcode?

iphonexcodefftw

提问by saurb

I'm trying to link third party libraries like fftw3 and sndfile to my iPhone project in Xcode3.2. I got it working in a regular Mac project by setting the "Header Search Path" to "/usr/local/include" and the "Other Linker Flags" to "-lfftw3 -lsndfile" under the project build configuration. However, it gave me "library not found for -lfftw3" with exit code 1 error message when I tried to build it in the iPhone project using the same settings.

我正在尝试将第三方库(如 fftw3 和 sndfile)链接到我在 Xcode3.2 中的 iPhone 项目。我通过在项目构建配置下将“标题搜索路径”设置为“/usr/local/include”并将“其他链接器标志”设置为“-lfftw3 -lsndfile”,使其在常规 Mac 项目中工作。但是,当我尝试使用相同的设置在 iPhone 项目中构建它时,它给了我“找不到 -lfftw3 的库”和退出代码 1 错误消息。

Does apple not allow this on the iPhone? Is there a way to get around this?

苹果不允许在 iPhone 上这样做吗?有没有办法解决这个问题?

回答by Nickun

I've modified Epskampie's script for IOS 5.0+
Used with fftw3.3.3 on OS X 10.7 with IOS SDK 6.0 and MacOSX SDK 10.8

我已经修改了 Epskampie 的 IOS 5.0+ 脚本,
在 OS X 10.7 上与 fftw3.3.3 一起使用,IOS SDK 6.0 和 MacOSX SDK 10.8

#!/bin/sh

# build_ios5.sh
# build an arm / i386 / x86_64 lib of fftw3
# make sure to check that all the paths used in this script exist on your system
#
# adopted from:
# http://robertcarlsen.net/2009/07/15/cross-compiling-for-iphone-dev-884
# changed by Nickun
# original:
# http://stackoverflow.com/questions/3588904/how-to-link-third-party-libraries-like-fftw3-and-sndfile-to-an-iphone-project-in


# make sure we start out clean
make distclean

# this is the folder where the results of our efforts will end up:
export RESULT_DIR=ios-library

# Select toolchains folder
export XCODE_TOOLCHAINS=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
# Select the desired iPhone SDK
export DEVROOT_IOS=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer
export SDKROOT_IOS=$DEVROOT_IOS/SDKs/iPhoneOS6.0.sdk
# Select the OSX SDK
export DEVROOT_OSX=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer
export SDKROOT_OSX=$DEVROOT_OSX/SDKs/MacOSX10.8.sdk

# ------------------------ armv7---------------------------
# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT_IOS/usr/include/ -mfpu=neon"
export CFLAGS="$CPPFLAGS -arch armv7 -mfpu=neon -no-cpp-precomp -miphoneos-version-min=5.0 -isysroot $SDKROOT_IOS"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch armv7 -std=gnu++11 -stdlib=libc++ -mfpu=neon"
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch armv7 -std=gnu99 -mfpu=neon"
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
#  remove '--enable-float' for double precision
#  and take a 'libfftw3.a' file instead
./configure --host=arm-apple-darwin --enable-float --enable-neon

make -j2

# Copy the ARM library to a temporary location
mkdir $RESULT_DIR
cp .libs/libfftw3f.a $RESULT_DIR/libfftw3f_armv7.a

# Copy the header file too, just for convenience
cp api/fftw3.h $RESULT_DIR/fftw3.h

# ------------------------ armv7s---------------------------
# Do it all again for i386
make distclean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT_IOS/usr/include/ -mfpu=neon"
export CFLAGS="$CPPFLAGS -arch armv7s -mfpu=neon -no-cpp-precomp -miphoneos-version-min=5.0 -isysroot $SDKROOT_IOS"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch armv7s -std=gnu++11 -stdlib=libc++ -mfpu=neon"
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch armv7s -std=gnu99 -mfpu=neon"
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
#  remove '--enable-float' for double precision
#  and take a 'libfftw3.a' file instead
./configure --host=arm-apple-darwin --enable-float --enable-neon

make -j2

# Copy the ARM library to a temporary location
mkdir $RESULT_DIR
cp .libs/libfftw3f.a $RESULT_DIR/libfftw3f_armv7s.a


# ------------------------ i386 ---------------------------
# Do it all again for i386
make distclean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

export CPPFLAGS="-I$SDKROOT_OSX/usr/include/"
export CFLAGS="$CPPFLAGS -arch i386 -no-cpp-precomp -mmacosx-version-min=10.7 -isysroot $SDKROOT_OSX"
export LD="$XCODE_TOOLCHAINS/usr/bin/ld"
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch i386 -std=gnu++11 -stdlib=libc++"
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch i386 -std=gnu99"
export CXXFLAGS="$CFLAGS"

# TODO: error checking
./configure --enable-float
make -j2

# Copy the FAT native library to the temporary location
cp .libs/libfftw3f.a $RESULT_DIR/libfftw3f_i386.a

# ------------------------ x86_64 ---------------------------
# Do it all again for x86_64
make distclean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

export CPPFLAGS="-I$SDKROOT_OSX/usr/include/"
export CFLAGS="$CPPFLAGS -arch x86_64 -no-cpp-precomp -mmacosx-version-min=10.7 -isysroot $SDKROOT_OSX"
export LD="$XCODE_TOOLCHAINS/usr/bin/ld"
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch x86_64 -std=gnu++11 -stdlib=libc++"
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch x86_64 -std=gnu99"
export CXXFLAGS="$CFLAGS"

# TODO: error checking
./configure --enable-float
make -j2

# Copy the FAT native library to the temporary location
cp .libs/libfftw3f.a $RESULT_DIR/libfftw3f_x86_64.a



# Create fat lib by combining the two versions
lipo -arch armv7 $RESULT_DIR/libfftw3f_armv7.a -arch armv7s $RESULT_DIR/libfftw3f_armv7s.a -arch i386 $RESULT_DIR/libfftw3f_i386.a -arch x86_64 $RESULT_DIR/libfftw3f_x86_64.a -create -output $RESULT_DIR/libfftw3f.a

# Remove intermediate binaries
#rm $RESULT_DIR/libfftw3_armv7.a
#rm $RESULT_DIR/libfftw3_i386.a
#rm $RESULT_DIR/libfftw3_x86_64.a

# Unset used environment variables
unset CPPFLAGS CFLAGS CPP LD LDFLAGS CXX CXXFLAGS

回答by Simon Epskamp

For compiling fftw3 for use in an iOS project, i've adapted the script posted here: http://robertcarlsen.net/2009/07/15/cross-compiling-for-iphone-dev-884

为了编译用于 iOS 项目的 fftw3,我修改了此处发布的脚本:http://robertcarlsen.net/2009/07/15/cross-compiling-for-iphone-dev-884

Used with fftw3.2.2 on OS X 10.6 with iOs SDK 3.2

在带有 iOs SDK 3.2 的 OS X 10.6 上与 fftw3.2.2 一起使用

#!/bin/sh

# build_iphone.sh
# build an arm / i386 lib of fftw3
# make sure to check that all the paths used in this script exist on your system
#
# adopted from:
# http://robertcarlsen.net/2009/07/15/cross-compiling-for-iphone-dev-884


# make sure we start out clean
make distclean

# this is the folder where the results of our efforts will end up:
export RESULT_DIR=ios-library

# Select the desired iPhone SDK
export DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer
export SDKROOT=$DEVROOT/SDKs/iPhoneOS3.2.sdk

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT/usr/lib/gcc/arm-apple-darwin9/4.0.1/include/ -I$SDKROOT/usr/include/ -miphoneos-version-min=2.2"
export CFLAGS="$CPPFLAGS -arch armv6 -pipe -no-cpp-precomp -isysroot $SDKROOT"
export CPP="$DEVROOT/usr/bin/cpp $CPPFLAGS"
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
./configure CC=$DEVROOT/usr/bin/arm-apple-darwin10-gcc-4.0.1 LD=$DEVROOT/usr/bin/ld --host=arm-apple-darwin

make -j4

# Copy the ARM library to a temporary location
mkdir $RESULT_DIR
cp .libs/libfftw3.a $RESULT_DIR/libfftw3_arm.a

# Copy the header file too, just for convenience
cp api/fftw3.h ios-library/fftw3.h

# Do it all again for i386
make distclean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LDFLAGS CXXFLAGS DEVROOT SDKROOT

export DEVROOT=/Developer
export SDKROOT=$DEVROOT/SDKs/MacOSX10.6.sdk

export CPPFLAGS="-I$SDKROOT/usr/lib/gcc/i686-apple-darwin10/4.0.1/include/ -I$SDKROOT/usr/include/ -mmacosx-version-min=10.5"
export CFLAGS="$CPPFLAGS -pipe -no-cpp-precomp -isysroot $SDKROOT -arch i386"
export CPP="$DEVROOT/usr/bin/cpp $CPPFLAGS"
export CXXFLAGS="$CFLAGS"

# TODO: error checking
./configure
make -j4

# Copy the native library to the temporary location
cp .libs/libfftw3.a $RESULT_DIR/libfftw3_386.a

# Create fat lib by combining the two versions
lipo -arch arm $RESULT_DIR/libfftw3_arm.a -arch i386 $RESULT_DIR/libfftw3_386.a -create -output $RESULT_DIR/libfftw3.a

# Remove intermediate binaries
rm $RESULT_DIR/libfftw3_arm.a
rm $RESULT_DIR/libfftw3_386.a

# Unset used environment variables
unset CPPFLAGS CFLAGS CPP LDFLAGS CPP CXXFLAGS DEVROOT SDKROOT

Run this script from the directory containing fftw3. The files you need should end up in the ios-library folder.

从包含 fftw3 的目录运行此脚本。您需要的文件最终应位于 ios-library 文件夹中。

回答by Elfred

You need to build your libraries as universal static libraries. The process varies from library to library but it generally goes something like this.

您需要将库构建为通用静态库。这个过程因图书馆而异,但通常是这样的。

  1. build the library as a static lib for the different platforms (armv6 and i386 at the least)
  2. use lipo to create a universal library from the individual static libraries built above
  3. drag and drop the universal lib into your xcode project
  4. drag and drop the header files into your xcode project
  1. 将库构建为不同平台的静态库(至少是 armv6 和 i386)
  2. 使用 lipo 从上面构建的各个静态库创建通用库
  3. 将通用库拖放到您的 xcode 项目中
  4. 将头文件拖放到您的 xcode 项目中

Step 1 is generally the trickiest since many libraries have different build procedures. It is usually done by setting the proper compiler flags to use the iphone sdk instead of the system wide compiler.

第 1 步通常是最棘手的,因为许多库都有不同的构建过程。通常通过设置适当的编译器标志来使用 iphone sdk 而不是系统范围的编译器来完成。

回答by Adam Freeman

I modified Nickun's script for Mac OS X 10.9.2, iOS 7.1, fftw-3.3.4. It also adds an arm64 slice to the fat file. Here is the script ->

我为 Mac OS X 10.9.2、iOS 7.1、fftw-3.3.4 修改了 Nickun 的脚本。它还向胖文件中添加了一个 arm64 切片。这是脚本->

#!/bin/sh

# build_lipo.sh
# build an arm64 / armv7s / armv7 / i386 / x86_64 lib of fftw3
# make sure to check that all the paths used in this script exist on your system
#
# adopted from:
# http://robertcarlsen.net/2009/07/15/cross-compiling-for-iphone-dev-884
# changed by Adam
# original: by Nickun
# http://stackoverflow.com/questions/3588904/how-to-link-third-party-libraries-like-fftw3-and-sndfile-to-an-iphone-project-in

# this is the folder where the results of our efforts will end up:
export RESULT_DIR=ios-library

# Select toolchains folder
export XCODE_TOOLCHAINS=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
# Select the desired iPhone SDK
export DEVROOT_IOS=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer
export SDKROOT_IOS=$DEVROOT_IOS/SDKs/iPhoneOS7.1.sdk
# Select the OSX SDK
export DEVROOT_OSX=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer
export SDKROOT_OSX=$DEVROOT_OSX/SDKs/MacOSX10.9.2.sdk

# ------------------------ i386 ---------------------------
# Do it for i386
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

export CFLAGS="-arch i386"

# TODO: error checking
./configure --enable-float --host=i386-apple-darwin9.2.0 --target=i386-apple-darwin9.2.0
make -j2

# Copy the FAT native library to a temporary location
mkdir $RESULT_DIR
cp .libs/libfftw3f.a $RESULT_DIR/libfftw3f_i386.a

# ------------------------ x86_64 ---------------------------
# Do it all again for x86_64
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

# TODO: error checking
./configure --enable-float
make -j2

# Copy the FAT native library to the temporary location
cp .libs/libfftw3f.a $RESULT_DIR/libfftw3f_x86_64.a

# ------------------------ armv7---------------------------
# Do it all again for armv7
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT_IOS/usr/include/ -mfpu=neon"
export CFLAGS="$CPPFLAGS -arch armv7 -mfpu=neon -no-cpp-precomp -miphoneos-version-min=5.0 -isysroot $SDKROOT_IOS"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch armv7 -std=gnu++11 -stdlib=libc++ -mfpu=neon"
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch armv7 -std=gnu99 -mfpu=neon"
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
#  remove '--enable-float' for double precision
#  and take a 'libfftw3.a' file instead
./configure --host=arm-apple-darwin --target=arm-apple-darwin --enable-float --enable-neon

make -j2

cp .libs/libfftw3f.a $RESULT_DIR/libfftw3f_armv7.a

# Copy the header file too, just for convenience
cp api/fftw3.h $RESULT_DIR/fftw3.h

# ------------------------ armv7s---------------------------
# Do it all again for i386
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT_IOS/usr/include/ -mfpu=neon"
export CFLAGS="$CPPFLAGS -arch armv7s -mfpu=neon -no-cpp-precomp -miphoneos-version-min=5.0 -isysroot $SDKROOT_IOS"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch armv7s -std=gnu++11 -stdlib=libc++ -mfpu=neon"
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch armv7s -std=gnu99 -mfpu=neon"
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
#  remove '--enable-float' for double precision
#  and take a 'libfftw3.a' file instead
./configure --host=arm-apple-darwin --target=arm-apple-darwin --enable-float --enable-neon

make -j2

# Copy the ARM library to a temporary location
cp .libs/libfftw3f.a $RESULT_DIR/libfftw3f_armv7s.a

# ------------------------ arm64 ---------------------------
# Do it all again for arm64
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT_IOS/usr/include/ -mfpu=neon"
export CFLAGS="$CPPFLAGS -arch arm64 -mfpu=neon -no-cpp-precomp -miphoneos-version-min=5.0 -isysroot $SDKROOT_IOS"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch arm64 -std=gnu++11 -stdlib=libc++ -mfpu=neon"
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch arm64 -std=gnu99 -mfpu=neon"
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
#  remove '--enable-float' for double precision
#  and take a 'libfftw3.a' file instead
./configure --host=arm-apple-darwin --target=arm-apple-darwin --enable-float --enable-neon

make -j2

# Copy the ARM library to a temporary location
cp .libs/libfftw3f.a ios-library/libfftw3f_arm64.a


# Create fat lib by combining the two versions
lipo -arch armv7 $RESULT_DIR/libfftw3f_armv7.a -arch armv7s $RESULT_DIR/libfftw3f_armv7s.a -arch i386 $RESULT_DIR/libfftw3f_i386.a -arch x86_64 $RESULT_DIR/libfftw3f_x86_64.a -arch arm64 $RESULT_DIR/libfftw3f_arm64.a -create -output $RESULT_DIR/libfftw3f.a

# Remove intermediate binaries
#rm $RESULT_DIR/libfftw3_armv7.a
#rm $RESULT_DIR/libfftw3_i386.a
#rm $RESULT_DIR/libfftw3_x86_64.a

# Unset used environment variables
unset CPPFLAGS CFLAGS CPP LD LDFLAGS CXX CXXFLAGS

回答by Graham Perks

It's not that Apple isn't allowing the library, it's that the version you are linking to is x86, and so it won't run on the iPhone. You need to build the library using the iPhone SDK, then link to that version.

并不是 Apple 不允许使用该库,而是您链接的版本是 x86,因此它无法在 iPhone 上运行。您需要使用 iPhone SDK 构建库,然后链接到该版本。

Alternatively, you can be a little naughty and include the 3rd-party source in your main project. Naughty, but it'll prove the point that Apple isn't stopping you, and show whether the library will run on the phone OK.

或者,您可以调皮一点,在您的主项目中包含第 3 方源代码。顽皮,但这将证明 Apple 并没有阻止您,并显示该库是否可以在手机上正常运行。

It's cleaner to keep the code in a separately-built library project though.

不过,将代码保存在单独构建的库项目中会更清晰。

回答by 10mitri

Build FFTW3 for iOS:

为 iOS 构建 FFTW3:

Here is a script to create .h and .a files for different iOS architectures (device, simulator, ...)

这是为不同的 iOS 架构(设备、模拟器等)创建 .h 和 .a 文件的脚本

Enjoy it!

好好享受!

#!/bin/sh

# build for iOS / Mac
# changed by 10mitri
# original:
# http://stackoverflow.com/questions/3588904/how-to-link-third-party-libraries-like-fftw3-and-sndfile-to-an-iphone-project-in


# this is the folder where the libs will be generated
export OUTPUT_DIR=ios-libs

# Select toolchains folder
export XCODE_TOOLCHAINS=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain


#$(CURRENT_ARCH)

build_target()
{
PLATFORM=
ARCH=
SDK_VERSION=
CONFIGURE_HOST=
IOS_DEPLOYMENT_TARGET=

export SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/$PLATFORM.platform/Developer/SDKs/$PLATFORM$SDK_VERSION.sdk

export CPPFLAGS="-I$SDKROOT/usr/include/"
export CFLAGS="$CPPFLAGS -arch $ARCH -isysroot $SDKROOT"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -arch $ARCH -fembed-bitcode"
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -arch $ARCH -fembed-bitcode"

echo ---------------------------------------------------
echo ---------------------------------------------------
echo ---------------------------------------------------
echo -------------- BUILD TARGET
echo -------------- PLATFORM : $PLATFORM
echo -------------- ARCH : $ARCH
echo -------------- SDK_VERSION : $SDK_VERSION
echo -------------- HOST : $CONFIGURE_HOST
echo -------------- MIN iOS : $IOS_DEPLOYMENT_TARGET
echo -------------- SDK PATH : $SDKROOT
echo ---------------------------------------------------
echo ---------------------------------------------------
echo ---------------------------------------------------

sleep 3

make clean

./configure --host=$CONFIGURE_HOST

make -j4

mkdir $OUTPUT_DIR/$ARCH

# Copy the lib
cp .libs/libfftw3.a $OUTPUT_DIR/$ARCH/libfftw3.a

unset CPPFLAGS CFLAGS LD CXX CC
}


mkdir $OUTPUT_DIR

rm -rf $OUTPUT_DIR/*

# Copy the header file too, just for convenience
cp api/fftw3.h $OUTPUT_DIR/fftw3.h

build_target "iPhoneOS" "armv7" "10.2" "arm-apple-darwin" "9.0"
build_target "iPhoneOS" "armv7s" "10.2" "arm-apple-darwin" "9.0"
build_target "iPhoneOS" "arm64" "10.2" "arm-apple-darwin" "9.0"
build_target "iPhoneSimulator" "x86_64" "10.2" "x86_64-apple-darwin" "9.0"
build_target "iPhoneSimulator" "i386" "10.2" "i386-apple-darwin" "9.0"

#build_target "MacOSX" "x86_64" "10.12" "i386-apple-darwin" "10.10"

回答by WangYudong

Based on the answer by 10mitri, working for fftw-3.3.8, iOS SDK 12.2, XCode 10.2.

基于 10mitri 的回答,为 fftw -3.3.8、iOS SDK 12.2、XCode 10.2 工作

#!/bin/sh

export XCODE_TOOLCHAINS=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain

export OUTPUT_DIR=ios-libs

mkdir -p $OUTPUT_DIR
rm -rf $OUTPUT_DIR/*

build_target()
{
    PLATFORM=
    ARCH=
    CONFIGURE_HOST=

    IOS_SDKROOT=`xcrun --sdk $PLATFORM --show-sdk-path`

    export CPPFLAGS="-I$IOS_SDKROOT/usr/include/"
    export CFLAGS="$CPPFLAGS -O3 -arch $ARCH -miphoneos-version-min=8.0 -isysroot $IOS_SDKROOT"
    export LD=$XCODE_TOOLCHAINS/usr/bin/ld
    export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -arch $ARCH -fembed-bitcode"
    export CC="$XCODE_TOOLCHAINS/usr/bin/clang -arch $ARCH -fembed-bitcode"

    echo -----------------------------------------
    echo ---- BUILD TARGET
    echo ---- PLATFORM : $PLATFORM
    echo ---- ARCH : $ARCH
    echo ---- HOST : $CONFIGURE_HOST
    echo -----------------------------------------

    sleep 3

    make clean

    ./configure --host=$CONFIGURE_HOST

    make -j4

    # Copy the lib
    cp .libs/libfftw3.a $OUTPUT_DIR/libfftw3_$ARCH.a

    unset CPPFLAGS CFLAGS LD CXX CC
}

build_target "iphoneos" "armv7" "arm-apple-darwin"
build_target "iphoneos" "armv7s" "arm-apple-darwin"
build_target "iphoneos" "arm64" "arm-apple-darwin"
# build_target "iphonesimulator" "x86_64" "x86_64-apple-darwin"
build_target "iphonesimulator" "i386" "i386-apple-darwin"

# Make fat lib
lipo -arch armv7 $OUTPUT_DIR/libfftw3_armv7.a\
     -arch armv7s $OUTPUT_DIR/libfftw3_armv7s.a\
     -arch arm64 $OUTPUT_DIR/libfftw3_arm64.a\
     -arch i386 $OUTPUT_DIR/libfftw3_i386.a\
     -create -output $OUTPUT_DIR/libfftw3_ios.a

# Copy the header file too, just for convenience
cp api/fftw3.h $OUTPUT_DIR/fftw3.h

echo "done"

回答by Ninji

I tried Adam Freeman's script, its awesome but I had to do the following to make it work, so I am here to share my finding. My goal is to make arm based fftw lib so I can build it++ lib through Xcode with arm architecture

我尝试了 Adam Freeman 的脚本,它很棒,但我必须执行以下操作才能使其正常工作,所以我在这里分享我的发现。我的目标是制作基于 arm 的 fftw lib,这样我就可以通过带有 arm 架构的 Xcode 构建它++ lib

I also run into the problem posted by loretoparisi

我也遇到了 loretoparisi 发布的问题

/libbench2/libbench2.a:5:255: warning: null character ignored [-Wnull-character] 
./libbench2/libbench2.a:4:8: error: source file is not valid UTF-8

the workaround is to strip away the make rule for "tests","tools" folders and any fftw-"wisdom" related stuff in Makefile.in and Makefile.am, I don't know how important are the files from those two folders, but I had to remove them so fftw build can success without UTF-8 error

解决方法是去掉 Makefile.in 和 Makefile.am 中“tests”、“tools”文件夹和任何 fftw-“wisdom”相关内容的 make 规则,我不知道这两个文件夹中的文件有多重要,但我必须删除它们,以便 fftw 构建可以成功而不会出现 UTF-8 错误

I also have to modify the script (I took awake the neon and float precision flag, again I also do not know how important are those flag)

我也必须修改脚本(我唤醒了霓虹灯和浮动精度标志,我也不知道那些标志有多重要)

#!/bin/sh

# build_lipo.sh
# build an arm64 / armv7s / armv7 / i386 / x86_64 lib of fftw3
# make sure to check that all the paths used in this script exist on your system
#
# adopted from:
# http://robertcarlsen.net/2009/07/15/cross-compiling-for-iphone-dev-884
# changed by Adam
# original: by Nickun
# http://stackoverflow.com/questions/3588904/how-to-link-third-party-libraries-like-fftw3-and-sndfile-to-an-iphone-project-in

# this is the folder where the results of our efforts will end up:
export RESULT_DIR=ios-library

# Select toolchains folder
export XCODE_TOOLCHAINS=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
# Select the desired iPhone SDK
export DEVROOT_IOS=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer
export SDKROOT_IOS=$DEVROOT_IOS/SDKs/iPhoneOS7.1.sdk
# Select the OSX SDK
export DEVROOT_OSX=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer
export SDKROOT_OSX=$DEVROOT_OSX/SDKs/MacOSX10.9.2.sdk

# ------------------------ i386 ---------------------------
# Do it for i386
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP CC LD CXX LDFLAGS CXXFLAGS

export CFLAGS="-arch i386"

# TODO: error checking
./configure --host=i386-apple-darwin9.2.0 --target=i386-apple-darwin9.2.0
make -j2

# Copy the FAT native library to a temporary location
mkdir $RESULT_DIR
cp .libs/libfftw3.a $RESULT_DIR/libfftw3_i386.a
rm -fr .libs/libfftw3.a

# ------------------------ x86_64 ---------------------------
# Do it all again for x86_64
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP CC LD CXX LDFLAGS CXXFLAGS

# TODO: error checking
./configure
make -j2

# Copy the FAT native library to the temporary location
cp .libs/libfftw3.a $RESULT_DIR/libfftw3_x86_64.a
rm -fr .libs/libfftw3.a

# ------------------------ armv7---------------------------
# Do it all again for armv7
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX CC LDFLAGS CXXFLAGS

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT_IOS/usr/include/ "
export CFLAGS="$CPPFLAGS -arch armv7  -no-cpp-precomp -miphoneos-version-min=6.1 -isysroot $SDKROOT_IOS"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch armv7 -std=gnu++11 -stdlib=libc++ "
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch armv7 -std=gnu99 "
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
#  remove '--enable-float' for double precision
#  and take a 'libfftw3.a' file instead
./configure --host=arm-apple-darwin --target=arm-apple-darwin

make -j2

cp .libs/libfftw3.a $RESULT_DIR/libfftw3_armv7.a
rm -fr .libs/libfftw3.a

# Copy the header file too, just for convenience
cp api/fftw3.h $RESULT_DIR/fftw3.h

# ------------------------ armv7s---------------------------
# Do it all again for i386
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX CC LDFLAGS CXXFLAGS

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT_IOS/usr/include/ "
export CFLAGS="$CPPFLAGS -arch armv7s  -no-cpp-precomp -miphoneos-version-min=6.1 -isysroot $SDKROOT_IOS"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch armv7s -std=gnu++11 -stdlib=libc++ "
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch armv7s -std=gnu99 "
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
#  remove '--enable-float' for double precision
#  and take a 'libfftw3.a' file instead
./configure --host=arm-apple-darwin --target=arm-apple-darwin

make -j2

# Copy the ARM library to a temporary location
cp .libs/libfftw3.a $RESULT_DIR/libfftw3_armv7s.a
rm -fr .libs/libfftw3.a

# ------------------------ arm64 ---------------------------
# Do it all again for arm64
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX CC LDFLAGS CXXFLAGS

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT_IOS/usr/include/ "
export CFLAGS="$CPPFLAGS -arch arm64  -no-cpp-precomp -miphoneos-version-min=6.1 -isysroot $SDKROOT_IOS"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch arm64 -std=gnu++11 -stdlib=libc++ "
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch arm64 -std=gnu99 "
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
#  remove '--enable-float' for double precision
#  and take a 'libfftw3.a' file instead
./configure --host=arm-apple-darwin --target=arm-apple-darwin

make -j2

# Copy the ARM library to a temporary location
cp .libs/libfftw3.a ios-library/libfftw3_arm64.a
rm -fr .libs/libfftw3.a

# Create fat lib by combining the two versions
lipo -arch armv7 $RESULT_DIR/libfftw3_armv7.a -arch armv7s $RESULT_DIR/libfftw3_armv7s.a -arch i386 $RESULT_DIR/libfftw3_i386.a -arch x86_64 $RESULT_DIR/libfftw3_x86_64.a -arch arm64 $RESULT_DIR/libfftw3_arm64.a -create -output $RESULT_DIR/libfftw3.a

# Remove intermediate binaries
#rm $RESULT_DIR/libfftw3_armv7.a
#rm $RESULT_DIR/libfftw3_i386.a
#rm $RESULT_DIR/libfftw3_x86_64.a

# Unset used environment variables
unset CPPFLAGS CFLAGS CPP LD LDFLAGS CC CXX CXXFLAGS

回答by garlix

I've adapted previous scripts to

我已经改编了以前的脚本

WORK WITH XCODE7 iOS9.3 MACOSX 10.11 FFTW 3.3.4

使用 XCODE7 iOS9.3 MACOSX 10.11 FFTW 3.3.4

#!/bin/sh

# build_lipo.sh
# build an arm64 / armv7s / armv7 / i386 / x86_64 lib of fftw3
# make sure to check that all the paths used in this script exist on your system
#
# adopted from:
# http://robertcarlsen.net/2009/07/15/cross-compiling-for-iphone-dev-884
# changed by garlix
# original: by Nickun
# http://stackoverflow.com/questions/3588904/how-to-link-third-party-libraries-like-fftw3-and-sndfile-to-an-iphone-project-in

######## EDIT HERE ############
export iOS_SDK_VERSION=9.3
export MACOSX_VERSION=10.11
###############################

# this is the folder where the results of our efforts will end up:
export RESULT_DIR=ios-library
export XCODE_DEV_PATH=`xcode-select -print-path`
# Select toolchains folder
export XCODE_TOOLCHAINS=$XCODE_DEV_PATH/Toolchains/XcodeDefault.xctoolchain
# Select the desired iPhone SDK
export DEVROOT_IOS=$XCODE_DEV_PATH/Platforms/iPhoneOS.platform/Developer
export SDKROOT_IOS=$DEVROOT_IOS/SDKs/iPhoneOS$iOS_SDK_VERSION.sdk
# Select the OSX SDK
export DEVROOT_OSX=$XCODE_DEV_PATH/Platforms/MacOSX.platform/Developer
export SDKROOT_OSX=$DEVROOT_OSX/SDKs/MacOSX$MACOSX_VERSION.sdk

export LIB_NAME=libfftw3f

# ------------------------ i386 ---------------------------
# Do it for i386
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

export CFLAGS="-arch i386"

# TODO: error checking
./configure --enable-float --host=i386-apple-darwin9.2.0 --target=i386-apple-darwin9.2.0
make -j2

# Copy the FAT native library to a temporary location
mkdir -p $RESULT_DIR
cp .libs/$LIB_NAME.a $RESULT_DIR/$LIB_NAME\_i386.a

# ------------------------ x86_64 ---------------------------
# Do it all again for x86_64
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

# TODO: error checking
./configure --enable-float
make -j2

# Copy the FAT native library to the temporary location
cp .libs/$LIB_NAME.a $RESULT_DIR/$LIB_NAME\_x86_64.a

# ------------------------ armv7---------------------------
# Do it all again for armv7
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT_IOS/usr/include/ -mfpu=neon"
export CFLAGS="$CPPFLAGS -arch armv7 -mfpu=neon -no-cpp-precomp -miphoneos-version-min=5.0 -isysroot $SDKROOT_IOS"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch armv7 -std=gnu++11 -stdlib=libc++ -mfpu=neon"
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch armv7 -std=gnu99 -mfpu=neon"
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
#  remove '--enable-float' for double precision
#  and take a 'libfftw3.a' file instead
./configure --enable-float --enable-neon --host=arm-apple-darwin --target=arm-apple-darwin

make -j2

cp .libs/$LIB_NAME.a $RESULT_DIR/$LIB_NAME\_armv7.a

# Copy the header file too, just for convenience
cp dft/api/fftw3.h $RESULT_DIR/fftw3.h

# ------------------------ armv7s---------------------------
# Do it all again for i386
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT_IOS/usr/include/ -mfpu=neon"
export CFLAGS="$CPPFLAGS -arch armv7s -mfpu=neon -no-cpp-precomp -miphoneos-version-min=5.0 -isysroot $SDKROOT_IOS"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch armv7s -std=gnu++11 -stdlib=libc++ -mfpu=neon"
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch armv7s -std=gnu99 -mfpu=neon"
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
#  remove '--enable-float' for double precision
#  and take a 'libfftw3.a' file instead
./configure --enable-float --enable-neon --host=arm-apple-darwin --target=arm-apple-darwin
make -j2

# Copy the ARM library to a temporary location
cp .libs/$LIB_NAME.a $RESULT_DIR/$LIB_NAME\_armv7s.a

# ------------------------ arm64 ---------------------------
# Do it all again for arm64
make clean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LD CXX LDFLAGS CXXFLAGS

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT_IOS/usr/include/ -mfpu=neon"
export CFLAGS="$CPPFLAGS -arch arm64 -mfpu=neon -no-cpp-precomp -miphoneos-version-min=5.0 -isysroot $SDKROOT_IOS"
export LD=$XCODE_TOOLCHAINS/usr/bin/ld
export CXX="$XCODE_TOOLCHAINS/usr/bin/clang -x c++ -arch arm64 -std=gnu++11 -stdlib=libc++ -mfpu=neon"
export CC="$XCODE_TOOLCHAINS/usr/bin/clang -x c -arch arm64 -std=gnu99 -mfpu=neon"
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
#  remove '--enable-float' for double precision
#  and take a 'libfftw3.a' file instead
./configure --enable-float --enable-neon --host=arm-apple-darwin --target=arm-apple-darwin

make -j2

# Copy the ARM library to a temporary location
cp .libs/$LIB_NAME.a ios-library/$LIB_NAME\_arm64.a


# Create fat lib by combining the two versions
lipo -arch armv7 $RESULT_DIR/$LIB_NAME\_armv7.a -arch armv7s $RESULT_DIR/$LIB_NAME\_armv7s.a -arch i386 $RESULT_DIR/$LIB_NAME\_i386.a -arch x86_64 $RESULT_DIR/$LIB_NAME\_x86_64.a -arch arm64 $RESULT_DIR/$LIB_NAME\_arm64.a -create -output $RESULT_DIR/$LIB_NAME.a

# Remove intermediate binaries
#rm $RESULT_DIR/libfftw3_armv7.a
#rm $RESULT_DIR/libfftw3_i386.a
#rm $RESULT_DIR/libfftw3_x86_64.a

# Unset used environment variables
unset CPPFLAGS CFLAGS CPP LD LDFLAGS CXX CXXFLAGS

According with @Ninji you have to modify Makefile.am

根据@Ninji 你必须修改 Makefile.am

 34c34
 < libbench2 $(CHICKEN_EGG) tests mpi doc tools m4
 ---
 > libbench2 $(CHICKEN_EGG) mpi doc m4
 95,108c95
 < pkgconfig_DATA = fftw3@[email protected]
 < 
 < WISDOM_DIR = /etc/fftw
 < WISDOM = wisdom@PREC_SUFFIX@
 < 
 < WISDOM_TIME=12 # default to 12-hour limit, i.e. overnight
 < WISDOM_FLAGS=--verbose --canonical --time-limit=$(WISDOM_TIME)
 < 
 < wisdom:
 <   tools/fftw@PREC_SUFFIX@-wisdom -o $@ $(WISDOM_FLAGS)
 < 
 < install-wisdom: wisdom
 <   $(mkinstalldirs) $(WISDOM_DIR)
 <   $(INSTALL_DATA) wisdom $(WISDOM_DIR)/$(WISDOM)
 ---
 > pkgconfig_DATA = fftw3@[email protected]
 \ No newline at end of file

and Makefile.in

Makefile.in

235c235
 <    libbench2 . threads tests mpi doc tools m4
 ---
 >    libbench2 . threads mpi doc m4
 447c447
 < libbench2 $(CHICKEN_EGG) tests mpi doc tools m4
 ---
 > libbench2 $(CHICKEN_EGG) mpi doc m4
 1053,1058d1052
 < wisdom:
 <    tools/fftw@PREC_SUFFIX@-wisdom -o $@ $(WISDOM_FLAGS)
 < 
 < install-wisdom: wisdom
 <    $(mkinstalldirs) $(WISDOM_DIR)
 <    $(INSTALL_DATA) wisdom $(WISDOM_DIR)/$(WISDOM)