How to create an EDE project for C++
Asked Answered
T

2

7

I have been trying to set up an EDE project for C++ (emacs24 + builtin CEDET) and I'm starting to get desperate because I can't seem to find the way I want the makefiles to be generated. I'm relatively new to Emacs. I'll try to describe what I'm doing:

I have a toy project set like so:

main.cpp
other/
  Utils.cpp 
  Utils.h
  CGrabBuffer.cpp
  CGrabBuffer.h

main.cpp includes both .h's inside the "other/" directory. These are the steps I follow to set up an EDE project with this simple directory setup:

  • Open main.cpp in emacs and do M-x ede-new ; type: Make ; name: main-proj.
  • Open one of the files in the "other" directory and do M-x ede-new ; type: Make ; name: aux-proj.
  • Now it's time to create the targets (which I believe are three in this case):
    • On the main.cpp buffer: M-x ede-new-target ; name: main ; type: program. When prompted, I add the main.cpp to this target.
    • I repeat the same for the other two targets (Utils which has Utils.cpp and Utils.h and CGrabBuffer which has CGrabBuffer.cpp and CGrabBuffer.h). Here I find the first problem. What type do these two targets have to be? I only want them to generate .o files.
  • Once this is done, I type M-x ede-customize-current-target to all three targets and I add some include paths, some libraries, etc.
  • After this, if I call M-x ede-compile-project it doesn't compile because:
    • It tries to compile main.cpp first; I have no idea how to specify (using EDE) that both Utils.o and CGrabBuffer.o are needed before attempting to build main.cpp.
    • If I manually change the order (editing the Makefile), it's not able to link main.cpp because it can't find Utils.o and CGrabBuffer.o.

As you can see, I am in the middle of a great mess. Maybe I'm not even understanding what "target" means in EDE. I have also read about the existence of ede-cpp-root-project which has to be specified inside the .emacs file. I haven't tried it because what I think it does is just help with the semantics. It doesn't generate Makefiles, does it? Can I have (or do I need) an EDE project built with Project.el's and the same thing using ede-cpp-root-project for the semantics? Or is it redundant?

Sorry If I misunderstood a lot of things but I'm very confused and being new to emacs makes things worse. Thanks for your patience!

EDIT: with some tinkering and the responses I received I have been able to figure out a lot of stuff, so thanks a lot. What I still don't understand is the use of the ede-cpp-root-project which has to be specified inside the .emacs file. Is it just for c++ semantics? Is it redundant to have the project with Project.el's AND also the elisp lines in .emacs?

Tolentino answered 21/2, 2012 at 12:46 Comment(3)
I am using CEDET but cannot figure out its project support for my life. I just use external Makefiles and add project type "simple" on the top of that.Eyot
Yeah, and that's the only thing that makes me stick with other IDEs like Eclipse that let you manage all this stuff way easier...Tolentino
Great question. I've spent the last few days trying to get this sort of thing to work, but just when I think I'm getting somewhere, it all crumbles. Saying that EDE is poorly documented is an understatement.Diocese
H
8

EDE is designed to handle many different kinds of projects, usually of a type where the build system was written outside of Emacs in some other tool.

The EDE project type that creates Makefiles for you can do quite a few things, but you need to have some basic understanding of build systems for it to be helpful, and you really do need to customize the projects to get anything of any complexity working.

I've recently added a section to the EDE manual to help with basic project setups that autogenerate Automake files. You can check out the tutorial here:

http://www.randomsample.de/cedetdocs/ede/ede/Quick-Start.html

The same steps will apply for projects that just use Make instead, but Make based projects often have trouble with shared libraries due to the extra complexity.

Mike's answer is quite good, but I think it is ok to just add .h files to the same target as your .cpp sources. It will keep track of them separately.

Another useful trick is to use the whole project compile keystroke (C-c . C) which uses a capital C whenever you change something big. That will regenerate the Makefiles, rerun any needed Automake features, and start at the top.

