Over the last two years, I've been doing most of my programming assignments in a Linux development environment. I've coded in Eclipse, Netbeans, Code::Blocks, Vim, (very briefly) emacs... and for build/config management I've used make, Ant, Maven, Ivy, and of course the IDEs. This is all to say that I've experienced a number of different approaches for building projects while I've been in school. Of course, sometimes getting these things functioning properly -- whether with homegrown code or projects based on code provided by instructors -- has required some extra steps and/or troubleshooting.
What's the point?
I've been puttering around attempting to set up some sort of developer environment. Homebrew and Homebrew Cask actually make a lot of installation tasks dead simple (yay for good command line tools!), but I ran in to trouble when I tried to test compile one of my academic projects. It uses a relatively simple makefile -- written for Linux of course. After double-checking the makefile, my assessment was that it should not need significant alteration to run in my OSX environment, but theory and practice are two different beasts!
I tried to compile without modification, which resulted in lots of warnings, and eventually failure with this message:
error: invalid integral value 'g' in '-Og'
The flag in question was introduced in GCC 4.8's changelog:
A new general optimization level, -Og, has been introduced. It addresses the need for fast compilation and a superior debugging experience while providing a reasonable level of run-time performance. Overall experience for development should be better than the default optimization level -O0.
Apparently Apple's LLVM version of clang doesn't support that particular compiler flag from GCC 4.8. Which is fine, but forced me to choose whether I wanted to change my makefile to fit OSX or to compile and install GCC...
I chose to install GCC.
brew install gcc
Which is a nice easy command, right? Suuuuure it is, but I might have saved some time if I had done more googling before pulling that trigger. Homebrew downloads and compiles things from source, but it also has "bottled" versions of software that are installed as binaries. I'm still not quite clear on how to determine which one you're getting or if there's a way to force one over the other, but my poor i5-2540m took 90 minutes to compile GCC. (If I find the answer I'll post an update.)
Edit: I've posted a follow-up here with additional information on the compile-from-source vs. binary situation.
Once GCC finally finished, I had to set it up to replace the OSX versions of things -- since I still didn't want to have to change my makefile. This wasn't hard and primarily consisted of adding export PATH=/usr/local/bin:$PATH
to ~/.profile
, ~/.bash_profile
, or ~/.bash_login
-- modify where appropriate for your shell of choice.
And last, I needed to name things correctly, since the GCC installation had not, by default. These commands did the trick:
cd /usr/local/bin
ln -s gcc-5 cc
ln -s gcc-5 gcc
ln -s c++-5 c++
ln -s g++-5 g++
Using symlinks allows me the flexibility to temporarily delete them if I need to restore Apple's LLVM compiler functionality for a specific piece of software, and they'll also get removed properly if I ever use the brew uninstall gcc
command to remove the whole package.
Once /usr/local/bin
is added to PATH
(so either reload the terminal or export manually), these aliases take precedence over the OSX defaults and should get called without any further intervention in things like makefiles.
Success!
All that done, and my makefile works. I did have to add another flag (-Wno-sign-compare
) to get rid of those other warnings that I wasn't getting under Linux. However, I didn't have any philosophical problems making that change since it will also work properly if I need to go back and compile in Linux again. Otherwise though, no changes necessary and my software builds and functions the same in an OSX terminal as it did in a Linux terminal. I'm pretty happy about that, because I like having flexibility and portability in my working environment.