How to build static libraries with cmake (and more)?

Brad King brad.king at kitware.com
Tue May 16 17:55:52 CEST 2006


Friedrich W. H. Kossebau wrote:
> Am Samstag, 13. Mai 2006 18:37, schrieb Alexander Neundorf:
>>Different targets could be built with different flags etc., so the object
>>files could differ. That's why the object files are not reused.
> 
> Yes, _could_. But what if I know and want that they are not? See the example 
> above: I want to create from the very same object files a static lib next to 
> the linked dynamic one because this seems to be needed for convenient unit 
> testing (due to symbol visibility, see the reference below).

To clarify: you want an archive of the object files in a shared library 
so that you can link them to an executable statically, correct?

This may not be too hard to add to cmake.  Perhaps we could add a target 
property to specify that such an extra archive should be created.  The 
generator would then add the call to the archiver/ranlib after linking 
the shared library to produce an archive with the same object files. 
This is easy in the makefile generators, but I'm not sure how to do it 
in Visual Studio and Xcode builds.  We will probably have to create an 
extra target (project file) that depends on the original and then just 
links together all the object files.

I just tried this on windows by hand and it has some interesting 
effects.  The static .lib file that is produced is full of objects that 
have dllexport tags.  When it is linked into an executable, say foo.exe, 
the linker produces a foo.lib import library.  Another problem on 
windows is that the static library cannot have the same name as the dll 
or it will clobber the import library paired with the dll.  This means 
that any target property we create to specify this behavior will also 
have to specify an alternative name for the archive.

Out of curiosity, why do the tests need access to non-public symbols? 
Shouldn't they test using the libraries the same way user code is 
expected to use them, through the public API?

>>So you link to libkfoosomething.so, and when running the app, it links to
>>the installed lib instead of the not-yet-installed one ?
>>Then use the RUN_UNINSTALLED option for KDE4_ADD_EXECUTABLE:
>>KDE4_ADD_EXECUTABLE(kfoo RUN_UNINSTALLED srcs...)
> 
> I do this already, and yes, it links to the uninstalled in the build, then 
> binds(?) to the installed if running!
> Test yourself: 
> 1. remove some visibility flag for a class in a lib, compile, install
> 2. put flag back, compile and link lib, but do not install
> 3. compile and link some not installed executable (e.g. a test) which needs 
> that class symbol
> 4. run executable -> symbol lookup error
> 5. install new lib from above -> executable runs fine...

Build with "make VERBOSE=1" and log the output.  Then look for 
-Wl,-rpath options to see what runtime library search path is used by 
your executable.

> I am looking for convenient adhoc testing which can be applied in the middle 
> of some development session without effects on the rest of that session. E.g. 
> for test-driven development.
> Workflow: Edit, compile, edit, compile and run tests ->fails, edit again, 
> compile and run tests ->ok, edit, compile, edit, compile, edit, compile and 
> run test ->ok, edit, compile, edit, ...
> 
> So this is a different use case from what seems supported now only, namely 
> nightly automatic builds. Can you better guess now what I (and others) 
> want? :)

There is much more than just nightly testing: ctest allows tests to be 
run in the build tree by hand.  After finishing the build, try this:

Run all tests:

   ctest

List all tests

   ctest -N

Run a subset of tests by regex:

   ctest -R mytest

See the ctest manpage for details.  In order to build just one 
executable and things it needs, specify the target name to make:

   make mytest_exe

You can also run a whole build/test stage and report results to the 
dashboard using the "Experimental" testing mode.  Try this:

   make Experimental

> auto*'s "make" and "make check" do fit nicely there. The default target(s) do 
> not include dependencies on the test targets. Only on the target "check" all 
> test dependencies are run, then automatically the tests executed.

This is exactly what ctest --build-and-test provides: the ability to 
have tests that build some code (that is not built during the normal 
build) and run an executable.  Alex may have to explore creating a few 
such tests as examples.

-Brad


More information about the Kde-buildsystem mailing list