compile C code for iOS armv7+arm64 using clang xcode 9 - ios

I'm trying to make one binary for both armv7 and arm64.
I am using this command to compile a simple C file:
clang -arch arm64 hello.c -o hello -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
How can I add armv7 to this command to support old devices like the iPad 4? Knowing that xCode 9 stop supporting armv7 in iOS 11?

Just add -arch armv7:
clang -arch armv7 -arch arm64 hello.c -o hello -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
This will yield a fat binary with both architectures.
Also just a note, you can use xcrun to avoid having to provide the full sys root:
xcrun -sdk iphoneos clang -arch armv7 -arch arm64

As an update to Siguza's answer, the way to get SYSROOT as of Xcode 11 is:
xcrun --sdk iphoneos --show-sdk-path

Related

armv7s missing from device architecture using xcodebuild and Xcode

I'm trying to understand how building frameworks works more in general. I created a new framework project in Xcode 10 and I can see in Build Settings arm64 armv7 armv7s all defined in Valid Architectures. When I make a build for Generic iOS Device and use lipo -info I get only armv7 arm64 and no armv7s. I tried to do it from the command line as well:
xcodebuild -configuration Release -sdk iphoneos -target FrameworkExample ONLY_ACTIVE_ARCH=NO BUILD_DIR="BUILD_DIR"
I also tried manually passing each architecture
-arch armv7s -arch arm64 -arch armv7 but I only got armv7 and arm64 again.
I also tried using destination
-destination generic/platform=iOS
Same result.
My project's Deployment Target and Framework Targets are both set to 8.0.

CFLAGS="-arch armv7" vs CFLAGS="-arch armv7 -arch arm64"

I want to compile a static library that supports both armv7 and arm64.What are the differences between the following two operations?
CFLAGS="-arch armv7" CFLAGS="-arch armv7" Build the two architectures separately and then use lipo to create a fat static libraries.
CFLAGS="-arch armv7 -arch arm64" Build static libraries that support both architectures at once.
There should be no difference. You can examine the libraries produced using the command
lipo -detailed_info YOUR_LIBRARY_NAME
Both of them should be fat files.

How can I cross-compile GCC to produce libgfortran for iOS devices (arm, armv7)?

I need to compile Fortran-77 subroutines to be accessible on iOS. I am using GCC with the DragonEgg plugin, so I can use gfortran with the LLVM backend. I followed this answer but I am stuck when it comes to build libgfortran for armv7, armv7s and arm64.
Can I build libgfortran alone or is it always necessary to compile the GCC suite completely?
What is the correct way of producing this library for a different target? Is it possible to use GCC for this step or do I need LLVM for the arm*-targets?
Building GCC with arm-targets using GCC I get these errors:
./configure --prefix=/tmp/out --host=arm-apple-darwin --enable-languages=fortran
make
…
make[2]: arm-apple-darwin-ar: No such file or directory
make[2]: *** [libiberty.a] Error 1
make[1]: *** [all-libiberty] Error 2
Building GCC with arm-targets using LLVM I have problems with configure:
export CC="$(xcrun -sdk iphoneos -find clang)"
export CPP="$CC -E"
export CFLAGS="-arch armv7 -arch armv7s -arch arm64 -isysroot $(xcrun --sdk iphoneos --show-sdk-path) -miphoneos-version-min=9.2"
export AR=$(xcrun -sdk iphoneos -find ar)
export RANLIB=$(xcrun -sdk iphoneos -find ranlib)
export CPPFLAGS="-arch armv7 -arch armv7s -arch arm64 -isysroot $(xcrun --sdk iphoneos --show-sdk-path) -miphoneos-version-min=9.2"
export LDFLAGS="-arch armv7 -arch armv7s -arch arm64 -isysroot $(xcrun --sdk iphoneos --show-sdk-path)"
./configure --prefix=/tmp/out --enable-languages=fortran --host=arm-apple-darwin --disable-shared
…
checking how to run the C preprocessor... /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -E
configure: error: in `/Users/timo/temp/gcc-4.8.5-build/fixincludes':
configure: error: C preprocessor "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -E" fails sanity check
See `config.log' for more details.
make[1]: *** [configure-fixincludes] Error 1
The configure script states that
configure: WARNING: If you wanted to set the --build type, don't use --host.
If a cross compiler is detected then cross compile mode will be used.
What is meant by If a cross compiler is detected? How do I define the target platform correctly?
LLVM uses -arch armv7 etc. as target definition. What is nedded when using GCC?
You are trying to build cross-gcc libraries without cross binutils. Here is a good manual for building cross-gcc for arm, you can follow it.
What is meant by If a cross compiler is detected? How do I define the
target platform correctly?
When configuring you should also set --target=arm-apple-darwin. (In my own experience I did not set --host at all)
make[2]: arm-apple-darwin-ar: No such file or directory
Before building arm cross-compiler target libraries you should build binutils for this target.
Can't say anything about llvm.
So just try to make all steps in the link above.

