Home > Mac administration, Packaging, Scripting, Xcode > Building a Grand Unified Xcode 5.0 installer for Mountain Lion

Building a Grand Unified Xcode 5.0 installer for Mountain Lion

Apple has released Xcode 5.0 through the Mac App Store for all Macs running 10.8.4 and higher. The command line tools can be installed separately through the Xcode preferences, in the Downloads section. You now need an Apple Developer Connection account to install the Xcode 5 command line tools via the Xcode preferences, though a free ADC membership is sufficient.

For my users who are developers, I wanted to include Xcode 5.0 in their new machine builds and also install the command line tools automatically without needing to enter an Apple ID. I also wanted to build this installer as a flat package, so I’m shifting from my previous method using Iceberg to using Packages to build the installer package. See below the jump for the details.

Download Xcode 5.0 from the Apple Developer site and drag the application into /Applications.

Download the latest Mountain Lion Command Line Tools for Xcode disk images from the Apple Developer site.

Verify that the permissions on the Xcode application in /Applications are correct by running the following command:

sudo chown -R root:wheel /Applications/Xcode.app

Screen Shot 2013-09-20 at 11.01.53 AM

 

Set up a new Packages project and select Raw Package.

Screen Shot 2013-09-20 at 10.27.14 AM

In this case, I’m naming the project Xcode 5.0.

Screen Shot 2013-09-20 at 10.28.47 AM

Click on the Settings tab and set the following:

In the Post-Installation Behavior section, set On Success: to Do Nothing

In the Options section, check the box for Require admin password for installation.

Screen Shot 2013-09-20 at 12.22.19 PM

 

Click on the Payload tab, then click on the Applications folder in the listing.

Screen Shot 2013-09-20 at 11.08.47 AM

Go to the Hierarchy menu and select Add Files…

 

Screen Shot 2013-09-20 at 10.32.15 AM

 

Select the Xcode application in /Applications


Screen Shot 2013-09-20 at 10.33.33 AM

 

Verify that it’s now showing up under Applications in your Packages project.

Screen Shot 2013-09-20 at 10.34.14 AM

Click on the Scripts tab in your Packages project.

Screen Shot 2013-09-20 at 11.10.50 AM

Select the Mountain Lion Command Line Tools for Xcode disk image and drag it into the Additional Resources section of your Packages project.

Screen Shot 2013-09-20 at 10.36.34 AM

The last pieces are removing any previous Xcode.app from /Applications and telling the Command Line Tools for Xcode installer to run.

To remove any previous Xcode.app from /Applications, I’m using the following preinstall script:


#!/bin/sh

# Remove existing /Applications/Xcode.app from machine

if [ -d /Applications/Xcode.app ]; then
  rm -rf /Applications/Xcode.app
fi

To install the command line tools, I’m using the following postinstall script:


#!/bin/bash

# Determine OS version
osvers=$(sw_vers -productVersion | awk -F. '{print $2}')

# Determine working directory

install_dir=`dirname $0`

if [[ ${osvers} -eq 8 ]]; then

#
# Installing the Xcode 5.0 10.8 Command Line Tools
#

# Create /tmp/Command Line Tools (Mountain Lion) mountpoint in /tmp

  /bin/mkdir "/tmp/Command Line Tools (Mountain Lion)"

# Mount the latest command line tools disk image as /tmp/Command Line Tools (Mountain Lion)

  /usr/bin/hdiutil attach "$install_dir/command_line_tools_os_x_mountain_lion_for_xcode__september_2013.dmg" -mountpoint "/tmp/Command Line Tools (Mountain Lion)" -nobrowse -noverify -noautoopen

# Install the Xcode command line tools

  /usr/sbin/installer -dumplog -verbose -pkg "/tmp/Command Line Tools (Mountain Lion)/Command Line Tools (Mountain Lion).mpkg" -target /

# Clean-up

# Unmount the command line tools disk image from /tmp/Command Line Tools (Mountain Lion)

  /usr/bin/hdiutil eject "/tmp/Command Line Tools (Mountain Lion)"

