Hi Jussi, before we continue let me add some words to avoid misunderstandings. In no way I'm trying to cast a bad light on CMake or want to defend our trial approach "just because". But before I consider to support a different approach I want to get the essential problems discussed in the same depth as we did it ourselves when evaluating the GNU Make approach.
If CMake solved our essential problems it could be a nice alternative as it gives us the additional benefit of possible "native" builds on Windows (I assume we could still choose to use GNU Make also on Windows/Cygwin for now). Of course, TANSTAAFL: I'm sure we will be the first to explore this (native Windows builds with CMake) for a project of such a big size and diversity. Surely we will find many "interesting" problems. But that shouldn't stop us from discussing it now. :-) Jussi Pakkanen wrote: > On Thu, Jan 21, 2010 at 10:50 AM, Mathias Bauer <mathias.ba...@sun.com> 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. As I wrote, it doesn't matter if we are looking at "modules" or single targets (libraries, jar files, executables etc.), the problem is the same. I just started with "modules" as this is what we have now. > 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. Sure? What if you do a parallel build and "by accident" the library A is built before C is linked? That's exactly what happens in our current build system. For this trivial example it is close to impossible that a bug like this one stays unnoticed. But the multitude of targets and dependencies we have in OOo makes it much more probable to happen. And experience proves that: it happens at times and is a major PITA. The step forward in the "all in one process" solution is that the possible link error is detected in the process of checking the dependency tree, regardless how much stuff is built afterwards and how many parallel processes you will use then. I still can't see how this is done with CMake. It's totally possible that this is my fault. ;-) The CMake documentation isn't very helpful here. I can mainly see very trivial examples, nothing that comes even close to the complexity we have in OOo. Beside that I wouldn't be astonished if CMake couldn't do that - in my current (admittedly limited) understanding CMake never is meant to explore the whole dependency tree from top level binaries down to the included header files (or even further in case they are generated from other sources). That's what happens in the created "native" makefiles. Or does CMake double that effort and evaluates all dependencies by itself before the "native" makefile does the same again? > 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. I would appreciate to be able to get my hands on it. :-) Trying is so much better than talking. Until now I only found rather trivial examples in the web (even more trivial like my examples with 4 libraries). I also will have a look on what Martin Hollmichel has created until now, maybe we already have something to try and see. >> Wouldn't it be better if the error detection is "built in"? > > Yes, and with CMake, it already is. :) So CMake *does* check all source and header files, libraries etc.? How does it do that? In GNU Make e.g. you either have to specify header files as prerequisites (what nobody with a sane mind would do) or generate .d files "on the fly" and include them into the makefile. > 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. So will CMake detect the missing dependency while it creates the "native" makefiles? BTW: those CMakeList.txt files are a PITA. We are currently moving away from cluttering our source tree with files that are not under control of the SCM. Is there a way to avoid the placement of these files into the source tree? Can it be put somewhere else? > 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. Again this is the problem I want to avoid: errors caused by missing dependencies/prerequisites don't appear before you actually execute the build. This leaves too much room for random behavior caused by parallel builds. BTW: how does CMake organize the parallel build? The "all in one process" approach has another major advantage: as it is one process, it can find the optimum distribution for the available processes. This is not possible if the build runs in several processes, even if they are called recursively. If we e.g. have 16 processes avalailable (a good number for 8 cores), a single process would always use 16 processes to build 16 targets and never run dry. In case the "central" make has to start e.g. 50 processes, it has to decide if it should start e.g. 4 of them and give each of them 4 processes or 8 of them with 2. The latter is what we do now and we already have proven that this give mediocre scalability already for 8 processes (4 cores). > 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. And the actual build (execution of GNU Make or VC++) would happen in one process? Regards, Mathias --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tools.openoffice.org For additional commands, e-mail: dev-h...@tools.openoffice.org