How to generate link map file for Clang on iOS?

I know for armcc(armlink), I can use -L--map flag to generate a map file. http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0474c/BABDJCAA.html
But for clang compiler and linker, I tried all these flags, but none of them can generate link map file:
flag1: xcrun -sdk iphoneos clang -arch armv7s -Wl,-dead_strip -Wl,--map -o exe objtest.o libtest.a
flag2: xcrun -sdk iphoneos clang -arch armv7s -Wl,-dead_strip -Wl,-M -o exe objtest.o libtest.a
flag3: xcrun -sdk iphoneos clang -arch armv7s -Wl,-dead_strip -Wl,-m -o exe objtest.o libtest.a
What's wrong with my flag? Thanks in advance.
Try -Wl,-map,output.map, that should do it.

Compiling to get armv7s slice

I am compiling libraries in the terminal with the following command to get an armv7 slice:
./configure CC=/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2 --host=arm
NOTE: I also change the ldflags, sysroot to provide the relevant path, although I don´t show that here to keep this short.
I have successfully generated code slices for: i686, i386 and armv7 and combined them, but I can´t get an armv7s slice.
What settings do I use for armv7s code slice?
You should specify -arch armv7s in CFLAGS. Below is what I use to build ICU:
INSTALL=`pwd`/..
if [ $# -eq 0 ]
then
$0 armv7 iPhoneOS
$0 armv7s iPhoneOS
$0 i386 iPhoneSimulator
mkdir -p $INSTALL/universal/lib
cd $INSTALL/armv7/lib
for f in *.a
do
echo $f
xcrun -sdk iphoneos lipo -output ../../universal/lib/$f -create -arch armv7 $f -arch armv7s ../../armv7s/lib/$f -arch i386 ../../i386/lib/$f
done
#cd ../..
else
echo $1 $2
ARCH=$1
PLATFORM=$2
TOOLCHAIN=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
export CC="$TOOLCHAIN/usr/bin/clang"
DEVROOT=/Applications/Xcode.app/Contents/Developer/Platforms/$PLATFORM.platform/Developer
SDK=6.1
SDKROOT=$DEVROOT/SDKs/$PLATFORM$SDK.sdk
export CFLAGS="-arch $ARCH -isysroot $SDKROOT -miphoneos-version-min=5.0 -I/Users/xxx/icu/source/tools/tzcode"
export CXXFLAGS="$CFLAGS"
gnumake distclean
../../icu/source/configure --host=arm-apple-darwin --enable-static --disable-shared --with-cross-build=/Users/xxx/icu-build/mac --prefix=$INSTALL/$ARCH
gnumake
gnumake install
fi
You could do something similar to get what you want.
EDIT: How to call make with clang:
export CFLAGS=-arch armv7s # add more compiler flags as needed here
export CC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
make
I've combined the crt.1.x.x.0, libarclite, and libclang Xcode of the three current device architectures in order to support armv6, armv7, and armv7s for my iOS app.
Original Stack Overflow post that helped me: https://stackoverflow.com/a/12836808/761902.
Since you are trying to compile a ARM (conventional iOS device) and Intel (OS X computer) architectures into one file, you can try getting the crt, libarclite, and libclang files specified in the original post.
As the ARM files were located under
Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/,
I would expect the equivalent i386 files to be located under
Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/
, I'm not sure what Xcode build platform i686 falls under since I don't recall seeing that before, but if it is a iPhoneSimulator.platform, it would be in the same files as the i386 platform.
You might also want to add i686 and i386 to your build settings. The below are my architecture settings for building for armv6, armv7, and armv7s.
If that doesn't work, you can also build i686, i386, and armv7s separately and merge the built binaries with lipo.

Resources