Import Kotlin/Native framework in Cocoapod - ios

I'm trying to add a vendored framework built with Kotlin/Native in a private CocoaPod but I get an error:
I have generated an iOS framework with Kotlin/Native.
I copy the framework folder (compiled/generated by Konan) into my custom pod folder
In the podspec, I add the framework path in the "vendored_frameworks" list
I launch pod repo push myCocoapodsRepo myProject.podspec --verbose"
I receive an error :
[iOS] xcodebuild: fatal error: lipo: input file (/Users/jeandaube/Library/Developer/Xcode/DerivedData/App-auugdpsmbbpvarfzghxatkvwftsn/Build/Products/Release-iphonesimulator/App.app/Frameworks/MyProject.framework/MyProject) must be a fat file when the -remove option is specified
Should I somehow change the format of how I export the framework with Konan in a first place?

You're getting the error because, by default, Kotlin Native only produces binaries for a single architecture. CocoaPods than fails when it tries to treat it as a "fat" binary with multiple architectures. Since you'll need multiple architectures anyway (at least arm64 for the device and x86_64 for the simulator) the approach I'm using is to create both architectures and then merge them with lipo The resultant fat framework can then be vended by CocoaPods or just drag/drop installed in Xcode.
def outputDirectory = "$export_dir/$projectName/$projectVersion"
def outputFramework = "$outputDirectory/${projectName}.framework"
konanArtifacts {
// Declare building into a framework, build arm64 for device, x64 for simulator
framework(projectName, targets: ['ios_arm64', 'ios_x64' ]) {
// The multiplatform support is disabled by default.
enableMultiplatform true
}
}
// combine original arm64 and x64 libraries into a single library in
// the exported framework folder
task combineArchitectures(type: Exec, dependsOn: compileKonanLibrary) {
executable 'lipo'
args = [
'-create',
'-arch',
'arm64',
new File(compileKonanLibraryIos_arm64.artifact, 'Library'),
'-arch',
'x86_64',
new File(compileKonanLibraryIos_x64.artifact, 'Library'),
'-output',
"$outputFramework/Library"
]
}
// export the arm64 (doesn't matter which really) framework, skipping
// the library binary itself
task exportFramework(type: Copy, dependsOn: compileKonanLibrary) {
from compileKonanLibraryIos_arm64.artifact
into outputFramework
exclude projectName
finalizedBy combineArchitectures
}
// build a pod spec by copying and updating a template file
task exportPodspec(type: Copy) {
from "Library.podspec"
into outputDirectory
filter {
it.replaceAll('##projectName##', projectName)
.replaceAll('##projectVersion##', projectVersion)
}
}
task export {
dependsOn "exportFramework"
dependsOn "exportPodspec"
}

