How to make cocoapods build for device only? - ios

I'm trying to create a cocoa pod out of my Cocoa Touch Framework project. The project is not intended to support iOS simulator, only devices. It doesn't even compile for simulator. And it becomes a problem, because cocoapods tries (at least I think so) to build it for simulator and fails.
When I run the following command:
pod spec lint --verbose
it failes and the part of the output is the following:
The following build commands failed:
CompileC /var/folders/_w/9b4kyb8x2lzb9hvpn94jtrh00000gp/T/CocoaPods/Lint/build/Pods.build/Release-iphonesimulator/jsoncpp.build/Objects-normal/i386/jsoncpp.o jsoncpp/dist/jsoncpp.cpp normal i386 c++ com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
-> RevSDK (0.1.0)
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code.
- NOTE | xcodebuild: Headers/Public/RevSDK/time.h:62:10: fatal error: 'base/base_export.h' file not found
Analyzed 1 podspec.
[!] The spec did not pass validation, due to 1 error.
I'm not really good at understanding how the whole process goes and what exactly is wrong, but this line in the output:
CompileC /var/folders/_w/9b4kyb8x2lzb9hvpn94jtrh00000gp/T/CocoaPods/Lint/build/Pods.build/Release-iphonesimulator/jsoncpp.build/Objects-normal/i386/jsoncpp.o jsoncpp/dist/jsoncpp.cpp normal i386 c++ com.apple.compilers.llvm.clang.1_0.compiler
makes me think that cocoapods is trying to compile my project for the simulator. So I need to exclude it somehow. I need to let it know that it should compile for device only. What I tried was adding the following into my .podspec file:
s.xcconfig = {
'VALID_ARCHS' => ['armv7', 'armv7s', 'arm64']
}
but unfortunately it produced no effect. And I literally don't know what to do. Can anyone help me?

This is probably the same or similar issue around VALID_ARCHS being deprecated in Xcode 12 and EXCLUDED_ARCHS needed.
s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }

Try this:
s.pod_target_xcconfig = { 'VALID_ARCHS' => 'armv7', 'armv7s', 'arm64' }

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.

Oracle JET : Unable to build ojet hybrid project after upgrading xcode to Version 12.0 (12A7209)

This morning I updated my xcode to Version 12.0 (12A7209) and since then I am not able to build the project for ios
Replication steps
ojet create testapp --template=navbar
cd testapp
ojet add hybrid
ojet build ios
Getting the below error
.........
In module 'Foundation' imported from /Users/hellonuh/Desktop/testapp/hybrid/platforms/ios/build/emulator/include/Cordova/CDVAppDelegate.h:20:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSURL.h:595:1: note: 'stringByAddingPercentEscapesUsingEncoding:' has been explicitly marked deprecated here
- (nullable NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)enc API_DEPRECATED("Use -stringByAddingPercentEncodingWithAllowedCharacters: instead, which always uses the recommended UTF-8 encoding, and which encodes for a specific URL component or subcomponent since each URL component or subcomponent has different rules for what characters are valid.", macos(10.0,10.11), ios(2.0,9.0), watchos(2.0,2.0), tvos(9.0,9.0));
^
3 warnings and 3 errors generated.
Cordova compile finished.
Error: Error: Command failed: cordova compile ios --debug --emulator
** BUILD FAILED **
The following build commands failed:
CompileC /Users/hellonuh/Library/Developer/Xcode/DerivedData/testapp-hfsgwahghfnpzecdcshskgzlpyep/Build/Intermediates.noindex/testapp.build/Debug-iphonesimulator/testapp.build/Objects-normal/x86_64/CDVWKWebViewEngine.o /Users/hellonuh/Desktop/testapp/hybrid/platforms/ios/testapp/Plugins/cordova-plugin-wkwebview-engine/CDVWKWebViewEngine.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
xcodebuild: Command failed with exit code 65
Please help

'pod lib lint' conflict between 'route.h' and <net/route.h>

I'm trying to run pod lib lint on a Cocoa Framework swift project and it returns the following error:
- ERROR | [iOS] xcodebuild: /MyProject/route.h:164:8: error: redefinition of 'rt_msghdr2'
- NOTE | [iOS] xcodebuild: /Applications/Xcode.app/Contents/Developer/Platforms
/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk
/usr/include/net/route.h:164:8:
note: previous definition is here
I have an Objective-C class (NetworkUtil.h - NetworkUtil.m) with the following import structure.
#if TARGET_IPHONE_SIMULATOR
#include <net/route.h>
#else
#include "route.h"
#endif
This, because route.h file only exist in the iOS Simulator SDK, but not in the actual iOS SDK (https://stackoverflow.com/a/23411469/5973853). I check whether it is an iPhone simulator, so the original < net/route.h > will be imported, or it runs on an actual iPhone, in that case it gets my manually copied 'route.h'.
Xcode manages to build and run the whole project correctly, but xcodebuild used by pod lib lint doesn't. For some reason, it imports both < net/route.h > and 'route.h' without considering the #if_TARGET_IPHONE_SIMULATOR validation and that makes the conflict due to "redefinition of several functions".
Is there any solution or workaround to this conflict?

'warning: directory not found for option' error on build

All of a sudden my app has started giving me an error when I try to build it. This is the error I'm getting:
ld: warning: directory not found for option '-L/Users/user/Documents/Developer/Alton-Towers-Times/build/Debug-iphoneos'
ld: file too small (length=0) file '/Users/user/Library/Developer/Xcode/DerivedData/Mouse_Times_Florida-eqhrhnbxmmkxtahdghmnvehbzbgt/Build/Intermediates/Mouse Times Florida.build/Debug-iphonesimulator/Mouse Times Florida WatchKit Extension.build/Objects-normal/x86_64/SecondInterfaceController.o' for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Only thing I've really done since I last managed to get it to run was changing the bundle IDs and I also changed the app name. I've tried a few things including deleting the derived data, but nothing seems to have helped.
Anyone have any ideas?
I solved this warning removing the following setting: "$(SDKROOT)/Developer/Library/Frameworks"
This options is located in Settings -> Build Settings -> Search Paths -> Framework Search Paths
Setting location
My project continues compiling and working fine, after removing this option.
Veladan answer helped me to sort out that issue on an iOS8 project freshly migrated to iOS9.
This worked fine on the main target of my project, but the warning lasted on the unit tests target, so in the end I edited directly the project.pbxproj file and modified the entries :
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
to :
FRAMEWORK_SEARCH_PATHS = "";

Resources