One of the FAQs of Xcode is “Why is Save As… disabled for my project file?” Or, put more bluntly, how do you duplicate or rename a project? It seems such an obvious omission in an ostensibly document-based Mac application.

The motivations to copy or rename a project are clear, but there are several different ones. Some want to rename the project because Marketing picked a new product name, or because the project with a code name now has a real one. Some want to archived finished project A and begin project B based on its skeleton. Some want to fork project A into a new project A-prime to do parallel development.

And at the root is a fundamental confusion about the naming of three different things: your product, the target that builds it, and the project that contains them. When you create a New Project from the template, Xcode only asks you for one name. It uses that name in dozens of different places.

It creates a directory with that name to put everything in.

It creates a project file wrapper with that name as the basename.

It creates a target in the project file with that name.

It creates source code files in the project with that basename.

It creates auxiliary files, like Info-plists and prefix headers, with that name.

It sets the appropriate build settings in the target to point to the auxiliary files.

It sets the product name of the target to that name, which propagates to the executable name, to Info.plist settings, etc.

In some cases it even creates strings in source files, Info.plist files, and .nib or .xib files with that name, so they appear in your application’s source code or user interface. This is in many ways a trapdoor operation: one name fans out to many uses. In some cases the relations are durable (you change the name of the product, and the executable name follows); in others, they’re unlinked (the target name, Info.plist file name, Prefix file build setting value, etc. are all independent). So it’s crucial to know beforehand what you want to change and why you want to change it, because you may not need to, or want to, change all occurrences of the original name.

For example, do you really want a different project or do you just want to change the name of the application that the project builds? You can do one, or the other, or both, but keep in mind that you can change the name of the build product (the app that the project generates) without changing the project’s own name. That’s a lot easier in itself. But let’s walk through the steps of renaming or duplicating a project.

1. Know the scope and reach of the project.

Most Xcode projects have a Project Folder (MyProject) containing a project file wrapper (MyProject.xcodeproj) and the files and directories for the source code. (Often the build folder is in there too; you can ignore it, perhaps Clean the project before starting to empty it out). If your project has sources that are peer to the project folder, you will have to take some care to find the total extent of the project. For example, you may have a MyProject folder, and inside it is a sources folder (src), a documentation folder (docs), and your Xcode project folder (Mac). The Mac/MyProject.xcodeproj project file refers to ../src/MySourceFile.m to get to its source files. You need to make sure that MyProject/ contains all the parts of your project, and maybe more importantly, doesn’t contain parts of other projects that would be damaged if you moved or renamed them.

2. Ensure the project’s self-relative integrity.

It helps to make sure that the project doesn’t have any embedded absolute paths. Try dragging the whole project folder to another directory on the same disk. If you can open it and nothing turns red, and you can build it, you’re in good shape; all your internal references are project-relative. If anything turns red, select it, Get Info, find the appropriate file, make sure the Reference Style is Relative to Project (Relative to Enclosing Group is usually good enough, and is the Default).

3. Copy and/or Rename the project folder and the project file.

Just do this in the Finder: change MyProject to MyNewProject and MyProject.xcodeproj to MyNewProject.xcodeproj. There. You’re done.

No, you aren’t. But that’s the minimum: now you can build MyProject and MyNewProject, edit their source files separately, and their builds and indexes won’t interfere with each other.

But that’s often not enough. If you want MyApp.app to be MyNewApp.app, then you need to do a little more.

4. If desired, change the Product Name in the main target’s build settings.

Open the new project, double-click the main target, choose the Build pane, and type “Product” into the search bubble. Enter the new app name into the Value column. That changes the value of PRODUCT_NAME, which is used in a lot of places in the build:

the wrapper for the built app, $(PRODUCT_NAME).app

the name of the executable inside the wrapper, $(PRODUCT_NAME).app/$(EXECUTABLE_NAME)

the executable name in the product’s Info.plist file

So in general you’ll get a new app, and when you build MyProject and MyNewProject, you’ll end up with MyApp and MyNewApp separately, even if you use a common build folder.

Remember that if you have hard-coded your bundle identifier (com.myCompany.myApp) into your source code anywhere, you need to change that in the source when you rename the Product Name.

5. And change all the strings relating to the app name in the source and the .nib or .xib files.

If you’ve changed your application name, you probably have references to it all over your source: in constant strings, in the Info.plist’s Copyright string, in string files, and (for Mac applications) in the title of the second menu in the menu bar in the nib file, the name of the About… item, and the string in the About box. You should remember to change all of these. Xcode’s Project Find can help find most of them.

6. For completeness and to reduce confusion, rename source and auxiliary files.

If you’re renaming from a code name to a final name, you may or may not want to keep the source files, class names, etc. as they are with the code name. If you’re spinning off a different project based on the old one’s source code, you probably want to change them. The Rename refactoring is your best friend here: select the class names and choose Refactor… and pick the Rename refactoring. It will change all logical references to that class, and optionally change the file and header file names too.

What it won’t pick up is auxiliary files like MyApp-Info.plist. You’ll have to rename that manually, and make sure to also change the corresponding Info.plist File build setting in the target. Same for export files, prefix files, or other non-source files referred to in your Target’s build settings.

A note about Source Code Management

If your code is under the aegis of an SCM system like Subversion, Perforce, cvs, git, Mercurial, etc. you are going to have to manage the SCM effects of every change you make. For Subversion, Perforce, and cvs, if your project is under SCM control in Xcode, file renames will be executed in the SCM system automatically, except for the renaming of the project file itself. So in step 3 above, do the rename of the project folder and project file wrapper in the SCM system instead of the Finder, then you can do everything else in Xcode. If you’re using git or Mercurial, you probably know what you have to do.

If you are spinning off a new application, you should probably export the project from the SCM system first. This ensures it’s not carrying its SCM metadata with it. (If you just do a Finder copy of MyProject/, rename it, make changes, and try to check it in, hilarity will ensue.) If you want to branch the project so that it retains the SCM history to date, but allows you to conduct separate future development on both MyProject and MyNewProject, then you should use the branching tools offered by the SCM system.

So I hope you can see why there isn’t yet a Save As… button in Xcode that does what you mean. What constitutes “renaming” or “cloning” may mean very different things to very different people, and depending on how thoroughly you’ve embedded the old name in source, filenames, build settings, string constants, etc. you may have a lot of manual work to do in order to achieve the results you want.

Update: This blog post was essentially the design spec for the Project > Rename feature in Xcode 3.2, now available in Snow Leopard. When you choose Rename, you get a dialog box that previews all the above changes, and you check which ones you want applied. Kudos to Kerry Hazelgren and Daniel Gobera for excellent implementation of this long-needed feature.