Jussi Pakkanen wrote:
Hi all

I'm looking into compiling OpenOffice.org with CMake. Currently it
uses dmake and a custom build tool. The basic structure is that every
logical component (Writer, widget toolkit etc) has its own
subdirectory. These are well separated.

The problem comes from the internal structure of these components. The
most common case is that the component produces one product (usually a
shared library) from source files scattered in several different
subdirectories. As an example:

dir1/foo.cxx
dir1/foo2.cxx
dir1/subdir/baz.cxx
dir2/sub1/ggg.cxx
dir2/sub2/rrr.cxx

And so on and so on. Each subdirectory has a dmakefile that lists the
source files to use. I have written a parser that converts these to
CMake's syntax. Every component has a subdirectory called "util". This
is where the final product is defined and built. What I want to know
is what is the correct cross-platform way to do this in CMake. Here
are some choices I came up with so far:

The easiest way is to put the add_library() call at the top-most directory
which shares all the sources and use relative paths to list them

  add_library(mylib SHARED dir1/foo.cxx dir1/foo2.cxx ...)

1) Build every subdir to a static library and link them to the final
shared library. I think this fails, because the files do not get all
the proper -FPIC switches and so on.

2) Build every subdir as a shared library and join them to the final
lib. I tried this ages ago and turned out merging shared libraries
(also static ones) was not possible. Probably still the case.

I recommend against these two.

3) Write source files to a variable and then add_library(foo SHARED
${SOURCE_FILES}). But what should I write in SOURCE_FILES? Should it
be "foo.cxx", "dir1/foo.cxx", or perhaps even "../dir1/foo.cxx" (since
add_library is done in the util subdirectory)? Also, do I need to set
the variable to cache, since changes in subdirectories must be visible
in their parent and siblings? Preferably the variable should not be
visible in other components.

This is the same as the solution I suggest above but moves the add_library
call into a subdirectory.  If you use it, you can either list the sources
by full path or by relative path from the CMakeLists.txt file containing
the add_library call.  It is much simpler to put the call at the top-most
location though.  CMake's makefile generator will still hide all the
object files out of sight.

Sounds easy so far? Well, there is still one more thing. Every source
file may be tagged with a special value, and those files must be
compiled with special compiler switches (dealing with exceptions).

By "compiler switches" do you mean real compiler flags or just preprocessor
symbol definitions?  The COMPILE_DEFINITIONS property is only for
preprocessor symbols.

If a file is not tagged, different compiler switches must be used. I can
set COMPILE_DEFINITIONS easily, but can I make it drop existing
switches? I can code logic to the converter script that calculates the
the set difference between all source files and tagged ones. Then I
can set COMPILE_DEFINITIONS for each of these separately, but I'd
rather not if there is an easier way. :-)

This is probably the best way.  If one were writing CMakeLists.txt files
by hand from scratch, this is how it should be done.  However, I suggest
not making excessive use of per-source build properties because they
do not perform very well in the VS IDE (this is not CMake, but the VS
IDE implementation).  The definitions will work, but they cause the IDE
to use a separate invocation of the compiler for every source file
instead of sharing one invocation for many sources in a target, which
leads to slower builds.

Can you provide more detail about the purpose of these switches?  Why
does every source file need one?

Thanks,
-Brad
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake

Reply via email to