On Thu, Jan 21, 2010 at 10:50 AM, Mathias Bauer <[email protected]> wrote:

> So, how can we implement "include, not execute" with CMake?

You can do this, if it is absolutely necessary. I'll describe that at
the end of the message.

> Consider that you have the modules A, B, C and D. D depends on B and C,
> that both depend on A. This is reflected by corresponding entries in the
> build.lst files of these modules. Let's assume what happens if I forget
> to add the dependency on A in the build.lst from C.
>
> When I do a complete build from scratch for module D, it will work if B
> is built before C as building B will also build A, so C got its
> precondition met and will build fine also. If C is built before B, the
> build will break as it will miss A.

CMake has no concept of "modules" as used in OOo. My understanding is
that a "module" is roughly one subdirectory (or as defined in
build.lst) that produces one or more libraries, executables and so on.

In CMake all dependencies are between deliverables (i.e. libraries,
binaries, etc). Subdirectories are just a convenience. So in your
example we would have in subdirectory A something like this:

add_library(A SHARED sourceA.cxx)

Then in B you would have

add_library(B SHARED sourceB.cxx)
target_link_libraries(B A)

Similarly in C you would have

add_library(C SHARED sourceC.cxx)
target_link_library(C A)

And finally in D:

add_executable(foo source.cxx)
target_link_library(D C B)

What happens if we change C to accidentally remove the dependency to A?

When make is run, it will produce a link error for C. It will not use
a stale library file one you may have in your build tree. Thus the
error will be immediately apparent to the person doing the change so
he will not check in code that will break on other people.

I tested the behavior just now with a sample to make sure it actually
does this. I can send a sample project if someone wants to try it
themselves.

> Wouldn't it be better if the error detection is "built in"?

Yes, and with CMake, it already is. :)

> A missing dependency declaration now means that the "super makefile"
> does not include the makefile that explains how a particular
> precondition can be built in case it isn't there (usually meaning: in
> the solver). In fact a missing dependency now becomes a missing rule.

What CMake does is roughly the same. Whenever you run make, it checks
whether the build setup has changed (in practice, whether
CMakeLists.txt's have been touched) in any way. If yes, then it will
automatically recheck the build system's validity and regenerate the
necessary makefiles. Then it runs make.

The single process GNU Make thing loads all makefiles  to validate
them (which is roughly the same as CMake checking itself) and then
uses that to build.

In both cases build stability is assured.

> there. Moreover, a missing rule will be detected even before the build
> starts, so mistakes are found faster: it is sufficient to call "make"
> with an empty solver to detect the missing rules.

If you do something like this in CMake:

target_link_libraries(some_exe misspelled_or_missing_library_name)

it will not detect it before build starts (because the latter may be a
system library such as xlib) but it will give an error when linking
some_exe. It will not allow it to pass.

> So unless you can't bear the overhead of evaluating all dependencies all
> the time (what hopefully will take less time than running through all
> modules today), you can always just call "make" after your changes
> anywhere in the code and the result will be OK.

This is precisely what CMake aims to do. Just type "make" or click
build on your IDE of choice and you will get a correctly built
product. Not doing this is _always_ a bug. And from what I know of
CMake's development, a rather serious bug at that.

> What does that tell us about CMake? If CMake does not allow us to use a
> "super makefile" including all other makefiles, we don't get the build
> stability improvements that the GNU Make approach can give us.

As far as I can see, CMake does provide all the stability improvements
you require. If there is anything more, just ask.

> So again: how can we implement "include, not execute" with CMake?

CMake allows CMake script files to include other files. You could
write a subdir.cmake file for each module/subdir and then just include
them in your master CMakeLists.txt. The end result is one makefile
(or, I guess, O(1) makefiles due to implementation issues).

Since CMake solves the stability issue differently, I do not think you
should do this. But if you really, really need to, you can.

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to