35

Duplicating a target in Xcode is a great way to create multiple app or framework/library products that have somewhat different features using the same codebase as a result of conditional code controlled by environmental variables set within the target build settings or related schemes. First duplicate your known-working basic version, then set the environmental variables each target will use, then start splitting up your code behavior with inline preprocessor #ifdef statements.

However, any duplicated target will be named "Original Target Name copy". This can be renamed, but the info.plist will also have this name, it may also appear in a couple of essential build settings, and it can be a tedious and error-introducing process to remove all references to the non-informative "copy" version of the duplicated target name depending on how you do it. When I create iOS frameworks this seems to be especially prone to introducing issues.

My question is whether there is any technique for duplicating a target which allows you to specify the new target name at the time of duplication, so there is never a temporary wrong target name or any files being created which contain that temporary wrong name. Or, alternately, if there is some way to use the "refactor" functionality to fix this is an automated way.

If there is some kind of wrong assumption contained within the question that explains why this feature hasn't been included in Xcode, let me know. I'm using 4.3.

john.k.doe
  • 7,474
  • 2
  • 35
  • 63
Halle
  • 3,557
  • 1
  • 33
  • 53

5 Answers5

6

Unfortunately, I'm pretty darn sure there's not any current UI for this, although I strongly agree that it would be a huge improvement; I can't speak for everyone, but I pretty much never want a target named Foo copy. I would suggest filing a Radar.

ipmcc
  • 28,584
  • 4
  • 78
  • 135
  • 1
    Since the only answer which is a concrete technical solution is to use CMake, which is interesting and informative but probably not practicable for many developers and may have fragile aspects with the interaction between the custom generated build system and Xcode's changing implementations, I am marking this one best in the hopes that it will encourage more radars on this. – Halle Feb 26 '14 at 09:20
0

You could, with some effort, use CMake for that. It's a build system generator.

It may be difficult at first to learn and setup the project, and some things are (currently) not easily possible for Xcode (like resource adding) but it would make creating new targets with a basic configuration very easy.

Basically, you write CMakeLists.txt files in your source tree to define your libraries and targets, then define the source files, etc., then generate the Xcode project each time.

Adding a new target would be very easy:

  1. ADD_EXECUTABLE( Target_Name Source_Files )
  2. SET_TARGET_PROPERTIES( Target_Name PROPERTIES COMPILE_DEFINITIONS Your_Additional_Defines )
  3. Rerun CMake. (Its not even required to close the Xcode project)

Disadvantages:

  • Takes time to setup.
  • Sometimes research is necessary to get some things to work
  • Some things are currently not well supported via CMake
ipmcc
  • 28,584
  • 4
  • 78
  • 135
ecreif
  • 1,124
  • 1
  • 11
  • 24
  • +1 I had no idea CMake could generate Xcode projects! Re: Step 3 -- Changing project files behind Xcode's back (i.e. without closing the project and/or quitting Xcode) can lead to weird, hard-to-diagnose misbehaviors. I always suggest *at least* closing the project, and for minimum misery, quitting Xcode all together. – ipmcc Feb 14 '13 at 13:20
  • Yep you might be right, better not to blindly trust XCode :). But at least I did not yet encountered problems by doing those "live" cmake reruns in the background. – ecreif Feb 14 '13 at 13:28
  • shoot, i hate to be a wet blanket on this, but the way you describe this, the "some effort" you are telling me i would have to do combined with the "some things are currently not well supported via CMake" plus the "Sometimes research is necessary to get things to work" sounds like more effort than the tedious, error-prone steps i'm trying to avoid. i'm having a hard time buying that the time and effort i would have to put in to learn CMake and do the setup wouldn't be otherwise better spent doing what i do know by hand, since i don't really do it that often. – john.k.doe Feb 15 '13 at 03:08
  • I gave you a way to duplicate faster than your method, just copy the lines, give your target a name and your target is cloned. I don't know the complexity of your project, if it is simple or you do not need to change it much over the time, a one time setup with CMake can safe you time. I found it very easy to learn. But I can understand you, you have to duplicate your target very often until you really start to benefit. The "necessary research sometimes" and not supported features depend on how "deep" you go into special XCode things. For most of these things there are workarounds around. – ecreif Feb 15 '13 at 11:03
-1

In Xcode 6 (not sure about earlier versions) duplicating a target will still generate the " copy" appendage and rename all localized menus for example. But, it is reversible by updating the Product Name under Packaging in Build Settings / All. Info.plist will still have to be taken care of as well as Scheme naming though.

caxix
  • 1,064
  • 1
  • 12
  • 23
-3

Doubleclick on the target to at least rename thetarget ... still looking to rename the product, but that's not so important if you can rename everything else (like the displayname etc))

MacD
  • 763
  • 7
  • 19
-4
  • select project in Navigator panel
  • select Target you want to duplicate
  • right mouse click and choose "Duplicate"
  • Rename Target in XCode: click on selected Target and inline edit starts.
  • Open Terminal and go to your project directory/folder
  • Run svn status to see the changes XCode just has made.
  • XCode has created new Infocopy.plist file and has added under version control if you use one. Typically you want to choose different name so follow these steps:
  • Cancel version control addition: $> svn revert Infocopy.plist
  • Rename it: $> mv Infocopy.plist YourNameInfo.plist
  • Add it to version control: $> svn add YourNameInfo.plist
  • Set the new name in your new Target Build Settings named "Info.plist File"
  • Rename target file properly: $> mv OrigTargetCopy.xcscheme YourTargetName.xcscheme
  • Add the new target file under version control: $> svn add YourTargetName.xcscheme
  • Rename you Product in your new Target Build Settings named "Product Name"
  • Very likely you will also want to set new "Preprocessor macros" Build Settings for your new Target.
  • Set proper values your YourNameInfo.plist
  • Set Target assignment for target specific files. Typically YourNameInfo.plist shall be part only of you new target. There may be plenty of other similar files (icon, splash screen, other graphics, etc).
Solorzano Jose
  • 572
  • 2
  • 6
  • 17
  • it's like the person who posted this answer read neither the title, the content of the question posted by the original author, nor the bit in the details of the bounty about looking for a 1 or 2 step way to do this. the solution described by the author, and the solution i've been using … both take fewer steps than this now. this is worse than what we're already doing, not better. – john.k.doe Feb 08 '13 at 02:24
  • This solution does not seem to account for every reference to the old name that I usually encounter in project.pbxproj. – Halle Feb 08 '13 at 08:09