xcodebuild command line hangs - xcode

The following command hangs on my osx:
xcodebuild -scheme myscheme clean archive -archivePath /tmp
This command yields two output lines, and then hangs:
User defaults from command line:
IDEArchivePathOverride = /tmp
Now, this project does NOT have a workspace generated as it was created from a cordova command line (cordova build ios). The only way around it is to open xcode and close it. this generates a workspace and then the above command succeeds.
Did anyone experience something similar and know a way out of this? Any way to generate that workspace from the command line?

I had the same problem and the only way of fixing it was to open the project from the command line, wait, and close it again after a certain time.
open "My Project.xcodeproj"
sleep 10
killall Xcode
xcodebuild -scheme "My Project" clean archive "build/MyProject"
Not nice, but works for me.

Try setting the scheme to be 'shared'.
This can be done by going to the 'Manage Schemes...' and checking the 'Shared' checkbox.
Apple documents this process here: https://developer.apple.com/library/ios/recipes/xcode_help-scheme_editor/Articles/SchemeShare.html

If you're already have, or are willing to make, Ruby available to your build system then you could use this solution.
Install the xcodeproj gem on your build system
sudo gem install xcodeproj
and then integrate the following ruby script into your project (renaming your xcodeproj path).
#!/usr/bin/env ruby
require 'xcodeproj'
xcproj = Xcodeproj::Project.open("platforms/ios/schemedemo.xcodeproj")
xcproj.recreate_user_schemes
xcproj.save
The article explains how to make it part of a cordova hook if you're doing that, I simply called ruby directly from my Jenkins build.
This works because when you recreate the proj files, you destroy the schemes, so you need to recreate them.

I believe xcodebuild hangs because some data is missing from the project. You can make a template for what this data looks like and use a hook to populate it if necessary.
cordova add platform ios
cordova build ...
open platforms/ios/Whatever.xcodeproj in xcode
create xcuserdata_template
cp -R platforms/ios/Whatever.xcodeproj/xcuserdata xcuserdata_template/
replace the unique id in that template with XXXXXXXXXX
update your hook that runs xcodebuild
Step 7 example:
XCODE_PROJ=path/to/Whatever.xcodeproj
# get the mysterious id
ID=`grep "Whatever \*\/ = {" $XCODE_PROJ/project.pbxproj | \
grep -io "[-A-Z0-9]\{24\}"`
mkdir -p $XCODE_PROJ/xcuserdata
XCUSERDATAD=$XCODE_PROJ/xcuserdata/`whoami`.xcuserdatad
if [ ! -d "$XCUSERDATAD" ]; then
cp -R path/to/xcuserdata_template/username.xcuserdatad \
$XCUSERDATAD
find $XCUSERDATAD -type f -exec sed -i '' -e "s/XXXXXXXXXX/$ID/g" {} \;
fi
xcodebuild ...

Related

Xcode Command Line Tool project. Path to the command?

Using Xcode 14.0.1, I am working on a Command Line Tool project.
As long as the command takes no argument it can be run and tested with the Xcode run button.
But I now want to use some arguments, I therefore need to run the command from a terminal.
Here comes my question:
How do I find the path for the command?
Edited because I misread the original question (see comments):
xcodebuild -project yourproj.xcodeproj -showBuildSettings from the location of your project should have that information. Might want to add a | grep TARGET_BUILD_DIR to filter for the output directory. It should be ~/Library/Developer/Xcode/DerivedData/projectname-[random-string]/Build/Products/Debug.
Previous answer about Xcode command line tools:
They should be under /Library/Developer/CommandLineTools/usr/bin, but xcodebuild and xcrun at /usr/bin, so should be in your PATH automatically. You can find out for sure with xcode-select --print-path.

Creating a skeleton project directory

