How do I extract object files from an iOS library (on a Mac)? - objective-c

I have a third party iOS library that links and runs fine in my app and in the simulator. I am trying to extract the object files from it in order to integrate it with another piece of third party software that repackages the object files with their own code. However, I am unable to extract the object files via ar; I consistently get the error, "Inappropriate file type or format".
The library in question is a fat library with armv7, armv7s, and i386 included. Stock lipo doesn't know about armv7s on my machine, but Xcode's does:
$ lipo -info library.a
Architectures in the fat file: library.a are: armv7 (cputype (12) cpusubtype (11)) i386
$ xcrun -sdk iphoneos lipo -info library.a
Architectures in the fat file: library.a are: armv7 armv7s i386
I can successfully thin it out with lipo:
$ xcrun -sdk iphoneos lipo library.a -thin armv7 -output library-armv7.a
$ xcrun -sdk iphoneos lipo -info library-armv7.a
Non-fat file: library-armv7.a is architecture: armv7
However, even after thinning it out, I can't manipulate it with ar:
$ xcrun -sdk iphoneos ar -tv library-armv7.a
ar: library-armv7.a: Inappropriate file type or format
$ xcrun -sdk iphoneos ar -xv library-armv7.a
ar: library-armv7.a: Inappropriate file type or format
I'm on OS X 10.8.2, Xcode 4.6 with development tools installed.
Is there any additional step I can take for this troublesome library?
Update in response to Martin's comment
file shows the following:
$ file library.a
library.a: Mach-O universal binary with 3 architectures
library.a (for architecture armv7): Mach-O object arm
library.a (for architecture cputype (12) cpusubtype (11)): Mach-O object arm
library.a (for architecture i386): Mach-O object i386
$ file library-armv7.a
library-armv7.a: Mach-O object arm
Looks like it's not a library at all!

The "library" is not actually a library, but is an object file itself. There is nothing further to extract.

This script works well. Try it.
https://code.google.com/p/ompt-intel-openmp/source/browse/itt/libomp_oss/tools/extract-objects.pl

Related

iOS 14, lipo error while creating library for both device and simulator

We have been using lipo command to create a framework which works on both device and simulator when integrated in other project.
following are the build commands used to generate device and simulator builds
xcodebuild -target SampleSDK ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" OBJROOT="${OBJROOT}/DependentBuilds"
xcodebuild -target SampleSDK ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" OBJROOT="${OBJROOT}/DependentBuilds"
after this we are copying swift modules from iphonesimulator(if it exists) to the copied framework dir
cp -R "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/Modules/SampleSDK.swiftmodule/" "${UNIVERSAL_OUTPUTFOLDER}/${PRODUCT_NAME}/Modules/${PROJECT_NAME}.swiftmodule/"
and then lipo command
lipo -create "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PRODUCT_NAME}/${PROJECT_NAME}" -output "${UNIVERSAL_OUTPUTFOLDER}/${PRODUCT_NAME}/${PROJECT_NAME}"
the above command is failing with following error
fatal error: lipo: /path/to/Library/Developer/Xcode/DerivedData/Sample-bhfmlauxsdympmdjkjyvujaljevg/Build/Products/Debug-iphonesimulator/SampleSDK.framework/SampleSDK and /Users/rramshettysiddaraju/Library/Developer/Xcode/DerivedData/Sample-bhfmlauxsdympmdjkjyvujaljevg/Build/Products/Debug-iphoneos/SampleSDK.framework/SampleSDK have the same architectures (arm64) and can't be in the same fat output file
I tried one of the answers in stackoverflow, about adding user-defined setting VALID_ARCHS and then removing it. but that didnt work
The reason for the error is that Xcode 12 includes a slice for the "arm64" architecture when building for the simulator (in addition to the usual "i386" and "x86_64" architectures for Xcode <12). This is probably for supporting the simulator on (future) Macs using Apple Silicon processors. As your device build also includes the "arm64" architecture, lipo does not know which of the two "arm64" slices you want and refuses to create a combined fat binary framework.
As a workaround, you can either exclude the "arm64" architecture from the simulator build by appending the EXCLUDED_ARCHS build variable:
xcodebuild -target SampleSDK ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" OBJROOT="${OBJROOT}/DependentBuilds" EXCLUDED_ARCHS="arm64"
Alternatively, use lipo -remove to remove the "arm64" architecture from the simulator build before combining the simulator and device frameworks into one:
lipo -remove arm64 "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/${PROJECT_NAME}" -output "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/${PROJECT_NAME}"
In the long run, you might be better off building an XCFramework, which should support devices and simulators without the need for using lipo. But I haven’t tested this yet.
styv is right.
You can also set Excluded Architectures in the Xcode Build Settings
#xtyv's suggestion is spot on: using an XCFramework is the way to go.
Here is a Makefile to generate an XCFramework (apply substitutions and add other architectures accordingly to your scenario):
ARCHS = aarch64-apple-ios aarch64-apple-ios-sim
LIB = lib<library_name>.a
XCFRAMEWORK = <framework_name>-iOS.xcframework
all: $(XCFRAMEWORK)
.PHONY: $(ARCHS)
$(ARCHS): %:
cargo build --target $#
$(XCFRAMEWORK): $(ARCHS)
xcodebuild -create-xcframework $(addprefix -library , $(foreach arch, $(ARCHS),$(wildcard target/$(arch)/debug/$(LIB)))) -headers <header_file> -output $#

