How to build Boost-Libraries for iPhone - ios

Can someone tell me, where to find a detailed guide, how to build the Boost-Libraries for using it on the iPhone-Device.
I've allready build the libs for Mac and can use them in my project (only on iPhone-Simulator). While building the project for iPhone-Device, XCode haunts me a warning: "file is not of required architecture" ond some other errors.
Please Help

Start a new project in Xcode using the iPhone Static Library project template.
Then import the source and headers, and compile it that way. The result should be an iPhone compatible static library

I started here:
http://lists.boost.org/boost-build/2009/02/21326.php
With most of Boost you probably don't need to actually compile it, just include the useful headers. In my case, I just did the compiler define in my own Xcode project.

Hey I have updated Pete Goodliffes script in my openFrameworks addon:
It currently has arm64, armv7, i386, x86_64
Boost 1.59.0 or previous
libc++ / std=c++11 -- Now optional release for libstdc++
Precompiled and Script to build yourself (so if you need libstdc++ quite easy to change)
Supports Xcode 7
[https://github.com/danoli3/ofxiOSBoost][1]

For boost libraries which have only headers files (.hpp) you can just set header search path from your project to them.
For boost libraries with sources you can build static libraries for both ios phone/simulator with next simple steps:
Download and unpack a boost release archive (from https://www.boost.org/users/download/) e.g.: https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.tar.bz2
Run bootstrap.sh with needed libraries to build for instance 'context' (format =library1,library2,...):
./bootstrap.sh --with-libraries=context
Add toolsets with correct paths to installed SDKs to project-config.jam:
# IOS ARM64
using clang : iphoneos
: xcrun clang -arch arm64 -stdlib=libc++ -std=c++11 -miphoneos-version-min=12.0 -fvisibility-inlines-hidden -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
;
# IOS x86_64
using clang : iphonesimulator
: xcrun clang -arch x86_64 -stdlib=libc++ -std=c++11 -miphoneos-version-min=12.0 -fvisibility-inlines-hidden -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
;
Create and run build.sh script (where lib name is libboost_<name>.a):
lib=libboost_context.a
dir='stage/lib'
# Build arm64
./b2 -a -j4 toolset=clang-iphoneos binary-format=mach-o abi=aapcs link=static stage
mv $dir/$lib $dir/arm64_$lib
# Build x86_64
./b2 -a -j4 toolset=clang-iphonesimulator binary-format=mach-o abi=sysv link=static stage
mv $dir/$lib $dir/x86_64_$lib
# Make fat
lipo -create $dir/arm64_$lib $dir/x86_64_$lib -output $dir/$lib
Now you have next compiled static libraries in "/stage/lib" dir for boost context: arm64_libboost_context.a, x86_64_libboost_context.a and fat one libboost_context.a.

We use boost too. To simplify its inclusion into new applications I have created a Xcode project you can drop into your workspace to include boost. It is based on a Makefile so you need the Xcode commandline tools installed.
The project is here https://github.com/Cogosense/iOSBoostFramework.
Clone the project into your workspace, then click on Menu File->"Add Files to workspace". Select iOSBoostFramework/iOSBoostFramework.xcodeproj in the file finder and click add.
The Makefile in the iOSBoostFramework directory controls what is built and how it is built. There is support for Xcode workspace dependencies, bitcode generation, and only the target architectures selected by Xcode are built.
The following libraries are built test, thread, atomic, signals, filesystem, regex, program_options, system date_time, serialization, exception, locale, and random.
All the separate libraries and architectures are combined, the final build output is a FAT boost.framework Framework bundle which can be linked into the application.
The version of boost is specified in the Makefile (currently 1.64.0), it is downloaded, built for all active architectures and installed in the BUILT_PRODUCTS_DIR specified by xcode.

The previous answer helped me when I wanted to build boost for the arm simulator. When you have a Mac with M1 processor and want to use the simulator, you cannot use the arm64 build for the iPhone.
I added this to the project-config.jam:
# IOS Arm Simulator
using clang : iphonesimulatorarm64
: xcrun clang -arch arm64 -stdlib=libc++ -std=c++11 -miphoneos-version-min=10.0 -fvisibility-inlines-hidden -target arm64-apple-ios10.0-simulator -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk ;
Then pass toolset=clang-iphonesimulatorarm64 to the b2 command.

Related

Build C Library from makefile for ios and not macos

I have a makefile that builds some C files and if I run it on an M1 mac the resulting library has the architecture arm64 which I thought it what is necessary for them to compile with an Xcode project for iOS. I discovered I can run the command otool -l libf2c.a | grep platform which should tell me what it was compiled for and in my case it returns platform1 which indicates macOS. Based on this, I think I need a value of platform2 for iOS.
The reason this is an issue is because in Xcode I get the error ld: building for iOS, but linking in object file built for macOS, file '/Users/e.../close.o' for architecture arm64.
Based on what I have been researching it seems iOS and macOS have the same architecture (arm64) but are a different 'platform'? But, I am not sure how the platform is determined. Is there some setting in my makefile I need to specify the platform? I am assuming that if I am able to get the platform to be iOS then Xcode will cooperate and be able to build the library I have generated.
The preferred way to compile for iOS via command line would probably be to use the xcrun command. This will allow you to specify the correct SDK for the platform you actually want to run on. For example:
prompt$ xcrun --sdk iphoneos --toolchain iphoneos clang -c test.c -o test.o -arch arm64
prompt$ otool -v -l test.o | grep platform
platform IOS
TL;DR: change your compiler invocation from plain clang to xcrun --sdk iphoneos --toolchain iphoneos clang.

Undefined symbols for architecture x86_64 using Swagger API:

I am having this error in my Xcode project....So basically what I am doing is creating a static library that uses a Swagger Api that I have installed using CocoaPods. I am able to import the header files and use the header files in the library, but when I put the static library in another Xcode project I receive this error where It says _OBJC_CLASS_$_SWG....", referenced from: objc-class-ref in Sendable.o.... which is basically the class where I am using the Swagger header files.....
Things I have attempted:
1: Delete Derived Data folder, cleaned and rebuilt
2: made sure POD, library, and project using library have the same architectures as well as
3: made sure architecture build active is set to NO for all
4: made sure $(inherited) is in both library and project using library
5: installed pod file again in library
Things I noticed:
1: the library itself does not have POD in the header search path
2: I get the following warnings but ignored them
3: using Pod update gives me error saying GitHub is offline make sure you have internet connection, only removing and installing seem to work successfully.
My guess is that you are building the library for a single architecture - you are building it either for a Generic iOS Device, or some speciffic iOS device. Either way, you will not be able to use the library on a simulator (x86_64 architecture). Vice versa, if you build the library for a simulator, you will not be able to use it on a device.
If you want to use the same build on both devices and simulator, you need to create an universal library using a tool called lipo, either manually or by Build Phase script. Check out this article. Short summary:
Add an Aggregate target to your library project
Add a Run Script Build Phase
Paste this script into it:
# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# Step 1. Build Device and Simulator versions
xcodebuild -target ${PROJECT_NAME} ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
xcodebuild -target ${PROJECT_NAME} -configuration ${CONFIGURATION} -sdk iphonesimulator -arch x86_64 -arch i386 -arch armv7 -arch armv7s -arch arm64 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 2. Create universal binary file using lipo
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a"
echo "Universal library can be found here:"
echo ${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}.a
# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/include" "${UNIVERSAL_OUTPUTFOLDER}/"
Build your Aggregate target and an universal library will be built

How to build Cocoa Touch Framework for i386 and x86_64 architecture?

After building a Cocoa Touch framework (Swift or Object-C) and adding it to another project as "Embedded Binaries" I get the following error message when I try to build
missing required architecture i386
...
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Following various existing answers and extended research I already added i386 to the Architectures build settings …
However this doesn't seem to have an effect. When I check using
lipo -info TesterFrameworkObjC
I only get
Architectures in the fat file: TesterFrameworkObjC are: armv7 arm64
… shouldn't i386 (and x86_64) appear here as well? What am I missing?
(I am using Xcode 6.2 + building for iOS 8.2)
Some new insights
Using a version of this build script I am able to build the missing architectures for the Swift version of the framework.
However when I add this framework to my app and build I still get errors
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$__TtC20TesterFrameworkSwift18TestFrameworkSwift", referenced from:
objc-class-ref in ViewController.o
ld: symbol(s) not found for architecture x86_64
Looking at the final build folder building for the simulator
Build/Products/Debug-iphoneos/TesterFrameworkSwift.framework/
I can see that the architectures are still missing although they were part of the framework (as shown). How can I ensure all the right architecture builds of my framework are included when building the app?
Update
Looking at all the error messages to me it looks like the issue isn't actually to have the wrong products/archictures being built but one step later there the Linker isn't using the correct paths to them. Not sure how correct this.
This is the same problem that I had.
Seems this is a Xcode bug, I workaround it by adding a build script.
It will just compile your library with all architectures, and lipo it to fat binary image.
Also note
Looking at the final build folder building for the simulator
Build/Products/Debug-iphoneos/TesterFrameworkSwift.framework/
you are looking x86_64 and i386 images in iphone build folder, they should be in Debug-iphonesimulator/TesterFrameworkSwift.framework/
Also there is a recursion issue in your script, I've corrected it.
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: Detected, stopping"
else
export ALREADYINVOKED="true"
# Step 1. Build Device and Simulator versions
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
# Step 3. Copy Swift modules (from iphonesimulator build) to the copied framework directory
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
# Step 5. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
# Step 6. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"
fi
6) Hit "cmd + B" (Build Project)
7) Open Product in Finder
8) Navigate 1 directory up ("cmd + ↑"), and you will see "Release-universal" directory.
There will be your "fat/universal" library, You are ready to go!
You can check it via
file test.dylib
test.dylib: Mach-O universal binary with 4 architectures
test.dylib (for architecture i386): Mach-O dynamically linked shared library i386
test.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
test.dylib (for architecture armv7): Mach-O dynamically linked shared library arm
test.dylib (for architecture arm64): Mach-O 64-bit dynamically linked shared library
I encounter the same problem and fortunately I solved it.
When you create a framework with Xcode and build it with the iPhone 5 simulator or the simulator before iPhone 5(such as iPhone 4s or iPhone 4),you will get a framework with i386 architecture.And if you build it with iPhone 5s simulator or the simulatro after iPhone 5s,you will get a framework with x86_64 architecture.
But if you use the framework in your project and you want to run the app on a simulator,the framework must contain both i386 and x86_64 architecture,otherwise you will get a linker error.
So you need to use lipo -create command to merge two framework,at this point your framework is ready for use.
Go to Build Settings -> Set Build Active Architecture Only to NO
Build your Framework in iPhone 5 and iPhone 6 or above Simulators.
Add the run script in post actions to generate the universal framework.
Go to terminal and type cd (path of your framework, or drag and drop your framework) which will take you to the frameworks directory
type file YOUR_FRAMEWORK_NAME which lists all the architectures your framework is supporting
you can see that your framework supports all four architectures i386, x86_64, armv7 arm64.
Active Architecture => NO
Valid Architecture => "armv7 armv7s arm64 i386 x86_64"
Use Above Build Setting when in are aggregating !!!
I worked for me for all Architecture Framework creation

