Eclipse CDT

  • Revision slug: Eclipse_CDT
  • Revision title: Eclipse CDT
  • Revision id: 3386
  • Created:
  • Creator: Jonathan_Watt
  • Is current revision? No
  • Comment 1 words added, 2 words removed

Revision Content

Using Eclipse CDT for Mozilla development

The Eclipse CDT (C/C++ Development Tools) is an open-source IDE for C and C++ development. The CDT is designed to support projects that have their own build systems and complex project structure. If you loathe emacs and want to use an editor with a modern UI with antialiased text and working syntax highlighting, and yet most of the features of emacs (e.g., alt-/ abbrev completion), then Eclipse CDT might be for you.

Note that Eclipse CDT will typically use in excess of 600 MB of RAM just to load an Eclipse project that has indexed a copy of the Mozilla source code. The functionality it provides makes this well worth it if you have enough RAM, but it may make Eclipse unusable with the Mozilla if you don't.

Initial setup

The following instructions are for Linux. If you have experience with Win32, please note it here.

  • Install Eclipse IDE for C/C++ Developers.
  • Obtain a clean copy of the Mozilla source.
  • Make a buildable Mozilla tree with the object files in an objdir. For example, sources in "src/", object files in "src/obj-debug".
  • Things will be a little quicker if you delete any unnecessary files from the source directory, e.g., "*~" emacs backups, "*.rej", "*.orig" and ".#*" patch detritus.
  • Start Eclipse and when prompted to "Select a workspace" just accept the default - we'll give our Mozilla project(s) their own workspace(s) rather than using this one anyway.
  • Fire up Eclipse and do File > New > C++ Project to start the C++ Project wizard.
    • Enter a meaningful project name identifying the Mozilla source tree this project will manage. (The Eclipse help docs say "do not use spaces or special characters in the project name".)
    • Uncheck the "Use default location" box, and enter the path of the directory containing the Mozilla source.
    • Pick "Makefile Project"
  • Now you can finish the wizard. You should get a Project view in the left with a directory tree you can browse to find files to edit. (Tip: Ctrl-F brings up a fast-find textbox for quick selection of files from opened directories.)
  • Doubleclick on a file to edit it. It should be syntax highlighted. There should be an outline in the right-hand pane that shows the gross constructs in the file. (Sometimes elements are missing because the parser was recovering from an error --- this view doesn't parse include files).
  • You can tweak preferences to improve your life: menu Window | Preferences
    • In the General | Keys page, in the Modify tab, you can select the Emacs scheme if your fingers demand it
  • Turn off "Build Automatically" in the Project menu.

Editing Tips

Alt-/ emacs-style abbrev completion just works.

In the default key bindings, ctrl-J does incremental search. Some users find that they like to use ctrl-G for "next match" (because Firefox does) but in Eclipse that tries to locate the definition of an identifier, which can be very slow in Mozilla with the CDT. You may want to rebind ctrl-G to "next match" if it isn't already so bound.

You probably need to adjust the CDT editor preferences to always use spaces instead of tabs, and to indent by 2 spaces.

Eclipse doesn't exactly provide the emacs buffers setup, but it does go some way towards it. Press ctrl-E to get a list of active editors; typing into it gives you autocompletion of the editor/buffer name for you to switch to.

Extra CDT features

Building

You can configure CDT to build Mozilla by calling "make". Select the project in the project view, right click, choose Properties, C/C++ Make project, then you can configure how "make" is called. (For example, you may want to input the command for building your project as "make -f client.mk build".) Do a build by choosing Project | Build Project in the menus. It works OK but the obvious approach does a full build which is quite slow in Mozilla (we go through all directories twice, once for exports and once for the real build).

If you're brave you can turn on "auto build on save" in the project properties under "C++ Make Project" in the "Make Builder" tab, and/or by turning on Build Automatically in the project menu. I don't recommend it.

Build output appears in the Console view near the bottom of the window. Eclipse will do an OK job of matching compiler errors/warnings to source lines if you configure your Mozilla build with the gcc option "-fmessage-length=0". Just add the lines

export CFLAGS="-fmessage-length=0"
export CPPFLAGS="-fmessage-length=0"

to your .mozconfig. Errors and warnings will be marked in the source when you open an affected file. They will also appear in the "Problems" view near the bottom of the window.

Be aware that Eclipse's parsing of the build output can be screwed up if you use parallel make.

Intelligent Code Navigation

The CDT offers intelligent code completion, and source navigation and indexing. These features are currently too slow and have a few bugs that stop me from using them regularly with Mozilla, but they're fun to play with.

First you have to teach the Eclipse parser which files get built and with what options. If you do a clean build from Eclipse and it doesn't get screwed up, Eclipse will discover all the include files/directories and predefined preprocessor symbols for each file in the project. These are visible via Properties (in the context menu) for each file. Eclipse will also learn which files get built and which don't. Maybe a more reliable way to teach Eclipse this information is to do a clean build, redirect the output to a file, then in project properties "C++ Make Project" Discovery Options you can specify the build log file and choose "Load".

Now you should be able to use intelligent code completion. Start typing an identifier and press ctrl-space. You should get a popup list of the completions that are valid in the current scope --- including global functions and variables, applicable "this" members, members if you're completing a member access, and even macros. Unfortunately in the current CDT this always does a parse of the current translation unit up to the completion point, which takes several seconds for a large Mozilla file with a decent number of includes, so this isn't good.

You should also be able to navigate within the current compilation unit by holding down ctrl and then clicking on an identifier to jump to its definition. Again this requires parsing of the compilation unit.

For really slick navigation you need to index the Mozilla project by turning on the indexer (Project properties, C++ Make Project, C++ indexer). Starting with Eclipse 3.3.2, the indexation process was greatly improved and is worth executing once.

If you like living dangerously, in Preferences | C/C++ you can select "follow #includes when parsing working copies". Eclipse will then follow #includes when it does parsing to update the outline view. This slows things down massively and is not recommended, but without it, many of our macros will not be defined and either cause syntax errors in the quick parser which cause some constructs to be omitted from the outline due to error recovery, or some constructs will not be parsed at all because they're #ifdefed and Eclipse doesn't know that the macro is defined.

Debugging

You can use Eclipse as a front end to gdb. It simplifies debugging and variable watching.

First, you need to create a debug configuration.

 Select Run->Open Debug Dialog… from the Eclipse menu
 Right-click on C/C++ Local Application and select New
 Project: firefox (or select your project name)
 C/C++ Application: (select browse and choose mozilla/../obj-i686-pc-linux-gnu/dist/bin/firefox-bin)

Specific configuration

  1. In the Arguments tab, change the working directory to mozilla/../obj-i686-pc-linux-gnu/dist/bin/
  2. In the Debugger tab, remove the checkbox on "Stop on startup at:"
  3. In the Environment tab, create two variables (make sure you trim the names and values)
 Name:  LD_LIBRARY_PATH
 Value: .:./plugins:.
 
 Name:  LIBRARY_PATH
 Value: .:./components:.
GDB Timeouts

Out of the box, you may/will get GDB connection timeouts. This is because Eclipse is trying to push every subfolder in GDB's environment. The easiest way to resolve this issue is to remove any source entry from the debug configuration (Run->Open Debug Dialog...) in the Source tab. Doing so will unfortunately remove the binding between the binaries and the source code. To keep this feature working, you need to add a "Path Mapping" by clicking "Add..." in the Source tab. Once a "Path Mapping" is created, select "Edit..." and add an entry with these values

 Compilation path: / 
 Local file system path: /

This is the only known workaround to bind binaries to source files. It has been tested and works perfectly under Eclipse Europa (3.3.2) with Eclipse-CDT (4.0.3).

Build Parallelism

You can use distcc and the MOZ_MAKE_FLAGS build variable to distribute the compilation across a network. This greatly improves the speed of the build. The complete informations are available in the Mozilla Team Documentation - distcc.

CDT Issues

The CDT has some problems with Mozilla that need to be worked on.

  • Code completion and other operations that require a full parse tree are really slow because they parse the compilation unit from scratch every time. This can be fixed -- there is a plan. But it's quite a lot of work.
  • The parser has bugs. I get a few internal parser errors when parsing the common Mozilla include files that use slightly tricky constructs (e.g., nsCOMPtr). Some of these bugs should be easy to fix, others maybe not. Apparently these bugs are only in the "old" parser which is deprecated and will be completely replaced by the "new" parser, "soon", so it's not really worth working on these bugs.
  • It would be nice if Eclipse could pass information about what files have changed to the build process, which could then decide on a faster way to do the build (e.g., "just make in layout/"). I've actually written a small change to the CDT Make builder that lets you specify that as an option, in which case Eclipse sends the names of all changed files to your build tool. The build tool is a Perl script that figures out if a faster build is possible and if so, does it.
  • Debugging.
  • Some editing operations get sluggish when you have lots of files open (say, more than 20).
  • The GDB thread terminates unexpectedly and detaches from the Firefox bin. This is caused by the breakpoints currently set. When you restart your Eclipse environment and face such issue. Delete and readd the breakpoints in your list.

Revision Source

<h2 name="Using_Eclipse_CDT_for_Mozilla_development">Using Eclipse CDT for Mozilla development</h2>
<p>The Eclipse <a class="external" href="http://eclipse.org/cdt">CDT (C/C++ Development Tools)</a> is an open-source IDE for C and C++ development. The CDT is designed to support projects that have their own build systems and complex project structure. If you loathe emacs and want to use an editor with a modern UI with antialiased text and working syntax highlighting, and yet most of the features of emacs (e.g., alt-/ abbrev completion), then Eclipse CDT might be for you.</p>
<div class="warning">Note that Eclipse CDT will typically use in excess of 600 MB of RAM just to load an Eclipse project that has indexed a copy of the Mozilla source code. The functionality it provides makes this well worth it if you have enough RAM, but it may make Eclipse unusable with the Mozilla if you don't.</div>
<h3 name="Getting_Started">Initial setup</h3>
<p>The following instructions are for Linux. If you have experience with Win32, please note it here.</p>
<ul> <li>Install <a class=" external" href="http://www.eclipse.org/downloads/" title="http://www.eclipse.org/downloads/">Eclipse IDE for C/C++ Developers</a>.</li> <li>Obtain a <a href="/En/Developer_Guide/Source_Code/Mercurial" title="En/Developer Guide/Source Code/Mercurial">clean copy of the Mozilla source</a>.</li> <li>Make a buildable Mozilla tree with the object files in an objdir. For example, sources in "src/", object files in "src/obj-debug".</li> <li>Things will be a little quicker if you delete any unnecessary files from the source directory, e.g., "*~" emacs backups, "*.rej", "*.orig" and ".#*" patch detritus.</li> <li>Start Eclipse and when prompted to "Select a workspace" just accept the default - we'll give our Mozilla project(s) their own workspace(s) rather than using this one anyway.</li> <li>Fire up Eclipse and do <code>File &gt; New &gt; C++ Project</code> to start the C++ Project wizard.<br> <ul> <li>Enter a meaningful project name identifying the Mozilla source tree this project will manage. (The Eclipse help docs say "<a class=" external" href="http://help.eclipse.org/helios/topic/org.eclipse.platform.doc.user/gettingStarted/qs-07b.htm" title="http://help.eclipse.org/helios/topic/org.eclipse.platform.doc.user/gettingStarted/qs-07b.htm">do not use spaces or special characters in the project name</a>".)</li> <li>Uncheck the "Use default location" box, and enter the path of the directory containing the Mozilla source.</li> <li>Pick "Makefile Project"</li> </ul> </li> <li>Now you can finish the wizard. You should get a Project view in the left with a directory tree you can browse to find files to edit. (Tip: Ctrl-F brings up a fast-find textbox for quick selection of files from opened directories.)</li> <li>Doubleclick on a file to edit it. It should be syntax highlighted. There should be an outline in the right-hand pane that shows the gross constructs in the file. (Sometimes elements are missing because the parser was recovering from an error --- this view doesn't parse include files).</li> <li>You can tweak preferences to improve your life: menu Window | Preferences <ul> <li>In the General | Keys page, in the Modify tab, you can select the Emacs scheme if your fingers demand it</li> </ul> </li> <li>Turn off "Build Automatically" in the Project menu.</li>
</ul>
<h3 name="Editing_Tips">Editing Tips</h3>
<p>Alt-/ emacs-style abbrev completion just works.</p>
<p>In the default key bindings, ctrl-J does incremental search. Some users find that they like to use ctrl-G for "next match" (because Firefox does) but in Eclipse that tries to locate the definition of an identifier, which can be very slow in Mozilla with the CDT. You may want to rebind ctrl-G to "next match" if it isn't already so bound.</p>
<p>You probably need to adjust the CDT editor preferences to always use spaces instead of tabs, and to indent by 2 spaces.</p>
<p>Eclipse doesn't exactly provide the emacs buffers setup, but it does go some way towards it. Press ctrl-E to get a list of active editors; typing into it gives you autocompletion of the editor/buffer name for you to switch to.</p>
<h3 name="Extra_CDT_features">Extra CDT features</h3>
<h4 name="Building">Building</h4>
<p>You can configure CDT to build Mozilla by calling "make". Select the project in the project view, right click, choose Properties, C/C++ Make project, then you can configure how "make" is called. (For example, you may want to input the command for building your project as "make -f client.mk build".) Do a build by choosing Project | Build Project in the menus. It works OK but the obvious approach does a full build which is quite slow in Mozilla (we go through all directories twice, once for exports and once for the real build).</p>
<p>If you're brave you can turn on "auto build on save" in the project properties under "C++ Make Project" in the "Make Builder" tab, and/or by turning on Build Automatically in the project menu. I don't recommend it.</p>
<p>Build output appears in the Console view near the bottom of the window. Eclipse will do an OK job of matching compiler errors/warnings to source lines if you configure your Mozilla build with the gcc option "-fmessage-length=0". Just add the lines</p>
<pre class="eval">export CFLAGS="-fmessage-length=0"
export CPPFLAGS="-fmessage-length=0"
</pre>
<p>to your .mozconfig. Errors and warnings will be marked in the source when you open an affected file. They will also appear in the "Problems" view near the bottom of the window.</p>
<p>Be aware that Eclipse's parsing of the build output can be screwed up if you use parallel make.</p>
<h4 name="Intelligent_Code_Navigation">Intelligent Code Navigation</h4>
<p>The CDT offers intelligent code completion, and source navigation and indexing. These features are currently too slow and have a few bugs that stop me from using them regularly with Mozilla, but they're fun to play with.</p>
<p>First you have to teach the Eclipse parser which files get built and with what options. If you do a clean build from Eclipse and it doesn't get screwed up, Eclipse will discover all the include files/directories and predefined preprocessor symbols for each file in the project. These are visible via Properties (in the context menu) for each file. Eclipse will also learn which files get built and which don't. Maybe a more reliable way to teach Eclipse this information is to do a clean build, redirect the output to a file, then in project properties "C++ Make Project" Discovery Options you can specify the build log file and choose "Load".</p>
<p>Now you should be able to use intelligent code completion. Start typing an identifier and press ctrl-space. You should get a popup list of the completions that are valid in the current scope --- including global functions and variables, applicable "this" members, members if you're completing a member access, and even macros. Unfortunately in the current CDT this always does a parse of the current translation unit up to the completion point, which takes several seconds for a large Mozilla file with a decent number of includes, so this isn't good.</p>
<p>You should also be able to navigate within the current compilation unit by holding down ctrl and then clicking on an identifier to jump to its definition. Again this requires parsing of the compilation unit.</p>
<p>For really slick navigation you need to index the Mozilla project by turning on the indexer (Project properties, C++ Make Project, C++ indexer). Starting with Eclipse 3.3.2, the indexation process was greatly improved and is worth executing once.</p>
<p>If you like living dangerously, in Preferences | C/C++ you can select "follow #includes when parsing working copies". Eclipse will then follow #includes when it does parsing to update the outline view. This slows things down massively and is not recommended, but without it, many of our macros will not be defined and either cause syntax errors in the quick parser which cause some constructs to be omitted from the outline due to error recovery, or some constructs will not be parsed at all because they're #ifdefed and Eclipse doesn't know that the macro is defined.</p>
<h4 name="Debugging">Debugging</h4>
<p>You can use Eclipse as a front end to gdb. It simplifies debugging and variable watching.</p>
<p>First, you need to create a debug configuration.</p>
<pre class="eval"> Select Run-&gt;Open Debug Dialog… from the Eclipse menu
 Right-click on C/C++ Local Application and select New
 Project: firefox (or select your project name)
 C/C++ Application: (select browse and choose mozilla/../obj-i686-pc-linux-gnu/dist/bin/firefox-bin)
