[CMake] Using objects in different targets

Michael Hertling mhertling at online.de
Sat May 22 03:45:36 EDT 2010


On 05/21/2010 03:05 PM, Christoph Rüdiger wrote:
> Am 20.05.2010 um 13:33 schrieb Michael Hertling:
> 
>> On 05/20/2010 01:04 PM, "Christoph Rüdiger" wrote:
>>> [...]
>>> I've a directory src containing the complete source code of the  
>>> program and
>>> another directory called test containing the source code for the  
>>> unit tests.
>>> In the top level directory is a CMakeLists.txt that points to the  
>>> subdirectories containing each an own CMakeLists.txt for building  
>>> the program or the unit tests.
>>>
>>> Now I want to use the already build object files from the src  
>>> directory one time for linking the program and one time for linking  
>>> to the unit tests.
>>>
>>> My current way is building a static library in the src directory  
>>> and link the unit tests against this library. But the sources would  
>>> be compiled twice: One time for the static library and one time for  
>>> the program itself.
>>
>> Link the program against the static library, too, while removing
>> the latter's source files from the program's ADD_EXECUTABLE().
> 
> Then I need either one big library which I can link against each unit  
> test, resulting in a unit test of the size of the whole program plus  
> the size of the unit test, [...]

OK, if your concern is not only to avoid multiple compilations but also
to avoid code duplication use a shared library instead of a static one.

> [...] or I create smaller static libraries but  
> need to know each library in both CMakeLists.txt explicitly.
> For later on there is a planning to build plugins which needs to be a  
> library I must explicit know in the unit test project, too. If  
> anything changes in the src tree, I have to modify the CMakeLists.txt  
> of the test tree, too.

This means you want to use as few libraries as possible, right? Build a
shared one with all code common to the program and the unit tests; the
dlopen-loadable plugins must be built as shared libraries anyway.

> I'm wondering if there is no solution for making files one time known  
> to the cmake process (the cpp files in my case) and use derived files  
> (the objects) in other process parts. I'm looking aroung for a  
> variable containing all objects, pass this to the linker and let the  
> linker figure out, which objects are needed in the current unit test.  
> The linking time increases, but at nightly test runs, this doesn't  
> matter.

Perhaps, it's possible to tell CMake to do so, but consider seriously
if this is really the way to go: Object files compiled from the same
source file can differ in several aspects, e.g. position independence,
optimization level, debugging information etc., and that is a primary
reason why object files are compiled individually for each target they
become a part of. Thus, maintaining a list of object files and passing
it to the linker for the creation of different targets is generally a
bad idea and shouldn't be done without a definite necessity. Besides,
when linking against a static library the linker transfers only code
which is referenced by the target executable, i.e. if your unit test
just uses 20% of the library the remaining 80% don't make it into the
resulting binary. Hence, there's no need to pass the object files to
the linker as themselves as you've outlined above, and nor would it
avoid code duplication.

> Is it possible to have all projects together in the top level  
> directory CMakeLists.txt and include a separate file with the cpp- 
> Variables? (Separate the long list of source files from the project  
> admin commands)

Use FILE(STRINGS sources.dat SOURCES) to read the name of source files,
one per line, from a file "sources.dat" and to store this list in a
variable "SOURCES".

Regards,

Michael


More information about the CMake mailing list