Kevin, I do cross platform development for Windows and OSX. I have an application consisting of about 120 source files that runs on both platforms.
TSG isn’t perfectly accurate in what he says. I loath development on the Mac platform, not Mac’s in general. For the end user, it is the greatest thing since sliced bread.
Ill give you a quick rundown of my experiences so far. Also if you seriously get into Mac Development, stay in contact with me, there is a lot of stuff I have not figured out yet. I am sure there will be a lot we can learn from each other. My area of expertise, if you can call it that, is the “under the hood” stuff to the OS, not GUI stuff. IE: Getting the user name, finding out the network status, looking at the process table and such…
Anyway on to my preview of Mac Development:
Development Environment: XCode 2.4
XCode sits on top of the GNU compiler. It is just a pretty front end for you. There are serious issues that arise because of this. I do not know if it is because of the limitations of the GNU compiler or the ineptitude of the XCode developers. I suspect it is the latter.
Debugging:
XCode’s debugger is very limited compared to Dev Studio.
-
You can not move the Program counter backwards.
-
You can not move it forwards.
-
You can not watch a variable’s value unless XCode sees fit to present you with its value. IE: If you want to see the value of Alpha, and XCode doesn’t happen to automatically show it, you can’t see its value.
-
Occasionally XCode will lie about a value you see. IE: You see the value of X as 20, then it goes past a statement that says X = 30, and it will still report X as 20.
-
You can never see ‘static’ values in the debugger. IE: “static unsigned long Timer;” will result in Timer being totally invisible to the debugger.
-
You can not change a variable’s value via the debugger.
-
On occasion, even in a full debug mode with no optimizations, the debugger with become out of synch with the actual code shown. Usually it fixes it if you move into or out of a function / method call.
The Source Editor:
-
It is ok, over all, as far as basic C++ source editors go.
-
It does not recognize a change when a source file on a disk changes. IE: You tamper with main.cpp and decide to undo the changes, so you grab the latest version from source control. The source editor doesn’t notice and will still show the changed version in your editor. If you compile, it will save it again. The only way I know of to re-synch it is to close the project and open it again. This is a real issue when you have the same source file for windows and OSX and are making changes in two editors at once.
-
Auto completion for functions is some what wonky, and even when it works, it is not really in a desirable format. In DevStudio you get a tool tip to show you what is next, highlighting the parameter you are on. In XCode it actually dumps out the entire function with stubbed in values.
IE: Say there is a function like “void DoStuff(int N, float X, String Name)”. XCode will put in your source file each time you use DoStuff “DoStuff(<int N>, <float X>, <String Name>)”. Maybe it is just a stylistic thing, but I find it annoying, especially since I can not double click on <float x> and just type the name out. Double clicking would only select “<float” so you need to constantly highlight with the mouse and delete that stuff.
- Finding documentation on a highlighted function is iffy. Sometimes it finds it, other times it doesn’t. I mean even on the same exact function. One day it can look up “fstat” and other days it can’t. I have no idea why.
Documentation in general:
This is very poorly organized. There is nearly zero cognitive organization. By that I mean, if you want to find the section on “file management” or “system information”, you won’t find anything. You already have to kind of know where to look and what it is called.
The documentation is also frequently wrong, but not ‘wrong’ in the way MSDN tends to be. On MSDN they will give you source code examples that might not compile because of syntactical problems, or crash because they do something dumb like delete a null pointer. The Apple documentation not only does all this, but will give examples of functions that do not even exist.
I was trying to find out how to be notified when the user was logging out or the system was shutting down. So I am digging and digging on the Apple Site, and find some article on that. It used something like AENotifyRegister or something like that. It gave some sample code. I cut and paste the code, and it doesn’t compile. It doesn’t know what this AENotifyRegister function even is. I have the right headers and all, according to the sample. So I look that function up on apple’s site. It returns 1 result, the example I was just looking at. I google it. It returns 1 result, the page I was looking at. This kind of stuff happens on occasion.
Finally, they have no unified documentation format. If something is a UNIX command, you will get a man page. If its an Apple thing, you will get an Apple page. If you look for a UNIX command via the apple documentation, you get no hits, and vice versa. It really sucks when you have no idea who owns API function such and such.
Overall their documentation is an abomination, but it is all you have to work with.
Compiler / IDE General stuff:
-
Your files list (source files) doesn’t auto sort. If you make a new file, it will be appended to the list and stay there. Obviously the more source files you have, the more annoying this is.
-
There are a whole mess of compiler switches you can change, with only the most threadbare documentation. To make matters worse, the ‘default’ configuration is almost never what you want. For example, if you write a function header, but forget to write the body, the compiler will compile it and link it. In DevStudio the linker will not allow this to happen. You run your app, it enters the function and crashes. This can easily happen if you include a header without adding the library associated with it. There is a compiler switch that you can change that will cause the linker to puke in such cases. Why this isn’t the ‘default’ setting, I have no idea.
-
Changing a project is very convoluted. You can’t just add a CPP file sometimes. You can add it to your build, but then it is not part of your ‘target’ and you need to do some funky stuff to get it to work. God help you if you have multiple targets.
Beyond XCode, general development notes:
I have said a few times in this forum, that OSX is really two OSs. People belittle me when I say this. If you do not accept my word on this, you will have to learn the hard way. The two OSs are, Darwin and Apple.
Darwin is the BSD-like UNIX core. It is pretty much what you expect out of UNIX based operating system. It is stable, secure, and cryptic. Once you understand it such that it is no longer cryptic, you will be happy as the proverbial bug in a rug.
The Apple OS is the big ugly thing that sits on Darwin. It is not secure by any stretch, it is unstable, and absolutely convoluted. It is layered with APIs as old as Mac OS 1.0 all the way up to the new Mac stuff. As one veteran apple developer from their official forums once told me, “Apple doesn’t fix bugs in their API. They just make a new API with new bugs. The newer the API the lest trustworthy it is. Always use the oldest API you can find that will do what you want.”
At this point it really isn’t clear they are two OSs, until you get more ‘under the hood’. The first thing you may notice is that the two OSs do not really talk to each other. If you make an Apple app, and register a signal to be sent when the system shuts down, you will never receive it. Signals are UNIX things, not Apple things.
If you have an Apple app, and try and do some ‘unix’ stuff, it can cause major instabilities in the entire system, not just your app. For example, lets say want to launch an application from your application. You look up the fork command and the exec command. You write your code, which maybe you have done 1000 times before, and compile it. Then you run your application, which might seem to be OK at first. However, sometimes your application will simply disappear from the task list without any reason, not even a crash. Sometimes, although it is very rare, the whole apple shell will crash. It is all because your new application was an Apple app, but launched via the UNIXdisappear system.
Similarly if you make a UNIX app, and then create their standard apple app directory structure, such as package / contents / macos / application and then run it, it is like playing Russian roulette. Most times it may work, but once in a while, something really weird happens.
What I am getting at, is that you need to be very careful when mixing API calls. Most minor calls, like fstat, chmod, and whatnot are quite safe. However, bigger impact ones are more likely to produce odd behavior.
Overall, I would give the Apple Development setup a D-. There is no real excuse for the state it is in. I am quite convinced that Apple spent more money on deciding what color their IPods should be then on the development setup. It is unfortunate they are the only game in town. Borland and Codewarrior no longer support Mac development.