[Cmake] Dependency handling problems with 1.8

Ken Martin ken . martin at kitware . com
Thu, 2 Oct 2003 09:07:07 -0400


Hi Amitha,

Good idea Amitha. I think this issue can be solved. We also came up with
something yesterday and I'm not sure which is the better idea. The =
makefiles
already have code to jump across and build targets that a target depends =
on.
Currently this is only done if the target doesn't exist. There is no =
reason
I know of that we couldn't perform that jump more frequently. =
Specifically,
in cases where we know the build order doesn't match the dependency =
order
(which is what that warning message indicates) then always jump to the
dependency target and build it (just do a make to make sure it is up to
date). For projects that have the correct build order nothing changes. =
For
projects that have a build order different than the dependency order, =
this
will handle it. It will cause more make invocations but either solution =
will
cause that. I think your approach will cause less extra make invocations =
but
the approach I just outlined provides better support for people building =
in
a subdirectory (which some insist should work even if they have never =
done a
make from the top). I think both approaches fail to support circular
dependencies (which for some reason some people insist on using). =
Comments?

Thanks
Ken



> -----Original Message-----
> From: cmake-admin at www . cmake . org [mailto:cmake-admin at www . cmake . org] On
> Behalf Of Amitha Perera
> Sent: Wednesday, October 01, 2003 4:14 PM
> To: cmake at www . cmake . org
> Subject: Re: [Cmake] Dependency handling problems with 1.8
>=20
> On Wed 01 Oct 2003, Ken Martin wrote:
> > The easiest is to make sure your
> > directories are in the right order. I don't know if this will help =
but
> you
> > might be able to do
> >
> > (toplevel CMakeLists.txt)
> >     SUBDIRS( a )
> >     SUBDIRS( b )
> >     SUBDIRS( a/a_gui )
>=20
> Unfortunately, this will be very difficult for the VXL project. As a
> short term solution, I have put in a bug report requesting a mechanism
> to supress this warning.
>=20
> > Some more information on this issue.  This is a UNIX makefile issue
> where
> > the subdirectories are processed in the order you specify.
> [details snipped]
>=20
> As I understand it, the main problem is that a "make" a top level (or
> higher level) will traverse the build tree in a SUBDIRS order, which
> may not match the dependency tree. A solution to this is to make sure
> that "make all" in any given directory will visit the targets in that
> directory and its subdirectories in dependency order and not in =
SUBDIRS
> order. If the SUBDIRS have been ordered as you suggested above, the
> dependency order is exactly equivalent to the SUBDIRS order, and
> therefore we have backward compatibility.
>=20
> Note that CMake already has all the information to generate these
> makefiles. A small example below to illustrate:
>=20
> The CMakeLists.txt files:
>=20
> (toplevel)/CMakeLists.txt
>    ADD_LIBRARY( root )
>    SUBDIRS( a )
>    SUBDIRS( b )
>=20
> a/CMakeLists.txt
>    ADD_LIBRARY( a )
>    SUBDIRS( gui )
>=20
> a/gui/CMakeLists.txt
>    ADD_LIBRARY( a_gui )
>    TARGET_LINK_LIBRARIES( a_gui b a )
>=20
> b/CMakeLists.txt
>    ADD_LIBRARY( b )
>    TARGET_LINK_LIBRARIES( b a )
>=20
>=20
> The dependency tree:
>    a <--- b <--- a_gui
>=20
>=20
> What would currently be in the makefiles:
>=20
> (toplevel)/Makefile:
>     all:
>         $(MAKE) libroot.a
>         (cd a && $(MAKE) all)
>         (cd b && $(MAKE) all)
>=20
> a/Makefile:
>     all:
>         $(MAKE) liba.a
>         (cd gui && $(MAKE) all)
>=20
> a/gui/Makefile:
>     all:
>         $(MAKE) liba_gui.a
>=20
> b/Makefile:
>     all:
>         $(MAKE) libb.a
>=20
>=20
>=20
> What I'm suggesting should be in the makefiles:
>=20
>=20
> (toplevel)/Makefile:
>     all:
>         $(MAKE) libroot.a
>         (cd a && $(MAKE) liba.a)
>         (cd b && $(MAKE) libb.a)
>         (cd a/gui && $(MAKE) liba_gui.a)
>=20
> a/Makefile:
>     all:
>         $(MAKE) liba.a
>         (cd gui && $(MAKE) libgui.a)
>=20
> a/gui/Makefile:
>     all:
>         $(MAKE) liba_gui.a
>=20
> b/Makefile:
>     all:
>         $(MAKE) libb.a
>=20
>=20
>=20
>=20
> Notice that if you do "make all" in any directory, that directory and
> it's subdirectories are processed in dependency order, but it'll not
> jump to a parent directory for any reason.
>=20
> > The other way is to include the full dependency tree of b into
> > the Makefile for a_gui. This makes for huge Makefiles for large =
projects
> and
> > more frequent rebuilding of Makefile (because they now depend on =
many
> more
> > header files)
>=20
> The approach I describe above does mean that the makefiles will be
> larger. For example, the toplevel makefile must list every target in
> the whole project tree. However, it does *not* need to list every
> header file. It need only list CMake targets (libraries and
> executables). There is, I'd say less than 300 of these in a
> project. So, the toplevel makefile will have 300 lines listing exactly
> the order in which the libraries are to be built. The dependency
> information, how to build the library, and all that information is
> captured in the Makefile in that library's directory.
>=20
> The makefile in a subdirectory will have fewer lines. It will only
> explicitly list that targets found that subtree.
>=20
> With this approach, the "magic" that jumps somewhere to build
> non-existent libraries is not required. If you run "make all" at a
> high enough level, the libraries will get built in the correct
> order. If you jump to a sub-directory and try to build, for example,
> a_gui, without first building b, then you will (rightfully) get an
> error message.
>=20
> Thoughts?
>=20
> Amitha.
> _______________________________________________
> Cmake mailing list
> Cmake at www . cmake . org
> http://www . cmake . org/mailman/listinfo/cmake