NetBeans IDE (as of version 7.0) is not yet usable for Mozilla C/C++ development. This page is currently being used to document how NetBeans would be set up for Mozilla development, and the problems that prevent it from being usable, or at least semi-usable. This documentation is currently primarily intended for the NetBeans developers, to help them reproduce the problems experienced when trying to use NetBeans for Mozilla development. The NetBeans work specifically to get NetBeans working well with Mozilla is tracked in NetBeans Bugzilla, bug 197297.
Building Firefox source
Why do we start a document on using an IDE with a section on building the source? For the code intelligence type features of IDEs like NetBeans to work correctly, it is necessary for the IDE to know a sane set of build options for the source files. It needs this information to determine the value of preprocessor defines, source file include paths (to find the correct headers, and the things that they define), etc. There are two ways that IDEs typically (and NetBeans specifically) determine this information for projects where the IDE does not managing the build system; either the IDE parses the output from an actual build (or a build log), or else the binaries must be built with specific debug information and the IDE examines the binaries. At any rate, that's why we're talking about building here...
With a few modifications (see below before proceeding!), the Simple Firefox build wiki page provides good documentation on how to get the Firefox source code and how to build that source.
Modification 1: To get the build to produce console output and binaries that NetBeans can extract the build options from, we need to set a few configuration options. To do this, create a file called ".mozconfig" in the root source directory, and give it the following contents:
. $topsrcdir/browser/config/mozconfig # Put the object files in an object directory: mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-debug # Make a debug build, since that's what most Mozilla devs would want: ac_add_options --enable-debug --disable-optimize ac_add_options --enable-debug-symbols # Build with
-g3-gdwarf-2for GCC (-g for Solaris) so that the binaries # will contain information about the build options. export CFLAGS="$CFLAGS -g3 -gdwarf-2" export CXXFLAGS="$CXXFLAGS -g3 -gdwarf-2" # Do NOT build with -j, otherwise the build log will be useless. Do # build with -w so that we get the "Entering/Leaving" lines in the output. mk_add_options MOZ_MAKE_FLAGS="-w"
Modification 2: Instead of building with simply 'make -f client.mk', log the build output to a file so that NetBeans can be asked to process the build output without doing a full build again. Do that by using:
make -f client.mk 2>&1 | tee build.log
Modification 3: Optional time saver. While it is preferable to get the source code from Mozilla's mozilla-central repository using hg so you're testing with the latest code, it is not absolutely necessary. If you're short on time, patience or bandwidth, you can download a snapshot of the source for the latest Firefox release instead. For example, Firefox 5.0's source is here (tar -xjvf to extract). Note that to build this source, instead of using 'make -f client.mk', I believe you need to use:
( configure && make ) 2>&1 | tee build.log
This applies both here and elsewhere in this document.
Once your build has successfully completed, you should have a firefox binary at obj-debug/dist/bin/firefox, and a build log in build.log.
Creating a NetBeans project
A project for a large codebase like Mozilla's requires extra memory, so start Eclipse with -J-Xmx1500m in the arguments:
When NetBeans opens:
- Click the New Project button, select "C/C++ Project with Existing Sources", then click "Next".
- Specify the root source directory of your copy of the Firefox source, select the configuration mode "Custom", then click "Next".
- Specify "Using an existing makefile", specify the path of the Makefile in the 'obj-debug' directory the earlier build created, UNselect the "Clean and Build after Finish" option, and click "Next".
- Specify the "Working Directory" to be the root source directory, specify the "Build Command" to be "make -f client.mk", specify the "Clean Command" to be "make -f client.mk clean", specify the "Build Result" to be the path to 'obj-debug/dist/bin/firefox', then click "Next".
- Change "Exclude Pattern" to "^(nbproject|.hg|test|tests)$", then click "Next". XXX really we want to at least partially exclude stuff from obj-debug, but there are a bunch of generated headers in there we need. Need to check if excluding that directory entirely prevents NetBeans from using include paths pointing into it.
- Select "Automatic Configuration" and click "Next".
- Give the project a meaningful name, probably you should change the "Project Location" to be the root source directory (rather than that directory's parent), UNselect "Set as Main Project", then click "Finish". XXX no, wait. Go back to step 5 and change 'nbproject' to the name you just gave the project, since that's the subdirectory that's about to be created in the root source directory.
Step 3 is not offer a good match to the way we build Mozilla. We really want to build using "make -f client.mk", but I guess the later steps allow working around this.
After clicking "Finish" in step 7, NetBeans did a clean and rebuild despite UNselect the "Clean and Build after Finish" option in step 3, which was rather annoying given how long it takes to build. (Really this checkbox should probably be on the finish screen anyway?)
Once the rebuild is complete, NetBeans spent an inordinate amount of time parsing the source and header files in the project - presumably this is the indexer at work? Whereas Eclipse will take about a minute to completely rebuild its index, NetBeans takes about twice as long as it takes to build the source, which for me was over an hour and a half. Once the parsing of all 12184 files was finished, it seemed to display the "parsing" message sitting at 100% for quite a while.
With the parsing finished, NetBeans was almost unusable because it took seconds to respond to user input. Click on a menu, wait for it to open. Go into a menu, wait for the sub menu to appear. Search for a file, wait seconds for it to find it (despite having and index). Open a file, wait quite a while for it to open. Try and scroll a file (nsFrame.cpp in my case), wait seconds between each change in scroll position.
I left my computer for a bit, and when I came back NetBeans was parsing all over again, and this time took over two hours. Once it reached 100% again, it said an exception had occurred: "java.io.UTFDataFormatException: malformed input around byte 55", and currently it is sitting at 100% CPU, and the 100% message isn't going away.