Egon Kocjan wrote:
I have a complicated situation :). I avoided the kind of approach, that you suggest because it's not modular - main project file contains add_subdirectory commands, which have to be maintained "by hand" - you can see the non-modular information leak here: "add_subdirectory( liba )".

Perhaps we have different definitions of modular. To me, the main CMakeLists.txt file doing nothing more than explicitly enumerating the nodes in your graph. Presumably, that's easy to find, even automatically. In fact, you can think of the add_subdirectory commands as the links of a tree-representation of your dependency graph. The target_link_libraries specify the full dependencies *for a given node*. It doesn't get more modular than that.

Instead of listing everything on a top level file, you could do add_subdirectory at lower levels. The issue with this is that the add_subdirectory typically corresponds to the build order. With visual studio, it doesn't matter as much, since the IDE will re-order things anyway. Even with Makefiles, CMake is clever enough to put rules to make sure dependencies are built first. However, it's bad practice; it's much better if the build order corresponds to a correct subtree of your full dependency graph.

That said, you could probably do what you did in your original email by using some cache variables to mark a directory as already processed. This may require CMake 2.6, since the reading and writing of cache variables occurs in different phases in CMake 2.4.

It would be nice to double-click on any project in the graph and have the build system figure out the needed dependencies from "lower" levels automatically. The reason that I want to have subgraph builds is that VS would probably break if I included the whole beast at once :).

This is what I referred to in my post when I wrote about "self-standing sub-project solutions". Since you are beginning this CMake adventure, I strongly suggest you begin at CMake 2.6. It fixes many, many quirks of 2.4. If, for example, you did

exea/CMakeLists.txt
  project( exea )
  ...
  add_executable( exea .. )
  target_link_libraries( exea liba libb )
  ...

You would (also) have a solution called "exea.sln". Opening this would get you exea, liba, libb, and all of liba's and lib's dependencies. Pretty modular, I think.

If exea depends exclusively on a library libc, then you could add

exea/CMakeLists.txt
  ...
  add_subdirectory( libc )
  ...

and "hide" libc from the other targets, maintaining your modularity. However, if both exea and exeb depend on libc, then I don't think it makes sense for each to pretend that libc is "hidden". From an overall build perspective, I think it's better to list libc *one* somewhere (e.g. at the top level), and just refer to that in exea and exeb.

On a philosophical note, I think you'll find that once you approach the problem in the CMake way (as opposed to forcing CMake to do it exactly as it was done before), you'll find that it works just as well.

> The task is to convert ~100 projects with acyclic (non-tree)
> dependencies to cmake.

I'll repeat again that the target_link_libraries is really what captures this dependency graph. add_subdirectories is simply an enumeration of the nodes. Ideally, the execution order of the add_subdirectories matches one of the tree traversals of your dependency graph, but it doesn't have to. And I strongly suggest that you start with CMake 2.6. It is at a release candidate stage now, but the issues that are being fixed are pretty complex corner cases that will not affect you getting your build system using CMake.


Cheers,
Amitha.

_______________________________________________
CMake mailing list
CMake@cmake.org
http://www.cmake.org/mailman/listinfo/cmake

Reply via email to