Re: Re: Building OpenOffice.org with GNU make

Jussi Pakkanen <[email protected]> Tue, 26 Jan 2010 14:19:22 +0200
Newsgroups gmane.comp.openoffice.devel.tools
Message-ID <[email protected]>
On Mon, Jan 25, 2010 at 7:55 PM, Mathias Bauer <[email protected]> wrote:

> 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.

Fair enough. I just feel that CMake would make an excellent solution
for your problem. I want to make sure that you evaluate it properly
before accepting or rejecting it.

BTW, what does the GNU Make solution use for platform configuration?
Autoconf? Some in-house tool?

> 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. :-)

KDE builds with CMake on Linux, OSX, and Windows. That's pretty big.

>> 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?

Yes, sure. If and only if you have target_link_libraries(some_exe
some_library) then the linker invocation for some_exe will have
'-lsome_library'. Whether or not it was built accidentally, CMake will
not link the exe against the library.

The other issue is what happens if you rename a library and forget to
update the name in some other target. The library with the old name
exists in the build tree so in theory you could link against that.
CMake will do the right thing also and fail during linking. In the
attached sample file there are directions on how you can verify this
yourself.

> 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 don't know about CMake's internals enough to tell you how it divides
the work between itself and make. But what I can tell you is that
CMake+make combo does handle the entire dependency chain from
executables to source, headers, generated headers etc. It has a
built-in dependency scanner for #includes.

I'll repeat a point from my earlier post: No matter what change you do
in your source tree, all you have to do to get a working result is to
run make.

> 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).

Attached is a sample with 3 shared libraries and one executable. To
run on Unix, extract it, cd into it, then:

mkdir builddir
cd builddir
cmake -DCMAKE_BUILD_TYPE=debug ..
make

It should build without any changes on Linux, OSX, Visual C, MinGW
etc. I always recommend creating a separate build directory so as not
to clutter your source tree with generated files.

> 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.

Yes, as discussed above.

> So will CMake detect the missing dependency while it creates the
> "native" makefiles?

I think no, because the library you specify might be an external
library. But the link will fail. When you fix the dependency, CMake
will not rebuild the stuff you had built at the time the link error
happened (unless of course some of their dependencies have been
changed also).

> 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?

CMakeLists.txt will be under SCM. They are the master build
information. The generated Makefiles will not be placed under revision
control. They and everything else that is generated can be put into a
separate build directory (this is in fact the recommended way to use
CMake). This allows you to have stuff like the following:

source
source/native-tool-build
source/gcc-experimental-build
source/mingw-crosscompile-build
...

That is, you have several build directories with different
configurations, compilers, etc. They are all separated from each other
but use the same source tree. You can code stuff using one build tree
as your mainline. Then when you are done, checking the other
configurations is just a matter of running make in those directories.
The build will be faster, because CMake will only rebuild the stuff
that has changed.

Nothing is generated in the source tree. Ever! Unless you want to.

> 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.

I don't see how the parallel build thing can happen. Does the current
system have some kind of a wildcard linking rule? Something like "link
against everything in such_and_such directory"?

> 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.

Again I don't know about the implementation. But when I run 'make -j
17' on a 16 core machine and then run top, I get 100% CPU utilization
almost all of the time. So it definitely "works for me". Whether it
does for you is a matter of testing.

> And the actual build (execution of GNU Make or VC++) would happen in one
> process?

As far as I can tell, yes it does. But you really should not take my
word on this particular issue.

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
cmake_linktest.zip (application/zip, 1.8 KB) - not displayed