Xcode - gpertea/stringtie GitHub Wiki

Working on StringTie using Xcode

StringTie was mainly developed on Linux and OS X using GCC's C++ compiler with GDB for debugging, using Eclipse as an IDE. Unfortunately lately on MacOS the gdb support/compatibility has become very poor, and working on Eclipse with gdb for debugging is practically impossible (at the time of this writing). So we have to switch to Xcode. Unfortunately Xcode doesn't fully work with Makefile projects as nicely as Eclipse does, so we have to create a new Xcode project for StringTie development, following specific steps in order to obtain a proper working environment with good code completion and interactive debugging features. These steps are shown below, and they are intended for developers who have no previous experience with Xcode (with some occasional comparisons with Eclipse).

1. Creating a Xcode project for a Makefile project

Xcode cannot directly "import" an existing project directory, so we'll have to create a new one and add our source files/directories to it. Unfortunately when doing that Xcode insists on creating its own directory structure with it, which in most cases does not work with the directory structure of our project. However we can simply create a new, dummy "command line tool" project, clean it up (remove the main.cpp and other directories created by default) and then simply move the .xcodeproj file (which is actually a directory) whereever we want - to our project directory.

Xcode project creation

Choose File -> New -> Project... and in the dialog that appears select the macOS tab and then Command Line Tool as the project type.

new project 01

Then click the Next button. In this example, in the dialog that follows simply enter "stringtie" as the Product Name and make sure you choose C++ as the language to use:

new project 02

Then you are prompted to choose a location (parent folder) for your Xcode project. In this dialog we can choose whatever folder we want - except for the parent directory of our existing 'stringtie' source folder, because Xcode is going to create its own project folder (with the same name as the Product name) where the stringtie.xcodeproj file/folder is going to be created etc. So let's just choose the Desktop folder as the (temporary) location for now -- and also make sure to uncheck the checkbox "Create Git repository on my Mac" before clicking the "Create" button (unless you have good reasons to leave it checked).

The big Xcode project window should open now, showing the directory structure of the project in the left-side pane. You can see that a 'stringtie' folder was actually created within the new 'stringtie' project folder created on the Desktop (sic!), and that has a single, dummy main.cpp file in it. Right-click (or Control+click) on that second stringtie text in that pane (the immediate parent folder of the main.cpp file) and choose Delete from that context menu.

new project 03

In the confirmation dialog that appears choose the Move to Trash button. Now that project structure should be much more simple:

new project 04

Now close (quit) XCode completely and then use Finder to go into the stringtie folder that was created on the Desktop (e.g. by double-clicking on the stringtie folder icon on the desktop) and copy/move the stringtie.xcodeproj entry (of kind Xcode Project) from that folder to the original base directory of our Makefile project. Let's assume that base stringtie source folder (or the git tree clone folder) is ~/Work/stringtie/, so the newly created Xcode Project file stringtie.xcodeproj should end up in that folder, next to the Makefile there.

Xcode project configuration

Preparing the source directory

Now we can open the bare stringtie Xcode project in its new location and start adding source code to it and configure the build accordingly. So in Finder go to the new location of the stringtie.xcodeproj file (~/Work/stringtie) and double click to open it in Xcode.

  • before adding source files/directories to the project it's good to make sure there are no object files, especially in the gclib sub-directory, and an easy way to do that is to run make clean in the terminal (in the project folder).

  • while still in the terminal let's also make sure that any libraries that are needed to be linked into the program are available; in our case we'll directly link libbam.a from the samtools-0.1.18 folder so let's make sure it's there first. In a terminal, go to the samtools-0.1.18 sub-directory and type this command to (re)build libbam.a there:

make clean lib

Adding source files to the Xcode project

Right-click (or control+click) the project name ('stringtie') in the left pane and select Add Files to "stringtie" from the menu.

add files 05

In the larger dialog that shows up select all source files and directories as needed (using Command+click) which for this project are as follows:

gclib (folder)
rlink.cpp
rlink.h 
stringtie.cpp
tablemaker.cpp
tablemaker.h
tmerge.cpp
tmerge.h 

Note that we don't need to add the samtools-0.1.18 source folder because we're going to use the pre-compiled library file (libbam.a) for that code, as we do not plan to do any further development to that samtools library code. (besides, that does not even compile properly with clang on MacOS)

Make sure you select Added folders: Create groups option before clicking the Add button:

add files 06

Adding libraries to the project

With the stringtie project root selected in the left pane and the General tab selected in the main pane, look for the section Linked Frameworks and Libraries and make sure it's expanded to show a region where, in the center it shows Add frameworks & libraries here. (You can collapse the other sections to focus on that section only). Switch to a Finder window and press Command+Shift+g (or Go -> Go to Folder... from the Finder menu) and enter /usr/lib/ and in there you should locate libz.dylib file and drag it to drop it into the Add frameworks & libraries here region of the Xcode window:

