Building a c based static library for iOS - ios

I need a network library for my c library so I can use it on both iOS and android. I've been searching around and tried to build libcurl as a static library but wasn't successful.
I built it with the following settings
$ export CC="clang"
$ export CFLAGS="-Wall -g -std=c11 -pipe -Os -gdwarf-2"
$ ./configure --enable-static
make install
It runs fine when I test the library with my test.c library. However, when I run it on my iOS project, I got a mismatch on CurlchkszEQ(long, CURL_SIZEOF_LONG)
I think the problem was that CURL_SIZEOF_LONG is set to be 8 while long in iOS is 4.
Does anyone know what went wrong with my config setting?

You want to cross-compile libcurl for iOS but the problem here is that you use clang which by default produces 64-bit x86_64 object files.
In other words you need to work with the iOS toolchain (xcrun -sdk iphoneos clang), provide the right architecture flag(s)[1] (e.g -arch armv7) and use the right sysroot path.
I recommend you to refer to:
curl-ios-build-scripts: a collection of handy scripts used to build (lib)curl for iOS 5+ and OSX 10.7+,
or, http://seiryu.home.comcast.net/~seiryu/libcurl-ios.html which provides a ready-to-use a precompiled binary.
[1]: you may want to produce a fat library that targets ARMv7, ARMv7s and i386 (simulator) architectures.

Related

Cannot cross-compile static C library for iPhone (arm64) on macOS (x86_64)

I've been trying to cross-compile a static C library for use in an iOS application.
I figured that this can be achieved by wrapping the headers and binaries in an XCFramework, but the compiled library is for an x86_64 architecture, so it can't run on iOS.
What I did was the following:
export IOS_SDK_LOC=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
export AARCH64_FLAGS="-arch arm64 -isysroot $IOS_SDK_LOC "
./configure --host=arm_apple_darwin --build=x86_64_apple_darwin --target=x86_64_apple_darwin
\ CFLAGS=$AARCH64_FLAGS CPPFLAGS=$AARCH64_FLAGS
I initially tried to just have the CFLAGS, but ended up passing the same arguments as CPPFLAGS as well following the answer at Can't cross compile C library for arm (iOS)
In either case, I get the same error:
configure: error: cannot run test program while cross compiling
How should I go about compiling my library in this case?
The workaround I found for compiling an arm64 static library on the same machine was to install QEMU (machine emulator), with the target OS in mind.
As luck would have it, Jonathan Afek from Aleph Security recently wrote a frame buffer for iOS QEMU, making it particularly easy to work with now.
More information here: https://www.reddit.com/r/jailbreak/comments/kxr0v8/news_ios_qemu_is_getting_a_graphical_display_ios/

Ios - Wrong architecture building WebRTC

I'm building WebRTC for iOS. To do that, I'm using the following bash script:
# Set flags to compile in arm64
export GYP_GENERATORS="ninja"
export GYP_DEFINES="build_with_libjingle=1 build_with_chromium=1 libjingle_objc=1 OS=ios target_arch=arm64"
export GYP_GENERATOR_FLAGS="output_dir=out_ios_arm64"
export GYP_CROSSCOMPILE=1
# Generate metadata for compile
gclient runhooks
# Compile webRTC in Release and verbose mode
ninja -v -C src/out_ios_arm64/Release-iphoneos AppRTCDemo
In the same machine and the same dir, I have compiled for armv7 and now when I try to build with the code above, the library is compiled for armv7. Maybe I have some metadata info in my dir that I'm not removing or something but I understand that if I set target_arch=arm64 in my GYP_DEFINES I should see my library compiled for this arch. Any idea what could be happening?
P.D: I need to build for both (armv7 and arm64) in order to generate with lipo an universal lib.

Errors when cross-compiling OpenSSL on OS X for iOS with Clang instead of gcc

