© Amit Singh. All Rights Reserved.Written in December 2003
Atom Text Editor has joined the list of best text editors for Mac and has already left its mark in being quite capable and powerful tool. Atom too is a free and open source text editing tool and is maintained through one of the well-known repository – GitHub. There's no software to install locally so you can use it on Mac OS X, Linux, or Windows and it works on all major modern browsers (eg. Chrome, Firefox, IE, Safari, and Opera). It supports connecting to PostgreSQL, MySQL, Oracle, and MS SQL Server databases. Download and install the best free apps for Coding Utilities on Windows from CNET Download.com, your trusted source for the top software picks.
Programming on Mac OS X
Mac OS X is a fertile field for all kinds of programming endeavors, especially if you have a *nix frame of reference. Life is still much better for a developer on Windows than on Mac OS X - no matter what one might think of the usability, etc. of Windows. Apple has been trying to improve things for developers lately, which is a good sign.
This page discusses some programming facilities, frameworks and tools available on Mac OS X.
Application Environments
Since Mac OS X is derived from various sources, it has a multitude of Application Environments. We discussed these in Above the Kernel. To recapitulate:
BSD
Mac OS X uses FreeBSD as a reference code base for its BSD derivations (Panther derives from FreeBSD 5.0). It includes a BSD-based POSIX API (BSD style system call vector,
uap
based argument passing, etc.). An example of intercepting system calls on Mac OS X is covered in the article Re-routing System Calls. OS X also supports System V IPC, asynchronous I/O, poll()
(emulated over select()
), etc. Arbitrary C programming is not any different than on any generic Unix platform. Here is an example of re-routing function calls by overwriting and injecting machine instructions.Carbon
This is a set of procedural C-based APIs for Mac OS X that are based on the old Mac OS 9 API (actually dating back as far back as Mac OS 8.1). Carbon was originally designed to provide an easy development migration path from Mac OS 9 to Mac OS X. The Carbon APIs are all-encompassing (they include legacy interfaces), covering most things that you are likely to do programmatically on Mac OS X. Carbon specific code is not portable to other platforms.
Classic
Mac OS X includes a Classic (Mac OS 9) emulator that executes in a protected memory environment so as to let users run programs written for Mac OS 9. Apple does not encourage you to actually develop for this environment.
Cocoa
This is an object-oriented Objective-C based API that's the preferred way of doing things in Mac OS X (if what you want to do can be done through Cocoa), particularly because of how well it's supported by Apple's Rapid Development tools. However, there are many parts of Mac OS X, and applications from 3rd party vendors, that have not converted to Cocoa completely, or at all. A Cocoa application can call the Carbon API when necessary. Cocoa is largely based on the OpenStep frameworks, and consists of primarily two parts: the Foundation (fundamental classes) and the Application Kit (classes for GUI elements).
Although Cocoa is not really portable across platforms, you might be able to get your Cocoa programs to work on a number of platforms if you take GNUstep into account. Here's what the GNUstep FAQ has to say about portability between Cocoa and GNUstep (quoted verbatim):
It's easier from GNUstep to Cocoa than Cocoa to GNUstep. Cocoa is constantly changing, much faster than GNUstep could hope to keep up. They have added extensions and new classes that aren't available in GNUstep yet. Plus there are some other issues. If you start with Cocoa:
- Be careful with Cocoa.h includes (Use #ifndef GNUSTEP, for instance)
- Do not use CoreFoundation
- Do not use Objective-C++
- Do not use Quicktime or other proprietary extension
- You need to convert .nib files (see section 1.1.3 Tools for porting)
- Some unfinished classes include NSToolBar and Drawers.
My definition of 'portability' (in the current context) is not about feasibility, but the practicality of doing so. Given enough resources, one could port anything to anything - often by emulating/implementing the 'source' API on the 'target'. The WINE project is a wonderful effort. Microsoft once used help from Mainsoft to get Internet Explorer and Outlook Express to run on Solaris. Still, Win32 code is not portable from a practical viewpoint.
Java
Mac OS X includes a complete J2SE implementation. The Swing implementation generates native OS X GUI elements for a uniform look and feel. JAR files are treated as shared libraries. Note that Cocoa includes Java packages that let you create a Cocoa application using Java as the programming language.
X11
Mac OS X includes (optionally) an X Window System implementation based on XFree86 4.3+. The X server has been optimized for OS X via integration with Quartz and supports OpenGL, rootless and full screen modes, an Aqua-compatible window manager (
quartz-wm
) and a menu in the Dock. The presence of a good quality X server and the X11 SDK is a big win because it makes possible to port (in most cases with no or minor changes) a large number of existing X11 applications to Mac OS X, including use of toolkits such as GTK, KDE, various others.As mentioned in Architecture of Mac OS X, Mac OS X has a number of very different APIs due to the many environments constituting it. The example of BSD and Carbon Process Manager processes was given before. Similarly, what thread API you use on Mac OS X is determined by what environment you are programming in. Mach provides low-level kernel threads. The
pthread
library, /usr/lib/libpthread.dylib
(actually a symlink to libSystem.dylib
) provides POSIX threads. Carbon includes a threads package for cooperatively scheduled threads (Thread Manager) and another for preemptively scheduled threads (Multiprocessing Services). Cocoa uses the NSThread
class, while Java uses java.lang.Thread
. All these are built using pthreads
.Bundles and Frameworks
Mac OS X uses a few concepts not found on many traditional BSD, Linux, Solaris etc. systems.
Bundle
A Bundle is a directory that stores executable code and the software resources (icons, splash images, sounds, localized character strings, interface builder 'nib' files,
.rsrc
resource files, etc.) related to that code. Although a bundle is a directory containing potentially numerous subdirectories and files, it is treated as a single entity for various purposes.Mac OS X can have different kinds of bundles:
- An 'Application' bundle (such as
Foo.app
) contains everything (except frameworks/libraries coming from elsewhere) needed to run theFoo
application. It is possible to simply dragFoo.app
to any location and it will work as expected (you do not even have to do anything to its Dock icon, if any - courtesy the fact that 'aliases' on HFS+ do not break if you move a file without replacing it). The/Applications
directory contains many such bundles. - A 'Framework' (such as
Bar.framework
) is a versioned bundle containing resources such as headers, documentation, etc. The/System/Library/Frameworks
directory contains numerous frameworks (such as for Kerberos, Python, QuickTime, ScreenSaver, and so on). - A 'Loadable' bundle can be a kernel extension (a
.kext
, similar to a loadable kernel module on Linux, say), many of which exist in/System/Library/Extensions
, a Plug-in or a Palette.
One of the Finder flags is
kHasBundle
, which, if set, makes the bundle appear as a file package (a single opaque entity), with exceptions and specific behavior for different bundle types.The various bundle extensions referred to above are only conventions - a bundle can have any extension. For example, instead of a
.app
, you can have a .debug
or .profile
to imply debug or profile code, respectively.Framework
A Framework, as stated above, is a type of a bundle that contains shared resources such as dynamic shared libraries, header files, icons and images, documentation, etc. Moreover, frameworks are versioned. Major versions are incompatible while minor versions are compatible. One framework can have multiple major versions.
Consider an example:
# ls -lF /System/Library/Frameworks/OpenGL.frameworktotal 32lrwxr-xr-x .. Headers@ -> Versions/Current/Headerslrwxr-xr-x .. Libraries@ -> Versions/Current/Librarieslrwxr-xr-x .. OpenGL@ -> Versions/Current/OpenGLlrwxr-xr-x .. Resources@ -> Versions/Current/Resourcesdrwxr-xr-x .. Versions/
The best quoting tool for mac. Except
Versions/
, everything else is a symbolic link (to entities from the current major version). The file OpenGL
is the dynamic shared library:# file -L OpenGLOpenGL: Mach-O dynamically linked shared library ppc
The default path for searching frameworks (as used by the dynamic link editor) is:
$(HOME)/Library/Frameworks/Library/Frameworks/Network/Library/Frameworks/System/Library/Frameworks
As we have seen, Mac OS X has complex entities (like a
.app
directory tree) exposed as a single, click-able entity through the Finder. The same effect as double-clicking on an entity's icon can be achieved on the command line through the open
utility. It opens a file, folder, or a URL, in an appropriate manner. For example, opening a .app
folder would launch that application, opening a URL would launch an instance of the default web browser with that URL, opening an MP3 file would open it in the default MP3 player, etc.Runtime Environments
Mac OS X has two primary runtime environments: one based on the dynamic link editor,
dyld
, and the other based on Code Fragment Manager (CFM). OS X does not support ELF, and there's no dlopen
, although the dlcompat
library provides a limited compatibility layer (using native OS X functions) so that common Unix source can be compiled easily.CFM determines addresses for referenced symbols in executables at build time (a static approach). The executable format used is called PEF (Preferred Executable Format).
dyld
resolves undefined symbols at execution time. The executable format is Mach-O (Mach object-file-format). Mac OS X is natively a
dyld
/Mach-O platform - all system frameworks are built using dyld
. In fact, the CFM/PEF environment is itself built on top of dyld
/Mach-O. However, there exist provisions to call dyld
code from CFM code. Moreover, if you wish to debug or trace a CFM application using GDB, you would need to use a Mach-O program called LaunchCFMApp
:/System/Library/Frameworks/Carbon.framework/Versions/A/Support/LaunchCFMApp
dyld
/Mach-O is similar in many respects to ld.so/ELF
, although they differ both conventionally and fundamentally. Some of these are:- Dynamic shared libraries on Mac OS X have the
.dylib
extension. The functionality of several traditional libraries (such aslibc
,libdl
,libinfo
,libkvm
,libm
,libpthread
,librpcsvc
, etc.) is provided by a single dynamically loadable framework,libSystem
.libc.dylib
etc. are simply symbolic links tolibSystem.dylib
. - Mac OS X builds libraries and applications with a two-level namespace (as compared to a flat namespace in traditional Unix systems). This topic is described in an Apple Developer Note called Two-Level Namespace Executables. This also means that
DYLD_INSERT_LIBRARIES
, thedyld
analog ofld.so
'sLD_PRELOAD
will not work with two-level namespace libraries. You can force a flat namespace, but that often messes up things enough to stop the application from running at all. Additionally, you cannot have 'weak' symbols (symbols that can be overridden) in libraries. - Functionality similar to
ldd
(on Linux, say) is provided by/usr/bin/otool
.
Mac OS X uses Mach-O and not ELF simply because NEXTSTEP used Mach-O. Apple had a large enough TODO list that moving to ELF for the sake of mainstream conformity was not justified. Like NEXTSTEP, Mac OS X supports 'fat' binaries where an executable image contains binaries for more than one platform (such as PowerPC and x86). Apple's port of GNU CC allow for fat binaries to be produced (provided assemblers and libraries are available for each specified architecture).
Prebinding
Mac OS X uses a concept called 'prebinding' to optimize Mach-O applications to launch faster. Prebinding is the reason you see the 'Optimizing ..' message when you update the system, or install certain software.
The dynamic link editor resolves undefined symbols in an executable (and dynamic libraries) at run time. This activity involves mapping the dynamic code to free address ranges and computing the resultant symbol addresses. If a dynamic library is compiled with prebinding support, it can be predefined at a given address range. This way,
dyld
can use predefined addresses to reference symbols in such a library. Of course, for this to work, libraries cannot have preferred addresses that overlap. Apple specifies address ranges for 3rd party (including your own) libraries to use to support prebinding.update_prebinding
is run to (attempt to) synchronize prebinding information when new files are added to a system. This can be a time consuming process even if you add or change a single file, say, because all libraries and executables that might dynamically load the new file must be found (package information is used to help in this, and the process is further optimized by building a dependency graph), and eventually redo_prebinding
is run to prebind files appropriately./usr/bin/otool
can be used to determine if a binary is prebound:# otool -hv /usr/lib/libc.dylib/usr/lib/libc.dylib:Mach headermagic cputype cpusubtype filetype ncmds sizeofcmds flagsMH_MAGIC PPC ALL DYLIB 10 1940 NOUNDEFS DYLDLINK PREBOUND SPLIT_SEGS TWOLEVEL
Xcode
Xcode is Mac OS X 'Panther's developer tools package. It includes components typical of a comprehensive IDE:
- A source code editor with code completion
- A file browser/organizer
- Support for version control (CVS and Perforce)
- A documentation viewer that can link symbols in the code to documentation
- A class browser
- Various compilers (the GNU suite, including
gcc 3.3
and integration withdistcc
for distributed builds,javac
,jikes
) - GDB based graphical and command-line debugging
- An Interface Builder application that provides a GUI for laying out interface objects (various GUI elements), customize them (resize, set and modify attributes), connect different objects together, and so on
- Support for packaging
A new Xcode project can be instantiated from a large number of templates. As can be seen, it supports development of various kinds of programs in C, C++, Objective-C, Objective-C++, Java and Assembly. For example, it is almost trivial to create things such as Screen Savers, Preference Panes (the kind you see under System Preferences), etc.
Xcode has some neat and useful features: Predictive compilation runs the compiler in the background as you edit the source. Once you are ready to build, the hope is that most of the building would have been done already. 'Zero Link' links at runtime instead of compile time, whereby only code needed to run the application is linked in and loaded. A related feature is 'Fix and Continue', courtesy which you can make a change to your code and have the code compiled and inserted into a running program. Distributed builds are also supported via integration with
distcc
.Programming Languages
Compilers and Libraries
Apple provides a customized/optimized GNU CC, with backends for C, C++, Objective-C and Objective-C++. For Java, two compilers are included:
javac
and IBM's jikes
. Compilers for many other languages are available either precompiled (such as the XL Fortran Advanced Compiler from IBM), or can be compiled from source, which is not any harder in general than compiling the same source on, say, Linux or FreeBSD. The same goes for development libraries - it should be easy to compile many open source platform-independent / multi-platform libraries from source on OS X. Many important libraries and APIs are either included with Mac OS X, or are readily available (Gtk/Gtk++, Java, OpenGL, Qt, QuickTime, Tcl/Tk, X11R6). The system comes with several special purpose (and/or optimized) libraries as well, such as for Numerical Computing and Image processing (BLAS
, vBigNum
, vDSP
, vImage
, LAPACK
, vMathLib
, etc.)Interpreters
A number of scripting languages are included in Mac OS X, such as AppleScript (including the AppleScript Studio IDE), Perl (Mac OS X 'Panther' has perl 5.8.1), PHP, Python (Panther has python 2.3, with bindings to CoreGraphics), Tcl, and Ruby. Mac OS X also supports the Open Scripting Architecture (OSA), using which it is possible to get JavaScript (a port of Mozilla JavaScript) in the form of an OSA component. You can get support for more languages (Lisp, Scheme, ..) via Fink, and it should be straightforward to compile most of them from source, if desired.
bash
, tcsh
, and zsh
are the *nix shells included.My Coding Tools
Scriptability
AppleScript is the preferred scripting system on Mac OS X, providing direct control of many parts of the system as well as applications. In other words, AppleScript lets you write scripts to automate operations, exchange data with and send commands to applications, etc.
While I personally find AppleScript syntax to be exasperating (I never really enjoyed COBOL for that matter), it is useful. Consider a contrived example for a taste of AppleScript:
tell application 'Finder' set system_version to (get the version) as number do shell script 'say 'This is Mac OSX' & system_version return system_versionend tell
Running the above (either in
ScriptEditor
or through the osascript
command line utility) should cause the say
utility (see below) to speak the version of Mac OS X (well, assuming you are running Mac OS X) to you. By the way, you do not need to run a shell command and use the say
utility: AppleScript has a say
command of its own.Now, whether you are impressed by (or happy with) Mac OS X's scriptability depends on which system you are contrasting with. As mentioned at the beginning of this section, if you are coming from a traditional Unix/Unix'ish world (FreeBSD, Linux, Solaris, *nix, ..), you should find it impressive, a lot perhaps (barring the miniscule possibility that you are an anti-Mac/pro-XYZ zealot). However, you might not think much of this if you have been using Microsoft's COM/DCOM/.NET.
Along the lines of making a *nix developer/user happy though, Apple has been exposing various aspects of Mac OS X functionality to be driven via a traditional command line. Consider some examples:
drutil
is a command line tool that interacts with the DiscRecording framework. The command:# drutil getconfig supported
will probably tell you more than you want to know about your CD/DVD burner.
https://leaderrenew784.weebly.com/blog/snipping-tool-for-mac-save-location.
hdiutil
is a powerful utility for manipulating disk images.say
is a command line utility to convert input text to speech using the Speech Synthesis manager. Partition recovery tool for mac.sips
is a command line interface to the Scriptable Image Processing Server. The graphical abilities of Mac OS X are exposed through this image processing service. The SIPS architecture contains tools for performing basic image alterations and support various image formats. The goal is to provide quick, convenient, desktop automation of common image processing operations.Chrome Cleanup Tool For Mac
Tools
The Developer Framework contains a wealth of tools for various programming, debugging, profiling and other developmental tasks. The CHUD (Computer Hardware Understanding Development) Tools are particularly useful for various kinds of benchmarking and optimization. Mac OS X Developer Tools Overview contains detailed information on almost all tools included in Xcode. Mac OS X Hacking Tools is a compendium of some useful programs on Mac OS X (mostly outside of Xcode).
Syntax Tool For Mac Coding Programs
Lastly, the OS X
Terminal.app
, is one of the better terminal applications around, which does matter to me while programming, since I do not use an IDE for everything. The terminal advertises itself as xterm-color
, has Unicode support (though broken), drag-and-drop support (dragging an icon to the terminal would drop its pathname or URL string), transparency support (has a minor problem in Panther - there's ghosting of text under certain conditions), etc.Paint Tool For Mac
<<< Mac OS X Filesystems | main | A Sampling of Mac OS X Features>>> |