GMP Library for iOS

I have a GMP Library that is used for BIG integer calculation in C++.
I am unable to compile the same in Xcode for iOS development.
Please Provide with details steps regarding how to compile GMP for iOS Development
I realize that there has been some considerable time gone by but none of the information in the previous answer worked for me. Here is how I was able to do it, hope this helps someone else in the future.
Grab the gmp snapshot from https://gmplib.org/download/snapshot/
It is in .lz format, it will need to be uncompressed. if you have a mac, uncompress it using lzip, install with homebrew brew install lzip
Once its uncompressed from lzip, then it will be a .tar file, the finder can take care of that for you. You will have a gmp folder with a bunch of files and other sub-folders.
You will need Xcode commandline tools installed. Make sure you have that pre-installed.
Run this configure line. Take care to note that you need to put in your path to the directory you want it to be stored, in --prefix.
./configure CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -fembed-bitcode -arch arm64e --sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk" CPPFLAGS="-fembed-bitcode -arch arm64e --sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk " --disable-shared --enable-static --host=arm-apple-darwin --disable-assembly --prefix="{ YOUR_PATH_HERE }/GMP_6_1_99/gmp-6.1.99-20200117/gmplib-iphoneos-arm64e"
Then you run (notice the same path as before for the log files)
make -j &> "{ YOUR_PATH_HERE }/gmp-6.1.99-20200117/gmplib-iphoneos-arm64e-build.log"
make install &> "{ YOUR_PATH_HERE }/gmp-6.1.99-20200117/gmplib-iphoneos-arm64e-install.log"
There are two main points to those lines that are changeable, the platform, and the architecture. The above uses the arm64e architecture but you can just as easily build for arm64, armv7, armv7s. Also you can change out the platform as well and build for macosx, watchos, iphonesimulator, or appletvos. To change the platform you need to find the sdk of where it lives on your machine. The other architecture options are x86_64 i386, To do that, type this into your terminal...
xcrun --sdk iphoneos --show-sdk-path
(replace "iphoneos" with the platform you are looking to use from above)
And replace the SDK path. Make sure you match with the correct architecture or else you will get an error, cannot find compiler.
As GenieWanted said, provide more information!!!
However, I compiled successfully the GMP library for iOS 7 64 bits following the next step:
./configure
CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
CPP="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
-E" CPPFLAGS="-target arm64-apple-darwin -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/
-miphoneos-version-min=7.0" --host=aarch64-apple-darwin --disable-assembly --enable-static --disable-shared --prefix=/your-path/
I would like to point out that it only creates the C library, I do not think is different for C++, however I will try this afternoon.
#bolnad's answer worked for me doing a small modification, removing the -fembed-bitcode flag both from CC and CPPFLAGS.
EDIT: it ended up not correctly compiling the different architectures, so I found this script on github https://github.com/FlowCrypt/GMP and was able to build correctly.

