7.3.1 ede-cpp-root

The ede-cpp-root project type allows you to create a single object with no save-file in your .emacs file. It allows EDE to provide the Semantic package with the ability to find header files quickly.

The ede-cpp-root class knows a few things about C++ projects, such as the prevalence of "include" directories, and typical file-layout stuff. If this isn’t sufficient, you can subclass ede-cpp-root-project and add your own tweaks in just a few lines. See the end of this file for an example.

In the most basic case, add this to your .emacs file, modifying appropriate bits as needed.

(ede-cpp-root-project "SOMENAME" :file "/dir/to/some/file")

Replace SOMENAME with whatever name you want, and the filename to an actual file at the root of your project. It might be a Makefile, a README file. Whatever. It doesn’t matter. It’s just a key to hang the rest of EDE off of.

The most likely reason to create this project, is to speed up searching for includes files, or to simplify bootstrapping Semantic’s ability to find files without much user interaction. In conjunction with Semantic completion, having a short include path is key. You can override the default include path and system include path like this:

(ede-cpp-root-project "NAME" :file "FILENAME"
    :include-path '( "/include" "../include" "/c/include" )
    :system-include-path '( "/usr/include/c++/3.2.2/" )
    :compile-command "make compile"
    :spp-table '( ("MOOSE" . "")
                  ("CONST" . "const") ) )

In this case each item in the include path list is searched. If the directory starts with "/", then that expands to the project root directory. If a directory does not start with "/", then it is relative to the default-directory of the current buffer when the file name is expanded.

The include path only affects C/C++ header files. Use the slot :header-match-regexp to change it.

The :system-include-path allows you to specify absolute names of include directories where system header files can be found. These will be applied to files in this project only.

With :compile-command you can provide a command which should be run when calling ede-compile-project.

The :spp-table provides a list of project specific #define style macros that are unique to this project, passed in to the compiler on the command line, or are in special headers. See the semantic-lex-c-preprocessor-symbol-map for more on how to format this entry.

If there is a single file in your project, you can instead set the :spp-files to a list of file names relative to the root of your project. Specifying this is like setting the variable semantic-lex-c-preprocessor-symbol-file in semantic.

If you want to override the file-finding tool with your own function you can do this:

(ede-cpp-root-project "NAME" :file "FILENAME" :locate-fcn 'MYFCN)

Where MYFCN is a symbol for a function. The locate function can be used in place of ede-expand-filename so you can quickly customize your custom target to use specialized local routines instead of the default EDE routines. The function symbol must take two arguments:

NAME

The name of the file to find.

DIR

The directory root for this cpp-root project.

When creating a project with ede-cpp-root, you can get additional configurations via Project Local Variables. Be aware that the format for project local variables is an association list. You cannot use M-x ede-set and have your project local variables persist between sessions.

If the cpp-root project style is right for you, but you want a dynamic loader, instead of hard-coding path name values in your .emacs, you can do that too, but you will need to write some lisp code.

To do that, you need to add an entry to the ede-project-class-files list, and also provide two functions to teach EDE how to load your project pattern

It would look like this:

(defun MY-FILE-FOR-DIR (&optional dir)
  "Return a full file name to the project file stored in DIR."
  <write your code here, or return nil>
  )

(defun MY-ROOT-FCN ()
  "Return the root fcn for `default-directory'"
  ;; You might be able to use 'ede-cpp-root-project-root'
  ;; and not write this at all.
  )

(defun MY-LOAD (dir)
  "Load a project of type `cpp-root' for the directory DIR.
Return nil if there isn't one."
  ;; Use your preferred construction method here.
  (ede-cpp-root-project "NAME" :file (expand-file-name "FILE" dir)
                               :locate-fcn 'MYFCN)
  )

(add-to-list 'ede-project-class-files
             (ede-project-autoload "cpp-root"
              :name "CPP ROOT"
              :file 'ede-cpp-root
              :proj-file 'MY-FILE-FOR-DIR
              :proj-root 'MY-ROOT-FCN
              :load-type 'MY-LOAD
              :class-sym 'ede-cpp-root)
             t)

This example only creates an auto-loader, and does not create a new kind of project.

See ede-cpp-root-project, for details about the class that defines the ede-cpp-root project type.