Building the Firefox source
First, get a copy of the Mozilla source and build it, and when that page talks about creating a .mozconfig file, create a .mozconfig containing something like the following:
# 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 # Parallelize and silence the build to speed it up: mk_add_options MOZ_MAKE_FLAGS="-j4 -s"
Once you work out any kinks and you manage to build successfully using the instructions linked above, then you can move on to setting up NetBeans to manage the code and to do your first build from inside NetBeans. (After the build you should have a firefox binary at obj-debug/dist/bin/firefox.)
Download and install one of the NetBeans installers that supports C/C++. You can try the latest NetBeans release, but you're more likely to get a better results using the latest NetBeans nightly since the NetBeans team has recently been working on fixing the issues that prevent it working well with the Mozilla source.
Choose a JVM. For example, Fedora 21 comes with OpenJDK 64-Bit Server VM (build 25.31-b07, mixed mode), which made debugging very slow and not responsive. NetBeans for PHP/C++ x64 comes with Oracle Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode). That was better than OpenJDK. Installing Oracle’s JDK 1.8.0_40 x64 as an RPM seems even better. Beware that development versions of NetBeans may contain bugs (e.g. netbeans-dev-201504030001-x64 showed strange exceptions, sometimes so many times that it was unusable).
IMPORTANT - Java heap space
NetBeans needs a very large amount of memory (3+ GB free) in order to complete a proper analysis of the Mozilla source code. Before you try and use NetBeans with the Mozilla source you need to increase its maximum heap space so that it can actually use that much though. There is no one size fits all value for this heap space setting, however - the value you should choose depends on your hardware and on the particular JVM that you have installed (the information below will help you choose a value). Just note that if you set too low a value, NetBeans will become increasingly slow as it approaches the heap limits. This is particularly likely to happen while NetBeans tries to analyze the source code, when too small a heap size may cause it to become completely unresponsive for extended periods, and may result in various out of memory exceptions (which may degrade the results of the analysis, assuming it even completes).
There are several things to consider when choosing your java version and your heap space limits. 64-bit JVMs may use twice as much memory as their 32-bit counterparts. Unfortunately, it may not be possible for you to use the 32-bit version of your JVM, since some 32-bit JVMs have too low a cap on the maximum heap space that you can set. That said, some 64-bit JVMs support
UseCompressedOops which can reduce their memory consumption closer to that of their 32-bit counterpart.
The first thing to do is to figure out how to run the different (the 32-bit and 64-bit) versions of your JVM. Sometimes these are at different paths, and sometimes you run the same JVM but pass it -d32 or -d64 to choose between the two (try 'java -version -d32' and 'java -version -d64' at a console to see if those work).
Next, test whether your 32-bit JVM supports 3 GB of heap space by running something like the following at a console window:
java -d32 -Xmx3G
If it does, then you can use the 32-bit JVM which will keep NetBeans' memory use to a mininum. If it doesn't, then test to see if your 64-bit JVM supports
UseCompressedOops, using something like:
java -d64 -XX:+UseCompressedOops
With these two pieces of information obtained, edit the netbeans.conf file in your NetBeans installation to increase the maximum heap space, to choose between the 32-bit or 64-bit JDK, and to pass
UseCompressedOops if you chose the 64-bit JVM and it supports that option. If you're using a 32-bit JVM, set the maximum heap space to 3 GB, and if you're using a 64-bit JVM set it to at least 4 GB. Note that you must prepend "-J" to the JVM options so that NetBeans knows to pass them on to the JVM -- so '-XX:+UseCompressedOops' would become '-J-XX:+UseCompressedOops', for example.
Creating a NetBeans project
- Open NetBeans, open its global preferences ("NetBeans > Preferences" on Mac; "Tools > Options" on Linux), select the "C/C++" tab and then the "Project Options" tab, make sure that "Use Smart Build Analyzer to Configure Code Assistance" is selected, then close the preferences window.
- Click the New Project button, select "C/C++ Project with Existing Sources", then click "Next".
- Select the root source directory of your copy of the Firefox source, select the configuration mode "Custom", then click "Next".
- Select "Use an existing makefile", set "Existing makefile" to the path of the client.mk file in the root source directory, untick "Clean and Build after Finish", then click Next.
- Set the working directory to the root source directory, set the build command to 'bash -l -c "make -f client.mk"' (invoking bash to run make is necessary to avoid errors due to dependencies not being found because NetBeans' PATH is missing certain paths), set the clean command to 'rm -rf obj-debug' ('make clean' is not 100% reliable), set the build result to "obj-debug/dist/bin/firefox", then click Next.
- Change the exclude pattern to "^(nbproject|test|tests)$", then click Next.
- Select Automatic Configuration then click Next.
- Give the project a meaningful name, and probably you should change the "Project Location" to be the root source directory (rather than that directory's parent, which is what NetBeans chooses by default), deselect "Set as Main Project", then click "Finish".
After a moment or two the New Project wizard window will close, and you should see the message "Analyzing project" in the status bar at the bottom right of the window.
ARGH! After the "Analyzing project" stage (30 second or so) NetBeans will start parsing the source files in the project, even though you deselected "Clean and Build after Finish" and therefore it won't yet have the build information it needs to make sense of the code. Cancel it.
Once you've turned off code assistance (for now), right click on the project name in the Projects tab on the left, and open the project specific properties by selecting Properties. Make the following changes:
- Select "Run" from the left and deselect "Build First" (otherwise NetBeans will first rebuild the entire tree each time you try to run Firefox, which will drive you mad).
That done, re-enable Code Assistance using the context menu for the project in the Projects tab on the left, then click the "Clean and Build project" button to start your first full rebuild from inside NetBeans. If you're asked to select an assembler, select /usr/bin/yasm. Once this is finished building, NetBeans will automatically start parsing the files in the source tree with the information it gathered during the build so that it can make better sense of the source code and provide much improved code assistance. This will take about XXX.
Just getting started on this list.
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, no, since that's when you're finishing?)
Why is NetBeans 7.1 on Fedora 16 refusing to allow the build to happen without first selecting an assembler? The Mozilla build system should be the only thing to check for the required tools.
Code assistance problems
There are various code assistance issues.
Type hierarchy not working
The type hierarchy feature doesn't seem to be working at all. For example, open the file nsSVGElement.h, select the symbol "nsSVGElement", right click on in and then from the context menu select "Navigate > View Type Hierarchy". The window that opens only contains a single "nsSVGElement" item. (This despite the fact that NetBeans seems to know the inherited classes since in the header it provides information about which base class methods the virtual methods are overriding.)
Call graph doesn't include callers in marcos
nsStyleFont::nsStyleFont(const nsStyleFont& aSrc) and
nsStyleFont::nsStyleFont(nsPresContext* aPresContext) are both called twice in the
COMPUTE_START_INHERITED macro when it's used on the very first line of
nsRuleNode::ComputeFontData. If you ask NetBeans for the call graph for either of these constructors, it fails to include
ComputeFontData among the callers though.