Xamarin iOS Objective-C library binding - Build errors when creating a fat binary using "make" command

I'm trying to create a Xamarin iOS binding for this Objective C library SPSlideTabController.
I have created a static library and am now in the process of creating a fat binary. I have the Makefile set up correctly and saved in the same folder as my static library. Not inside the static library folder though. Then I run the make command in the terminal.
Each time I have tried, only one file is generated libSPSlideTabController-i386.a then I get 4 build errors:
** BUILD FAILED **
The following build commands failed:
CompileC build/SPSlideTabBarController.build/Release-iphoneos/SPSlideTabBarController.build/Objects-normal/armv7/SPAppearance.o SPSlideTabBarController/Appearance/SPAppearance.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC build/SPSlideTabBarController.build/Release-iphoneos/SPSlideTabBarController.build/Objects-normal/armv7/SPSlideTabBarItem.o SPSlideTabBarController/SPSlideTabBar/SPSlideTabBarItem.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC build/SPSlideTabBarController.build/Release-iphoneos/SPSlideTabBarController.build/Objects-normal/armv7/SPSlideTabBar.o SPSlideTabBarController/SPSlideTabBar/SPSlideTabBar.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC build/SPSlideTabBarController.build/Release-iphoneos/SPSlideTabBarController.build/Objects-normal/armv7/SPSlideTabBarController.o SPSlideTabBarController/SPSlideTabBarController.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
(4 failures)
make: *** [libSPSlideTabBarController-armv7.a] Error 65
The ---armv7.a and the ---SDK.a files are not generated.
What am I doing wrong?
Here's my Makefile
XBUILD=/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
PROJECT_ROOT=./SPSlideTabBarController
PROJECT=$(PROJECT_ROOT)/SPSlideTabBarController.xcodeproj
TARGET=SPSlideTabBarController
all: lib$(TARGET).a
lib$(TARGET)-i386.a:
$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphonesimulator
-configuration Release clean build
-mv $(PROJECT_ROOT)/build/Release-iphonesimulator/lib$(TARGET).a $#
lib$(TARGET)-armv7.a:
$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch
armv7 -configuration Release clean build
-mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(TARGET).a $#
lib$(TARGET)-arm64.a:
$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch
arm64 -configuration Release clean build
-mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(TARGET).a $#
lib$(TARGET).a: lib$(TARGET)-i386.a lib$(TARGET)-armv7.a
lib$(TARGET)-
arm64.a
xcrun -sdk iphoneos lipo -create -output $# $^
clean:
-rm -f *.a *.dll
It's better that you share your MAKE file.
I normally open the code in XCode then add a runscript using my GIST here
You could follow this guide for more details.

Cannot combine the resulting libraries using the lipo command

