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.
Related
To compile PJSIP library for iPhone device, I am using this code
make distclean && make clean
ARCH='-arch arm64' ./configure-iphone --enable-opus-codec
make dep
make
This code allows me to install my app for single architecture only.
To compile pjsip for all the architectures (armv7, armv7s, arm64, i386, x86_64), Which command or tool I can use
--- One Way to build PJSIP libraries --- test with pjsip 2.6
//Updated for XCode 8.
Building PJSIP
$ cd /Users/ravimalviya/Developer/Dev2/trunk
//If you want to specify the minimum supported iOS version
//export MIN_IOS="-miphoneos-version-min=8.0"
Compile Library and Build For Default iPhone 4 use armv7 architecture
$ ./configure-iphone && make dep && make clean && make
Build For iPhone 5, use armv7s architecture
$ ARCH='-arch armv7s' ./configure-iphone && make dep && make clean && make
Build For iPhone 5s, use arm64 architecture
$ ARCH='-arch arm64' ./configure-iphone && make dep && make clean && make
Build For Simulator, use i386 architecture
export DEVPATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer
ARCH="-arch i386" CFLAGS="-O2 -m32 -mios-simulator-version-min=5.0" LDFLAGS="-O2 -m32 -mios-simulator-version-min=5.0" ./configure-iphone
make dep && make clean && make
Build For Simulator, use x86_64 architecture
export DEVPATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer
ARCH="-arch x86_64" CFLAGS="-O2 -m32 -mios-simulator-version-min=5.0" LDFLAGS="-O2 -m32 -mios-simulator-version-min=5.0" ./configure-iphone
make dep && make clean && make
The compilation result
pjlib/lib
pjlib-util/lib
pjmedia/lib
pjsip/lib
pjnath/lib
third_party/lib
Note add into project..
Combine resulting archtecture(arm64,armv7,armv7s,i386, x86_64) supported library .a file.
//goto directory where you collect all build library. create folder name arm64, armv7s, armv7, i386, x86_64 and put all library respectivly. each having only one arch supported library file.
//rename file in all these 5 folders it's a easy way to make universal library.
//Also create folder named unified where all unversal library will create.
$ export LIB_NAME="libg7221codec.a"
$ lipo -arch armv7 armv7/$LIB_NAME -arch armv7s armv7s/$LIB_NAME -arch arm64 arm64/$LIB_NAME -arch i386 i386/$LIB_NAME -arch x86_64 x86_64/$LIB_NAME -create -output unified/$LIB_NAME
//-arch armv7s armv7s/$LIB_NAME means support armv7s get library from directory armv7s/$LIB_NAME and $LIB_NAME file name that only support armv7s.
//-arch arm64 arm64/$LIB_NAME ............
//-arch armv7 armv7/$LIB_NAME ............
//-arch i386 i386/$LIB_NAME ..............
//-arch x86_64 x86_64/$LIB_NAME ..............
//unified/$LIB_NAME is directory where unversal library will build using lips. with same name $LIB_NAME that export. do it same.
//check which arch you lib is supporting
xcrun -sdk iphoneos lipo -info unified/$LIB_NAME
$ export LIB_NAME="libgsmcodec.a"
$ lipo -arch armv7 armv7/$LIB_NAME -arch armv7s armv7s/$LIB_NAME -arch arm64 arm64/$LIB_NAME -arch i386 i386/$LIB_NAME -arch x86_64 x86_64/$LIB_NAME -create -output unified/$LIB_NAME
$ export LIB_NAME="libilbccodec.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpj.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjlib-util.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjmedia-audiodev.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjmedia-codec.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjmedia-videodev.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjmedia.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjnath.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjsdp.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjsip-simple.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjsip-ua.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjsip.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjsua.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjsua.a"
$ .....same as above in lipo......
$ export LIB_NAME="libpjsua2.a"
$ .....same as above in lipo......
$ export LIB_NAME="libresample.a"
$ .....same as above in lipo......
$ export LIB_NAME="libspeex.a"
$ .....same as above in lipo......
$ export LIB_NAME="libsrtp.a"
$ .....same as above in lipo......
$ export LIB_NAME="libyuv.a"
$ lipo -arch armv7 armv7/$LIB_NAME -arch armv7s armv7s/$LIB_NAME -arch arm64 arm64/$LIB_NAME -arch i386 i386/$LIB_NAME -arch x86_64 x86_64/$LIB_NAME -create -output unified/$LIB_NAME
Note: Unversal libraries you can add into your project and also mention in library search path.
//In order to use the pjsip libraries, we need to include folder that ahve header files that access .a files. Naturally, the header files are located in:
pjlib/include
pjlib-util/include
pjmedia/include
pjnath/include
pjsip/include
Note: do't add into project..buz you can not import like import <pjsip-lib/pjsip.h>
so just place these folder into project directory where ever you want but mention in header search path.
Enjoy (:)
Steps to compile for all devices.
compile for all devices separately
merge with lipo
eg.
-create /libsrtp-arm64-apple-darwin_ios.a /libsrtp-i386-apple-darwin_ios.a -output output_file_name
then use output_file_name.a as a universal library for all device and simulator
to check supported architecture : output_file_name.a
lipo -info name_of_static_lib
output :
/libsrtp-universal-apple-darwin_ios.a are: armv7 armv7s i386 x86_64 arm64
Compile PJSIP 2.5 Library for all archietectures
Thanks
We wrote a cocoapod that will create a static library that you can include in your project. For the moment you can only use it in an Objective C cocoapod environment. We are working on a version that will create a dynamic library so it can be used with Swift.
Please check it out on:
https://github.com/VoIPGRID/Vialer-pjsip-iOS
We've made an open source wrapper that makes integrating PJSIP in your iOS project a lot easier:
https://github.com/VoIPGRID/VialerSIPLib
the merge like this as posted
lipo -create /My\ Project/pjsip-universal/x86_64/libgsmcodec-x86_64-apple-darwin_ios.a /My\ Project/pjsip-universal/i386/libgsmcodec-i386-apple-darwin_ios.a /My\ Project/pjsip-universal/armv7s/libgsmcodec-armv7s-apple-darwin_ios.a /My\ Project/pjsip-universal/armv7/libgsmcodec-armv7-apple-darwin_ios.a /My\ Project/pjsip-universal/arm64/libgsmcodec-arm64-apple-darwin_ios.a -output /My\ Project/pjsip-universal/universal/libgsmcodec-universal-apple-darwin_ios.a
finally test it
lipo -info /My\ Project/pjsip-universal/libgsmcodec-universal-apple-darwin_ios.a
output:
Architectures in the fat file: /My Project/pjsip-universal/libgsmcodec-universal-apple-darwin_ios.a are: i386 armv7s armv7 x86_64 arm64
Once you generate the universal architecture:
Follow this link to add in you project from this line in link
Adding the header files into the project
how to add in project
Hope this will help you.
I am using this script to build pjsip for my archs.
I am running it in the pjsip root folder, it creates a uni folder containing the resulting libraries which I then link/add into my project.
#!/bin/bash
ARCHS="armv7 armv7s arm64"
mkdir -p uni
echo "Compiling..."
for arch in $ARCHS
do
echo $arch
echo "=================================="
echo
ARCH="-arch $arch" ./configure-iphone && make dep && make clean && make
echo "Done."
echo
done
RESULT_PATHS="pjlib/lib pjlib-util/lib pjmedia/lib pjsip/lib pjnath/lib third_party/lib"
for path in $RESULT_PATHS
do
echo $path
for file in `ls $path/*-armv7-*`
do
library=`echo $file | sed "s/-armv7-\(.*$\)//g"`
library_tail=`echo $file | sed "s/.*-armv7-//g"`
lipo -arch armv7 $library-armv7-$library_tail -arch armv7s $library-armv7s-$library_tail -arch arm64 $library-arm64-$library_tail -create -output $library.a
cp -vi $library.a uni
done
done
I'm trying to compile a project developed in C language for iOS devices. It uses custom library file, libcurl, libcrypto, libssl and libpthread. I have successfully compiled it for Mac OS X, but having issues compiling it for iOS. Also, any help I try to find online is more of Xcode GUI help, and I need command line help for it. Need to compile it through commands instead of Xcode GUI.
First it needs to compile couple of C files, then make a static library file out of these compiled files, which further used when compiling a native binary.
This is how I generated iOS arm ouptut files from c files inside file01:
Store the iphoneos sdk path in environemnt variable:
CC="$(xcrun --sdk iphoneos9.2 --find clang) -isysroot $(xcrun --sdk iphoneos9.2 --show-sdk-path) -arch armv7 -arch armv7s -arch arm64 -arch armv6 -arch arm64"
Compile the c files in file01 with command:
$CC -c -O2 *.c
To check which architect these files are compiled for can be checked with this lipo command. Example:
$ lipo -info example_file01.o
Architectures in the fat file: example_file01.o are: armv7 armv7s armv6 arm64
To make a static library file I can get iOS ar file path using command:
$ xcrun --sdk iphoneos9.2 --find ar /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar
I could store the path in an environment variable, but it was not working throwing error not recognising ar command arguments rcu. So, used the ar path instead to create the library file with this command:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar rcu ../output/libfile01.a *.o
If checking which architectures this lib file supports it gives this output:
$ lipo -info ../output/libfile01.a
fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: archive with no architecture specification: ../output/libfile01.a (can't determine architecture for it)
But, it should have given output similar to this one:
$ lipo -info ../ios/lib/libcurl.a
Architectures in the fat file: ../ios/lib/libcurl.a are: i386 armv7 armv7s x86_64 arm64
This is causing error when trying compiling files in using the generated static lib file with command:
$CC -o ../output/FinalProjectFile -O2 *.c ../output/libfile01.a ../ios/lib/libcurl.a ../ios/lib/libssl.a ../ios/lib/libcrypto.a -lpthread -lm
Error: ld: warning: ignoring file ../output/libfile01.a, file was built for archive which is not the architecture being linked (armv7): ../output/libfile01.a
Thanks for help
I finally solved the issue by using different argument for ar.
Instead of using
$ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar rcu ../output/libfile01.a *.o
used
$ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar -rcs ../output/libfile01.a *.o
The only difference was it's -rcs instead of rcu.
When checking the info of this libfile it shows the output like this:
$ lipo -info ../output/libfile01.a
Architectures in the fat file: ../output/libfile01.a are: armv7 armv7s armv6 arm64
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.
I've been writing a makefile which will need to compile for multiple platforms. Right now I only need to compile for iOS, but as I already know that I'll need to support Mac OS X in a near future I've also been looking on how to compile for that as well. Notice that I'm not using Xcode. That's not an option as the project will also have to support other platforms.
I already have a makefile compiling for iPhone. It's working (tested on the simulator, even) but I still have a few doubts.
Specifically I've read about many tools and right now I'm a bit confused about some of them:
xcodebuild and clang I get clang, it's a compiler, but what about xcodebuild? Does it just use clang for compiling and also runs some tests? Are there upsides to using? Downsides?
libtool vs ar pretty much the same thing. How do these differ? I've read that ar should be followed by a call to ran lib (although it's not clear on the why), so there must be downsides, but which? Edit: forgot to include lipo in the discussion
Finally, and I hope I'm not getting off topic, I'm generating fat files for iphoneos and iphonesimulator. Here's how; first I compile for each platform:
ifeq ($(ARCH), iphoneos)
ARCHFLAGS = -arch armv7 -arch armv7s -arch arm64
else
ARCHFLAGS = -arch i386 -arch x86_64
endif
ifeq ($(ARCH), iphoneos)
VERFLAGS = -miphoneos-version-min=7.0
else
VERFLAGS = -mios-simulator-version-min=7.0
endif
CC = $(shell xcrun --sdk $(ARCH) --find clang)
CFLAGS := -isysroot $(shell xcrun --sdk $(ARCH) --show-sdk-path)
CFLAGS += $(ARCHFLAGS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $#
Some flags, variables, and rules are omitted. This generates two sets of .o files. I then use ar (should it be libtool?):
AR = ar
ARFLAGS = crv
$(BINARY): $(OBJECTS) # This rule depends on the previous one
$(AR) $(ARFLAGS) $(BINARY) $(OBJECTS)
By now I have a static library (.a) file for each platform. I proceed to generate the fat file:
$(LIBTOOL) $(LIBTOOLFLAGS) -o $(call libfile,iphone,debug) $(call libfile,iphoneos,debug) $(call libfile,iphonesimulator,debug)
Note: libfile is a function which returns the file name for the given configuration.
Two questions now:
Could I just skip the generation of the two separate .a files and jump to the the fat file by specifying ARCHFLAGS = -arch armv7 -arch armv7s -arch arm64 -arch i386 -arch x86_64? That is, all platforms in a single call. Is it the same thing?
This was the closest I got to listing supported architectures (not a good option, I'd say). Could I just list all (or a subset) of them, generate an "obese" (lol) file and expect the compiler to optimize the file's size when linked against an actual implementation? Or are fat files shipped with the final product?
Thank you for reading so far.
Best.
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.