{"id":100,"date":"2008-05-23T10:41:11","date_gmt":"2008-05-23T17:41:11","guid":{"rendered":"http:\/\/www.smallersystems.com\/people\/mar\/blog\/?p=80"},"modified":"2008-05-23T10:41:11","modified_gmt":"2008-05-23T17:41:11","slug":"embedding-a-command-line-tool-within-a-cocoa-application","status":"publish","type":"post","link":"https:\/\/michaelrichmond.net\/blog\/2008\/05\/23\/embedding-a-command-line-tool-within-a-cocoa-application\/","title":{"rendered":"Embedding a command line tool within a Cocoa application"},"content":{"rendered":"<p>Back in 2006 I posted a forum question seeking help with embedding a command line tool inside a Cocoa application. After a few days I had muddled out a way to both embed the command line tool and set up Xcode to automatically build the command line tool when the Cocoa wrapper is rebuilt. I posted my solution answering my own question.<\/p>\n<p>Recently I received a message from someone who stumbled on my solution and found it useful. I&#8217;m reposting the solution here so that this information does not get lost.<\/p>\n<p><b>My original question:<\/b><\/p>\n<div style=\"margin: 0 3em 0 3em; background: #DDDDDD; padding: 2em 2em 2em 3em;\">I&#8217;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.<\/p>\n<p>Poking around in the package contents for a few applications I&#8217;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.<\/p>\n<p>I&#8217;m developing in Xcode and have manged to import the source code for the command line tool as say <code>command_line.c<\/code>. What do I need to do to have this file built as a command line tool that is embedded in the main Cocoa application?\n<\/div>\n<p><b>My solution:<\/b><br \/>\n(Warning: Long and technical post.)<br \/>\n<!--more--><\/p>\n<div style=\"margin: 0 3em 0 3em; background: #DDDDDD; padding: 2em 2em 2em 3em;\">\nI wanted to end up with the application structure of:<\/p>\n<div style=\"margin: 0 3em 0 3em; font-family: courier, monospace; background: #FFFFFF; padding: 0 1em 1em 0.5em;\">\n<pre>MyCocoaApp.app\/\n    Info.plist\n    Contents\/\n        MacOS\/\n            MyCocoaApp\n            some_command_line_tool\n        PkgInfo\/\n        ...<\/pre>\n<\/div>\n<p>Where <code>MyCocoaApp<\/code> is the main Cocoa executable for this application and <code>some_command_line_tool<\/code> is a standard BSD C application coded to know nothing about Objective-C or Cocoa.<\/p>\n<p>After creating a Cocoa application project for <code>MyCococaApp.app<\/code> in Xcode the steps below will add the command line tool into the project.<\/p>\n<p>First we need to add the source files for <code>some_command_line_tool<\/code> into the Xcode project. In this example the command line tool is implemented in one file named <code>some_command_line_tool.c<\/code>.<\/p>\n<ol>\n<li>Click to highlight the project group for <code>MyCocoaApp<\/code> in Xcode. This is the first item in the <i>Groups &#038; Files<\/i> tree view.<\/li>\n<li>Right-click (control-click) on the project group and select the <i>Add->New File&#8230;<\/i> option from the context menu.<\/li>\n<li>Select <i>BSD C File<\/i> in the File Assistant and click <i>Next<\/i>.<\/li>\n<li>Specify a name for the file, in this example the name is <code>some_command_line_tool.c<\/code>.<\/li>\n<li>Accept the default location and select the <code>MyCocoaApp<\/code> from the <i>Add to Project<\/i> drop-down.<\/li>\n<li>Do not select any <i>Targets<\/i>.<\/li>\n<li>Click <i>Finish<\/i>.<\/li>\n<\/ol>\n<p>Now we need to tell Xcode about this new command line by setting up a new target for it. This target will compile the <code>some_command_line_tool.c<\/code> file to produce the <code>some_command_line_tool<\/code> executable.<\/p>\n<ol>\n<li>Double-Click to expand the <i>Targets<\/i> group in the <i>Groups &#038; Files<\/i> tree view.<\/li>\n<li>Right-Click (control-click) on the <i>Targets<\/i> group and select the <i>Add->New Target..<\/i> option from the context menu.<\/li>\n<li>Select <i>BSD->Shell Tool<\/i> in the Target Assistant and click <i>Next<\/i><\/li>\n<li>Specify a name for the target, in this example the name is <code>some_command_line_tool<\/code>.<\/li>\n<li>Select the <code>MyCocoaApp<\/code> project from the <i>Add to Project<\/i> drop-down.<\/li>\n<li>Click <i>Finish<\/i>.<\/li>\n<li>Close the Target Info window that opens.<\/li>\n<\/ol>\n<p>You can now select the <code>some_command_line_tool<\/code> as the active target from the project menu and open <code>some_command_line_tool.c<\/code> 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 <code>MyCocoaApp<\/code> and continue with these instructions.<\/p>\n<p>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.<\/p>\n<ol>\n<li>Right-Click (control-click) on the <code>MyCocoaApp<\/code> target and select the <i>Get Info<\/i> option.<\/li>\n<li>In the Target Info window that pops up select the <i>General<\/i> tab.<\/li>\n<li>Click on the + button at the bottom of the window and add the command line tool target from the pop-up list.<\/li>\n<li>Close the Target Info window.<\/li>\n<\/ol>\n<p>Now, if you select the Project group and select <i>Build->Clean All Targets<\/i> from the menubar followed by a build on the <code>MyCocoaApp<\/code> target you should notice that the <code>some_command_line_tool<\/code> is also built.<\/p>\n<p>The remaining step is to automate copying the <code>some_command_line_tool<\/code> executable file into the correct place in the <code>MyCococaApp.app<\/code> bundle. This is done by adding a new build phase to the <code>MyCococaApp<\/code> target.<\/p>\n<ol>\n<li>Right-Click (control-click) on the <code>MyCocoaApp<\/code> target and select the <i>Add->New Build Phase->New Copy Files Build Phase<\/i> option.<\/li>\n<li>You want to copy an executable file so set the <i>Destination<\/i> to be <i>Executable<\/i> in the pop-up window. Do not specify a <i>Path<\/i>. The <i>Destination<\/i> setting means that the files copied in this phase will be copied to <code>Contents\/MacOS<\/code> in the Cocoa application bundle. The <i>Path<\/i> setting is to specify a sub-path below the <code>MacOS<\/code> folder.<\/li>\n<li>Close the Copy Files Phase Info window.<\/li>\n<li>Double-click to expand the <code>MyCocoaApp<\/code> target and notice the <i>Copy Files<\/i> target at the bottom of the build phases.<\/li>\n<li>Click to highlight the project group for <code>MyCocoaApp<\/code>.<\/li>\n<li>Find your <code>some_command_line_tool<\/code> executable file in the right side of the window and drag-and-drop the file onto the new <i>Copy Files<\/i> phase in the <code>MyCocoaApp<\/code> target.<\/li>\n<li>Clean and build the Cocoa application target.<\/li>\n<\/ol>\n<p>If you now use the Finder or Terminal to navigate to the build folder in your Xcode project folder you will find the Cocoa application. Navigating into the package contents for the application should show both <code>MyCocoaApp<\/code> and <code>some_command_line_tool<\/code> executables in the <code>MacOS<\/code> folder.\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m developing in XCode and have manged to import the source code for the command line tool as say <code>command_line.c<\/code>. What do I need to do to have this file built as a command line tool that is embedded in the main Cocoa application? <a href=\"https:\/\/michaelrichmond.net\/blog\/2008\/05\/23\/embedding-a-command-line-tool-within-a-cocoa-application\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,10,16,48],"tags":[],"class_list":["post-100","post","type-post","status-publish","format-standard","hentry","category-apple","category-cocoa","category-development","category-xcode"],"_links":{"self":[{"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/posts\/100","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/comments?post=100"}],"version-history":[{"count":0,"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/posts\/100\/revisions"}],"wp:attachment":[{"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/media?parent=100"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/categories?post=100"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaelrichmond.net\/blog\/wp-json\/wp\/v2\/tags?post=100"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}