CMake: reuse object files built for a lib into ano

2019-01-22 13:29发布

问题:

I'm trying to move my project to CMake, and at the same time have some optimization on the compilation process.

Here's the deal:

  • I have several subdirs that are (have to be) each compiled into a static library (this works).
  • I want to gather all the object files from each subdir into another bigger, complete, static library.

It looks like this:

.
libBig.a  # made from object from subdir1 and subdir2
subdir1/
   src/
   libSubdir1.a
subdir2/
   src/
   libSubdir2.a

Today, I managed to use a global variable in which every subdir CMakeLists.txt will append its own source files. I use this variable as a "source" input in my big library:

# the big library depends on all the source files
# ${all_src} is automatically filled with each subdir's cpp file
get_property( BigLib_src GLOBAL PROPERTY all_src)
add_library( Big STATIC ${BigLib_src}) # recompiles all the sources

Now, this works, not too bad, but the thing is, all my source files get compiled twice: once for the subdir library, and once for the big library.

CMake seems to forget that it has already built them.

I have to keep the subdir libraries and ar can't merge two static libraries.

Do you know how to do that?

回答1:

You can use the new OBJECT library feature introduced in CMake 2.8.8. The idea is explained here. Basically, the OBJECT library is a similar concept to the convenience library known from Autotools to group object files.

Check the complete CMake OBJECT library tutorial.



回答2:

As of CMake 2.8.8, you can do this using the OBJECT library type. See mloksot's answer. The old situation was that each target had its own directory and CMake would build every dependent object for every target. This guards against a case where one source file could be used multiple times with different CFLAGS. (Note that by default CMake is more conservative than automake here: automake will stop reusing object files for different targets only if the targets are built with different CFLAGS (and probably CPPFLAGS, too).