Minimalist OS X Dev Environment

Hi there!

This is a shoutout to everyone who is developing on OS X without the use of big IDE's like Xcode.

I am looking for tools to develop programs like Casey does without these big monsters with thousands of functions.

Right now I'm using Atom and a shell script to compile. But how do you guys debug?

How do you setup your dev environments ons OS X? There isn't really much documentation online because mostly everybody seems to use Xcode or other big alternatives.
Quick aside: I would like to get 1935 building on the Mac sometime in the future, and so I'd be interested in finding out what people are doing for building/debugging on there as well. I'd like to know what the best was is to make a simple build.bat-style build that can actually do stuff like build a Mac OS X version of the program, or iOS version of the program, etc.

- Casey
I use Sublime text for my editing needs and then use either lldb in the console or Xcode to debug. I create a little batch-like script by placing the commands I need a file and then chmod +x it. This what I've done on Mac for numerous years now and it works for me.

Xcode can be annoying as it really wants you to just develop in it rather than use it as a debugger so I have to do some weird things. It's not nice but it works. I'll have to do a video explaining it sometime as it's not intuitive.
For building its easy - you don't need to install full Xcode. You can install only "Xcode Command Line Tools". You can do that by running
1
xcode-select --install
in command line. Or download dmg installer from Apple Developer site, it's free.

For debugging it's trickier. I'm not aware of any good GUI, so either installing full Xcode GUI or using lldb (included in Xcode Command Line Tools) in console seems to be only option. lldb has experimental TUI mode (type "gui" in lldb command prompt) but I'm not sure how complete or buggy it is.
lldb TUI is absolutely unusable and would not wish upon anyone. Unfortunately, the only half-decent GUI debugger is XCode but even that's not as good as Visual Studio.

However, saying all that, the XCode "instruments" (or whatever they are called now) are pretty good for profiling code.
To be a little bit more specific:

For writing code I use Atom. Which I also write my build.sh script with. Though there isn't a lot to write. My build script contains the following single line of code:

1
clang -Wall -framework Cocoa -framework OpenGL code/main.mm -o build/main


I don't quite understand whats actually about all these build system and IDE's. However I'm not an experienced programmer but I don't know what anyone would add to this build script. It compiles and stuff works. Unfortunately I haven't found any tutorial on what build scripts do and should do.

Then to run the build.sh I use iTerm2. iTerm2 is like the default Terminal on OS X but with more Preferences.
For example I set iTerm2 to act like the Quake terminal which slides down from the top. So on pressing alt & space the terminal slides down and is also the active window. So I don't have to click and can directly type "sh build.sh" to compile the code. An improvement would probably be an editor that has a built in console like Casey's version of Emacs seems to have. But OS X's Emacs looks way different. And I haven't tried it yet. There is also Vim? Which is preinstalled on OS X as Emacs.

Yeah and thats quite it. I don't know yet how to setup Xcode to just act as a debugger. As it is now I had the experience that Xcode actually sees different contents in the .m/.h files then atom does. And I also don't know if you need a .xcodeproj and how this would affect the code.

Since I'm not too experienced I thought about creating a own debugger but this step now seems extremely complicated as you would have to do mostly everything in Assembly I guess.

Thats it. But if you don't know iTerm2, I can't recommend it enough. I discovered it today because I was searching for a way to dock the Terminal somehow to the Desktop. And now it fades in from the top triggered by key and stays docked at the top until you want it to be gone.
cmuratori
Quick aside: I would like to get 1935 building on the Mac sometime in the future...

And what does that mean?

Edited by Adrian on
It means Casey will want to run/ship his 1935 game on OSX.

Btw running just the clang to compile & create executable output file will create only a darwin executable. To create proper OSX app, you'll need to do a bit more stuff. OSX apps are actually folders with special structure and bunch of metadata like icons.
Here's more documentation on it: https://developer.apple.com/libra...es/Introduction/Introduction.html
They can be easily created by hand, Xcode is not mandatory for this.

iOS applications have exactly same app format.


Edited by Mārtiņš Možeiko on
Yes, it's the whole create-a-bundle situation that I was curious about. I remember shipping Granny on OSX way back in the 1999-2004 time period when OSX was just coming around, and I seem to remember writing an actual little utility that created the right files and hierarchy after the build was done... I would be interested to know what people are doing for that, if anyone is...

- Casey
I think the only new thing would be code signing, which is done with codesign
I'm far from an expert but I have played around with this stuff a bit. It's an understatement to say that Apple's developer tools aren't really designed with cross-platform development in mind.