add libs

Then in Finder navigate to the ~/Work/stringtie/samtools-0.1.18 folder and similarly drag & drop libbam.a into the same region (the library file should be there since you built it with make lib in the terminal as indicated above). After these operations the Linked Frameworks and Libraries section should look like this:

libs added

Adding/adjusting search paths

Select the 'Build Settings' tab in the main pane, then select the 'All' tab on the row below (see screenshot below), then look for the Search Paths section. The Library Search Paths entry there should already contain the full path to the samtools-0.1.18 directory, that was automatically added when we added the library libbam.a in the previous step. You can click twice (slowly) on that path in order to edit it and turn it into a relative path to the project base directory, so it can only have this text there: samtools-0.1.18.

However it is mandatory to fill in the Header Search Paths entry there. For that you can click twice (slowly) on the empty space to the right of that entry label in order to enter editing mode for that item and then type in the same relative path there : samtools-0.1.18

libs added

At this point the project should build successfully (albeit with a lot of warnings, but it's important to not get any build errors). So choose Product -> Build from the Xcode menu (or press Command+b) and check there are no red stop icons anywhere..

Changing build output location

By default Xcode places the built executable in some obscure place (why?!) so we'd have to take extra steps in order to have it generated somewhere in/under the project directory. Despite multiple attempts I was not able to force Xcode to place the "final product" of the build in the project directory itself (next to the Makefile and the stringtie.cpp files). The best I could do is to have Xcode build the program into ./build/Debug/ path relative to the project directory (so the full path to the built executable will be ~/Work/stringtie/build/Debug/stringtie in our example project here).

In order to get that output location choose File -> Project Settings... in the menu, the dialog that shows up should look like this:

libs added

Click the Advanced... button there and in the next dialog choose Custom then in the drop down next to it select Relative to Workspace, then in the Products field below enter just build, then for Intermediates enter build/Intermediates.noindex and if you have the 3rd entry there labeled Index Datastore (I see it for Xcode 10.1) enter build/Index/DataStore there.

libs added

Now if you Build the project again, the ./build/Debug/ folder will be created and the executable will be generated as ./build/Debug/stringtie (which can be sym-linked into the base project directory for quick access to it in the terminal).

Setting running directory

For debugging or running the program with input found in the base project directory (~/Work/stringtie in this example), it would be convenient to force Xcode to launch the built executable in that project directory as the working directory. To do this we have to edit the current running "Scheme" which can be done by selecting Product -> Scheme -> Edit Scheme... from the menu (or pressing Command+Shift+, key combination), or clicking the name of the project at the very top of the current project window and selecting Edit Scheme from that small menu that comes up:

edit scheme

In the dialog that shows up select the Options tab and check the Working Directory [ ] Use custom working directory option, then enter the following in the edit box below that: $(PROJECT_DIR)

scheme wrk dir

2. Using Xcode for StringTie development and debugging

Assuming there is a working Xcode project which can build the target program successfully (following the guidelines above), here are a few notes about performing basic development/debugging tasks in Xcode (for first-time Xcode users).

Starting a debug session

Note that Xcode, as opposed to Eclipse, does not have a dedicated "start debugging" button. Instead, the same Play/Run button is being used in Xcode to run the program and to start a debugging session. That's why a breakpoint should be first set in order to make the program execution stop and actually enter "debug mode", or "step-by-step debugging". A breakpoint can be easily set by clicking on any of the line numbers shown on the left side ruler in the source code editing window.

Setting command line arguments

Xcode has the concept of "Scheme" ( "Running Scheme" ?) which seems to control the execution of the program within Xcode. In order to add arguments for the program execution in Xcode, edit the current running "Scheme" by selecting Product -> Scheme -> Edit Scheme... from the menu, or pressing the Command + Shift + , key combination), or clicking the name of the project at the very top (in the title bar) of the current project window and selecting Edit Scheme from that small menu that comes up:

edit scheme

In the next dialog select the Arguments tab and then add a line (using the '+' button) to the section Arguments Passed On Launch.

arguments

Adding debug expressions

Once a step-by-step debug session is initiated and (the program stopped execution at a break point), the lower-left region below the source editing area is the "debugger window" which shows a list/table with some local or context relevant variables to inspect (watch). Right-clicking ( or Control+clicking) that variable watch area brings up a context menu which has an Add Expression.. option and allows the developer to set add expression or specific variables to evaluate in the current program execution context.

scheme wrk dir