PDA

View Full Version : Help with embedding a command line tool within a Cocoa application?




mrichmon
Feb 22, 2006, 09:46 PM
I'm hacking together a small Cocoa application in XCode. I have all the GUI and events coded up and now I need to integrate a command line tool that I coded up in C a while back.

Poking around in the package contents for a few applications I've noticed that it is not uncommon for developers to package up small command line tools within the main Cocoa application. Presumably these command line tools are executed as a new process from the Cocoa application.

I'm developing in XCode and have manged to import the source code for the command line tool as say command_line.c. Now, what do I need to do to have this file built as a command line tool that is embedded in the main Cocoa application?

Also, how do I exec the command line tool from the Cocoa application?

Pointers to any examples would help since my google-fu is not good today.



therevolution
Feb 23, 2006, 12:24 AM
Might I suggest that, instead of deleting the entire thread, you post the solution that you discovered? It may be of use to others in the future.

mrichmon
Feb 23, 2006, 01:25 AM
Might I suggest that, instead of deleting the entire thread, you post the solution that you discovered? It may be of use to others in the future.

Sure. :)

Warning: Long post and technical post.

I wanted to end up with the application structure of:

MyCocoaApp.app/
Info.plist
Contents/
MacOS/
MyCocoaApp
some_command_line_tool
PkgInfo/
...


Where MyCocoaApp is the main Cocoa executable for this application andsome_command_line_tool is a standard BSD C application coded to know nothing about Objective-C or Cocoa.

After creating a Cocoa application project for MyCococaApp.app in X-Code the following steps will add the command line tool into the project:

First we need to add the source files for some_command_line_tool into the X-Code project. In this example the command line tool is implemented in one file named some_command_line_tool.c.


Click to highlight the project group for MyCocoaApp in X-Code. This is the first item in the Groups & Files tree view.
Right-click (control-click) on the project group and select the Add->New File... option from the context menu.
Select BSD C File in the File Assistant and click Next.
Specify a name for the file, in this example the name is some_command_line_tool.c.
Accept the default location and select the MyCocoaApp from the Add to Project drop-down.
Do not select any Targets.
Click Finish.


Now we need to tell X-Code about this new command line by setting up a new target for it. This target will compile the some_command_line_tool.c file to produce the some_command_line_tool executable.


Double-Click to expand the Targets group in the Groups & Files tree view.
Right-Click (control-click) on the Targets group and select the Add->New Target.. option from the context menu.
Select BSD->Shell Tool in the Target Assistant and click Next
Specify a name for the target, in this example the name is some_command_line_tool.
Select the MyCocoaApp project from the Add to Project drop-down.
Click Finish.
Close the Target Info window that opens.


You can now select the some_command_line_tool as the active target from the project menu and open some_command_line_tool.c to hack away at implementing the command line tool and testing it. Once you have it implemented, set the active target for the project back to the Cocoa target MyCocoaApp and continue with these instructions.

Since our Cocoa application will invoke the command line tool we want to set up a dependency between the Cocoa application target and the command line tool target. This dependency will ensure that whenever the Cocoa application target is built then the command line tool will also be built.


Right-Click (control-click) on the MyCocoaApp target and select the Get Info option.
In the Target Info window that pops up select the General tab.
Click on the + button at the bottom of the window and add the command line tool target from the pop-up list.
Close the Target Info window.


Now, if you select the Project group and select "Build->Clean All Targets" from the menubar followed by a build on the MyCocoaApp target you should notice that the command_line_tool is also built.

The remaining step is to copy the command_line_tool executable file into the correct place in the MyCococaApp.app bundle. This is done by adding a new build phase to the MyCococaApp target.


Right-Click (control-click) on the MyCocoaApp target and select the Add->New Build Phase->New Copy Files Build Phase option.
You want to copy an executable file so set the Destination to be Executable in the pop-up window. Do not specify a Path. The Destination setting means that the files copied in this phase will be copied to Contents/MacOS in the Cocoa application bundle. The Path setting is to specify a sub-path below the MacOS folder.
Close the Copy Files Phase Info window.
Double-click to expand the MyCocoaApp target and notice the Copy Files target at the bottom of the build phases.
Click to highlight the project group for MyCocoaApp.
Find your command_line_tool executable file in the right side of the window and drag-and-drop the file onto the new Copy Files phase in the MyCocoaApp target.
Clean and build the Cocoa application target.


If you now use the Finder or Terminal to navigate to the build folder in your X-Code project folder you will find the Cocoa application. Navigating into the package contents for the application should show both MyCocoaApp and some_command_line_tool executables in the MacOS folder.