|
|
(3 intermediate revisions by one other user not shown) |
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]. |
| | |
| add_library(myObjects OBJECT a.c b.c)
| |
| | |
| 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:
| |
| | |
| # CMakeLists.txt
| |
| add_library(big ${many_srcs})
| |
| | |
| 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:
| |
| | |
| # A/CMakeLists.txt
| |
| add_library(A ${A_srcs})
| |
|
| |
| # B/CMakeLists.txt
| |
| add_library(B ${B_srcs})
| |
| | |
| and then refer to those libraries from the top directory:
| |
| | |
| # CMakeLists.txt
| |
| add_subdirectory(A)
| |
| add_subdirectory(B)
| |
| add_library(big ${other_srcs})
| |
| target_link_libraries(big A B)
| |
| | |
| 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:
| |
| | |
| # A/CMakeLists.txt
| |
| add_library(A '''OBJECT''' ${A_srcs})
| |
|
| |
| # B/CMakeLists.txt
| |
| add_library(B '''OBJECT''' ${B_srcs})
| |
| | |
| Then we change the top-level directory to refer to the object libraries as sources of the main library:
| |
| | |
| # CMakeLists.txt
| |
| add_subdirectory(A)
| |
| add_subdirectory(B)
| |
| add_library(big ${other_srcs} '''$<TARGET_OBJECTS:A>''' '''$<TARGET_OBJECTS:B>''')
| |
| | |
| 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.
| |