Using custom built OpenCV for iOS on XCode produces ___sincos_stret undefined symbol

I'm trying to use a C++ static library into my iPhone app which uses a modified version of OpenCV for iOS and I'm stuck with this issue at linking time:
Undefined symbols for architecture armv7:
"___sincos_stret", referenced from:
cv::initInterTab2D(int, bool) in opencv2(imgwarp.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I really do not understand what I'm missing, that function does not seem to be present in OpenCV and I do not find anything meaningful on the web; I'm wondering if it's in some mathematical library, but I haven't found anything yet.
I've compiled OpenCV with Clang and using the default libc++ library.
The libmylibrary.a and the OpenCV2 framework are correctly in the list of linked libraries.
I'm new to XCode, therefore I could have missed something trivial in the compilation of the static library and/or in the linking of it into my project.
I haven't changed the source code of that object as my changes were related to another part of the imgproc module of OpenCV, therefore I guess that this could have happen even using the default version.
Do you have any clues?
For fixing this problem with the Xcode 5 toolchain I specified the minimum supported iOS version as a compiler option to match the configuration in Xcode. For example:
-miphoneos-version-min=5.0
You can add this to the C and CXX flags in the makefile
CFLAGS += -miphoneos-version-min=5.0
CXXFLAGS += -miphoneos-version-min=5.0
For those who don't want to build with lower version of XCode, try changing python build script of OpenCV iOS. In build_framework.py, I added IPHONEOS_DEPLOYMENT_TARGET=6.0 in lines and rebuilt OpenCV for iOS.
os.system("xcodebuild -parallelizeTargets ARCHS=%s -jobs 8 -sdk %s -configuration Release -target ALL_BUILD" % (arch, target.lower()))
os.system("xcodebuild ARCHS=%s -sdk %s -configuration Release -target install install" % (arch, target.lower()))
to get
os.system("xcodebuild IPHONEOS_DEPLOYMENT_TARGET=6.0 -parallelizeTargets ARCHS=%s -jobs 8 -sdk %s -configuration Release -target ALL_BUILD" % (arch, target.lower()))
os.system("xcodebuild IPHONEOS_DEPLOYMENT_TARGET=6.0 ARCHS=%s -sdk %s -configuration Release -target install install" % (arch, target.lower()))
For me that fixed the issue. A nice read on the symbol __sincos_stret
TODO: Though that fixes the issue, in OpenCV.xcodeproj (in build folder) generated from the python script, it still has deployment target as iOS 7.0. There might be a cleaner way.
I ran into this problem after installing the XCode 5 developer preview and building OpenCV with the build_framework.py script. ___sincos_stret appears to be coming from using the new compiler version.
I fixed this problem by changing the path to the command-line tools.
In Terminal, verify the XCode command-line path:
xcode-select --print-path
If it prints a path inside XCode5-DP.app, then switch to the tools for Xcode 4:
xcode-select --switch /Applications/XCode.app/Contents/Developer
And rebuild the framework. Then try recompiling the project.
Per a quick search in support of Adam's question elsewhere, the symbol is defined in [path to SDK]/usr/lib/system/libsystem_m.dylib. Proof:
nm /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/usr/lib/system/libsystem_m.dylib | grep sincos
Rather than sticking to old versions of the tools or SDK, just make sure you're linking against that.

Resources