</pre>
<p>Specific configuration</p>
<ol> <li>In the Arguments tab, change the working directory to mozilla/../obj-i686-pc-linux-gnu/dist/bin/</li> <li>In the Debugger tab, remove the checkbox on "Stop on startup at:"</li> <li>In the Environment tab, create two variables (make sure you trim the names and values)</li>
</ol>
<pre class="eval"> Name:  LD_LIBRARY_PATH
 Value: .:./plugins:.
 
 Name:  LIBRARY_PATH
 Value: .:./components:.
</pre>
<h5 name="GDB_Timeouts">GDB Timeouts</h5>
<p>Out of the box, you may/will get GDB connection timeouts. This is because Eclipse is trying to push every subfolder in GDB's environment. The easiest way to resolve this issue is to remove any source entry from the debug configuration (Run-&gt;Open Debug Dialog...) in the Source tab. Doing so will unfortunately remove the binding between the binaries and the source code. To keep this feature working, you need to add a "Path Mapping" by clicking "Add..." in the Source tab. Once a "Path Mapping" is created, select "Edit..." and add an entry with these values</p>
<pre class="eval"> Compilation path: / 
 Local file system path: /
</pre>
<p>This is the only known workaround to bind binaries to source files. It has been tested and works perfectly under Eclipse Europa (3.3.2) with Eclipse-CDT (4.0.3).</p>
<h3 name="Build_Parallelism">Build Parallelism</h3>
<p>You can use distcc and the MOZ_MAKE_FLAGS build variable to distribute the compilation across a network. This greatly improves the speed of the build. The complete informations are available in the <a class="link-https" href="https://wiki.ubuntu.com/MozillaTeam/Develop/distcc">Mozilla Team Documentation - distcc</a>.</p>
<h3 name="CDT_Issues">CDT Issues</h3>
<p>The CDT has some problems with Mozilla that need to be worked on.</p>
<ul> <li>Code completion and other operations that require a full parse tree are really slow because they parse the compilation unit from scratch every time. This can be fixed -- <a class="external" href="http://dev.eclipse.org/mhonarc/lists/cdt-dev/msg04750.html">there is a plan</a>. But it's quite a lot of work.</li> <li>The parser has bugs. I get a few internal parser errors when parsing the common Mozilla include files that use slightly tricky constructs (e.g., nsCOMPtr). Some of these bugs should be easy to fix, others maybe not. Apparently these bugs are only in the "old" parser which is deprecated and will be completely replaced by the "new" parser, "soon", so it's not really worth working on these bugs.</li> <li>It would be nice if Eclipse could pass information about what files have changed to the build process, which could then decide on a faster way to do the build (e.g., "just make in layout/"). I've actually written a small change to the CDT Make builder that lets you specify that as an option, in which case Eclipse sends the names of all changed files to your build tool. The build tool is a Perl script that figures out if a faster build is possible and if so, does it.</li> <li>Debugging.</li> <li>Some editing operations get sluggish when you have lots of files open (say, more than 20).</li> <li>The GDB thread terminates unexpectedly and detaches from the Firefox bin. This is caused by the breakpoints currently set. When you restart your Eclipse environment and face such issue. Delete and readd the breakpoints in your list.</li>
</ul>
Revert to this revision