Working Directories and Build locations with Xcode 9 and C++

Introduction

This post describes how Xcode manages Project Working Directories and what options do we have to setup it correctly. In the end you learn how to setup custom build locations for you compiled binaries.

Definitions:

  • Project Working Directory – is working directory associated with process created by executing built binary
  • Project Directory – is directory with project source code
  • Products Directory – is directory where built sources are placed to

Option 1 – default Project Working Directory

If you create fresh new command line tools project you will get following directory structure:

The default build scheme builds and places debug binary to:

/Users/[my_user]/Library/Developer/Xcode/DerivedData/wd_example-[some_random_string]/Build/Products/Debug/wd_example

Now consider following code snippet which simply reads text file content. What’s worth paying attention here is that we provided just relative file path to std::ifstream::open() method!

#include<fstream>
#include<iostream>
#include<string>


using std::cout;
using std::endl;
using std::ifstream;
using std::ios_base;
using std::string;


int main()
{
    ifstream myFile;
    myFile.open("HelloFile.txt", ios_base::in);
    
    if (myFile.is_open())
    {
        cout << "File open successful. It contains: " << endl;
        string fileContents;
        
        while (myFile.good())
        {
            getline(myFile, fileContents);
            cout << fileContents << endl;
        }
        
        cout << "Finished reading file, will close now" << endl;
        myFile.close();
    }
    else
        cout << "open() failed: check if file is in right folder" << endl;
    
    return 0;
}

Let’s create HelloFile.txt test file in that wild Xcode default Project Working Directory and see if it works.

/Users/[my_user]/Library/Developer/Xcode/DerivedData/wd_example-[some_random_string]/Build/Products/Debug/wd_example/HelloFile.txt

Buildin’n’Runin ( CMD + R ) in Xcode we get:

File was read successfully.

Option 2 – Xcode copies file(s) during build phase to Project Working Directory

Another solution is to let the Xcode copy your file from your Project Directory to Project Working Directory.

  • Copy HelloFile.txt to Project Directory:

  • Reference the file with your project:

  • Open your project’s settings via project navigator:

  • Select Build Phases:

  • Select Copy Files:

 

You need to set Destination to Products Directory because Products Directory is Project Working Directory by default. Next click “+” and add HelloFile.txt. Note that your files actually don’t need to be strictly in Project Directory but in arbitrary location. Uncheck “Copy only when installing” otherwise files will not be copied during debug build process.

 

  • After Build’n’Run ( CMD + R ) you can check that your file was indeed copied to the Products Directory:

 

Option 3 – set custom Project Working Directory and Build directory

Let’s create custom project structure adding data/ directory where we can place our HelloFile.txt.

  • Use New Group option from context menu which will create new directory and adds (references) it to the project:

  • Copy HelloFile.txt to data/ directory and add it to project! You should end up with structure like this:

  • Set custom Project Working Directory:

  • Set the custom working directory to your main.cpp location:

  • Before we can test if C++ program finds HelloFile.txt in data/ directory we need to slightly change the file relative path:

  • After Build’n’Run ( CMD + R ) program finds and reads HelloFile.txt.

Now we will setup custom Products Directory.

  • Open Xcode Preferences:

  • Open Locations tab and set Derived Data to “Relative”. DerivedData/ directory should be already set.

  • Open Advanced settings and set Build Location to Shared FolderBuild/

  • Try to Build’n’Run your project ( CMD + R ) and you should get DerivedData/ directory created in place where your .xcodeproj file resides. Note that we have set build location globally so compiled binaries with every new project will follow this directory structure.

 

TIP: If you want to set custom build paths and locations per-project basis you need to edit build paths in File > Project Settings…

 

Conclusion

You learned how to setup working directories and locations for compiled binaries. However one method wasn’t discussed – using absolute paths in program. This method is not recommended because it reduces code portability and should be used just in development stage if ever.

Leave a Reply