[CMake] Avoiding error when using add_subdirectory twice on same path (CMake 2.6.4)

Brad King brad.king at kitware.com
Wed Jun 17 09:07:19 EDT 2009


[approach using package meta-data files to control build]
 > This approach minimizes the orchestrating effort and allows
 > developers to work on their part of an package without worrying
 > about unrelated projects.

Take a look at this thread:

   http://www.cmake.org/pipermail/cmake/2009-May/029239.html

and at the approach the Boost folks use:

   https://svn.boost.org/trac/boost/browser/branches/release
   https://svn.boost.org/trac/boost/browser/branches/release/tools/build/CMake/BoostUtils.cmake

These projects use a meta-data file in each directory with project
name and dependencies (module.cmake in the case of Boost).  The
top-level directory loads the files and does a topological sort on the
dependencies.  Then it adds all the subdirectories in the proper
order.  No individual developer needs to worry about non-local
information.

 > The old way requires more prudence when creating complex CMake
 > scripts, but it can be handled by analogy with c++ headers and their
 > include guards.

Yes, and this same care can be used to avoid hitting the new error.

We cannot allow CMake to generate the same build tree location twice,
even if it is from the same source directory.  It is not well-defined.
Consider:

   # Top/CMakeLists.txt
   add_subdirectory(A)
   add_subdirectory(B)

   # A/CMakeLists.txt
   set(foo 1)
   add_subdirectory(../C ../C)

   # B/CMakeLists.txt
   set(foo 0)
   add_subdirectory(../C ../C)

   # C/CMakeLists.txt
   if(foo)
     # Which of these
   else(foo)
     # two options?
   endif(foo)

Switching A and B on/off or switching their order can lead to
surprising changes in behavior.

 > a policy-based possibility to switch back would be very welcome in
 > order to give developers more freedom if they are willing to take
 > care about the "consequences". The old behavior doesn't generate
 > errors by default. It is only more error prone (due to its degree of
 > freedom) and thus less suited for beginners or "normal" projects.

CMake Policies are purely a deprecation and compatibility mechanism.
They should never be used to choose among multiple desirable
behaviors.  Eventually support for the OLD policy behavior will be
removed.

Perhaps we should have made a policy for this behavioral change.
However, at the time we made it every case of this happening we had
seen was producing strange behavior so we didn't expect any real
projects were using the missing check as a "feature".

Even if it were a policy, any project that tries to do this would get
the warning.  Yes, it could temporarily avoid the warning by setting
the policy to OLD, but it should *still* be updated to the NEW
behavior!  Again, policies are not used for choosing among desirable
behaviors.

-Brad



More information about the CMake mailing list