I am a rookie in Python who has been working on Learn Python the Hard Way. This whole process goes well as I have a smattering knowledge on Python until I march into ex46 where I get stuck in the 'Creating the skeleton Project Directory' section. I have no idea where I should run those commands guided on this book. Following are the excerpt of this part:
First, create the structure of your skeleton directory with these commands:
$ mkdir projects
$ cd projects/
$ mkdir skeleton
$ cd skeleton
$ mkdir bin
$ mkdir NAME
$ mkdir tests
$ mkdir docs
I have tried to run these commands in Windows Powershell, only to be warned that these commands can’t be recognized. I also fumbled to execute them in Pycharm, but all in vain. Could someone point out how I could get it done?
In addition, I am somewhat curious about this method because there seems to be handy way to approach this on Pycharm. Could I achieve the same goal on that?
I am using Python 2.7 and all previous exercises operate well until ex46.
You get that error because you're typing a superfluous $ at the beginning of each command. That $ is the (Linux) command prompt. On your Windows machine, it's something like C:\WINDOWS\system32>. Don't type that.
Just type
mkdir projects
and press Enter. That creates a folder (directory) named "projects". Then type
cd projects
and press Enter. That changes the current directory to that new folder you just created. And so on.
Content migrated from comments since this is what actually solved the issue.
Remove the dollar sign $ from the statement, as this is just the symbol used as a CLI prompt not part of the statement itself.
Then type the mkdir command and it should work e.g.
mkdir my_directory

How to uninstall Xcode 5 command line tools (Mac OS X 10.9 Mavericks)? [duplicate]

