CMake/Tutorials/Object Library: Difference between revisions

From KitwarePublic
Jump to navigationJump to search
(Remove leading space rectangles from preformatted blocks)
(Replace content with link to new CMake community wiki)
 
Line 1: Line 1:
= Introduction =
{{CMake/Template/Moved}}


CMake 2.8.8 introduced an "<code>OBJECT</code>" library type that can be created with <code>add_library</code>:
This page has moved [https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/Object-Library here].
 
<pre>
add_library(myObjects OBJECT a.c b.c)
</pre>
 
CMake generates rules to compile the source files into object files but does not link archive or link them into a library file.
Instead the object files may be included in ''other'' targets created by <code>add_library</code> or <code>add_executable</code>
by listing the object library as a source with special syntax <code>$<TARGET_OBJECTS:''objlib''></code>,
where "<code>''objlib''</code>" is the object library name.
 
= Motivation =
 
Consider a project that compiles a large number of source files and links them into a single library.
One approach is to list all sources in a single <code>add_library</code> invocation:
 
<pre>
# CMakeLists.txt
add_library(big ${many_srcs})
</pre>
 
This is okay if all the source files need to compile with the same preprocessor definitions, include directories, and other flags.
However, large projects typically organize their source files into groups, often in separate subdirectories, that each need different include directories and preprocessor definitions.
For such projects it is more convenient for developers to create a separate library target for each group.
For example, we can create two subdirectories:
 
<pre>
# A/CMakeLists.txt
add_library(A ${A_srcs})
 
# B/CMakeLists.txt
add_library(B ${B_srcs})
</pre>
 
and then refer to those libraries from the top directory:
 
<pre>
# CMakeLists.txt
add_subdirectory(A)
add_subdirectory(B)
add_library(big ${other_srcs})
target_link_libraries(big A B)
</pre>
 
This approach is easy to use and helps organize the project source tree.
Since CMake tracks link dependencies automatically it is easy to refer to the "<code>big</code>" library in <code>target_link_libraries</code> calls elsewhere in the project and let CMake propagate the dependency on A and B.
 
The drawback to the approach is that it creates a separate library file on disk for each group.
In this case library files such as <code>libbig.a</code>, <code>libA.a</code>, and <code>libB.a</code> will be created instead of one large <code>libbig.a</code>.
The additional files may not be desirable for packaging, distribution, or use externally by other build systems.
 
CMake's OBJECT library type provides a way to avoid this drawback and get the best of both above approaches.
 
= Usage =
 
Let's convert the above example to use OBJECT libraries.
First we change the two subdirectories to specify the <code>OBJECT</code> library type:
 
<pre>
# A/CMakeLists.txt
add_library(A '''OBJECT''' ${A_srcs})
 
# B/CMakeLists.txt
add_library(B '''OBJECT''' ${B_srcs})
</pre>
 
Then we change the top-level directory to refer to the object libraries as sources of the main library:
 
<pre>
# CMakeLists.txt
add_subdirectory(A)
add_subdirectory(B)
add_library(big ${other_srcs} '''$<TARGET_OBJECTS:A>''' '''$<TARGET_OBJECTS:B>''')
</pre>
 
CMake will compile all the sources in <code>A</code> and <code>B</code> but does not produce any library files.
Then it will compile all the normal sources in <code>big</code>.
Finally CMake will construct a single library file using objects compiled from all three targets.
 
In this case one large library file such as <code>libbig.a</code> is produced.
It can be installed and distributed as a single library file, effectively hiding the details of the source tree organization.
 
= Restrictions =
 
Object libraries may contain only sources (and headers) that compile to object files.
They may contain custom commands generating such sources, but not PRE_BUILD, PRE_LINK, or POST_BUILD commands.
Object libraries cannot be imported, exported, installed, or linked.
 
Most of these restrictions disallow behavior that is not yet implemented but may be defined in the future.
They are intended for forward compatibility with future versions of CMake that allow such operations.
 
{{CMake/Template/Footer}}

Latest revision as of 15:40, 30 April 2018


The CMake community Wiki has moved to the Kitware GitLab Instance.

This page has moved here.