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
Related
I have created library for my Apple watch based on the Ray Wenderlich Tutorial. Steps I fallowed in brief.
Step 1 : I chosen template as Xcode -> File -> New -> watchOS -> Framework & Library -> Watch Static Library
Step 2 : Added files which are needed to make as library.
step 3 : Added header files in the library build in to public files.
step 4 : Run the application
step 5 : I want to create a universal library so I added target as Xcode -> File -> New -> Target -> Other -> Aggregate
step 6 : Added run script for simulator and watch os as
# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
xcodebuild -target RBWatchModelManager ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator -arch x86_64 -arch i386 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
UNIVERSAL_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-universal
mkdir -p "${UNIVERSAL_BUILD_DIR}"
# Step 2. Create universal binary file using lipo
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-watchos/lib${PROJECT_NAME}.a"
# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/include" "${UNIVERSAL_OUTPUTFOLDER}/"
and I tried one more script but tried either one of these two available scripts
# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# Step 1. Build Device and Simulator versions
xcodebuild -target RBIWatchModelManager ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
xcodebuild -target RBIWatchModelManager -configuration ${CONFIGURATION} -sdk iphonesimulator -arch i386 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
xcodebuild -target RBIWatchModelManager ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk watchos 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" "${BUILD_DIR}/${CONFIGURATION}-watchos/lib${PROJECT_NAME}.a"
# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/include" "${UNIVERSAL_OUTPUTFOLDER}/"
Using any one of this script i Created Library successfully.
Step 7 : I added this library (Universal folder library and header files (include folder)) to my actual project.
step 8 : selected library in the build phases Link Binary with Libraries
step 9 : Added Header search Path
Step 10 : Run the application. In simulator, and Device its running properly.
But While creating Archive of this project, I'm getting one error as shown in the image below.
Then I searched about this error, I tried the suggestion :
Suggestion I tried :
Changing the bit code. Because of I'm using watchOS there is no bit code option available in build settings while creating library So there is no scope for this solution.
Added -fembed-bitcode for Custom Compiler Flags in build setting of the Library while creating it. But no use. I'm getting the same error.
I thought this error because of particular file name showed in the error log. So I tried of separating those files and I created new library but then I'm getting same error for other files that are used for creating library. So no use..
I tried of enabling and disabling Enable Bitcode Option in Build settings of my original project where i have added this created library, no use at all.
At finally... Is there any other solution available to resolve this error. And One thing from apple i found is
For iOS apps, bitcode is the default, but optional. For watchOS and
tvOS apps, bitcode is required. If you provide bitcode, all apps and
frameworks in the app bundle (all targets in the project) need to
include bitcode.
After you distribute your app using iTunes Connect, you can download the dSYMs file for the build, described in Viewing and
Importing Crashes in the Devices Window.
Help me out ??
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
Few days ago i create static-library (Universal) that work's fine with Xcode5.0 SDK7. After Update Xcode5.1 with SDK7.1 that not work if i select simulator iPhone Retina(4-inch 64-bit). Then i am going to update my lib with Bellow setting change.
I do the same for three Target:-
For sporting simulator as well as device i put Universal lib and in to this i run script this:-
After this i Build Again lib and used as i done Before in to my project. But still getting same issue with iPhone Retina(4-inch 64-bit) Undefined symbols for architecture x86_64:
So, My question is that is there any additional change required for updating lib for arm64 or i did any mistake in above step. Please current me if i am wrong.
what change needed for update my static-library for supporting 64Bit architecture
NOTE:
I am asking for my own created Library Update. i am not using third-party Library.
Update
I used this lipo -info testingLibImport/libLibNSlog.a command in to my Terminal that output is:
Architectures in the fat file: testingLibImport/libLibNSlog.a are: armv7 armv7s i386 arm64
Another solution I found with XCode 6.4 is to add ONLY_ACTIVE_ARCH=NO and not specify the architecture. So
xcodebuild -target TargetName ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
Will build i386 and x86_64 architectures in your library.
Here's my full universal lib run script to build all the architectures.
# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# Step 1. Build Device and Simulator versions
xcodebuild -target TargetName ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
xcodebuild -target TargetName ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator 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"
# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/include" "${UNIVERSAL_OUTPUTFOLDER}/"
I too ran into the same problem yesterday and after lot of googling and trying on different solutions, i gave up and tried on my own. All i could understand from the different solutions provided was that when i run "lipo -info library.a" it was not built for x86_64 architecture. So, decided to give up the aggregate approach and made a simple attempt.
as advised in this post, i added armv7, armv7s and arm64 to the architectures.
build the static library project with iphone simulator (32 bit)
build the static library project with iphone simulator (64 bit)
build the static library project with iOS device
go to the build path (under derived data)
copied both simulator and device output to a common folder
used lipo command in terminal window to create the universal library
lipo command: lipo -create -output newlibraryname.a simulatorlibraryname.a devicelibraryname.a
integrated the newly created universal static library and it WORKED!!!
After lots of stuff i got solution. some of xcode dont know there is automatic appear Standard architectures (including 64-bit) (armv7,armv7s,arm64) but in my case there is not option into my Static Library Project. so i am going to add this Manually like:-
and select this Option:-
After this i re-Build My static Library and used in to in my project that working fine now. and I also checked with lipo command in to terminal that output going to different now:-
testingLibImport/libLibNSlog.a are: armv7 armv7s i386 x86_64 arm64
Sorry for posting another solution so late. I had found this solution long time back when i was trying to find a solution that would save me from the manual work of creating a universal library using lipo command every time i had to build the universal library.
So, here is the another approach, for those using aggregate approach to build the universal library
just make one small change as mentioned below in your aggregate script for simulator to build the universal library -
xcodebuild -target ProductName -configuration ${CONFIGURATION} -sdk iphonesimulator ARCHS="i386 x86_64" BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" SYMROOT="${SYMROOT}"
Please observe the inclusion of multiple architectures instead of using single architecture approach -
xcodebuild -target ProductName -configuration ${CONFIGURATION} -sdk iphonesimulator -arch i386 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" SYMROOT="${SYMROOT}"
Just ARCHS="i386 x86_64" will do the magic for you.
You can confirm this by using the following lipo command
lipo -info newLibraryName.a
Hope this saves time for many others like me!!!
i am new to Apple iOS development. I am trying to create static library and add it to Main application.
Created Library Project and added it as a dependency project to the Main application. It works.
Now I took the lib.a (static library) from the Library project (present under debug-iphoneos) and copied to Main application. Tested the Main application - it works.
Now when i tried to copy the Main application to some other location (or even change the folder name - in which Main application is present) and try to run on Simulator, then i get following error:
ignoring file /Users/.../lib.a, missing required architecture i386 in file /Users/.../lib.a
I don't really understand the relation/dependency on the path.
the problem is solved.
I am using XCode 5.0.2 and iOS 7. when ever i compile the static library, the Xcode says it is building a universal library (but it is actually not). The 'Products' directory shows libxyz.a (which is in iphoneos/ directory) - this is actually for ARM6 & ARM7 for iPhone device. So when i took this 'libxyz.a' file and used it in another projects the linker used to throw a warning ' missing required architecture i386 '.
i have followed http://www.raywenderlich.com/41377/creating-a-static-library-in-ios-tutorial
used the script to generate single binary which contains both simulator & iphone device binary.
# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# Step 1. Build Device and Simulator versions
xcodebuild -target ImageFilters ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
xcodebuild -target ImageFilters -configuration ${CONFIGURATION} -sdk iphonesimulator -arch i386 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"
# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/include" "${UNIVERSAL_OUTPUTFOLDER}/"
This is the first time I have ever tried to create a custom iOS Framework. I'm trying to create custom iOS Framework using xCode by following this tutorial. I have gotten all the way to the very last step (Step 12).
Step 12: Build Project with Aggregate scheme
Select Aggregate("UniversaliOS") Scheme
Select iOS device
Build Project (⌘-B)
But the build fails with a Shell Script Invocation Error: Command /bin/sh failed with exit code 1. The error details are:
ditto: can't get real path for source
lipo: can't create temporary output file: /Users/pdl/Library/Developer/Xcode/DerivedData/InnerID-iOS-SDK-dgyjuudeootshidhpzlejhbyqvco/Build/Products/InnerID-iOS-SDK-Bundle.framework/InnerID-iOS-SDK-Bundle.lipo (No such file or directory)
Command /bin/sh failed with exit code 1
I have absolutely no clue as to what to do now. Any suggestions? I can provide the PhaseScriptExecution dump if necessary.
Thank you in advance for your help.
This is the correct shell script to be used (for swift).
CONFIG=Release
# Step 1. Make sure the output directory exists
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIG}-universal
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 2. Build Device and Simulator versions
codebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIG} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIG} -sdk iphonesimulator -arch x86_64 -arch i386 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
# Step 3. Copy the framework structure to the universal folder. Subsequently copy the files of the swiftmodule (in Modules directory) of -iphonesimulator to the swiftmodule of universal framework directory.
cp -R "${BUILD_DIR}/${CONFIG}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
cp -R "${BUILD_DIR}/${CONFIG}-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}/${CONFIG}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIG}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
If you still have any doubts, you can look at the video tutorial.
You didn't compile your iOSBundle for both(Step 10) and directly attempt to merge both iOS simulator and device(Step 12).
Basically what Step 10 is doing?
Its's just creating Framework for both Simulator and Device, So for some reason your build folder gets empty and your script not able find framework for iOS-Simulator and Device both or any one.
Quick resolution :
Perform Step 10, one more time before Step 12, this will create iOS-simulator Framework and Device Framework both, After that build project for your Aggregate scheme, this will merge both framework.
You can find all three(iOS-Simulaor, Device, Merged) framework at below
/Users/jaym/Library/Developer/Xcode/DerivedData/iOSFramework-doeqysadgntrrlguuvcivuhapnlr/Build/Products/
In your case, /Users/pdl/Library/Developer/Xcode/DerivedData/InnerID-iOS-SDK-dgyjuudeootshidhpzlejhbyqvco/Build/Products/