Going to develop an iOS VoIP app as my final project, but not finding a proper SDK to be used for making app to work like Skype/ Viber, for Voice and Video Call.
Or suggest me another FREE library.
I working on this from the previous 2 months...
Thanks.
EDIT:
When I perform 'lipo' command this occurs:
iMac-2:lib mac$ lipo -arch libpj-arm64-apple-darwin_ios.a -arch libpj-armv7-apple-darwin_ios.a -arch libpj-armv7s-apple-darwin_ios.a -arch libpj-x86_64-apple-darwin16.0.0.a -create -output libpjlib.a
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: unknown architecture specification flag: libpj-arm64-apple-darwin_ios.a in specifying input file -arch libpj-arm64-apple-darwin_ios.a -arch
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: known architecture flags are: any little big ppc64 x86_64 x86_64h arm64 ppc970-64 ppc i386 m68k hppa sparc m88k i860 veo arm ppc601 ppc603 ppc603e ppc603ev ppc604 ppc604e ppc750 ppc7400 ppc7450 ppc970 i486 i486SX pentium i586 pentpro i686 pentIIm3 pentIIm5 pentium4 m68030 m68040 hppa7100LC veo1 veo2 veo3 veo4 armv4t armv5 xscale armv6 armv6m armv7 armv7f armv7s armv7k armv7m armv7em arm64v8
fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: Usage: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo [input_file] ... [-arch <arch_type> input_file] ... [-info] [-detailed_info] [-output output_file] [-create] [-arch_blank <arch_type>] [-thin <arch_type>] [-remove <arch_type>] ... [-extract <arch_type>] ... [-extract_family <arch_type>] ... [-verify_arch <arch_type> ...] [-replace <arch_type> <file_name>] ...
If you got errors in library means, Either you have not properly configure the PJSIP project in Your system (or) you missed any library that you want to add in your xcode project.
If you want to run project in simulator or iphone?
There is two different configuration for pjsip project. For iphone and simulator, configuring project is different.
For properly configure your PJSIP Project in your system, follow this below link.
Source : https://trac.pjsip.org/repos/wiki/Getting-Started/iPhone
Please post the error message completely in your xcode, to solve the problem.
You missed architecture name
was:
lipo -arch libpj-arm64-apple-darwin_ios.a -arch libpj-armv7-apple-darwin_ios.a ...
Need:
lipo -arch arm64 libpj-arm64-apple-darwin_ios.a -arch armv7 libpj-armv7-apple-darwin_ios.a ...
For each -arch you need set name and than lib name

Compile Mach-o arm object file

Im trying to compile a mach-o arm object file to mach-o arm executable using the command line. I have used various commands like these
clang -arch armv7 helloapp.o -o helloapp
clang helloapp.o -o helloapp
gcc helloapp.o -o helloapp
They all return different errors saying compiling for wrong architecture or missing neccessary files. What is the command I need to compile this properly??
The default compilers (the ones in your $PATH) reference the ones that can compile for your local machine. You need a cross-compiler that knows how to create ARM binaries. If you've got Xcode with iOS SDK installed you can use for example:
PATH_TO_Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc
or
PATH_TO_Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
For example, on my machine:
ARM_GCC=~/Documents/Xcode4.6.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc
IOS_SDK=~/Documents/Xcode4.6.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk
# Compile
$ARM_GCC -arch armv7 -c test.c -o test.o
# Link
$ARM_GCC -arch armv7 -isysroot "$IOS_SDK" test.o -o test
If I then run file test I get:
test: Mach-O executable arm

Build static Graphviz libraries for iOS

