mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-24 09:09:43 -05:00
Help: Document linking behavior of OBJECT libraries
Inspired-by: Deniz Bahadir <dbahadir@benocs.com> Issue: #14778
This commit is contained in:
@@ -110,10 +110,10 @@ along with those compiled from their own sources. Object libraries
|
|||||||
may contain only sources that compile, header files, and other files
|
may contain only sources that compile, header files, and other files
|
||||||
that would not affect linking of a normal library (e.g. ``.txt``).
|
that would not affect linking of a normal library (e.g. ``.txt``).
|
||||||
They may contain custom commands generating such sources, but not
|
They may contain custom commands generating such sources, but not
|
||||||
``PRE_BUILD``, ``PRE_LINK``, or ``POST_BUILD`` commands. Object libraries
|
``PRE_BUILD``, ``PRE_LINK``, or ``POST_BUILD`` commands. Some native build
|
||||||
cannot be linked. Some native build systems (such as Xcode) may not like
|
systems (such as Xcode) may not like targets that have only object files, so
|
||||||
targets that have only object files, so consider adding at least one real
|
consider adding at least one real source file to any target that references
|
||||||
source file to any target that references ``$<TARGET_OBJECTS:objlib>``.
|
``$<TARGET_OBJECTS:objlib>``.
|
||||||
|
|
||||||
Alias Libraries
|
Alias Libraries
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ unspecified.
|
|||||||
:ref:`Object Libraries` under :generator:`Xcode` have special handling if
|
:ref:`Object Libraries` under :generator:`Xcode` have special handling if
|
||||||
multiple architectures are listed in :variable:`CMAKE_OSX_ARCHITECTURES`.
|
multiple architectures are listed in :variable:`CMAKE_OSX_ARCHITECTURES`.
|
||||||
In this case they will be exported as :ref:`Interface Libraries` with
|
In this case they will be exported as :ref:`Interface Libraries` with
|
||||||
no object files available to clients.
|
no object files available to clients. This is sufficient to satisfy
|
||||||
|
transitive usage requirements of other targets that link to the
|
||||||
|
object libraries in their implementation.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|||||||
@@ -187,6 +187,8 @@ export file itself, call ``install(EXPORT)``, documented below.
|
|||||||
They install no artifacts but will be included in an associated ``EXPORT``.
|
They install no artifacts but will be included in an associated ``EXPORT``.
|
||||||
If :ref:`Object Libraries` are listed but given no destination for their
|
If :ref:`Object Libraries` are listed but given no destination for their
|
||||||
object files, they will be exported as :ref:`Interface Libraries`.
|
object files, they will be exported as :ref:`Interface Libraries`.
|
||||||
|
This is sufficient to satisfy transitive usage requirements of other
|
||||||
|
targets that link to the object libraries in their implementation.
|
||||||
|
|
||||||
Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
|
Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
|
||||||
set to ``TRUE`` has undefined behavior.
|
set to ``TRUE`` has undefined behavior.
|
||||||
|
|||||||
@@ -183,6 +183,70 @@ is not ``NEW``, they are also appended to the
|
|||||||
``general`` (or without any keyword) are treated as if specified for both
|
``general`` (or without any keyword) are treated as if specified for both
|
||||||
``debug`` and ``optimized``.
|
``debug`` and ``optimized``.
|
||||||
|
|
||||||
|
Linking Object Libraries
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
:ref:`Object Libraries` may be used as the ``<target>`` (first) argument
|
||||||
|
of ``target_link_libraries`` to specify dependencies of their sources
|
||||||
|
on other libraries. For example, the code
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
add_library(A SHARED a.c)
|
||||||
|
target_compile_definitions(A PUBLIC A)
|
||||||
|
|
||||||
|
add_library(obj OBJECT obj.c)
|
||||||
|
target_compile_definitions(obj PUBLIC OBJ)
|
||||||
|
target_link_libraries(obj PUBLIC A)
|
||||||
|
|
||||||
|
compiles ``obj.c`` with ``-DA -DOBJ`` and establishes usage requirements
|
||||||
|
for ``obj`` that propagate to its dependents.
|
||||||
|
|
||||||
|
Normal libraries and executables may link to :ref:`Object Libraries`
|
||||||
|
to get their objects and usage requirements. Continuing the above
|
||||||
|
example, the code
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
add_library(B SHARED b.c)
|
||||||
|
target_link_libraries(B PUBLIC obj)
|
||||||
|
|
||||||
|
compiles ``b.c`` with ``-DA -DOBJ``, creates shared library ``B``
|
||||||
|
with object files from ``b.c`` and ``obj.c``, and links ``B`` to ``A``.
|
||||||
|
Furthermore, the code
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
add_executable(main main.c)
|
||||||
|
target_link_libraries(main B)
|
||||||
|
|
||||||
|
compiles ``main.c`` with ``-DA -DOBJ`` and links executable ``main``
|
||||||
|
to ``B`` and ``A``. The object library's usage requirements are
|
||||||
|
propagated transitively through ``B``, but its object files are not.
|
||||||
|
|
||||||
|
:ref:`Object Libraries` may "link" to other object libraries to get
|
||||||
|
usage requirements, but since they do not have a link step nothing
|
||||||
|
is done with their object files. Continuing from the above example,
|
||||||
|
the code:
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
add_library(obj2 OBJECT obj2.c)
|
||||||
|
target_link_libraries(obj2 PUBLIC obj)
|
||||||
|
|
||||||
|
add_executable(main2 main2.c)
|
||||||
|
target_link_libraries(main2 obj2)
|
||||||
|
|
||||||
|
compiles ``obj2.c`` with ``-DA -DOBJ``, creates executable ``main2``
|
||||||
|
with object files from ``main2.c`` and ``obj2.c``, and links ``main2``
|
||||||
|
to ``A``.
|
||||||
|
|
||||||
|
In other words, when :ref:`Object Libraries` appear in a target's
|
||||||
|
:prop_tgt:`INTERFACE_LINK_LIBRARIES` property they will be
|
||||||
|
treated as :ref:`Interface Libraries`, but when they appear in
|
||||||
|
a target's :prop_tgt:`LINK_LIBRARIES` property their object files
|
||||||
|
will be included in the link too.
|
||||||
|
|
||||||
Cyclic Dependencies of Static Libraries
|
Cyclic Dependencies of Static Libraries
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
@@ -113,9 +113,9 @@ and it uniquely identifies the bundle.
|
|||||||
Object Libraries
|
Object Libraries
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The ``OBJECT`` library type is also not linked to. It defines a non-archival
|
The ``OBJECT`` library type defines a non-archival collection of object files
|
||||||
collection of object files resulting from compiling the given source files.
|
resulting from compiling the given source files. The object files collection
|
||||||
The object files collection can be used as source inputs to other targets:
|
may be used as source inputs to other targets:
|
||||||
|
|
||||||
.. code-block:: cmake
|
.. code-block:: cmake
|
||||||
|
|
||||||
@@ -125,22 +125,31 @@ The object files collection can be used as source inputs to other targets:
|
|||||||
|
|
||||||
add_executable(test_exe $<TARGET_OBJECTS:archive> test.cpp)
|
add_executable(test_exe $<TARGET_OBJECTS:archive> test.cpp)
|
||||||
|
|
||||||
``OBJECT`` libraries may not be used in the right hand side of
|
The link (or archiving) step of those other targets will use the object
|
||||||
:command:`target_link_libraries`. They also may not be used as the ``TARGET``
|
files collection in addition to those from their own sources.
|
||||||
in a use of the :command:`add_custom_command(TARGET)` command signature. They
|
|
||||||
may be installed, and will be exported as an INTERFACE library.
|
|
||||||
|
|
||||||
Although object libraries may not be named directly in calls to
|
Alternatively, object libraries may be linked into other targets:
|
||||||
the :command:`target_link_libraries` command, they can be "linked"
|
|
||||||
indirectly by using an :ref:`Interface Library <Interface Libraries>`
|
|
||||||
whose :prop_tgt:`INTERFACE_SOURCES` target property is set to name
|
|
||||||
``$<TARGET_OBJECTS:objlib>``.
|
|
||||||
|
|
||||||
Although object libraries may not be used as the ``TARGET``
|
.. code-block:: cmake
|
||||||
in a use of the :command:`add_custom_command(TARGET)` command signature,
|
|
||||||
the list of objects can be used by :command:`add_custom_command(OUTPUT)` or
|
|
||||||
:command:`file(GENERATE)` by using ``$<TARGET_OBJECTS:objlib>``.
|
|
||||||
|
|
||||||
|
add_library(archive OBJECT archive.cpp zip.cpp lzma.cpp)
|
||||||
|
|
||||||
|
add_library(archiveExtras STATIC extras.cpp)
|
||||||
|
target_link_libraries(archiveExtras PUBLIC archive)
|
||||||
|
|
||||||
|
add_executable(test_exe test.cpp)
|
||||||
|
target_link_libraries(test_exe archive)
|
||||||
|
|
||||||
|
The link (or archiving) step of those other targets will use the object
|
||||||
|
files from object libraries that are *directly* linked. Additionally,
|
||||||
|
usage requirements of the object libraries will be honored when compiling
|
||||||
|
sources in those other targets. Furthermore, those usage requirements
|
||||||
|
will propagate transitively to dependents of those other targets.
|
||||||
|
|
||||||
|
Object libraries may not be used as the ``TARGET`` in a use of the
|
||||||
|
:command:`add_custom_command(TARGET)` command signature. However,
|
||||||
|
the list of objects can be used by :command:`add_custom_command(OUTPUT)`
|
||||||
|
or :command:`file(GENERATE)` by using ``$<TARGET_OBJECTS:objlib>``.
|
||||||
|
|
||||||
Build Specification and Usage Requirements
|
Build Specification and Usage Requirements
|
||||||
==========================================
|
==========================================
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
object-library-linking
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
* The :command:`target_link_libraries` command now supports
|
||||||
|
:ref:`Object Libraries`. Linking to an object library uses its object
|
||||||
|
files in direct dependents and also propagates usage requirements.
|
||||||
Reference in New Issue
Block a user