# Remove /tmp/Command Line Tools (Mountain Lion) from /tmp

  /bin/rm -rf "/tmp/Command Line Tools (Mountain Lion)"

fi

Once you’ve got the preflight and postflight script built, run the following commands to make the scripts executable:

sudo chmod a+x /path/to/preinstall
sudo chmod a+x /path/to/postinstall

Once completed, add the preinstall and postinstall scripts to your Packages project.

Screen Shot 2013-09-20 at 10.39.13 AM

Last step, go ahead and build the package. (If you don’t know to build, check the Help menu for the Packages User Guide. The information you need is in Chapter 3 – Creating a raw package project and Chapter 10 – Building a project.)

Testing

Once the package has been built, test it by taking it to a test machine running 10.8.4 or 10.8.5 that doesn’t have Xcode 5.0 and install it. The end result should be that Xcode 5.0 installs along with the Xcode command line tools without requiring an Apple ID.

  1. September 20, 2013 at 11:21 am

    Just curious as to a) whether the _MASReceipt makes updating problematic with Xcode like it is with iLife apps, and b) why you choose to package the dmg of the command line tools rather than the pkg it contains?

    • September 20, 2013 at 11:33 am

      Ben,

      If you get Xcode 5 from the Apple Developer site (instead of getting it from the App Store), there isn’t a _MASReceipt included with ADC’s Xcode 5. That avoids the issue of the Xcode 5 installation being tied to a particular Apple ID.

      The reason I packaged the .dmg instead of just using the command line tools’ metapackage is because there’s two ways to build a metapackage.

      The first way is with all of the installer packages stored inside the metapackage, so that everything you need is copied over when you copy the metapackage to a new location.

      The second way is to have the installer packages stored outside the metapackage, and that’s the situation here. The metapackage is actually referencing installer packages stored in an invisible directory on the disk image named Packages. By mounting the disk image and running the metapackage from the disk image, the install can run properly because the metapackage can access the installers in that hidden directory.

  2. September 20, 2013 at 11:50 am

    What great timing! I have to do this today for our Gatton Academy students!

  3. Erik
    September 20, 2013 at 11:14 pm

    Great write up, but couldn’t you use Munki to package the app/do permissions and then add a update_for for the tools? You could also add a pre_install script for the removal of the old Xcode.

    • September 21, 2013 at 7:01 am

      Erik,

      That’s true, you could do that with Munki’s capabilities. However, not everyone uses Munki in their environments.

      Building an Xcode installer using this method allows Xcode 5 to be deployed with a variety of solutions. If your preferred deployment tool can push an installer package, Xcode 5 can be installed this way.

  4. September 21, 2013 at 12:25 pm

    Hi Rich,

    I’ve been using Packages for about a year now and I have a few notes that should simplify your instructions and maybe entice those who who think this is too complex.

    1) Setting the permissions on Xcode.app is not required beforehand. “sudo chown -R root:wheel /Applications/Xcode.app” is unneccesary. Packages sets those permissions by default when you add the app, and is easy to modify by clicking on the app inside Packages and using the GUI.

    2) To make this package more configurable in its target location, I have found it useful to use $3 in paths. I would rewrite the preinstall script as:
    #!/bin/sh

    # Remove existing /Applications/Xcode.app from machine

    if [ -d “$3/Applications/Xcode.app” ]; then
    rm -rf “$3/Applications/Xcode.app”
    fi

    3) In the Additional Resources section, if you add the PKG file that is contained inside the DMG, you can simplify your postinstall script significantly.
    – You will not need to know the install directory, eliminating the “install_dir=`dirname $0`” command.
    – Files inside this directory are placed in a subdirectory inside /tmp already, rendering “/bin/mkdir “/tmp/Command Line Tools (Mountain Lion)” unneccesary.
    – You won’t have to mount or detach the DMG, eliminating both “hdiutil” commands.
    – The postinstall script will run from the same directory as the Additional Resources files, so you do not need to reference the PKG with a path.

    I would rewrite the postinstall script as:
    #!/bin/bash

    # Determine OS version
    osvers=$(sw_vers -productVersion | awk -F. ‘{print $2}’)

    if [[ ${osvers} -eq 8 ]]; then

    #
    # Installing the Xcode 5.0 10.8 Command Line Tools
    #

    # Install the Xcode command line tools
    /usr/sbin/installer -dumplog -verbose -pkg “Command Line Tools (Mountain Lion).mpkg” -target “$3”

    # Remove /tmp/Command Line Tools (Mountain Lion) from /tmp
    /bin/rm -rf “Command Line Tools (Mountain Lion).mpkg”

    fi

    3) Packages will make the preinstall and postinstall scripts executable during the build process, so you can skip “sudo chmod a+x /path/to/preinstall” and “sudo chmod a+x /path/to/postinstall” as well.

    Thank you for everything you do. Your site, among others, really helped when teaching myself how to manage macs.

    -Scott

  5. September 23, 2013 at 9:36 am
  6. MiqViq
    September 25, 2013 at 5:46 am

    I may be sidetracking here but have you been trying to update docsets?

    I am using OS X 10.8.4-10.8.5 and Xcode from ADC.

    I downloaded updated docsets, expanded installer packages, modified the install-path to /Applications/Xcode.app/Contents/Developer/Documentation/DocSets.
    Docsets are installed nicely to /Applications/Xcode.app/Contents/Developer/Documentation/DocSets but for some reason Xcode 5.0 will not recognize these new docsets installed.
    It will only see those that are in user’s ~/Library/Developer/Shared/Documentation/DocSets.

    I found out that Xcode recognized the updated docsets if I left the receipts of updated docsets in user’s ~/Library/Developer/Shared/Documentation/DocSets/Library/Receipts.

    Also keeping the receipts of updated docsets in /Applications/Xcode.app/Contents/Developer/Documentation/DocSets/Library/Receipts and symlinking
    ln -s /Applications/Xcode.app/Contents/Developer/Documentation/DocSets/Library ~/Library/Developer/Shared/Documentation/DocSets/Library
    works, although with symlink there may be issue when trying to update docsets in the future if user has no write permissions in /Applications/Xcode.app/Contents/Developer/Documentation/DocSets/Library.

    There is probably some settings file somewhere which keeps track of docsets in /Applications/Xcode.app/Contents/Developer/Documentation/DocSets?

    -MiqViq

  7. Peter Langone
    October 3, 2013 at 8:32 pm

    Thanks, your posts have been very helpful to me, especially the packaging ones. I do have a question/thought/suggestion:

    Why have the postflight check for OS X 10.8.x before trying to install the command line tools? I would guess that Xcode.app will get copied over OK, but maybe won’t run? I’m not sure if the CL tools installations would blow up if you tried them on the wrong OS version or not.

    I would suggest adding a requirement of the package to have 10.8.4 or greater. I am doing this via Iceberg, requiring system version >=4228.

    I found this a long time ago to help me with this: http://codeblog.vurdalakov.net/2011/03/how-to-check-mac-os-x-version-in.html

    (1084 in hex converted to decimal is 4228)

    I’m also glad we don’t have to run those two other small packages inside of the Xcode app anymore in order to get a complete install.

    • October 3, 2013 at 8:36 pm

      Peter,

      The OS check is there because the Command Line tools installation is OS-specific.

      • Peter Langone
        October 3, 2013 at 9:32 pm

        But so is Xcode 5.0, right? As far as I know, it only runs on 10.8.4+ or 10.9.

      • October 3, 2013 at 10:42 pm

        Correct, but the command-line tools are currently specific to 10.8.x. When 10.9 comes out, you will likely see a separate command-line tools installer for that version of the OS.

  8. PE
    November 6, 2013 at 10:21 am

    @rtrouton any suggestions for Mavericks? try to get it work with Mavericks but i get an installation error thanks

  1. No trackbacks yet.

Leave a reply to SutoCom Cancel reply