There are basically two "minimal" ways to build a Mac App. One is to create an Xcode project and then just do all the building from the command line with the xcodebuild utility. This is a bit of a pain but it has the advantage that you can open the project up in Xcode when you do want to use some of Xcode's features.

This has disadvantages: it's not totally "minimal" and it is substantially slower than building a binary with just llvm. Plus anytime you add a file you need to add it to the project in Xcode, too. But it has advantages. It can sometimes be tricky to figure out what flag you actually want to pass to which part of the toolchain because the documentation really just refers to the gui settings in Xcode, so sometimes just doing things the way Apple wants you to saves time.

The other way is to just use a build script or make or whatever and build a binary with llvm.

You can build a bundle hierarchy in your build script with just mkdir. It works just fine in El Capitan. I've tried running a bundle that really just contains a binary in 'Contents/MacOS/' and it works, but I don't think it's actually supposed to work. You're supposed to have an Info.plist (just an xml file with some configuration information) and some other stuff. You definitely can just build that stuff up yourself if you want to. See https://developer.apple.com/libra..._ref/doc/uid/10000123i-CH101-SW19 (this is "Anatomy of an OS X Application Bundle" in Apple's developer docs in case that link breaks).

Another option is to build and run your debug builds with just a build script to speed development up, (you can invoke the binary from the command line without a surrounding app bundle and it will run) and use Xcode to make the bundle for your release. Obviously just running the executable will only work if you're not using any of the functions that require the app bundle structure to fetch resources or dynamic libraries

I use lldb from the command line sometimes because it's noticeably faster than using it through Xcode. At least with the last version I tried it with, Xcode will crash if you try to debug more than one process at once, so if you're working on anything multi-process you'll need to use the command line lldb.

Edited by honestb on
honestb
There are basically two "minimal" ways to build a Mac App. One is to create an Xcode project and then just do all the building from the command line with the xcodebuild utility. This is a bit of a pain but it has the advantage that you can open the project up in Xcode when you do want to use some of Xcode's features.

This has disadvantages: it's not totally "minimal" and it is substantially slower than building a binary with just llvm. Plus anytime you add a file you need to add it to the project in Xcode, too. But it has advantages. It can sometimes be tricky to figure out what flag you actually want to pass to which part of the toolchain because the documentation really just refers to the gui settings in Xcode, so sometimes just doing things the way Apple wants you to saves time.

It's worth mentioning that when you do this, you can go to xcode's build log to see what commands it runs--it's certainly the case Apple's documentation is heavily geared towards xcode, but the tools are documented by man pages. xcodebuild ultimately doesn't do anything except manage the build process, so each necessary step in doing it yourself can be discovered this way (afaik!)

for many people writing a script to compile on OSX is setting up an xcode project and running xcodebuild, which is faintly absurd to me

honestb
Another option is to build and run your debug builds with just a build script to speed development up, (you can invoke the binary from the command line without a surrounding app bundle and it will run) and use Xcode to make the bundle for your release. Obviously just running the executable will only work if you're not using any of the functions that require the app bundle structure to fetch resources or dynamic libraries

I've had success just dumping newly compiled executables into a pre-existing bundle. Xcode can be a bit finicky about what it thinks it is able to debug, though, and this kind of half solution is why I know that xcode will set DYLD_LIBRARY_PATH environment variable, and that calling dlopen() with an absolute path will first check to see if the leaf name matches anything in DYLD_LIBRARY_PATH before checking the actual absolute path you gave it, which I am still extremely upset, confused, and hurt by
For my project I write code in a text editor (Sublime), build from the command line, and debug from Xcode like Casey does with VisualStudio on Windows.

So my setup is:

1) Bash file to build executable and create app bundle:

clang [...] -c my_game.mm
clang [...] -o my_game my_game.o

mkdir -p MyGame.app/Contents/MacOS
mkdir -p MyGame.app/Contents/Resources
cp my_game MyGame.app/Contents/MacOS/MyGame
cp my_assets/my_icon.icns MyGame.app/Contents/Resources/icon.icns
cp my_assets/my_info.plist MyGame.app/Contents/Info.plist

2) Dummy Xcode project to debug executable

To do that:

- Create a new OSX Xcode project
- Delete the existing target
- Create a new "External Build System" target
- Give it an empty bash file to build
- Edit the scheme
- In the Run options give it the path to the executable to debug.

You can can also point Xcode to your code directory if you want to browse your files.

You can do the same thing with iOS.