Ignore .metal files when building for iOS Simulator target - ios

Whenever I build a project that includes a metal shader to an x86_64 target (iOS simulator), I get a dependency analysis warning:
warning: no rule to process file '[File Path]/Shaders.metal' of type sourcecode.metal for architecture x86_64
I know this isn't a huge issue but I like to keep my projects free from warnings when I build, so that when a real issue does arise, I actually notice the yellow warning triangle.
Any quick way to get Xcode to ignore metal files for simulator targets?

You can resolve this by precompiling your .metal file into a Metal library during the build step, and removing the .metal source code from your app target.
Remove .metal file from target
Select your .metal file in the project navigator, and uncheck the target that is giving you the warning.
Metal library compile script
Create a bash script called CompileMetalLib.sh in your project, alongside your .metal file, with contents like this:
xcrun -sdk iphoneos metal -c MyShader.metal -o MyShader.air
xcrun -sdk iphoneos metallib MyShader.air -o MyShader.metallib
rm MyShader.air
Make sure to give it executable permissions by running chmod +x CompileMetalLib.sh.
MyShader.air is the intermediate compile step, and MyShader.metallib is the fully compiled metal library. Read all about compiling a Metal file here
If you're compiling for OS X, change iphoneos to macosx.
Run compile script during build
Now you'll want to trigger this script in your Build Phases.
Add a New Run Script Phase to your target. The contents should look like this:
cd ${SRCROOT}/path/to/folder/containing/yourshader
./CompileMetalLib.sh
It's important to drag this step so that it happens before the Copy Bundle Resources step.
Change your code to use your compiled Metal library
You'll now load the compiled Metal library from your app bundle.
Here's some pseudo-Swift:
let metalLibPath = Bundle.main.path(forResource: "MyShader", ofType: "metallib")
let myLibrary = try metalDevice.makeLibrary(filepath: metalLibPath)
Result
You are manually compiling your .metal file with an external script, and copying the compiled library into your bundle resources. Your code loads this library. Now that you don't have any .metal files in your target, the simulator will no longer throw a warning about not being able to compile for x86_64.

As of Xcode 11, Simulator supports Metal when running on macOS Catalina. Metal files are supported during the build, including when running on macOS Mojave or when building with an older deployment target. Metal won't be functional in those scenarios but you no longer need to exclude files from the build. (Of course when running iOS 13 / tvOS 13 simulators on 10.15 Metal actually works).

Related

How to unit test iOS package with `swift test`?

I have an iOS library with Swift package manager. I am trying to run unit tests with swift test
The reason why I am not using xcodebuild is, I am trying to remove the .xcodeproj from my source control. Also, there is a warning when we create xcodeproj with spm, that generate-xcodeproj will be deprecated soon.
TL;DR
This library depends on Lottie
I tried just running swift test in the root directory, but it gives lot of errors. like /.build/checkouts/lottie-ios/lottie-swift/src/Public/Animation/AnimationView.swift:859:11: error: cannot find 'superview' in scope
I tried
swift test -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios14.5-simulator"
Then it gives the error error: module 'XCTest' was created for incompatible target x86_64-apple-macos10.15. I did not specify macos10.15 anywhere, I am on macOS 11.5.1
I can build the package using the above command by replacing test with build. What is wrong with my test command?
As I understand this is because I am not specifying the target simulator, is it possible to specify the target simulator with swift test?
swift test only works for macOS testing. It does not support cross builds for iOS.
You do not need an existing Xcode project to use xcodebuild. Run the command, xcodebuild -list to initialize a Package.swift file for testing.
See the example here.

Xcode 10 warning: Stale file '/path/to/file' is located outside of the allowed root paths

Xcode 10 produces this warning when running xcodebuild in a run script phase of a build target. I do this to produce the binary for the other platform (simulator/real device) to lipo into a fat binary for distribution. The warning is produced for every file in the target intermediates directory, for example:
warning: Stale file '/Users/nick/Library/Developer/Xcode/DerivedData/App-ctjxvxdmomwoobfgvvasfhwvcnhy/Build/Intermediates.noindex/Library-Target.build/Debug-iphonesimulator/Sub-Library-Target.build/Objects-normal/i386/Sub-Library-Class.o' is located outside of the allowed root paths.
What are the root paths? Why is this warning produced? Is there any way I can resolve or suppress it?
I had it on Xcode 11.2
solved it by
1. Clean (Cmd+Shift+K) and then:
Cmd+Shift+R ( build for Running )
For some reason you might have copied the .framework to an external path. To solve this annoying warning you should run (as sudo) the command to delete the framework:
In your case:
sudo rm -rf /Users/nick/Library/Developer/Xcode/DerivedData/App-ctjxvxdmomwoobfgvvasfhwvcnhy/Build/Intermediates.noindex/Library-Target.build/Debug-iphonesimulator/Sub-Library-Target.build/Objects-normal/i386/Sub-Library-Class.o
If you are using Objective-C to create frameworks you may end up with those anoying warnings. The solution I've found is to add
-UseModernBuildSystem=NO
at end of every xcodebuild command in your Run Script.

