For the more curious

This section is for those who want to learn more about how to use sherpa-ncnn in an iOS project.

Files generated by running ./build-ios.sh

After running:

./build-ios.sh

You may be curious about the generated files.

Hint

Please have a look at ./build-ios.sh so that you know what it does for you.

The above command generates files inside the directory ./build-ios:

sherpa-ncnn fangjun$ ls -lh build-ios
total 1912
drwxr-xr-x   6 fangjun  staff   192B Feb 26 16:48 build
drwxr-xr-x   4 fangjun  staff   128B Feb 26 16:46 install
drwxr-xr-x  15 fangjun  staff   480B Feb 14 18:09 openmp-11.0.0.src
-rw-r--r--   1 fangjun  staff   952K Dec  8  2021 openmp-11.0.0.src.tar.xz
drwxr-xr-x   6 fangjun  staff   192B Feb 26 16:44 openmp.xcframework
drwxr-xr-x   6 fangjun  staff   192B Feb 26 16:48 sherpa-ncnn.xcframework

What is interesting here is the two framework folders openmp.xcframework and sherpa-ncnn.xcframework. All other folders can be safely removed. We only need the two framework folders.

In the following, we describe the content in these two framework folders.

openmp.xcframework

$ tree build-ios/openmp.xcframework/
build-ios/openmp.xcframework/
├── Headers
│   └── omp.h
├── Info.plist
├── ios-arm64
│   └── libomp.a
└── ios-arm64_x86_64-simulator
    └── libomp.a

3 directories, 4 files

Explanation:

  • omp.h: The header file, which is used by ncnn

  • Info.plist: A file that is dedicated for framework on macOS/iOS

  • ios-arm64/libopm.a: A static library for iOS device, e.g., for iPhone

  • ios-arm64_x86_64-simulator/libomp.a: A static library for iOS simulators, including simulators for Intel chips and Apple Silicon (e.g., M1)

sherpa-ncnn fangjun$ file build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a
build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a: Mach-O universal binary with 2 architectures: [x86_64:current ar archive random library] [arm64:current ar archive random library]
build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a (for architecture x86_64):     current ar archive random library
build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a (for architecture arm64):      current ar archive random library

sherpa-ncnn fangjun$ lipo -info build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a
Architectures in the fat file: build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a are: x86_64 arm64

sherpa-ncnn fangjun$ file build-ios/openmp.xcframework/ios-arm64/libomp.a
build-ios/openmp.xcframework/ios-arm64/libomp.a: current ar archive random library

sherpa-ncnn fangjun$ lipo -info build-ios/openmp.xcframework/ios-arm64/libomp.a
Non-fat file: build-ios/openmp.xcframework/ios-arm64/libomp.a is architecture: arm64

sherpa-ncnn.xcframework

sherpa-ncnn fangjun$ tree build-ios/sherpa-ncnn.xcframework/
build-ios/sherpa-ncnn.xcframework/
├── Headers
│   └── sherpa-ncnn
│       └── c-api
│           └── c-api.h
├── Info.plist
├── ios-arm64
│   └── sherpa-ncnn.a
└── ios-arm64_x86_64-simulator
    └── sherpa-ncnn.a

5 directories, 4 files

Explanation:

  • c-api.h: The header file, which is copied from https://github.com/k2-fsa/sherpa-ncnn/blob/master/sherpa-ncnn/c-api/c-api.h

  • Info.plist: A file that is dedicated for framework on macOS/iOS

  • ios-arm64/sherpa-ncnn.a: A static library for iOS, e.g., iPhone

  • ios-arm64_x86_64-simulator/sherpa-ncnn.a: A static library for simulators, including simulators for Intel chips and Apple Silicon (e.g., M1)

sherpa-ncnn fangjun$ file build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a
build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a: Mach-O universal binary with 2 architectures: [x86_64:current ar archive] [arm64]
build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a (for architecture x86_64):   current ar archive
build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a (for architecture arm64):    current ar archive

sherpa-ncnn fangjun$ lipo -info build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a
Architectures in the fat file: build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a are: x86_64 arm64

