Adding files to xcode projects from command line

There are projects where building from terminal is so convenient that i’ve used it in a lot of scripts, however there is a drawback to this technique and I hope to solve it in this article, and that is drawback is

Currently there is no way of adding files to a project without opening up Xcode and doing it manually.

For automated builds this is a major drawback! Want to dump resources into your project and build from command line? Too bad your gonna have to open up Xcode and add the files to the project yourself. Want to use a separate IDE to create your .h and .m files then build the project through a script? again too bad…

I was pretty surprised at this, so I set out to research the ‘.xcodeproj’ file format and find a solution. (Hit “Read more” to continue the article)

Firstly, this may not be a surprise but the .xcodeproj file, like many files in OSX is actually just a container for many more files (right click any .xcodeproj select “Show package contents” and you will see what I mean)
Screen Shot 2014-08-11 at 20.57.44
The important file in this case, the one that Xcode uses to keep track of the project’s state is ‘project.pbxproj’.
Screen Shot 2014-08-11 at 20.58.04

As far as I can tell .pbxproj is a completely undocumented format (Thanks apple!) on the plus side it does have a ‘JSON like’ structure. To explore it I started to add different file types to a project and studied the changes in the .pbxproj entries.

I saw that the comments in the .pbxproj are actually very useful, for example “/* Begin PBXCopyFilesBuildPhase section */“ tells you that the items listed are destined for the copy file build phase and the ‘files’ array contains the ID for each file to be added in that section. Every file in your Xcode project has a unique ID generated by Xcode and you can find every file’s ID by taking a look in the ‘PBXFileReference’ section, an example entry in this section can be seen below.
B240659C199957A4000782C3 /* LukesProjectTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LukesProjectTests.m; sourceTree = ""; };

This entry translates to:
B240659C199957A4000782C3 = Entry ID
PBXFileReference = Entry type
sourcecode.c.objc = File type
LukesProjectTests.m = Relative location

With this knowledge, I quickly wrote a small command line application in C++ called “Xcode Proj Adder” to add a file to an Xcode project from command line. You can find links to the application and source code at the end of the article.

Adding files to an Xcode project through command line is now as simple as entering this

$ ./XcodeProjAdder -XCP /Users/jimjohn/Products/TestProj.xcodeproj -SCSV ../tst1.cpp,../tst2.cpp,../tst1.h

the -XCP parameter supplies the fully qualified path of ‘.xcodeproj’ (the project you want to add files to) and -SCSV is a CSV list of source file locations relative to the .xcodeproj file (In this example the .cpp files are in the folder above the .xcodeproj), when adding the files to your Xcode project the tool also creates a backup incase you want to remove the files you just added, to revert the project back to the state it was before you added these files you can run the following command.

$ ./XcodeProjAdder -XCP /Users/jimjohn/Products/TestProj.xcodeproj -RESTORE

I have found this functionality useful for files that are supposed to be updated with every run of a script, an example is a project where images are constantly getting updated by a designer. I have my Xcode project with none of the changing images added to it, then I run a script that uses this tool to add all the latest images to the project from a specific folder, the script then builds the project through command line and lastly uses the tool to ‘restore’ the project removing the images ready for next run, this ensures that when built the project always has the most up-to-date images.

Get the tool

The Xcode-Proj-Adder tool is available Here (May need to run chmod a+x XcodeProjAdder to make it executable)

The source is also available on GitHub

Xcode Proj Adder is confirmed working with Xcode versions 4,5 and 6. It looks like the .pbxproj file format has not changed in a very long time so I expect this to be my solution for atleast a while.

Luke Hines

Luke is a husband, father and software engineer who enjoys spending his time in a multitude of technologies. If he's not writing software then he's probably on a motorcycle.

6 thoughts on “Adding files to xcode projects from command line

  1. Hi, is there any possibility to add new cpp files only? Something like delete all files from project and then add all files again with new one included?

    1. Hey Travis,
      If you were to start off with an empty project you could then add files from the command line with this tool. Afterwards; you could use the tool’s ‘RESTORE’ command and this would leave you with your original empty project ready to add your new cpp files.

      1. Thx for the fast reply. This is actually not solution of my problem. We develop on multiple platforms, on windows we use visual studio, on linux simple makefile and xcode on osx. I want to create tool for our osx developers which recursively adds all new source files created by others in src directory. I can’t leave project empty.

        1. Hey Travis,

          All my Xcode projects use GIT for the functionality you mention, so I did not implement a sync feature into this tool. I will certainly consider it for the future, or if you do implement it please throw a pull request my way!

          If you have any more questions feel free to get in touch.

  2. Hi Luke. The project is really good. I can’t find c++ based another option until today.
    I used your solution but I have a problem. There are my class files in “Classes” named folder in the xcode project. So the class file was adding to ios folder when I use your solution. I want to add my class file to “Classes” folder. Because there is the class file in the “Classes” named folder.
    For example;
    ./XcodeProjAdder -XCP /Users/erayzesen/…./Turquoise2DProject.xcodeproj -SCSV ../Classes/Level1.h
    But “Level1.h” named class was adding “ios” named folder in the xcode project.

    I’m waiting your helps, thank you.

  3. Thanks for simple and clean approach for adding files into xcode project.

    Is there any way to add files to in a particular folder?
    e.g. add test.png file at JS/assets/ logical folder in xocde.

    Thanks in advance.

Leave a Reply

Your email address will not be published. Required fields are marked *