[CMake] Redundant linking when modifying shared libraries

Itay Chamiel itay.chamiel at orcam.com
Thu Feb 14 05:24:26 EST 2019


Hi,

I've asked this question on Stack Overflow almost a year ago with no useful
responses (with the same topic if you wish to search for it), so I'm trying
my luck here.

I work on a large commercial C++ project comprised of a couple dozen
dynamically linked shared libraries, each of which has many associated unit
tests. Many libs are also dependent on other libs because a lib for some
specific functionality will use the code from one of the more common libs.
And finally of course there are the production executables which depend on
the libs.

There is no question that a change in the API (a header file) of some core
common lib should trigger a major recompilation of nearly the entire
system. But typically there is only a change in some function's
implementation, and the only file compiled is the modified .cpp file, and
in theory just the modified lib would need to be linked - thanks to dynamic
linking there should be no need to relink anything else. But CMake goes
ahead and does it anyway: after relinking the lib it relinks all the unit
tests associated with that lib. Then it relinks all the libs in that lib's
dependency tree and all their unit tests. Finally it relinks the production
executables. Due to the scale of the project this takes a lot of precious
time.

I have reproduced this behavior with a simple project based on the example
at cmake.org/examples (comments removed for brevity and lib type changed to
shared). My system is Ubuntu 16 on an Intel PC and my CMake version is
3.5.1.

Start with an empty directory. Create subdirectories Demo and Hello and
then create these files:

* CMakeLists.txt

cmake_minimum_required (VERSION 2.8.11)
project (HELLO)
add_subdirectory (Hello)
add_subdirectory (Demo)

* Demo/CMakeLists.txt

add_executable (helloDemo demo.cpp)
target_link_libraries (helloDemo LINK_PUBLIC Hello)

* Demo/demo.cpp

#include "hello.h"
int main() { hello(); }

* Hello/CMakeLists.txt

add_library (Hello SHARED hello.cpp)
target_include_directories (Hello PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

* Hello/hello.h

void hello();

* Hello/hello.cpp

#include <stdio.h>
void hello() { printf("hello!\n"); }

* now run the commands:

mkdir build
cd build
cmake ../
make

* You may now execute Demo/helloDemo and see hello!.

Now, touch Hello/hello.cpp and make again. You will see that libHello is
built and linked as expected, but then the helloDemo executable is also
relinked ("Linking CXX executable helloDemo"). The latter step is
completely redundant; even if hello.cpp is modified to print a different
string the relinked executable remains binary identical.

Is there a way to prevent these redundant build actions? This would be a
huge time saver for us.

Thank you,

itay
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20190214/163dc7d1/attachment.html>


More information about the CMake mailing list