I would like to cross-compile OpenSSL 1.0.1h for iOS on OS X without gcc installed by following instructions in the WWDC 2014 session 305 video and from the OpenSSL web site.
I unzip/untar and the switch from gcc to clang (almost) as suggested here.
OLD_LANG=$LANG
unset LANG
sed -i "" 's|\"iphoneos-cross\"\,\"llvm-gcc\:-O3|\"iphoneos-cross\"\,\"clang\:-Os|g' Configure
sed -i "" 's/CC= cc/CC= clang/g' Makefile.org
sed -i "" 's/CFLAG= -O/CFLAG= -Os/g' Makefile.org
export LANG=$OLD_LANG
Notice that I had to stick with the makedepend tool for otherwise already the make depend step will fail (as was also mentioned elsewhere). Installing that tool with brew install makedepend is not an issue for me (but installing gcc next to Clang would be). Now
./Configure iphoneos-cross
make depend
make
leads to warnings (during make depend) and errors (during make) about missing include files (such as stdlib.h). The typical include path passed to clang is apparently -I. -I.. -I../include.
I assume this is to related to clang not receiving specific C options by default, but if so, what is the most sensible way for making the compilation work e.g. by fixing the sed edits or by setting environment variables. (Currently I don't have any CC* environment variables set. There is e.g. /usr/include/stdlib.h on my system.)
I rarely use OS X C compilers on the command line and the solution is therefore not obvious to me.
UPDATE Here is the question in a more specific for whose valid answer will be awarded with a bounty: What specific edits (similar to the first code snippet above) have to be performed on the files in latest version of OpenSSL source code (e.g. openssl-1.0.1h.tar.gz) so that one can cross-compiles it by issuing commands similar to the second code snippet above for iOS 7 (soon iOS 8) architectures on OS X 10.9 with Xcode 5.1.1 (soon Xcode 6) installed, without gcc installed and with makedepend optionally installed?
First, you must make sure that the current Xcode developer directory is set:
xcode-select -p
This should output something like this:
/Applications/Xcode.app/Contents/Developer
If you want to change this, for example to switch between Xcode 6 and Xcode 5 (or if that command outputted a blank line), you would use xcode-select as follows:
xcode-select -s /Applications/OldXcode.app/Contents/Developer
With that done, next you will need to choose an SDK to use. Since you're trying to build for iPhone, it would be some version of the iPhoneOS SDK. You can find which version it will try to use by default using this command:
xcrun --sdk iphoneos --show-sdk-version
Which will output something like 7.1 . If you need a different SDK version, you can provide it by using the specific SDK name with the version, i.e. iphoneos7.1. This of course must already be installed in the version of Xcode that you selected with xcode-select.
So assuming you have all those ducks in a row, using that information to cross compile is pretty easy. For example:
make CC="$(xcrun --sdk iphoneos --find clang) -isysroot $(xcrun --sdk iphoneos --show-sdk-path) -arch armv7 -arch armv7s -arch arm64"
This will pass the CC commands through xcrun, with the arguments to use the current iphoneos SDK of the Xcode set by xcode-select, building using the SDK root as the sys root and building for architectures armv7, armv7s, and arm64. Building for the iOS Simulator would be similar to the above, but passing the iphonesimulator in place of iphoneos as the SDK, and setting the architectures to i386 and x86_64.
With that, things should pretty much just work and you may not need to do anything further -- unfortunately I'm not in a position to try this myself and I'm referring to notes from a previous project. You may run into subsequent issues that are specific to OpenSSL or it's build scripts.
Note that all of the above can be used to compile for MacOS X as well, obviously with different SDK and architecture values.
I don't know if it's exactly what you want... but I compile OpenSSL for iOS following this script:
https://github.com/x2on/OpenSSL-for-iPhone/blob/master/build-libssl.sh
and it's very straightforward...
anyways, this answer here can help somebody else looking for how to compile OpenSSL for iOS.

How to build V8 for armv7

i'm trying to use Google's v8 in my iPhone Application.
I built the libraries using "make arm" as stated on Google's website.
Unfortunately I get several linker errors telling me that the library is build "for archive".
The terminal tells me that the library's architecture is i386:
lipo -info libv8_base.a
input file libv8_base.a is not a fat file
Non-fat file: libv8_base.a is architecture: i386
So, how do I actually build a armv7 library?
BTW: I don't really know much about this library building stuff. Maybe I can only build for ARM on an actual ARM device? I don't get why I can't just download the prebuilt files anywhere, too.
You can find instructions to cross-compile for ARM on the v8 wiki.
When running on an x86 machine
make arm
builds a simulator, not an actual ARM binary.
You can also compile a release shell natively if you have ARM hardware:
scons arch=arm -j2
EDIT:
You may also want to learn about cross-compilation.
There is a simulator for armv7 built in the v8 source. If you check v8/src/arm/ you will find simulator files.
To build, make sure your CC, CXX and LINK are point to native gcc / g++ tools. And then do
Make arm.release -j8
This will make for arm and look into *.gypi files for more build options. Hope this is useful.

I want to know how to make a makefile for iOS "fat" library

I want to create a (non-xcode) makefile to create a fat library (emulator + device(s)) that can be imported into an XCode project using a makefile that calls the basic command line tools directly (not running XCODE from the command line, but the MAC Gcc and it's related utilities) - this is for .m, .mm, .c, and .cpp source files.
Ideal would be to find an example that works for a simple library (not by calling a makefile generator that makes an almost non human readable makefile)
anyway anyone know of such a thing or appropriate mechanism for doing the same?
Also an ability to extract the complier flags from an XCode project would be real handy :)
The purpose is I want to add a module to my cross platform libraries so I can integrate them into an iOS project.
Thanks!!
You can extract the compiler flags by viewing the build details or, more simply, running xcodebuild from the command line.
To create a fat binary, you either take advantage of the compiler toolchain's built-in support on the Mac OS X platform by passing multiple -arch arguments, like so:
clang -arch i386 -arch x86_64 -framework Foundation simple.m -o simple
Alternatively, you build the binary once for each desired architecture, then wrap all those binaries into a single fat binary using lipo. This is handy when working with ported Unix software; just change the build result directory each time, then smash them all together after building with lipo. Assuming you have simple-i386 and simple-x86_64, you would then do:
lipo simple-i386 simple-x86_64 -create -output simple
This would create a fat binary named simple containing simple-i386 and simple-x86_64.
Ok - I found this which is a great HOWTO o building a fat library using XCODE that outlines the process and how to create the projects
http://blog.boreal-kiss.net/2011/03/15/how-to-create-universal-static-libraries-on-xcode-4/
being a newbie to XCode and iOS development I had to discover a few things.
you can view the actual command line output of a build to see what the gcc flags are.
View->Navigators->Log - then control click on the messages list to "expand all Transcripts"
to see what stdout and stderr from the chosen build's build output.
You can execute an "external build tool" with your .bashrc and .bash_profile environment settings by making the command and arguments a login shell: "bash --login -c 'mybuildtool [my tools args] $(ACTION)', and thus bypass having to deal with the hard to maintain MacOSX launchd settings etc. this works for things like using ruby and rake as well as make etc.

Resources