Source Code DNA for Mac OS X Applications
by Chuck Houpt <email@example.com>
AppDNA is a small XCode shell script which efficiently packages a Mac OS X Application's source code into the application itself. The resulting embedded project directory is fully functional, allowing the code and resources to be examined, modified and re-built. The application is self-compiling when a Release build is performed.
Mac OS X 10.4 with the included XCode 2.1 (may work with other versions, but untested)
AppDNA Sample Application: Protozoa
The Protozoa sample application is just a default XCode Cocoa application, built with the AppDNA script, a modified help menu item, and simple 'Hello World' code. Like a protozoa, it can do little more that run and build itself.
To see the code, run Protozoa.app and select 'Show Source Code' from the Help menu, which will open the embedded XCode project.
Try changing the 'Hello World' to 'Hello Mars' in ProtozoaController.m, and build with the Release configuration. Restart Protozoa.app to see your mutation live. Share, Compile and Enjoy.
How it Works
The script copies the project directory, excluding resources, into Content/Source in the Application's bundle. The embedded XCode project file is then modified to find resources in Content/Resources. The Current Project Version setting is also changed to make modified versions of the application (mutants) easy to identify.
When the embedded project is built, the script copies the results back to the outer wrapping application, thus making the system self-compiling. The script only runs during Release/Deployment builds, so it doesn't interfere with Debug builds.
Note: Always advise users to design intelligently so the resulting mutations are happy ones.
How to Install the AppDNA Script
For application that follow the typical XCode source tree layout and use standard resource types, the three step basic install is all that is needed.
- Copy AppDNA.sh into your project directory. For reference, you might also want to add it to the Project's Groups & Files list.
- In the application's target, add a new Shell Script Build Phase after the link phase. For reference, name it 'Bundle Source'.
- In the Script Build Phase Info, enter the follow script:
Excluding Additional Resources, Files and Directories
When copying the source tree, the AppDNA.sh script automatically excludes most common resource files, such as .lproj, .icns, .tiff, etc. To exclude more files, use the --exclude argument (see rsync manual page for full options).
For example, to exclude JPEG 2000 images, and the NOTES.txt file:
bash AppDNA.sh --exclude '*.jp2' --exclude 'NOTES.txt'
Case Study: Application Size of Fugu with AppDNA
A common concern for developers is the question of how much AppDNA will bloat an application. Every application is unique in its mix of resources and code, but for many UI heavy applications, the resources are the bulk of its size. This is especially true for multi-language and multi-architecture application, where resources and object code are duplicated many times. Therefore, adding source code typically only increases the application size by a small percent. In addition, source code compresses well, so downloadable disk image sizes will increase even less.
As a concrete example, consider the following case study using Fugu, the award winning secure file transfer application from the University of Michigan's Research Systems Unix Group. In this study, the source of Fugu (CVS Head 2007-02-25) was built as a Universal binary (PPC, i386) with and without AppDNA, in both compressed (zip) and uncompressed forms. In addition, the size of Fugu with its default 10-language resources is compared with a 1-language version. Let's see just how much AppDNA "puffs up" Fugu.
Comparison of Fugu with and without embedded source code
As the table shows, adding source code to Fugu only increases the download size by about 8%, and the unpacked size by 12%. The single-language version only increase 17% when compressed.
Applications that use AppDNA
Related Ideas and Projects
The secret to creativity is knowing how to hide your sources.
- Albert Einstein