Browse Source

Help: Document linking behavior of OBJECT libraries

Inspired-by: Deniz Bahadir <[email protected]>
Issue: #14778
Brad King 7 years ago
parent
commit
bafe655b11

+ 4 - 4
Help/command/add_library.rst

@@ -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
 that would not affect linking of a normal library (e.g. ``.txt``).
 They may contain custom commands generating such sources, but not
-``PRE_BUILD``, ``PRE_LINK``, or ``POST_BUILD`` commands.  Object libraries
-cannot be linked.  Some native build systems (such as Xcode) may not like
-targets that have only object files, so consider adding at least one real
-source file to any target that references ``$<TARGET_OBJECTS:objlib>``.
+``PRE_BUILD``, ``PRE_LINK``, or ``POST_BUILD`` commands.  Some native build
+systems (such as Xcode) may not like targets that have only object files, so
+consider adding at least one real source file to any target that references
+``$<TARGET_OBJECTS:objlib>``.
 
 Alias Libraries
 ^^^^^^^^^^^^^^^

+ 3 - 1
Help/command/export.rst

@@ -45,7 +45,9 @@ unspecified.
   :ref:`Object Libraries` under :generator:`Xcode` have special handling if
   multiple architectures are listed in :variable:`CMAKE_OSX_ARCHITECTURES`.
   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.
 
 ::
 

+ 2 - 0
Help/command/install.rst

@@ -187,6 +187,8 @@ export file itself, call ``install(EXPORT)``, documented below.
 They install no artifacts but will be included in an associated ``EXPORT``.
 If :ref:`Object Libraries` are listed but given no destination for their
 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
 set to ``TRUE`` has undefined behavior.

+ 64 - 0
Help/command/target_link_libraries.rst

@@ -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
 ``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
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

+ 25 - 16
Help/manual/cmake-buildsystem.7.rst

@@ -113,9 +113,9 @@ and it uniquely identifies the bundle.
 Object Libraries
 ^^^^^^^^^^^^^^^^
 
-The ``OBJECT`` library type is also not linked to. It defines a non-archival
-collection of object files resulting from compiling the given source files.
-The object files collection can be used as source inputs to other targets:
+The ``OBJECT`` library type defines a non-archival collection of object files
+resulting from compiling the given source files.  The object files collection
+may be used as source inputs to other targets:
 
 .. 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)
 
-``OBJECT`` libraries may not be used in the right hand side of
-:command:`target_link_libraries`.  They also may not be used as the ``TARGET``
-in a use of the :command:`add_custom_command(TARGET)` command signature.  They
-may be installed, and will be exported as an INTERFACE library.
+The link (or archiving) step of those other targets will use the object
+files collection in addition to those from their own sources.
 
-Although object libraries may not be named directly in calls to
-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>``.
+Alternatively, object libraries may be linked into other targets:
 
-Although object libraries may not be used as the ``TARGET``
-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>``.
+.. code-block:: cmake
+
+  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
 ==========================================

+ 6 - 0
Help/release/dev/object-library-linking.rst

@@ -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.