I have an XCode project with two executable targets, which I use for my own work (that is, I don't sell or publish the applications, but they are still important to me), which depends on one external project. Until now, it has been unproblematic to build the Application(s) and install into the /Applications folder. What I did, was go into the command line and type:
sudo xcodebuild -scheme Trainer install
This would install the target Trainer into the Applications folder, and the application could be run from there. If I tried to specify the target using -target Trainer instead, it would not work, as it would not find dependencies in the external project. Anyway, since last time it worked, two things have happened:
I have upgraded to OS X 10.11
I have upgraded XCode to Version 7.1.1 (7B1005)
Whatever the reason, xcodebuild does no longer install the built product into the /Applications folder. The last lines from the build log, when building with xcodebuild now are:
Touch /var/root/Library/Developer/Xcode/DerivedData/SoundSample-bvsqlgnuhfmtjkgkhevztdzbjbie/Build/Intermediates/ArchiveIntermediates/Trainer/BuildProductsPath/Release/Trainer.app.dSYM
cd /Users/pbholmen/Projects/SoundSample
/usr/bin/touch -c /var/root/Library/Developer/Xcode/DerivedData/SoundSample-bvsqlgnuhfmtjkgkhevztdzbjbie/Build/Intermediates/ArchiveIntermediates/Trainer/BuildProductsPath/Release/Trainer.app.dSYM
RegisterWithLaunchServices /var/root/Library/Developer/Xcode/DerivedData/SoundSample-bvsqlgnuhfmtjkgkhevztdzbjbie/Build/Intermediates/ArchiveIntermediates/Trainer/InstallationBuildProductsLocation/Applications/Trainer.app
cd /Users/pbholmen/Projects/SoundSample
builtin-lsRegisterURL /var/root/Library/Developer/Xcode/DerivedData/SoundSample-bvsqlgnuhfmtjkgkhevztdzbjbie/Build/Intermediates/ArchiveIntermediates/Trainer/InstallationBuildProductsLocation/Applications/Trainer.app
** INSTALL SUCCEEDED **
I have tried to simply copy the Trainer.app that it builds into the /Applications folder, but if I double-click on it, it just won't run. Of course, the Application works when built and run from within XCode, both with the "Debug" and "Release" configuration.
Back when it did work, this would be the last lines of the build log (in Terminal):
Touch build/Release/Trainer.app.dSYM
cd /Users/pbholmen/Projects/SoundSample
/usr/bin/touch -c /Users/pbholmen/Projects/SoundSample/build/Release/SoundSample.app.dSYM
RegisterWithLaunchServices /Applications/Trainer.app
cd /Users/pbholmen/Projects/SoundSample
builtin-lsRegisterURL /Applications/Trainer.app
** INSTALL SUCCEEDED **
If I try to go into the build log from within XCode, find where it puts the builds, and maneuver into that location in Finder and start the application from outside of XCode, that doesn't work either.
Here you can see my Deployment build settings for the target:
Build settings
Under "Deployment location" I have tried both "YES" and "NO", and under "OS X Deployment target" I have tried both "OS X 10.10" and "OS X 10.11". And all four combinations of the two.
After hours of twiddling, I finally figured out the answer. First off, the command
sudo xcodebuild -scheme Trainer install
is wrong. It was a workaround, because I couldn't get XCode to manage my external dependencies from the command line, even though they were managed correctly within XCode. The correct invocation, for a target other than the project's main target is
sudo xcodebuild -target Trainer install
Previously, the first invocation would work, the product would be installed even though the scheme doesn't really include an "Install" action. This is clearly no longer so with XCode 7.1. The reason I couldn't use -target instead of -scheme previously, was because my target was dependent on a framework in another project, which was added to my main project (the external project was added, not just the framework). All dependencies were set up correctly in my main project, and from the command line it worked only when specifying the scheme, not when specifying the target. When running xcodebuild with -target specified, xcodebuild would not find the modules in the external project (a Swift framework).
I have now figured out the reason for this. The project which contained the external framework was not set up correctly. It was set up to install the framework into a bogus location (/tmp/ProjectName.dst/Library/Frameworks, which is the default). In addition, my main project needed to add /Library/Frameworks into the framework search paths. It seems that when the project is built inside XCode, or for archiving etc... libraries and executables are built into a "private" folder structure separate from the system itself. When running xcodebuild install, however, it tries to install the external frameworks into the proper system folders, and link it there. Therefore, setups that work inside XCode may not work when running 'xcodebuild'.
EDIT: It works now, but StackOverflow won't let me mark it as correct before two days.
Related
I want to replace cocoapods with SPM. I have decided to go at it one library at a time. I removed the swinject library from cocoapods and added it via File->Swift Packages->Add Package Dependency
This was successful and the project built and ran as expected.
I then asked other people in my team to check out the branch and see if they can build the project on their side without issues. We then ran into the error "Missing package product 'Swinject'". We resolved this error by performing File->Swift Packages->Resolve Package Versions in Xcode.
I need to get this working on the build server as well. I tried typing in swift package --help in the Terminal app to see what commands are available. The resolve command looked promising so I tried that to no avail. (error: root manifest not found)
So, my question then, is there a terminal command that does the same as File->Swift Packages->Resolve Package Versions?
Note: When I added the 3rd party library via SPM, it created one file for me: Proj.xcworkspace/xcshareddata/swiftpm/Package.resolved. It also made various changes to the Proj.xcodeproj/project.pbxproj file. No package.swift file was created.
Update:
The closest I have gotten to an answer was that I should try xcodebuild -resolvePackageDependencies, unfortunately the command does not do the same as File->Swift Packages->Resolve Package Versions.
I was struggling with the SPM in my project. It seems that you need to pass the -clonedSourcePackagesDirPath [directory]
xcodebuild -resolvePackageDependencies -workspace ck550.xcworkspace -scheme ck550-cli -clonedSourcePackagesDirPath .
xcodebuild -workspace ck550.xcworkspace -scheme ck550-cli -clonedSourcePackagesDirPath .
The first command resolves and downloads all Swift Packages into the ./checkouts and some other ./[dirs] are also created.
The second command initiates the build of your application, and those SPM packages are also built.
Here is output from the build server:
https://travis-ci.org/vookimedlo/ck550-macos/builds/626438212
Travis-CI configuration:
https://github.com/vookimedlo/ck550-macos/blob/master/.travis.yml
From what I have seen, there are 2 Package.resolved files. One on the workspace and one on the project. For some reason the workspace has old versions of the packages and running
xcodebuild -resolvePackageDependencies -workspace myworkspace.xcworkspace -scheme my scheme
does not work. However, resolving on the project (since the project's Package.resolved has the correct packages version info) does work
xcodebuild -resolvePackageDependencies -project myproject.xcodeproj -scheme my scheme
Does xcode use of the xcodebuild command behind the scenes to build?
If so, how can I find the exact xcodebuild command that is run?
I checked the report navigator but couldn't find it in there.
I would have thought that running xcodebuild -sdk iphonesimulator -configuration Debug -project <myproject>.xcodeproj -scheme <myscheme> would be identical to selecting product -> build in xcode (with a scheme/destination matching the command line), but they seem to have slightly different behavior.
For example, when running the command line above with the -showBuildSettings option, I noticed that BUILD_ACTIVE_RESOURCES_ONLY=NO even though it should be set to YES according to the target's build settings. When running product -> build from xcode, the build settings logs (generated by following #Slipp D. Thompson's answer here) show BUILD_ACTIVE_RESOURCES_ONLY=YES.
There are few other strange differences I noticed as well.
No. One could do an experiment: move all xcodebuild binaries in some local folder and check that Xcode still able to build some application.
Since Apple presents xcodebuild as a self contained command line tool for building Xcode projects, it is reasonable to suspect that use code sharing between both tools.
Until now, all of my experience compiling PhoneGap apps has been via the excellent PhoneGap:Build service. However, I now find myself in a situation where I need to compile locally, because I need to use a plugin that includes a binary file, which precludes it from being included for use with PG:B.
So for these reasons, I need to compile locally. "Great!" I thought, I'll just use the new CLI...
I have developed my app, and I can test it on-device via deploy over USB from Xcode, but trying to get a release build, and sign it, with the provisioning profile embedded, has been a nightmare.
For completeness, this is the basic outline of everything I've done, aside from the app development itself.
$ pwd
/users/adam/dev/myapp/mobile/
$ cordova create build_local com.foo.bar MyApp
Creating a new cordova project with name "MyApp" and id "com.foo.bar" at location "/Users/adam/DEV/myapp/build_local"
$ cd build_local
$ cordova platform add ios
Creating ios project...
$ cordova platform add android
Creating android project...
Creating Cordova project for the Android platform:
Path: platforms/android
Package: com.foo.bar
Name: MyApp
Android target: android-19
Copying template files...
<snip>
Project successfully created.
$ cordova plugin add https://github.com/hazemhagrass/BackgroundJS
Fetching plugin "https://github.com/hazemhagrass/BackgroundJS" via git clone
Installing com.badrit.BackgroundJS (android)
Fetching plugin "https://github.com/apache/cordova-plugin-device.git" via git clone
Installing org.apache.cordova.device (android)
Installing com.badrit.BackgroundJS (ios)
Installing org.apache.cordova.device (ios)
$ cordova plugin add de.appplant.cordova.plugin.local-notification
Fetching plugin "de.appplant.cordova.plugin.local-notification" via plugin registry
Installing de.appplant.cordova.plugin.local-notification (android)
Installing de.appplant.cordova.plugin.local-notification (ios)
$ cordova plugin add https://github.com/kdzwinel/phonegap-estimotebeacons
Fetching plugin "https://github.com/kdzwinel/phonegap-estimotebeacons" via git clone
Installing pl.makingwaves.estimotebeacons (android)
Installing pl.makingwaves.estimotebeacons (ios)
For what it's worth, this last plugin is the reason that I have to compile locally.
Now, here's one other potential monkey wrench: This app is actually two apps. It's the same core codebase, merged into two different deployment branches of the repo, one for each client. So each app will have its own id, name, and config stuff. Because of this, I actually have more than one cordova project folder (1 for each final app) and after creating each project through the steps above, I remove the generated www folder and replace it with a symlink to the shared www folder that exists outside of these phonegap project directories.
This is supported behavior; the CLI allows you to generate your app with a symlink via the --link-to flag (see cordova help create for details). However, doing so seems to have issues; so I've resorted to doing all of the app config up front and then replacing the generated www folder with a symlink after everything is ready to compile.
At this point, I can deploy to either the iOS simulator or Android emulator, and I can deploy to devices over USB, and everything works just fine; all of my plugins are available and function as expected. So I'm ready to compile a release build. Android is easy. iOS, not so much.
$ cordova build ios
<snip>
** BUILD SUCCEEDED **
However, this is a DEV build. The generated file is in the build/emulator/ folder, and when I attempt to sign it, I'm told that it's not signed because of the I386 architecture (which indicates that it's a development build).
$ xcrun -sdk iphoneos PackageApplication -v "platforms/ios/build/emulator/MyApp.app" -o "/users/adam/dev/myapp/MyApp.ipa" --sign "iPhone Distribution: {our cert name} ({our cert id})"
<snip>
Codesign check fails : platforms/ios/build/emulator/MyApp.app: code object is not signed at all
In architecture: i386
<snip>
I've attempted to generate a release build from the cordova CLI. I haven't been able to find the --release flag documented anywhere, but the CLI doesn't complain, and it usually does if it doesn't recognize a flag.
$ cordova build ios --release
<same result as previously>
Attempting to sign this build results in the same problem.
At this point, I started attempting to work directly in Xcode. I've set the .mobileprovision file and the signing credentials up appropriately, to the best of my knowledge:
With these values set, Xcode no longer allows me to build:
So I'm stuck: I have no choice but to build locally, and I can't figure out how to get it to build for release and sign! Please help!
Additionally, if I attempt to embed a provisioning profile, that fails because of an issue with entitlements. I'm not exactly sure what this means, but I'm hopeful that it's a result of working with a dev build, and resolving that will resolve this as well.
$ test -e ~/.ios/DEV.mobileprovision && echo exists
exists
$ xcrun -sdk iphoneos PackageApplication -v "platforms/ios/build/emulator/MyApp.app" -o "/users/adam/dev/myapp/MyApp.ipa" --embed "~/.ios/DEV.mobileprovision"
<snip>
error: Failed to read entitlements from '/var/folders/zs/j2hmt69n12sbjm6gyn0m_q4c0000gn/T/tyYvYPQKf3/Payload/MyApp.app'
Update 1:
This SO question helped in one regard. I don't know how the active scheme (I'm not really sure what that means, but that's the tooltip when I hover over the control) got changed as part of specifying keys/etc, but clearly it did. Changing this back to an iOS Device, like iPhone, allows me to build my project, and even Archive (which, to the best of my understanding, means it's creating the .ipa file I need to submit to the app store), but I can't find the archived file. Where should it be? Can I define this in a setting somewhere in Xcode?
Update 2:
By fiddling with certificates and provisioning profiles I've finally been able to create an archive from Xcode, which I've been told is a release build (is it?). Ideally I would like to be able to build from the command line so that I can automate it as much as possible, so that's where I'll be picking up in the morning. Any advice on that front would be quite welcome!
If you managed to create an archive in Xcode, then your signing certificate and provisioning profiles are known to Xcode, so cordova build ios --release --device should make it.
The steps are:
1) Import your iOS developer certificate for production to the keychain by downloading and double clicking on it in Finder (or get it via Xcode)
2) Download your provisioning profile (with the App ID set to the id attribute of the widget element in config.xml) and double click it on Finder so it goes to the Xcode provisioning profile store
3) cordova build ios --release --device
it looks like you're trying to sign the app with a wildcard provisioning profile (the XCode screenshot). Can you try creating and downloading a distribution certificate and provprofile to your Mac? Then import the .cer file in the keychain access app (doubleclicking should suffice) and doubleclick the provprofile as well.
Now you should be able to select the appropriate values from the release dropdowns in the XCode build settings.
Hope this helps somewhat...
Eddy
One other issue I am seeing from your screenshot is I don't think you can Build an Archive (Release) version using the Developer Signing Idenetity, you would need to create a Distribution certificate and use that one for the Release (Archive) version.
So when I am trying to build my code from xcode terminal it is failing and giving me an error of 'Cordova/CDVViewController.h' file not found but when I am building this from xcode then it is building just fine.
In my Xcode, I've done the whole Cordova sub directory thing Upgrade Cordova. Also when I ran list. This is what I see below:
xcodebuild -list
Information about project "myProject":
Targets:
myProject
Build Configurations:
Debug
Release
If no build configuration is specified and -scheme is not passed then "Release" is used.
Schemes:
myProject
CordovaLib
Environment: Xcode5, OS 10.8.5
Is there anything I am missing? The reason why I am doing this because I am trying to run this through jenkins. I thought it was a jenkins issue but then I got it down to the xcode terminal not seeing the CordovaLib.
I've spent too much time figuring out the solution for this so it is a shame not to share. There can be many possible reasons why this problem arise but if you feel like you've set up everything right in the CordovaLib (like me!) and still has the same problem. This can be one of the causes. What's happening is when I ran the
xcodebuild -scheme myProject -configuration "Release"
it is building successfully, but if you don't supply "-scheme" it it will fail by default it is using the "Release". The parameters of the scheme will control which targets are built and how they are built, myProject scheme contains the subfolder and reference to Cordovalib.
Now, moving to Jenkins, is you need to supply the scheme in the "Xcode Schema File" text box in the Advanced Xcode build options section of the XCode Plugin.
My set-up is Xcode as my slave but this may still apply to whatever Xcode and Jenkins combination you have - so when I ran the
xcodebuild -list
I receive the message the following message:
If no build configuration is specified and -scheme is not passed then "Release" is used.
This project contains no schemes.
The solution for this is, in your xcode project, go to Product|Scheme|Manage Scheme and checked "Shared" to both projects myProject and CordovaLib. Compile. Check-in (because I am grabbing this from TFS). Ran again the "-list" command and you will see the schemes that you just shared.
Hope this helps!
Thanks a lot !
Just adding "-scheme" and "-configuration" parameters fixed the problem for me.
If it can help someone else, here is the full command line i used :
xcodebuild -scheme MyProject -configuration "Release" -arch i386 -sdk iphonesimulator7.1
I used it to generate a ios simulator build in order to submit an Phonegap / Cordova application to the Facebook Review
In build settings
add this item to "Header Search Path"
$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include
I see this mentioned in multiple places "only do X during install" but in XCode 4.5 I don't even see an "install" option. Is this something to do with preparing an app for distribution, or something to do with copying the App into simulator/device for testing?
An official link covering this would be great... my web searches aren't turning up much definitive.
For iOS apps, the install step is executed during Archive (or by running xcodebuild install), and installs the package into INSTALL_PATH (Installation Directory) under DSTROOT. The archive step overrides DSTROOT to point into the package it's creating.
It's controllable using the "Skip Install" option (SKIP_INSTALL in xcconfig). This should generally be No, since you do want to install the package during archiving.
It is unusual to configure the installation step on iOS, but is more common on Mac if you need to build a package installer.