EDIT: You only need one EDE project for a give project area. The ede-cpp-root project is useful when no other automatic project type works. That's when you create that in your .emacs file so that the other tools that need a project definition, like semantic's smart completion, and tag lookup, will work.

Hydr answered 24/2, 2012 at 5:9 Comment(3)
That tutorial is what I was looking for a few weeks ago, when I started to take a first look at EDE, but I couldn't find anything like it. It's very helpful and new users are going to love the information there, so thanks a lot :)Tolentino
Eric, what's missing from that tutorial is any description of how to actually use the ede-cpp-root-project type. By the time you get to that part of the manual you're seeing non-user-centric things like eieio subclasses, etc. Does one set up a project file, for example? How do you actually set things up with that project type?Beano
The link is broken and should be updated to randomsample.de/cedetdocs/ede/Quick-Start.html I tried to edit but there is a silly rule about edits needing to be more than 6 characters.Roberto
D
3

Well, I think I actually have it figured out this time, but it's ugly. Utils.cpp and CGrabBuffer.cpp should not get their own individual targets, because there doesn't seem to be an appropriate target type. Instead, you'll need to create an archive or library, which will automatically compile Utils.cpp and CGrabBuffer.cpp for you. Below, I'll assume you want static, but it's easy to change.

[For anyone to whom archives or libraries are not familiar, they basically just gather up .o files into a separate unit. It doesn't actually make the compilation harder. Read more here.]

1) Follow the first two and a half steps above (including making the main target, but not the other targets).

2) Switch to Utils.cpp and do M-x ede-new-target ; name: aux ; type: archive. When prompted, add Utils.cpp to this target.

3) Switch to CGrabBuffer.cpp and do C-c . a ; Target: aux .

4) Regenerate the Makefile with M-x ede-proj-regenerate. At this point, if you run make in the other subdirectory, you should get the archive libaux.a.

5) Switch back to main.cpp and do M-x ede-customize-current-target. This brings up an interactive emacs customization buffer, which allows you to edit details of the ede configuration. Under the Ldflags section, click [INS]. This pops out a new line that says Link Flag: and has some different-colored box for you to type in (mine is grey). Type -Lother -laux, so that other/libaux.a is included when compiling main. Then, at the top of the buffer, press [Accept], which should save that change and switch back to main.cpp.

6) Regenerate the Makefile with M-x ede-proj-regenerate.

Now, unfortunately, the Makefile makes the main target first, then descends into the other directory and makes that. Unfortunately, this means that a make from the top-level directory will not work on a clean tree. I don't know why this is, because it seems like that would never be what you want in any project that is ever made with EDE. I can't find any way to change that, except for this hack:

7) Do M-x customize-project; under Inference-Rules click [INS]. Then enter Target: all ; Dependencies: aux main ; Rules: [INS] ; String @: . (This last one is just to prevent an error on an empty rule with a tab; presumably an EDE bug.) Click [Accept], and regenerate the Makefiles.

So now, in your top directory, you can just run make, and main should be a working executable.

I'm quickly becoming convinced that EDE is not yet ready to be used by people other than its authors. Despite its size and the amount of effort they've clearly put into it, it is too buggy, too counterintuitive, and just not smart enough. That's a shame. Emacs needs something like this.

Diocese answered 23/2, 2012 at 19:17 Comment(2)
After asking the question I continued tinkering with the project types and I ended up doing something similar to what you say. I made two targets of type archive (one for CGrabBuffer and the other for Utils) instead of one. And, as you say, I had to call make on the other directory first. This way of proceeding seems "weird" but it works :).Tolentino
Eric's new tutorial is definitely really helpful. In particular, it sounds like using Automake will solve a lot of these problems. That said, I realized you could also just include other/Utils.cpp and other/CGrabBuffer.cpp as sources in the main target, and they'll get built correctly. You don't even need separate targets for them.Diocese

© 2022 - 2024 — McMap. All rights reserved.