Kotlin/Native does not produce multiarchitecture (aka fat) binaries (see https://en.wikipedia.org/wiki/Fat_binary) thus an attempt to run lipo on the framework it produces does not make sense.

Related

iOS swift app build fails with cyclic dependency error in Xcode 14+

I have a swift iOS app with two static libraries - lib1 and lib2 (say). Lib2 has a dependency on Lib1 (i.e it imports Lib1 to use its types). Lib1 and Lib2 are set as dependencies for the AppTarget (when built, results in the .app file).
I get the following cyclic dependency error when building Lib1. Similar error is observed when building the other targets.
SwiftDriverJobDiscovery normal x86_64 Compiling <FileName1>.swift (in target '<Lib1>' from project '<ProjectName>')
error: Cycle inside <Lib1>; building could produce unreliable results.
Cycle details:
→ Target '<Lib1>': Libtool /Users/<user-name>/<some-path>/<Lib1>.a normal
○ Target '<Lib1>' has Swift tasks not blocking downstream targets
○ Target '<Lib1>': SwiftGeneratePch normal x86_64 Compiling bridging header
○ Target '<Lib1>': SwiftCompile normal x86_64 Compiling <FileName2>.swift /Users/<user-name>/<some-path>/<Filename2>.swift
○ Target '<Lib1>': SwiftGeneratePch normal x86_64 Compiling bridging header
Raw dependency cycle trace:
target: ->
node: <all> ->
command: <all> ->
node: /Users/<user-name/<some-path>/<Lib1>.a -> command: P1:target-<Lib1>-6d14b29d8d3402955e18e7b7c2cd5bd8502d5dd7097f7536813aba73cac1c1d5-:Debug:Libtool /Users/<user-name>/<some-path>/<Lib1>.a normal ->
node: /Users/<user-name>/<some-path>/x86_64/<FileName3>-8014457a59adc1f8a995a14873eb809b.o ->
command: P0:target-<Lib1>-6d14b29d8d3402955e18e7b7c2cd5bd8502d5dd7097f7536813aba73cac1c1d5-:Debug:SwiftDriver Compilation <Lib1> normal x86_64 com.apple.xcode.tools.swift.compiler ->
CYCLE POINT ->
customTask: <SwiftDriverJob identifier=-4908891831242875468 arch=x86_64 variant=normal job=<PlannedSwiftDriverJob [target(7)]:GeneratePch <Lib1> dependencies=["target(8)", "target(9)", "target(10)"]> isUsingWholeModuleOptimization=false compilerPath=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc> ->
customTask: <SwiftDriverJob identifier=-4908891831242875468 arch=x86_64 variant=normal job=<PlannedSwiftDriverJob [target(8)]:Compile <Lib1> <FileName2>.swift dependencies=["target(7)"]> isUsingWholeModuleOptimization=false compilerPath=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc> ->
customTask: <SwiftDriverJob identifier=-4908891831242875468 arch=x86_64 variant=normal job=<PlannedSwiftDriverJob [target(7)]:GeneratePch <Lib1> dependencies=["target(8)", "target(9)", "target(10)"]> isUsingWholeModuleOptimization=false compilerPath=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc>
In the above error message, FileName1 and FileName2 are swift files that invoke C++ methods using an intermediate ObjC++ bridge layer. I have two files named FileName3 but different extensions - .swift and .mm. Since, FileName2 is referred as .o here, I think it is referring to FileName3.mm (i.e the ObjC++ file).
I have checked the code thoroughly for any form of cyclic dependency (like, two classes depending on each other - as mentioned in many stackoverflow posts), but it's all good. What's more, the same build worked on Xcode 13.x. After updating to Xcode 14.x, I'm getting this cyclic dependency error.
But in the last three lines of the error message, you can see a cyclic dependency.
First step: [Target(7)] Generate pch and depends on [target(8), target(9), target(10)]
Second step: [Target(8)] Compile FileName2.swift, depends on [target(7)]
Target(7) is dependent on target(8) and target(8) is dependent on target(7). What is target(7), target(8) etc? Where can I find out what kind of target it exactly is?
I use cmake to set the dependencies and generate the Xcode project.
What is this error? What am I missing here?
I've been stuck for days and any help would be greatly appreciated.
After so much time spent on searching, this is the answer.
Checkout ctietze's answer to this post in Apple forum
defaults write com.apple.dt.XCBuild EnableSwiftBuildSystemIntegration 0
After disabling the new build system, I'm not getting the cyclic dependency error anymore.

iOS: How to build a static framework based on CocoaPods dependencies?

I am trying to build a framework that makes use of the geopackage-ios CocoaPods dependency. I would then like to statically embed this framework into one or more apps.
Similar questions have been asked before, but I couldn't find a solution to my problem. Here's what I've been trying so far:
First Approach: Building Manually
In this approach, I would create a static library using Xcode, add the CocoaPods dependencies to it and build it. The problem with this approach, however, is that the resulting framework will not have the CocoaPods dependencies embedded into it.
Create a new static library from Xcode (File > New > Project… > iOS: Static Library) named "MyLibrary" with language Swift.
Create a Podfile in the project root directory with the following content:
target 'MyLibrary' do
pod 'geopackage-ios', '~> 7.2.1'
end
Run pod install. (This will install the geopackage-ios pod and 10 depending pods.)
Open the newly created MyLibrary.xcworkspace and add a BridgingHeader.h to the "MyLibrary" group having the following content:
#ifndef BridgingHeader_h
#define BridgingHeader_h
#import "geopackage-ios-Bridging-Header.h"
#endif
Reference the bridging header by clicking on the "MyLibrary" project in the project navigator, selecting the "MyLibrary" target and, in the Build Settings, specifying MyLibrary/BridgingHeader.h as the "Objective-C Bridging Header".
Modify MyLibrary.swift to use the GeoPackage dependency:
public class MyLibrary {
public init() {}
public func test() {
let manager = GPKGGeoPackageFactory.manager()!
print("Manager:", manager)
}
}
Build the library for the iOS simulator by pressing Cmd + B.
Optionally, create a static framework using a shell script like the one in this article (which will compile the library once for the simulator and once for physical devices and then combine the two results to a universal framework using the lipo command).
When I embed either the static library (along with the MyLibrary.swiftmodule) or the universal framework into an app, linking will fail for this app:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_GPKGGeoPackageManager", referenced from:
objc-class-ref in libMyLibrary.a(MyLibrary.o)
"_OBJC_CLASS_$_GPKGGeoPackageFactory", referenced from:
objc-class-ref in libMyLibrary.a(MyLibrary.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I could also add the geopackage_ios.framework (found in the build folder of "MyLibrary") to the app (making sure to choose the Embed & Sign embedding option), which will allow the app to be built successfully. Then, however, the app will crash upon launch:
dyld[79209]: Library not loaded: #rpath/ogc_api_features_json_ios.framework/ogc_api_features_json_ios
Referenced from: /Users/admin1/Library/Developer/CoreSimulator/Devices/C3D61224-CFE8-45CC-951B-7B6AB54BC8B3/data/Containers/Bundle/Application/D41A82D6-4E69-4BB6-AC59-6BC28AE58795/TestApp.app/Frameworks/geopackage_ios.framework/geopackage_ios
One might be able to fix this by adding all eleven pod frameworks to the app, which, however, is what I'm trying to avoid.
Second Approach: Using PodBuilder
A second approach would be to use PodBuilder, which aims at automating this particular kind of build task. This approach, however, fails with a build error, the cause of which I can't quite make out.
Again, I would start out with a new Xcode project. This time, I'd create an iOS Swift app named "MyApp".
I would create a Podfile with almost the same content as above:
use_frameworks!
target 'MyApp' do
pod 'geopackage-ios', '~> 7.2.1'
end
Then, I'd run pod install.
Next, I would install PodBuilder, create an empty Git repository (which PodBuilder requires for some reason), initialize PodBuilder, and start the build task:
sudo gem install pod-builder
git init
pod_builder init
pod_builder build geopackage-ios
The build will fail, however, with errors like these written to /tmp/pod_builder/pod_builder.err:
Undefined symbols for architecture arm64:
"_PROJ_WEB_MERCATOR_MAX_LAT_RANGE", referenced from:
+[GPKGTileBoundingBoxUtils toWebMercatorWithBoundingBox:] in GPKGTileBoundingBoxUtils.o
+[GPKGTileBoundingBoxUtils boundDegreesBoundingBoxWithWebMercatorLimits:] in GPKGTileBoundingBoxUtils.o
-[GPKGTileDao isXYZTiles] in GPKGTileDao.o
-[GPKGTileGenerator adjustXYZBounds] in GPKGTileGenerator.o
"_PROJ_UNDEFINED_CARTESIAN", referenced from:
-[GPKGSpatialReferenceSystemDao createIfNeededWithSrs:andOrganization:andCoordsysId:] in GPKGSpatialReferenceSystemDao.o
"_PROJ_AUTHORITY_NONE", referenced from:
-[GPKGSpatialReferenceSystemDao createIfNeededWithSrs:andOrganization:andCoordsysId:] in GPKGSpatialReferenceSystemDao.o
[…]
This seems to be a problem with the geopackage-ios pod itself, which can be fixed by cloning our own version of the repo …
cd ..
git clone --branch 7.2.1 https://github.com/ngageoint/geopackage-ios.git
…, installing the pods …
cd geopackage-ios
pod install
… manually copying the proj-ios source files …
cp -r Pods/proj-ios/proj-ios geopackage-ios
…, and opening the geopackage-ios.xcodeproj to reference the proj-ios files in the geopackage-ios group inside that project.
Then telling CocoaPods to use our local version of the pod …
use_frameworks!
target 'MyApp' do
pod 'geopackage-ios', :path => '../geopackage-ios'
end
…, reinitializing PodBuilder …
cd ../MyApp
pod_builder deintegrate
pod deintegrate
pod install
pod_builder init
… and allowing PodBuilder to use local pods by editing the ./PodBuilder/PodBuilder.json file:
{
…,
"allow_building_development_pods": true,
…
}
Then, one can try to rebuild:
pod_builder build geopackage-ios
This time, the build will fail with a different error:
The following build commands failed:
CompileC /tmp/pod_builder/build/Pods.build/Release-iphoneos/sf-proj-ios.build/Objects-normal/arm64/SFPGeometryTransform.o /tmp/pod_builder/Pods/sf-proj-ios/sf-proj-ios/SFPGeometryTransform.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler (in target 'sf-proj-ios' from project 'Pods')
(1 failure)
The SFPGeometryTransform.m file, however, looks fine.
The full build log is available here.
Third Approach: Using Rome
The third approach would be to use cocoapods-rome.
To use it, one would install Rome …
sudo gem install cocoapods-rome
…, get rid of the PodBuilder stuff …
pod_builder deintegrate
pod deintegrate
…, quickly adjust the Podfile:
use_frameworks!
platform :ios, '13.0'
plugin 'cocoapods-rome', { :pre_compile => Proc.new { |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '5.0'
end
end
installer.pods_project.save
},
dsym: false,
configuration: 'Release'
}
target 'MyApp' do
pod 'geopackage-ios', :path => '../geopackage-ios'
end
… and install the pods:
pod install
This, however, will fail with the exact same error as PodBuilder.
Can anyone give me some advice on any of these approaches? Or does anyone perhaps have a whole different idea on how to build such a framework?
(EDIT: It seems like the PROJProjectionTransform.h file imported to SFPGeometryTransform.m cannot be found. Anyway, I don't think these approaches are expedient. So any help is highly appreciated.)
Solved the problem by simply feeding all the aggregated source files from the pod installation into a new static library, then using either the lipo command to make a fat binary out of it or creating an Xcode framework from it (as described here). The compiled framework could then be used to create another framework built on top of it.

Link to fat Static Library inside Swift Package

I’m trying to build a Swift Package that wraps a fat static library written in C: libndi_advanced_ios.a from NewTek's Apple Advanced NDI SDK.
I am having trouble linking the pre-compiled library (only headers files and .a binary package is available) to my Swift Package. I have done a lot of research and tried different solutions, but none of them worked. Here is a quick list:
Cannot bundle in an XCFramework because libndi_advanced_ios.a supports multiple platforms (arm_v7, i386, x86_64, arm64) and xcodebuild -create-xcframework return the error binaries with multiple platforms are not supported (this solution is discussed on Swift Forums too);
Using .linkedLibrary in targets as suggested on SPM Documentation (that is outdated) gives the warning system packages are deprecated; use system library targets instead, and I don’t even remember if it builds successfully;
Playing around with different flags and settings (like linkerSettings) has not been successful. Maybe I just missed the right combination.
I can link dozens of Stackoverflow's questions and other posts that didn’t help, but it will be useless (a, b, c).
At the moment I have this configuration:
With Package.swift that contains the following code:
let package = Package(
name: "swift-ndi",
platforms: [.iOS(.v12)],
products: [
.library(
name: "swift-ndi",
targets: ["swift-ndi"])
],
dependencies: [],
targets: [
.target(name: "CiOSNDI", path: "Libraries"),
.target(
name: "swift-ndi",
dependencies: ["CiOSNDI"]),
.testTarget(
name: "swift-ndiTests",
dependencies: ["swift-ndi"]),
]
)
You can find the whole project at alessionossa/swift-ndi.
The only result at the moment are some warnings and the module CiOSNDI do not build:
I tried also .systemLibrary(name: "CiOSNDI", path: "Libraries/"), with this configuration: alessionossa/swift-ndi/tree/systemLibrary; but I get these errors:
NOTE
NDI_include is actually an alias/symbolic link to /Library/NDI Advanced SDK for Apple/include, while NDI_iOS_lib points to /Library/NDI Advanced SDK for Apple/lib/iOS.
I always cleaned build folder after changes to Package.swift.
UPDATE 10/01/2022: libndi_advanced_ios.a requires libc++.tbd. That can be easy linked in an app in Build Phases -> Link Binary With Libraries, but I don’t know how to link in a Swift Package.
Binary targets need to specified with .binary_target. See the docs and example here.
An example of a static library wrapped in an .xcframework looks like this from the file command:
$ file GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement
GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement: Mach-O universal binary with 2 architectures: [arm_v7:current ar archive] [arm64]
GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement (for architecture armv7): current ar archive
GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement (for architecture arm64): current ar archive
One way to create the .xcframework file is to use Firebase's ZipBuilder that creates a .xcframework files from static libraries that are specified with a CocoaPods podspec file.
I also needed to add the NDI SDK as a Swift package dependency in my app.
I found a couple of approaches that worked:
You can create an XCFramework bundle by extracting a thin arm64 library from the universal library:
lipo "/Library/NDI SDK for Apple/lib/iOS/libndi_ios.a" -thin arm64 -output "$STAGING_DIRECTORY/libndi.a"
Then create an XCFramework bundle:
xcodebuild -create-xcframework -library "$STAGING_DIRECTORY/libndi.a" -headers "/Library/NDI SDK for Apple/include" -output "$STAGING_DIRECTORY/Clibndi.xcframework"
I ended up not using this approach because hosting the XCFramework as a downloadable binary release on GitHub required me to make my repo public (see this issue).
Instead I am using a system library target, in my Package.swift:
targets: [
.target(
name: "WrapperLibrary",
dependencies: ["Clibndi"],
linkerSettings: [
.linkedFramework("Accelerate"),
.linkedFramework("VideoToolbox"),
.linkedLibrary("c++")
]),
.systemLibrary(name: "Clibndi")
]
Then, I have WrapperLibrary/Sources/Clibndi/module.modulemap that looks like:
module Clibndi {
header "/Library/NDI SDK for Apple/include/Processing.NDI.Lib.h"
link "ndi_ios"
export *
}
Finally, my application target (part of an Xcode project, not a Swift package) depends on WrapperLibrary, and I had to add "/Library/NDI SDK for Apple/lib/iOS" (including the quotation marks) to "Library Search Paths" in the "Build Settings" tab.
As an alternative to modifying the application target build settings, you could add a pkg-config file to a directory in your pkg-config search paths. For example, /usr/local/lib/pkgconfig/libndi_ios.pc:
NDI_SDK_ROOT=/Library/NDI\ SDK\ for\ Apple
Name: NDI SDK for iOS
Description: The NDI SDK for iOS
Version: 5.1.1
Cflags: -I${NDI_SDK_ROOT}/include
Libs: -L${NDI_SDK_ROOT}/lib/iOS -lndi_ios
Then use .systemLibrary(name: "Clibndi", pkgconfig: "libndi_ios") in your package manifest. I found this less convenient for users than just adding the setting to my application target, however.
Ideally you could add the NDI SDK's dependency library and frameworks to the pkg-config file as well (Libs: -L${NDI_SDK_ROOT}/lib/iOS -lndi_ios -lc++ -framework Accelerate -framework VideoToolbox), but it appears there is a bug in Swift's pkg-config parsing of -framework arguments, so I filed a bug: SR-15933.

Importing GoogleWebRTC pod fails: module 'GoogleWebRTC' not found

I am currently working on a Kotlin multiplatform and am trying to interface with the GoogleWebRTC pod.
The pod exists, I was able to import it in a separate project (without Kotlin multiplatform). I can see the .framework is created in my build directory, however when doing a gradle sync or building from Xcode, I get the following error:
Exception in thread "main" java.lang.Error: /var/folders/hv/9cx28nxx4gz9hj_m86bp5rx40000gn/T/tmp362966650322311128.m:1:9: fatal error: module 'GoogleWebRTC' not found
at org.jetbrains.kotlin.native.interop.indexer.UtilsKt.ensureNoCompileErrors(Utils.kt:152)
at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesASTFiles(ModuleSupport.kt:67)
at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesInfo(ModuleSupport.kt:13)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.buildNativeLibrary(main.kt:499)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLib(main.kt:264)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.interop(main.kt:72)
at org.jetbrains.kotlin.cli.utilities.InteropCompilerKt.invokeInterop(InteropCompiler.kt:45)
at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:19)
at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:37)
Execution failed for task ':shared:cinteropGoogleWebRTCIosArm64'.
> Process 'command '/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
AFNetworking seems to work fine, but adding the WebRTC pod seems to break the project.
Am I missing a limitation of Kotlin multiplatform or something?
This is my build.gradle.kts:
cocoapods {
// Configure fields required by CocoaPods.
summary = "Some description for a Kotlin/Native module"
homepage = "Link to a Kotlin/Native module homepage"
// You can change the name of the produced framework.
// By default, it is the name of the Gradle project.
frameworkName = "shared"
ios.deploymentTarget = "10.0"
pod("GoogleWebRTC", "~> 1.1")
pod("AFNetworking", "~> 4.0.0")
}
I was able to reproduce this issue but I didn't figure out the reason why.
It seems a there's something wrong with GoogleWebRTC pod and the Kotlin-native/cocoapods integration.
I've opened an issue here.
We have an official help.
It seems that the frameworks name is different from the pod name. So a possible solution could be that:
kotlin {
cocoapods {
[...]
pod("GoogleWebRTC", moduleName = "WebRTC", version = "~> 1.1")
[...]
}
[...]
}
I tried it and it works.

Marmalade iOS multiple architectures support

The instruction for building marmalade extension static lib-wrappers from the official site shows how to build only single architecture (armv6) extension. I tried to include many architectures into the project:
if {{defined I3D_OS_IPHONE}}
{
includepath incoming
files
{
["MyTracker Library armv7"]
(incoming/armv7)
"*.o"
["MyTracker Library armv7s"]
(incoming/armv7s)
"*.o"
["MyTracker Library armv64"]
(incoming/armv64)
"*.o"
["source"]
(use_first_found, source/iphone, source/generic)
MyTracker_platform.mm
#Add any iphone-specific files here
}
}
But I got many error messages after trying to build it:
Executing: '/usr/local/bin/scons -Q compiler=clang'
scons: warning: Support for pre-2.7.0 Python version (2.6.8) is deprecated.
If this will cause hardship, contact dev#scons.tigris.org.
File "/usr/local/bin/scons", line 192, in <module>
Librarian [ar] /Users/misha/Documents/MyTracker/lib/iphone/libMyTracker.a
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib: archive member: /Users/misha/Documents/MyTracker/lib/iphone/libMyTracker.a(MyDispatcher.o) cputype (7) does not match previous archive members cputype (12) (all members must match)
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib: archive member: /Users/misha/Documents/MyTracker/lib/iphone/libMyTracker.a(MyTracker.o) cputype (16777223) does not match previous archive members cputype (12) (all members must match)
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib: archive member: /Users/misha/Documents/MyTracker/lib/iphone/libMyTracker.a(MyNetwork.o) cputype (16777228) does not match previous archive members cputype (12) (all members must match)
....
malformed object (unknown load command 1)
ar: internal ranlib command failed
scons: *** [/Users/misha/Documents/MyTracker/lib/iphone/libMyTracker.a] Error 1
Executing 'scons -Q' failed. (return code 2). Retry
error: Executing 'scons -Q' failed. (return code 2)
FAILED (error code=3)
How to build an extension with multiple architectures support?
This is typically not the advised way to handle this. You look like you're trying to bring in symbols from those libs, something that the EDK does not support. Your best option is to include these libs (or most probably, just the arm6/7 lib, depending on how low you want to take it) at deploy time along with the compiled extension and instead, compile the extension using a header file (either supplied by the developer of any SDK you're using, or one you've written to compile those .o libs).
Building for multiple targets is something that is being refactored. My understanding is that at some stage both the documentation and the underlying code has got stale. I believe the approach will be quite different from what you are trying to do - I'm not sure why you are pulling in .o files but generally that does work too well in marmalade.

Resources