Project Builds and Runs, but does not Archive

I have a project which builds and runs fine on the simulator and device, but fails when archiving.
The project is very old, but I have created a separate component which I have added in the workspace.
The main project is written in Objective-C, the new project is written in Swift 4. The project also uses CocoaPods and also includes another subproject written in Swift 3.2
There are various errors which all boil down to the same thing, the sub project is not producing any output when it is compiled. OR it is just not compiled. I see no errors in the code itself, just when trying to reference it:
//1
error: /Users/<user>/Library/Developer/Xcode/DerivedData/<id>/Build/Intermediates.noindex/ArchiveIntermediates/<app name>/BuildProductsPath/Release-iphoneos/Framework.framework: No such file or directory`
//2
Signing Identity: "iPhone Developer: <redacted>“
/Users/<user>/Library/Developer/Xcode/DerivedData/<id>/Build/Intermediates.noindex/ ArchiveIntermediates/<app name>/InstallationBuildProductsLocation/Applications/<app name>/Frameworks/<framework>.framework: No such file or directory
Command /usr/bin/codesign failed with exit code 1
//3
#import ModuleName;
Module ‘ModuleName’ not found
Here’s what I’ve tried:
Clear derived data
Restart Mac
Add $(SRCROOT) to Main Target > Build Settings > Framework Search Paths > Release
Confirmed project is present in Embedded Binaries
Confirmed project is present in Linked Frameworks and Libraries
Removing and re-adding project to embedded binaries and frameworks and libraries
Removing the import declaration
I am opening the workspace and not the project
Skip install set to YES in Subproject build settings
Comparing build settings from the working sub project with the failing one (they are the same)
Running pod update
Changing Always Embed Standard Swift Libraries makes no difference either way
Other notes:
In /Users/<user>/Library/Developer/Xcode/DerivedData/<id>/Build/ Intermediates.noindex/ArchiveIntermediates/<app name>/ InstallationBuildProductsLocation/Applications/<app name>.app/Frameworks/ there is a .framework file for the other sub project and all the pods, but not for this one
In podfile, use_frameworks! is present
Update:
After running an archive today I am only seeing the error:
Module 'ModuleName' not found
The other errors are gone
The issue was to do with the iOS Deployment Target setting:
The main project: iOS 10
Sub project: iOS 11
In Debug it is building only for the current architecture, in Release it builds for all. Obvious once you know.
Setting the sub project to build for iOS 10 fixed the issue.
The most frustrating part: I double checked the build log and it doesn't mention the version issue anywhere :(
It's impossible to tell what exactly causing it to fail archiving. BUT I'm pretty sure I can give you the correct direction =]
Running on simulator or even a real device - compiles the project for "Debug"
Archiving tough, compiles for "Release"
I bet that if you set that running on simulator will compile on Release mode, it will fail!
Check it!!
If I correct you just need to set some of the Build Settings for Release to match Debug
My first guess is: All the search paths (Framework search path, and Runpath search path)
I saw a similar behavior here
I got it to archive after all.
It looked like the SDK-Project was missing a build configuration
Adhoc. Which Project used to archive the project for a specific build
scheme. I think the compiler was looking for modules in the
$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) path
I was having this error, and while my deployment targets did not match, that wasn't actually the fix for me. I had added a new build configuration that I was trying to use for my archive, but I forgot to run pod install after adding it. After running pod install, I was able to archive my app just fine, even though the deployment targets for some of the Pods are iOS 10 while the main app target is iOS 11.
Might be not relevant to you, but helpful to others:
If you using multi-modular SwiftPM-based architecture, then you should read errors carefully and find out if some of your package targets import some other one in sources without integrating it in the Package.swift file. In this case, even the release build will resolve dependencies somehow and succeed if some other package contains your dependency, but the archive will fail.
Package graph examples:
––––––––––
App
├– PackageA [target1(import PackageC.target1)]
└– PackageB [target1(import PackageC.target1)]
└– PackageC [target1]
👆 Builds with success, archives with errors (Can't find module PackageC.target1 in PackageA.target1)
––––––––––
App
├– PackageA [target1(import PackageC.target1)]
| └– PackageC [target1]
└– PackageB [target1(import PackageC.target1)]
└– PackageC [target1]
👆 Builds and archives with success
Cocoapods and Architecture settings
I had a Podfile that set EXCLUDED_ARCHS to arm64 in a post-install script and this was consistent with my main target. This setting was ok for building on Debug mode (x86_64) but didn't work for release building (Archives). I realised the script set EXCLUDED_ARCHS for the Pod targets even on physical devices (Any iOS SDK) rather than only on Simulators.
Steps
I ran pod deintegrate.
I deleted Derived Data.
I deleted Podfile.lock (now we have a fresh start).
I updated the Podfile iOS version to be the lowest supported version in each Pod.
Refactor EXCLUDED_ARCHS script.
Refactoring EXCLUDED_ARCHS script
I refactored:
config.build_settings['EXCLUDED_ARCHS'] = 'arm64'
from the Podfile post-install script to the following:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
...
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
end
end
end
I haven't done watchOS here because it wasn't a watchOS app, however, we need to do this for all supported simulated device targets.
I left EXCLUDED_ARCHS to arm64 to Any iOS Simulator SDK in the main target for Release mode in the main target. The same logic here applies to other sims.
pod install
Archive again. :D

how to build DLIB for iOS

I'm trying to build DLIB for an iOS project. Running the cmake results in a libdlib.a and a load of .o files.
When I add the library to an Xcode project I get warning that the library hasn't been built for arm64.
My question is two-part:
How can I build DLIB for iOS (I tried cmake **path_to_source** -DCMAKE_OSX_ARCHITECTURE="arm64" but it caused loads of errors e.g. unknown type name '__uint32_t'; did you mean '__uint128_t')?
What is the purpose of all the .o files that get built when you run cmake? Do I need to include them in an Xcode project?
I finally figured out how to do this:
Requirements
X11 (on a mac you can just open the X11 app and if X11 isn't installed it'll take you to the download).
Xcode
cmake (you can use home-brew for that)
Steps
In terminal make the lib-xx.xx/examples your root
Run:
mkdir build
cd build
cmake -G Xcode ..
cmake --build . --config Release
This will create a folder called dlib_build in which you can find an Xcode project that compiles the library. In the build settings of that Xcode project you can set the build architecture and SDK for any Xcode supported OS you like!
EDIT:
You have to include a lot of custom compiler flags and 3rd party libraries to get dlib to work in a project. Check out the examples.xcproject build settings.
To compliment RASS's answer, I am attaching screenshots showing how to change this to and from an iOS and OSX lib
After opening the project,
Select the project file from the project navigator
Select the dlib target all the way down the bottom
Select 'Build Settings'
Expand 'Base SDK' drop down
Select either iOS or macOS (OSX)
I hope this helps some people out! gl
Rob Sanders and mylogon already show how to build dlib for ios, here is how to use it:
add libdlib.a to project, and add path to library search paths
add all source to include directory(do not add to project), and add path to header search paths.
add accelerate framework, which contains blas symbols.
add preprocessor macros, from building settings, "custom compiler flag"/"other c flags". these macros make sure the header files match the lib.
-DDLIB_JPEG_SUPPORT
-DDLIB_NO_GUI_SUPPORT
-DNDEBUG
-DDLIB_USE_BLAS
-DDLIB_USE_LAPACK

Xcode Compile Error: Lipo: can't open input file

/fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: can't open input file: /Users/zicjin/Library/Developer/Xcode/DerivedData/Baozou-iOS-gsgjiwiqjwffeheenpeffrqpytqx/Build/Intermediates/Baozou-iOS.build/Debug-iphoneos/Baozou-iOS.build/Objects-normal/armv7/Baozou-iOS (No such file or directory)
Use virtual machines to compiler does not complain, but switched to the real machine (iphone5s) runtime compilation error will be so
the sourcecode on github
Set your Build Active Architecture Only to YES, then it will work
This happened to me. I'm using a static library in my project and the issue was that I put the aggregate with the universal script as a target instead of using the library itself.
This happens when the universal script tries to generate the universal library but the library itself is not compiled, this script needs the library to be created before running.
In Xcode 7.2 I had to set Enable Bitcode to No in Build Settings > Build Options.
I ran into this problem while migrating my project from Xcode 5.0.2 to Xcode 6.1. These are the steps that I followed to get it working.
There was a warning generated - "Used recommended settings ... blah blah" - I allowed Xcode to change my project to whatever recommended settings there was.This did not stop the error though.
In TARGET -> BUILD SETTINGS -> BUILD ACTIVE ARCHITECTURES ONLY . I turned the flag to YES.
set TARGET -> BUILD SETTINGS -> Linking -> Other Linker Flags : $(OTHER_LDFLAGS)
After step 3 -I cleaned and then build my project and Whoa the error just vanished!!!!!
In your project > Build Phases
Place your lipo run script after CocoaPods scripts, your lipo will run after cocoapods finishes building its frameworks
As you can see here
This same thing happened to me in Xcode 12.4, in Mac os CataLina This issue was occured by Not Enough Storage, I have deleted derived and some other data, then Build for Diawi link was successfully created.

Resources