Compiling the C30 gcc compiler on Mac OS X (Leopard)
UPDATE July 23, 2009: I’ve added a build transcript to the tarball so that you can compare your build output to mine, and also added the full path to sed in the script. Get it here.
I switched to Mac a couple of years ago, but still find myself dependent on MS Windows for electronics and embedded software development. Fortunately more tools are getting available for Linux and hence Mac as well, which is good (AVR tools are a great example).
This week I’ve been fiddling with a dsPIC33 device from Microchip. It works fine in MPLAB (apart for the occasional crash or USB hang for the programmer) but I get tired of having to work with MS Windows. So I started searching for a C30 compiler for Mac. Unfortunately, I haven’t found (a free) one yet, but I discovered that the MPLAB C30 compiler is actually based on the gcc compiler, so it should be possible to make it work on OS X.
Microchip has published the gcc and binutils source code on their website (which they have to do due to the GPL) so that’s an easy start. After some googling I also found the debian packages made by John Steele Scott.
Compiling gcc and using the patches from the debian packages made me come close to a working compiler, but not completely. These were the problems I still had to address before getting a working compiler:
- binutils: I got configure errors due to the fact that conftest.dSYM directories were left in the way. Apparently this is due to a new default option with Xcode when compiling with debug option on. To fix it I would have to regenerate the configure files with a newer autoconf/automake. Instead I solved it by compiling without the debug option (removed -g from the CFLAGS).
- gcc: at startup gcc would crash in some internationalization init code. I solved this one by compiling with –disable-nls, which disables the internationalization in gcc. I think I can do without compiler warnings in dutch…
- gcc: crash at startup in some default library path juggling code. I found out that gcc would start up without crashing when I moved it out of the install directory. Fixed it by patching out the offending code.
- gcc: at install it would put double target strings in executable names (like pic30-elf-pic30-elf-gcc), fixed with an extra sed command after installing.
The build script and patches are based on version 3.10 of the compiler and binutils.
Download the build scripts and patches tar ball here.
Make sure you read the README file, it contains more info than written down here.
To build, you’ll need to do the following:
- Unpack the tar ball in a suitable location.
- Get an installation of MPLAB C30 on a Windows machine. Find the MPLAB C30 directory in the MPLAB installation directory and zip it. Make sure the resulting zip file is named “MPLAB C30.zip” and copy it to the same directory as where the build script is located.
- Download mplabalc30_v3_10.tar.gz (binutils) and mplabc30v3_10.tar.gz (gcc) from the MPLAB website. Look for the C30 compiler and then archived versions. Put the two tar.gz files in the same directory as where the build script is located.
- Run the build script. It will unpack, patch, compile and install the files into the directory “install” (residing in the same directory as the build script).
- Review the installation in the install directory. Now you can do three things: a. add the install directory to your path and call it a day, b. manually copy everything over to another place or c. change the PREFIX variable at the top of the build script and run it again (maybe you’ll need to sudo depending on the permissions in the PREFIX directory)
Now the next challenge will be to incorporate it into Xcode…
January 11th, 2009 at 2:46 am
Hey, thanks for posting this. I tried out your instructions but a crash dialog came up while building the GCC toolchain. Nonetheless, the build script runs through to completion. However, any time I try to run the compiler it says things like this:
main.c:1: error: Invalid -mcpu option. CPU 30f3013 not recognized.
no matter what value of -mcpu I pass in.
Here is the contents of the Crash Reporter dialog box:
Process: as [10915]
Path: /opt/pic-mac/install/pic30-elf/bin/as
Identifier: as
Version: ??? (???)
Code Type: X86 (Native)
Parent Process: sh [10914]
Date/Time: 2009-01-10 21:41:54.951 -0500
OS Version: Mac OS X 10.5.6 (9G55)
Report Version: 6
Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0×0000000000084318
Crashed Thread: 0
Thread 0 Crashed:
0 libSystem.B.dylib 0×9471a7c4 strcpy + 52
1 as 0×0006c95b process_resource_file + 59
2 as 0×0006d012 pic30_update_resource + 258
3 as 0×0003c30d bfd_init + 29
4 as 0×00004ae7 main + 183
5 as 0×00001dd6 start + 54
Thread 0 crashed with X86 Thread State (32-bit):
eax: 0×0000002f ebx: 0×0006c28b ecx: 0×00084327 edx: 0×00000008
edi: 0×00084318 esi: 0×00084335 ebp: 0xbfffeec8 esp: 0xbfffee88
ss: 0×0000001f efl: 0×00010206 eip: 0×9471a7c4 cs: 0×00000017
ds: 0×0000001f es: 0×0000001f fs: 0×00000000 gs: 0×00000037
cr2: 0×00084318
Binary Images:
0×1000 – 0×85fe7 +as ??? (???) /opt/pic-mac/install/pic30-elf/bin/as
0×8fe00000 – 0×8fe2db43 dyld 97.1 (???) /usr/lib/dyld
0×906dd000 – 0×906e1fff libmathCommon.A.dylib ??? (???) /usr/lib/system/libmathCommon.A.dylib
0×946ef000 – 0×94856ff3 libSystem.B.dylib ??? (???) /usr/lib/libSystem.B.dylib
0×95815000 – 0×9581cfe9 libgcc_s.1.dylib ??? (???) /usr/lib/libgcc_s.1.dylib
0xffff0000 – 0xffff1780 libSystem.B.dylib ??? (???) /usr/lib/libSystem.B.dylib
January 11th, 2009 at 10:19 am
Hi Leo,
Looks like something didn’t build correctly on your system. What crash dialog did you see when running the build script? Or better:
would you be able to do a complete build from scratch with the build script, and send its output to a file, like this:
./build >& build.out
and send the build.out file to me?
January 11th, 2009 at 6:44 pm
I’ll try that next. Meanwhile, I got it to build by skipping the patches that change the search paths for .h and .inc files. I am mostly using the default support directory layout from Microchip’s C30 distribution. As far as I can tell, everything is working except for lines inside linker scripts that look like this:
OPTIONAL(-lp33FJ256GP710)
This line appears to instruct the linker to include the library that contains definitions of functions from uart.h, etc. The linker complains that this directive is a “syntax error.” If I comment out that line in the linker script and manually add the flag “-lp33FJ256GP710″ to my invocations of pic30-coff-ld, then my builds work.
Do you know why the linker would complain about that linker script directive?
January 11th, 2009 at 10:13 pm
Leo: now that you mention it, I recall having the same problem with the linker script as well.
if you include the pic30-rules.mk file in your Makefile (see makefile_example) it will automatically add the “-lp33FJ256GP710″ (depending on the processor you mention in your own makefile) so I didn’t bother looking into it.
The OPTIONAL keyword is not mentioned in the gnu documentation for the linker, so maybe it is something Microchip added in their Windows version? I don’t know.
January 12th, 2009 at 2:34 am
It appears the trick is that you have to ‘touch’ all of the .y and .f files in the “acme” directory before building binutils. Once you do this, pic30-ld will recognize those linker scripts. I appear to now have a fully functional C30 toolchain, using a stock “support” folder from the MPLAB C30 distribution. I’ll try to clean up what I did so I can send you the modifications I made to your build script.
I’m very grateful for the instructions you posted. I have been using C30 under Wine for some time, and though it was very reliable it was also very slow. It used to take several minutes for me to build the firmware on the device that I am working on; with the new toolchain I built it takes about two seconds (on a MacBok Pro, 2.16 GHz Intel Core 2 Duo).
January 12th, 2009 at 7:14 am
Ah! The acme directory! I did touch the .y files in the gcc build, but forgot to do that in the acme build!
Thanks for finding this. I’ll update the script. I’m curious to see what other changes you made for building!
January 12th, 2009 at 1:38 pm
Hi.
Thanks a lot for your effort, this is much needed!
I happen to have the same crash than Leo (first comment), what ever I do. Simply calling “pic30-elf-as” leads to the crash, with similar log. “pic30-elf-gcc” seems to rely on pic30-elf-as, and thus wont work (indicating that pic30-elf-as crashed).
Any idea how to fix that?
Thanks a lots
Antoine
January 12th, 2009 at 6:13 pm
Hi Antoine,
Did you follow the build script exactly or did you make changes for your own setup?
Can you try again from scratch and send me a log of the build?
(like above:
and send me the build.out file)
Thanks!
January 12th, 2009 at 6:45 pm
How do I attach a file to this page? I want to send my build script.
January 12th, 2009 at 6:51 pm
bas,
I’ve followed pretty much exactly your instruction for the build. I’ll send you an email asap with a log and further details on what breaks.
Thanks again for your efforts!
Antoine
@Leo: I guess you can use the email address at the bottom of this page
January 12th, 2009 at 11:44 pm
Based on the feedback from Leo and Antoine (thanks!) I’ve updated the build script in the tar ball. Click here to get it (same link as in the text above).
I’ve added a command that touches all .y and .l files in the binutils before building, so that the lex and yacc scripts will be rebuild, and I’ve added a
option to the configure script of binutils (appearantly not only gcc suffers from this problem, but also binutils). This avoids a failing linker binary for users with different locale settings/libraries than me.
January 13th, 2009 at 9:23 am
“Side side note”: the RSS feed for these comments does not seem to work. It’s a shame, because I would not want to miss anything
January 13th, 2009 at 6:41 pm
It appears that the GNU license permits redistribution of this compiler in binary form. Would it be legal to distribute a Mac OS X installer for pic30-gcc and binutils? I don’t see any reason why not.
The standard library, headers, and linker scripts would have to come separately, of course. That wouldn’t be a big problem because any user that has any kind of license, whether the full professional version or the free educational version, for Microchip C30 has a copy of the standard library already.
I have been using Xcode with SCons for cross-platform embedded development for about a year. However, I see no reason why one couldn’t use Xcode directly for building PIC30 projects. Xcode should be able to parse debugging symbols from C30 object files, for auto-complete.
I am tempted to take a stab at a set of Xcode project templates for C30.
January 13th, 2009 at 7:52 pm
Here’s a page that has some info on how to put together Xcode plugins:
http://maxao.free.fr/xcode-plugin-interface/index.html
However, the compiler spec appears to be outdated. For one, the “.pbcompspec” files that they talk about are replaced by “.xcpsec” files in Xcode 3. Some reverse engineering would be required to make an Xcode plugin for PIC30.
January 13th, 2009 at 8:14 pm
Sounds like a nice plan!
Until now lack of time has held me back of trying to plug it into Xcode (I’m using textmate right now).
Now if we could implement remote debugging via Xcode, that would be code nirvana
January 13th, 2009 at 9:32 pm
@Antoine: did you subscribe to the feed linked just above the start of the comments (at the end of the text) or did you use the RSS icon in the address bar? The former should track changes to the comments on this page, the latter tracks changes to the blog itself.
January 13th, 2009 at 10:05 pm
Oh. Strangly enough, firefox wont show any content for the feed, but my feed reader (actually Mail.app) shows the correct content. (I was using the correct link.) It’s all fine now, thanks!
January 14th, 2009 at 4:40 pm
So I symlinked all the pic30-coff-* executables to pic30-* because my build scripts all use the pic30-* variants. I put the symlinks in a separate directory from the executables. When I tried building my project, the compiler crashed. This was because it was looking for the file “c30_device.info” relative the symlink I made.
Bas, many of your patches relate to the resource paths and hard-coding them into the compiler. Microchip’s convoluted path parsing code is clearly designed to handle the situation where the whole packing is copied to a folder specified by the user, long after the package was built with “make install”. Is Microchip’s technique for doing this worth keeping? Someone should try moving the base folder of their pic30 installation and see if it still works. If it does, then Microchip’s relative paths might make creating an installer much simpler.
Also, I realized that my patch for the file “c30_resource_paths.h” was only necessary because in Microchip’s distribution there are two copies of the .gld and .inc files: with the assembler and with the compiler. There are two ways to handle this: 1) modify the toolchain’s hardcoded relative search paths or 2) symlink/copy resouces the the appropriate locations so that the directory layout is identical to Microchip’s. Which would be preferable?
January 15th, 2009 at 1:05 am
That’s right, the resource path handling leaves a lot to be desired.
The resource path stuff built by Microchip is probably targeted towards the windows platform, and probably not tested for unix like file systems, hence the crash.
Anyway, my goal (and others, who actually made the patches – I just copy pasted mostly) was simply: ‘make it compile, get it to work’. Hence the shortcut taken by hardcoding the paths during the build process.
I think resolving this with symlinks feels a bit like a ‘last resort’. It would be better to fix the relative resource path code and include a couple of standard places where to go look for resource files (and gracefully fail if not found rather than crash). Those standard places should follow the way Apple organizes resource paths (for example for iPhone, or find out how it was done for the AVR gcc compiler).
July 24th, 2009 at 7:18 am
The best information i have found exactly here. Keep going Thank you