sherpa-ncnn fangjun$ file build-ios/sherpa-ncnn.xcframework/ios-arm64/sherpa-ncnn.a
build-ios/sherpa-ncnn.xcframework/ios-arm64/sherpa-ncnn.a: current ar archive

sherpa-ncnn fangjun$ lipo -info build-ios/sherpa-ncnn.xcframework/ios-arm64/sherpa-ncnn.a
Non-fat file: build-ios/sherpa-ncnn.xcframework/ios-arm64/sherpa-ncnn.a is architecture: arm64

How to use files generated by ./build-ios.sh in Xcode

In this section, we describe how to use openmp.xcframework and sherpa-ncnn.xcframework in Xcode.

The underlying implementation of sherpa-ncnn is in C++. It also provides C API.

To use C API in Xcode with Swift, we have to write a bridging header.

We provide a bridging header for you: SherpaNcnn-Bridging-Header.h. All you need is to add this file to your iOS project and click Build Settings -> Swift Compiler - General and set Objective-C Bridging Header to ${PROJECT_DIR}/../../swift-api-examples/SherpaNcnn-Bridging-Header.h. See the screenshot below for reference:

Screenshot for setting the bridging header

Fig. 30 Screenshot for setting the bridging header

We list the content of the bridging header below for reference:

#ifndef SWIFT_API_EXAMPLES_SHERPANCNN_BRIDGING_HEADER_H_
#define SWIFT_API_EXAMPLES_SHERPANCNN_BRIDGING_HEADER_H_

#import "sherpa-ncnn/c-api/c-api.h"

#endif  // SWIFT_API_EXAMPLES_SHERPANCNN_BRIDGING_HEADER_H_

After adding the bridging header to your iOS project, Xcode will complain it cannot find sherpa-ncnn/c-api/c-api.h. The fix is to add the path build-ios/sherpa-ncnn.xcframework/Headers to Header Search Paths by changing Build Settings -> Search Paths -> Header Search Paths, as is shown in the following screenshot:

Screenshot for setting the header search paths

Fig. 31 Screenshot for setting the header search paths

Hint

Instead of using an absolute path, we use ${PROJECT_DIR}/../../build-ios/sherpa-ncnn.xcframework/Headers/

For instance, my sherpa-ncnn is downloaded to /Users/fangjun/open-source/sherpa-ncnn and the path to sherpa-ncnn.xcframework is /Users/fangjun/open-source/sherpa-ncnn/build-ios/sherpa-ncnn.xcframework.

The value of PROJECT_DIR is /Users/fangjun/open-source/sherpa-ncnn/ios-swift/SherpaNcnn, so we can use ${PROJECT_DIR}/../../build-ios/sherpa-ncnn.xcframework/Headers/.

Also note that PROJECT_DIR is a pre-defined variable in Xcode.

Please also add SherpaNcnn.swift to your iOS project, which is a utility to make it easier to access functions from the bridging header.

The next thing is to add openmp.xcframework and sherpa-ncnn.xcframework as dependencies to you iOS project. Select Build Phases -> Link Binary with Libraries and then click + to add sherpa-ncnn.xcframework and openmp.xcframework. See the screenshot below for reference:

Screenshot for adding a framework to your project

Fig. 32 Screenshot for adding a framework to your project

Hint

After clicking +, please select Add Other... -> Add Files.., and then add the path to sherpa-ncnn.xcframework.

Repeat the step for openmp.xcframework.

See the screenshot below for reference:

Screenshot for adding a framework

Fig. 33 Screenshot for adding a framework

One more thing you need to do after adding the framework is to setup the framework search path. Click Build Settings -> Search Paths -> Framework Search Paths and add the path to build-ios/. See the screenshot below:

Screenshot for setting framework search paths

Fig. 34 Screenshot for setting framework search paths

If you encounter link errors about the C++ standard library, please add -lc++ to link against libc++ by clicking Build Settings -> Linking -> Other Linker Flags and adding -lc++. See the screenshot below for reference:

Screenshot for adding ``-lc++`` to linker flags

Fig. 35 Screenshot for adding -lc++ to linker flags

That is all you need to add sherpa-ncnn to your iOS project.