I am trying build the static libraries for Graphviz to include them in in an iOS app, but I can't get it to work. Here's what I have done so far, using graphviz 2.28.0], Xcode 4.1, OSX 10.7 and I am targeting the iOS simulator.
I found Glen Low's configure instructions, and with some informed guesswork updated these to:
./configure --build=i486-apple-darwin --host=arm-apple-darwin9 --disable-dependency-tracking --enable-shared=no --enable-static=yes --enable-ltdl-install=no --enable-ltdl=no --enable-swig=no --enable-tcl=no --with-codegens=no --with-fontconfig=no --with-freetype2=no --with-ipsepcola=yes --with-libgd=no --with-quartz=yes --with-visio=yes --with-x=no --with-cgraph=no CC="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2" CPP="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -E" CXX="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++-4.2" CXXCPP="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++-4.2 -E" OBJC="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2" LD="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld" CPPFLAGS="-arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk -miphoneos-version-min=4.0" CXXCPPFLAGS="-arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk -miphoneos-version-min=4.0"
This works, but then the "make" runs for a while and errors out with:
Making all in gvpr
CCLD mkdefs
ld: warning: ignoring file mkdefs.o, file was built for armv6 which is not the architecture being linked (i386)
ld: warning: ignoring file /usr/local/lib/libSystem.dylib, missing required architecture i386 in file
ld: warning: symbol dyld_stub_binder not found, normally in libSystem.dylib
Undefined symbols for architecture i386:
"_exit", referenced from:
start in crt1.10.6.o
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
make[3]: *** [mkdefs] Error 1
make[2]: *** [all-recursive] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
I don't quite understand all the architecture specifications, so any help to get this to work is most welcome.
Problem is imo that mkdefs is executed during the build process itself after it was created. So if you build for armv6 or armv7 the file can't be executed on the command line of Mac OS X. My workaround was to build a mkdefs for architecture i386 (which is needed for the iPhone simulator too) and copy it in the lib/gvpr directory after getting this error. Make sure that the file could not be overwritten and restart the build.
I got this working. The build script fails at the end when it tried to make an executable since it's compiled for i386 instead of x86 or x86_64 but all the libraries build just fine.
# For iPhoneOS
export DEV_iOS=/Developer/Platforms/iPhoneOS.platform/Developer
export SDK_iOS=${DEV_iOS}/SDKs/iPhoneOS5.0.sdk
export COMPILER_iOS=${DEV_iOS}/usr/bin
export CC=${COMPILER_iOS}/gcc
export CXX=${COMPILER_iOS}/g++
export LDFLAGS="-arch armv7 -pipe -Os -gdwarf-2 -no-cpp-precomp -mthumb -isysroot ${SDK_iOS}"
export CFLAGS=${LDFLAGS}
export CXXFLAGS=${LDFLAGS}
export LD=${COMPILER_iOS}/ld
export CPP=${COMPILER_iOS}/llvm-cpp-4.2
export AR=${COMPILER_iOS}/ar
export AS=${COMPILER_iOS}/as
export NM=${COMPILER_iOS}/nm
export CXXCPP=${COMPILER_iOS}/llvm-cpp-4.2
export RANLIB=${COMPILER_iOS}/ranlib
./configure --host=arm-apple-darwin11 --disable-dependency-tracking --enable-shared=no --enable-static=yes --enable-ltdl-install=no --enable-ltdl=no --enable-swig=no --enable-tcl=no --with-codegens=no --with-fontconfig=no --with-freetype2=no --with-ipsepcola=yes --with-libgd=no --with-quartz=yes --with-visio=yes --with-x=no --with-cgraph=no
It appears that the linker is trying to link to the system libraries installed on your Mac. Those libraries are all going to be compiled for i386 or x86_64 which isn't going to work when compiling libraries for iPhone. You'll need to reconfigure the linker to link against the libraries that come in the iPhone SDK.
It should also be noted that you will probably have to compile the library twice - once as armv6 and again as armv7. iPhone 3G and some of the older iPod Touches use the armv6 architecture, while newer iPhones use the armv7 architecture. After you've compiled the libraries under both architectures you can use lipo (type "man lipo" in your Terminal for more info) to create a single static library with both architectures in it. If you are going to develop your app using the iPhone/iPad simulator, then I also suggest compiling once as i386 so that you can use your library with the simulator. Again, lipo can create a single static library with all 3 architectures in it.
Now the GraphViz website appears to be unreachable at the moment, so I could not download the library and run the configure script like you did, but I suspect that before you run "make" you should make the following changes to the makefile that is produced by the configure script. Depending on which version of the iOS SDK you are targeting and what version of gcc you have on your machine you may have to tweak some of the changes below so they are appropriate for your environment. The instructions below will build for armv6. You'll need to change the settings to build for armv7 once you are ready to tackle that architecture.
Find CC= cc and change it to:
CC= /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2
Find -arch i386 in CFLAG and change it to:
-arch armv6
Find CFLAG and add to the BEGINNING!!:
-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.0.sdk
Find SHARED_LDFLAGS=-arch i386 -dynamiclib and change it to:
SHARED_LDFLAGS=-arch armv6 -dynamiclib