I upgraded to xcode 5 Command Line Tools on Friday. Something is not working correctly and I want to go back to the last 4.x version ox xcode. How do I uninstall xcode 5 command line tools? I don't see anything in the release notes.
Depending on whether you are running Xcode 5 in Mavericks or not, you will need to do two different things to uninstall the command line tools.
In Mavericks, Xcode includes its own copy of the Command line tools (i.e. they are bundled as part of Xcode.app). Therefore, uninstalling the Xcode (check instructions below) will remove the Command line tools too.
For older Mac OSX versions running Xcode 5 or older versions (Xcode 4.x), you can find previous SO answers which explain how to uninstall Xcode's command line tool. You can use this script (Read more about it in this post):
# remove_CLI_tools.sh
# written by cocoanetics:http://www.cocoanetics.com/2012/07/you-dont-need-the-xcode-command-line-tools/
# modified by yoneken
#!/bin/sh
RECEIPT_FILE1=/var/db/receipts/com.apple.pkg.DevSDK.bom
RECEIPT_PLIST1=/var/db/receipts/com.apple.pkg.DevSDK.plist
RECEIPT_FILE2=/var/db/receipts/com.apple.pkg.clang.bom
RECEIPT_PLIST2=/var/db/receipts/com.apple.pkg.clang.plist
RECEIPT_FILE3=/var/db/receipts/com.apple.pkg.llvm-gcc4.2.bom
RECEIPT_PLIST3=/var/db/receipts/com.apple.pkg.llvm-gcc4.2.plist
RECEIPT_FILE4=/var/db/receipts/com.apple.pkg.DeveloperToolsCLI.bom
RECEIPT_PLIST4=/var/db/receipts/com.apple.pkg.DeveloperToolsCLI.plist
if [ ! -f "$RECEIPT_FILE4" ]
then
echo "Command Line Tools not installed."
exit 1
fi
echo "Command Line Tools installed, removing ..."
# Need to be at root
cd /
# Remove files and dirs mentioned in the "Bill of Materials" (BOM)
lsbom -fls $RECEIPT_FILE1 $RECEIPT_FILE2 $RECEIPT_FILE3 $RECEIPT_FILE4 | sudo xargs -I{} rm -r "{}"
# remove the receipt
sudo rm $RECEIPT_FILE1 $RECEIPT_FILE2 $RECEIPT_FILE3 $RECEIPT_FILE4
# remove the plist
sudo rm $RECEIPT_PLIST1 $RECEIPT_PLIST2 $RECEIPT_PLIST3 $RECEIPT_PLIST4
echo "Done! Please restart XCode to have Command Line Tools appear as uninstalled."
You can run this easily by opening a Terminal and running this command (it will download the script and execute it automatically):
curl "https://gist.github.com/yoneken/3284561/raw/db665bb64f93e38ce138b5ca620b9edd18dc31e4/remove_CLI_tools.sh" | sh
If everything worked fine, you could open Xcode and see that the Command Line Tools appear as to be installed.
Then, depending on what you want, you could downgrade Xcode to a lower version and reinstall the Command Line Tools for that version, for example.
To downgrade Xcode, as explained in this SO answer:
Uninstall Xcode 5: go to /Applications and delete the Xcode app.
Restart the Mac.
Then you can download the desired Xcode version from here and install it from scratch.
I stumbled upon this while trying to uninstall Command Line Tools v6.
I had the full Xcode 6 installed, but moving Xcode to trash did NOT uninstall/delete CLT as well. I still had /usr/bin/clang for example. The solution was to manually remove CLT using the .bom contents (similar to #veducm's answer):
cd /
lsbom -fls /var/db/receipts/com.apple.pkg.CLTools_Executables.bom | sudo xargs -I{} rm -rf "{}"
lsbom -fls /var/db/receipts/com.apple.pkg.DevSDK_OSX109.bom | sudo xargs -I{} rm -rf "{}"
sudo rm /var/db/receipts/com.apple.pkg.{CLTools_Executables,DevSDK_OSX109}.{bom,plist}
Replace DevSDK_OSX109 with the version you have. You may have multiple ones, in which case, apply the same command to all of them (e.g. I had both DevSDK_OSX109 and DevSDK_OSX1010 because I had installed CLT for Mavericks and Yosemite too).
NOTE: This will delete the files listed in the .bom. You can view the contents them first by doing just lsbom -fls /var/db/receipts/com.apple.pkg.CLTools_Executables.bom etc if you are unsure.
NOTE2: You need the cd / since paths reported by lsbom are relative. You can also remove CLT by simply doing rm -rf /Library/Developer/CommandLineTools.
The rm command removes (deletes) files or directories.
Delete CLT from following command
sudo rm -rf /Library/Developer/CommandLineTools
from terminal.

How to run xcode from terminal?

My question is very simple: suppose there is an xcode project a.xcodeproj, could I open it with the command: xcode a.xcodeproj?
If I try this, I receive the following error message:
-bash: xcode: command not found
Xcode should be the default application for .xcodeproj files, so this should work:
$ open a.xcodeproj
If that opens a different application, you can force it to use xcode:
$ open -a Xcode a.xcodeproj
If you want the command xcode to work, you can just alias it:
$ alias xcode="open -a Xcode"
then you can just xcode a.xcodeproj (and add this to ~/.bash_profile)
You could also simply run xed . in the project's root directory, apparently it will try to load a project in a hierarchical manner, i.e. the first that exists:
the folder, if it's a Package (Xcode 11+)
xcworkspace
xcodeproj
playground
which means you don't need to verify yourself the existing file structure in order to choose the best one to open.
Can't remember where I came across this script, but I use this ruby script for finding either a *.xcodeproj or *.xcworkspace file in the working directory and opening that file (without Xcode opening any previous projects)
#!/usr/bin/env ruby
# Open xcode without any previous projects being opened as well.
# We first look for a workspace, then a project in the current directory, opening the first that is found.
f = []
f.concat Dir["*.xcworkspace"]
f.concat Dir["*.xcodeproj"]
if f.length > 0
puts "opening #{f.first}"
`open -a /Applications/Xcode.app #{f.first} --args -ApplePersistenceIgnoreState YES`
exit 0
end
puts "No Xcode projects found"
exit 1
Following command should do it:
open a.xcodeproj
open terminal, then go to the path where Xcode is installed. Then, go to its "Contents/MacOS". And when you reach this folder, then type - sudo ./Xcode
Or else follow the following code: (you can use "sudo" if the user has privilege issue)
cd /
cd Applications
cd Xcode.app
cd Contents/MacOS
sudo ./Xcode
incase, if you want to open a Xcode project from a workspace use the following command line.
user$ open -a xcode ProjectName.xcworkspace/
I just type open *xcw*. This command looks up a workspace in the current directory and then opens is with Xcode.
I have a few functions in my .zshrc that accomplish what you're looking for:
cap () { tee /tmp/capture.out; }
ret () { cat /tmp/capture.out; }
x () {
# Substitute .xcworkspace with .xcodeproj for your case.
find . -type d -name "*.xcworkspace" -d 1 | cap
xed "$(ret)"
}
Then, from the same directory as your *.xcodeproj, simply execute x, e.g.:
$ x

Building distribution Installer package (.pkg) with postflight script without requiring authentication

I'm using the new domain feature of PackageMaker (introduced for Mac OS 10.5) to target the user home directory. I have created a .pmdoc file in PackageMaker.app, and everything works perfectly until I add my post-install script. Then, suddenly, my package wants root authorization when it didn't before. I've tried building from the command-line using packagemaker --doc mypackage.pmdoc --info Dist/PackageInfo supplying a tweaked PackageInfo file that explicitly specifies auth="none", but this doesn't work. When I investigate the output package by extracting it with xar -xf package.pkg, authentication seems to be specified in package.pkg/Distribution, an XML file that packagemaker generates for itself.
Due to frustration with the GUI, I've switched to using only packagemaker on the command line. However, now my packages don't display my user interface files (although they are included in the .pkg archive), and still demand root authentication. The offending line in the generated Distribution file is (notice auth="Root"):
<pkg-ref id="org.myUniqueID.pkg" installKBytes="12032" version="1.0" auth="Root">#grooveshark.pkg</pkg-ref>
This is how I run packagemaker:
packagemaker -r ./Grooveshark -f ./Dist/PackageInfo -s ./Dist/Scripts -e ./Dist/Resources -v --domain user --target 10.5 --no-relocate --discard-forks --no-recommend -o ./out.pkg
This is the layout of Dist:
Dist/Distribution # this isn't used by packagemaker, it generates its own
Dist/PackageInfo
Dist/Resources/en.lproj/background
Dist/Resources/en.lproj/License
Dist/Resources/en.lproj/ReadMe
Dist/Resources/en.lproj/Welcome.rtfd
Dist/Resources/en.lproj/Welcome.rtfd/gsDesktopPreview-mini.png
Dist/Resources/en.lproj/Welcome.rtfd/gsDesktopPreview-searchSmall.png
Dist/Resources/en.lproj/Welcome.rtfd/TXT.rtf
Dist/Scripts/jsuuid # specified as a postinstall in Dist/PackageInfo
Dist/Scripts/postflight
How can I configure my package so it will run a postinstall script without demanding root authentication? Is there some way I'm missing to specify both a PackageInfo file and a Distribution install-script XML file via the command line?
I ended up moving files int place in a distribution layout, then I used the following script to first build a traditional flat package, then expand it, copy in the settings that allow for per-user installation, then use a different process to compact it in-place, without processing, back into a PKG.
#!/usr/bin/bash
# Build Package for local install using witchcraft
PROJECT="some/filesystem/location/with/your/files"
BUILDDIR="$PROJECT/Dist/build"
PKGROOT="$PROJECT/Dist/Package_Root"
INFO="$PROJECT/Dist/PackageInfo"
DIST="$PROJECT/Dist/Distribution"
RESOURCES="$PROJECT/Dist/Resources"
SCRIPTS="$PROJECT/Dist/Scripts"
# Remove .DS_Store files
find "$PKGROOT" -name ".DS_Store" | sed 's/ /\\ /' | xargs rm
# make build dir
mkdir "$BUILDDIR"
# build flat package that needs root to install
packagemaker -r "$PKGROOT" -f "$INFO" -s "$SCRIPTS" $ARGS -o "$BUILDDIR/flat.pkg"
# Build distribution that installs into home dirs by unpacking the flat pkg
echo "Building Distribution"
echo " Copying filesystem"
cp -r "$RESOURCES" "$BUILDDIR/Resources"
cp "$DIST" "$BUILDDIR/Distribution"
echo " extracting flat package"
pkgutil --expand "$BUILDDIR/flat.pkg" "$BUILDDIR/grooveshark.pkg/"
rm "$BUILDDIR/flat.pkg"
echo " flattening distribution"
pkgutil --flatten "$BUILDDIR" "$PROJECT/$1.pkg"
echo "Finished!"

Resources