summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2018-05-03 12:11:02 (GMT)
committerKitware Robot <kwrobot@kitware.com>2018-05-03 12:11:20 (GMT)
commit7c2866ec6094cc4d423469f8399c1a34d36ed5c3 (patch)
tree8212293f78b96646c7ce55dfcbdcdf7fee6b3289
parent1e788a964d198fc3c135afd053afdefc531bf369 (diff)
parent7e8046e20b766b5363bc91a1bcae4eae2fc9263b (diff)
downloadCMake-7c2866ec6094cc4d423469f8399c1a34d36ed5c3.zip
CMake-7c2866ec6094cc4d423469f8399c1a34d36ed5c3.tar.gz
CMake-7c2866ec6094cc4d423469f8399c1a34d36ed5c3.tar.bz2
Merge topic 'namelink-component'
7e8046e20b Help: add release notes for NAMELINK_COMPONENT c02eeb0853 Help: clarify "undefined behavior" in install(EXPORT) command edcb545a24 install: add test for new NAMELINK_COMPONENT parameter 0212d7c762 install: add NAMELINK_COMPONENT argument cbb609072f Help: clean up install(TARGETS) documentation b81280ba1f Help: add list of command signatures to top of INSTALL page Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Alex Turbov <i.zaufi@gmail.com> Merge-request: !1982
-rw-r--r--Help/command/install.rst242
-rw-r--r--Help/release/dev/namelink-component.rst7
-rw-r--r--Source/cmInstallCommand.cxx46
-rw-r--r--Source/cmInstallCommandArguments.cxx20
-rw-r--r--Source/cmInstallCommandArguments.h3
-rw-r--r--Tests/RunCMake/CMakeLists.txt8
-rw-r--r--Tests/RunCMake/install/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-all-check.cmake73
-rw-r--r--Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all-result.txt1
-rw-r--r--Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all-stderr.txt5
-rw-r--r--Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all.cmake9
-rw-r--r--Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc-result.txt1
-rw-r--r--Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc-stderr.txt5
-rw-r--r--Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc.cmake10
-rw-r--r--Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-dev-check.cmake11
-rw-r--r--Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-lib-check.cmake50
-rw-r--r--Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-uns-check.cmake38
-rw-r--r--Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT.cmake68
18 files changed, 529 insertions, 75 deletions
diff --git a/Help/command/install.rst b/Help/command/install.rst
index d3818d6..a81714f 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -7,6 +7,14 @@ install
Specify rules to run at install time.
+This command accepts several signatures:
+
+* :ref:`install(TARGETS) <install-targets>`
+* :ref:`install(FILES|PROGRAMS) <install-files>`
+* :ref:`install(DIRECTORY) <install-directory>`
+* :ref:`install(SCRIPT|CODE) <install-script>`
+* :ref:`install(EXPORT|EXPORT_ANDROID_MK) <install-export>`
+
Introduction
^^^^^^^^^^^^
@@ -81,6 +89,8 @@ Command signatures that install files may print messages during
installation. Use the :variable:`CMAKE_INSTALL_MESSAGE` variable
to control which messages are printed.
+.. _install-targets:
+
Installing Targets
^^^^^^^^^^^^^^^^^^
@@ -93,6 +103,7 @@ Installing Targets
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
+ [NAMELINK_COMPONENT <component>]
[OPTIONAL] [EXCLUDE_FROM_ALL]
[NAMELINK_ONLY|NAMELINK_SKIP]
] [...]
@@ -100,63 +111,144 @@ Installing Targets
)
The ``TARGETS`` form specifies rules for installing targets from a
-project. There are six kinds of target files that may be installed:
-``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``OBJECTS``, ``FRAMEWORK``, and
-``BUNDLE``. Executables are treated as ``RUNTIME`` targets, except that
-those marked with the ``MACOSX_BUNDLE`` property are treated as ``BUNDLE``
-targets on OS X. Static libraries are treated as ``ARCHIVE`` targets,
-except that those marked with the ``FRAMEWORK`` property are treated
-as ``FRAMEWORK`` targets on OS X.
-Module libraries are always treated as ``LIBRARY`` targets.
-For non-DLL platforms shared libraries are treated as ``LIBRARY``
-targets, except that those marked with the ``FRAMEWORK`` property are
-treated as ``FRAMEWORK`` targets on OS X. For DLL platforms the DLL
-part of a shared library is treated as a ``RUNTIME`` target and the
-corresponding import library is treated as an ``ARCHIVE`` target.
-All Windows-based systems including Cygwin are DLL platforms. Object
-libraries are always treated as ``OBJECTS`` targets.
-The ``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``OBJECTS``, and ``FRAMEWORK``
-arguments change the type of target to which the subsequent properties
-apply. If none is given the installation properties apply to all target
-types. If only one is given then only targets of that type will be
-installed (which can be used to install just a DLL or just an import
-library).
-
-The ``PRIVATE_HEADER``, ``PUBLIC_HEADER``, and ``RESOURCE`` arguments
-cause subsequent properties to be applied to installing a ``FRAMEWORK``
-shared library target's associated files on non-Apple platforms. Rules
-defined by these arguments are ignored on Apple platforms because the
-associated files are installed into the appropriate locations inside
-the framework folder. See documentation of the
-:prop_tgt:`PRIVATE_HEADER`, :prop_tgt:`PUBLIC_HEADER`, and
-:prop_tgt:`RESOURCE` target properties for details.
-
-Either ``NAMELINK_ONLY`` or ``NAMELINK_SKIP`` may be specified as a
-``LIBRARY`` option. On some platforms a versioned shared library
-has a symbolic link such as::
-
- lib<name>.so -> lib<name>.so.1
-
-where ``lib<name>.so.1`` is the soname of the library and ``lib<name>.so``
-is a "namelink" allowing linkers to find the library when given
-``-l<name>``. The ``NAMELINK_ONLY`` option causes installation of only the
-namelink when a library target is installed. The ``NAMELINK_SKIP`` option
-causes installation of library files other than the namelink when a
-library target is installed. When neither option is given both
-portions are installed. On platforms where versioned shared libraries
-do not have namelinks or when a library is not versioned the
-``NAMELINK_SKIP`` option installs the library and the ``NAMELINK_ONLY``
-option installs nothing. See the :prop_tgt:`VERSION` and
-:prop_tgt:`SOVERSION` target properties for details on creating versioned
-shared libraries.
-
-The ``INCLUDES DESTINATION`` specifies a list of directories
-which will be added to the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
-target property of the ``<targets>`` when exported by the
-:command:`install(EXPORT)` command. If a relative path is
-specified, it is treated as relative to the ``$<INSTALL_PREFIX>``.
-This is independent of the rest of the argument groups and does
-not actually install anything.
+project. There are several kinds of target files that may be installed:
+
+``ARCHIVE``
+ Static libraries are treated as ``ARCHIVE`` targets, except those
+ marked with the ``FRAMEWORK`` property on OS X (see ``FRAMEWORK``
+ below.) For DLL platforms (all Windows-based systems including
+ Cygwin), the DLL import library is treated as an ``ARCHIVE`` target.
+
+``LIBRARY``
+ Module libraries are always treated as ``LIBRARY`` targets. For non-
+ DLL platforms shared libraries are treated as ``LIBRARY`` targets,
+ except those marked with the ``FRAMEWORK`` property on OS X (see
+ ``FRAMEWORK`` below.)
+
+``RUNTIME``
+ Executables are treated as ``RUNTIME`` objects, except those marked
+ with the ``MACOSX_BUNDLE`` property on OS X (see ``BUNDLE`` below.)
+ For DLL platforms (all Windows-based systems including Cygwin), the
+ DLL part of a shared library is treated as a ``RUNTIME`` target.
+
+``OBJECTS``
+ Object libraries (a simple group of object files) are always treated
+ as ``OBJECTS`` targets.
+
+``FRAMEWORK``
+ Both static and shared libraries marked with the ``FRAMEWORK``
+ property are treated as ``FRAMEWORK`` targets on OS X.
+
+``BUNDLE``
+ Executables marked with the ``MACOSX_BUNDLE`` property are treated as
+ ``BUNDLE`` targets on OS X.
+
+``PUBLIC_HEADER``
+ Any ``PUBLIC_HEADER`` files associated with a library are installed in
+ the destination specified by the ``PUBLIC_HEADER`` argument on non-Apple
+ platforms. Rules defined by this argument are ignored for ``FRAMEWORK``
+ libraries on Apple platforms because the associated files are installed
+ into the appropriate locations inside the framework folder. See
+ :prop_tgt:`PUBLIC_HEADER` for details.
+
+``PRIVATE_HEADER``
+ Similar to ``PUBLIC_HEADER``, but for ``PRIVATE_HEADER`` files. See
+ :prop_tgt:`PRIVATE_HEADER` for details.
+
+``RESOURCE``
+ Similar to ``PUBLIC_HEADER`` and ``PRIVATE_HEADER``, but for
+ ``RESOURCE`` files. See :prop_tgt:`RESOURCE` for details.
+
+For each of these arguments given, the arguments following them only apply
+to the target or file type specified in the argument. If none is given, the
+installation properties apply to all target types. If only one is given then
+only targets of that type will be installed (which can be used to install
+just a DLL or just an import library.)
+
+In addition to the common options listed above, each target can accept
+the following additional arguments:
+
+``NAMELINK_COMPONENT``
+ On some platforms a versioned shared library has a symbolic link such
+ as::
+
+ lib<name>.so -> lib<name>.so.1
+
+ where ``lib<name>.so.1`` is the soname of the library and ``lib<name>.so``
+ is a "namelink" allowing linkers to find the library when given
+ ``-l<name>``. The ``NAMELINK_COMPONENT`` option is similar to the
+ ``COMPONENT`` option, but it changes the installation component of a shared
+ library namelink if one is generated. If not specified, this defaults to the
+ value of ``COMPONENT``. It is an error to use this parameter outside of a
+ ``LIBRARY`` block.
+
+ Consider the following example:
+
+ .. code-block:: cmake
+
+ install(TARGETS mylib
+ LIBRARY
+ DESTINATION lib
+ COMPONENT Libraries
+ NAMELINK_COMPONENT Development
+ PUBLIC_HEADER
+ DESTINATION include
+ COMPONENT Development
+ )
+
+ In this scenario, if you choose to install only the ``Development``
+ component, both the headers and namelink will be installed without the
+ library. (If you don't also install the ``Libraries`` component, the
+ namelink will be a dangling symlink, and projects that link to the library
+ will have build errors.) If you install only the ``Libraries`` component,
+ only the library will be installed, without the headers and namelink.
+
+ This option is typically used for package managers that have separate
+ runtime and development packages. For example, on Debian systems, the
+ library is expected to be in the runtime package, and the headers and
+ namelink are expected to be in the development package.
+
+ See the :prop_tgt:`VERSION` and :prop_tgt:`SOVERSION` target properties for
+ details on creating versioned shared libraries.
+
+``NAMELINK_ONLY``
+ This option causes the installation of only the namelink when a library
+ target is installed. On platforms where versioned shared libraries do not
+ have namelinks or when a library is not versioned, the ``NAMELINK_ONLY``
+ option installs nothing. It is an error to use this parameter outside of a
+ ``LIBRARY`` block.
+
+ When ``NAMELINK_ONLY`` is given, either ``NAMELINK_COMPONENT`` or
+ ``COMPONENT`` may be used to specify the installation component of the
+ namelink, but ``COMPONENT`` should generally be preferred.
+
+``NAMELINK_SKIP``
+ Similar to ``NAMELINK_ONLY``, but it has the opposite effect: it causes the
+ installation of library files other than the namelink when a library target
+ is installed. When neither ``NAMELINK_ONLY`` or ``NAMELINK_SKIP`` are given,
+ both portions are installed. On platforms where versioned shared libraries
+ do not have symlinks or when a library is not versioned, ``NAMELINK_SKIP``
+ installs the library. It is an error to use this parameter outside of a
+ ``LIBRARY`` block.
+
+ If ``NAMELINK_SKIP`` is specified, ``NAMELINK_COMPONENT`` has no effect. It
+ is not recommended to use ``NAMELINK_SKIP`` in conjunction with
+ ``NAMELINK_COMPONENT``.
+
+The ``install(TARGETS)`` command can also accept the following options at the
+top level:
+
+``EXPORT``
+ This option associates the installed target files with an export called
+ ``<export-name>``. It must appear before any target options. To actually
+ install the export file itself, call ``install(EXPORT)``, documented below.
+
+``INCLUDES DESTINATION``
+ This option specifies a list of directories which will be added to the
+ :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property of the
+ ``<targets>`` when exported by the :command:`install(EXPORT)` command. If a
+ relative path is specified, it is treated as relative to the
+ ``$<INSTALL_PREFIX>``.
One or more groups of properties may be specified in a single call to
the ``TARGETS`` form of this command. A target may be installed more than
@@ -178,11 +270,6 @@ the ``mySharedLib`` DLL will be installed to ``<prefix>/bin`` and
``/some/full/path`` and its import library will be installed to
``<prefix>/lib/static`` and ``/some/full/path``.
-The ``EXPORT`` option associates the installed target files with an
-export called ``<export-name>``. It must appear before any ``RUNTIME``,
-``LIBRARY``, ``ARCHIVE``, or ``OBJECTS`` options. To actually install the
-export file itself, call ``install(EXPORT)``, documented below.
-
:ref:`Interface Libraries` may be listed among the targets to install.
They install no artifacts but will be included in an associated ``EXPORT``.
If :ref:`Object Libraries` are listed but given no destination for their
@@ -197,6 +284,8 @@ The install destination given to the target install ``DESTINATION`` may
use "generator expressions" with the syntax ``$<...>``. See the
:manual:`cmake-generator-expressions(7)` manual for available expressions.
+.. _install-files:
+
Installing Files
^^^^^^^^^^^^^^^^
@@ -230,6 +319,8 @@ The install destination given to the files install ``DESTINATION`` may
use "generator expressions" with the syntax ``$<...>``. See the
:manual:`cmake-generator-expressions(7)` manual for available expressions.
+.. _install-directory:
+
Installing Directories
^^^^^^^^^^^^^^^^^^^^^^
@@ -311,6 +402,8 @@ given to the directory install ``DESTINATION`` may use "generator expressions"
with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
manual for available expressions.
+.. _install-script:
+
Custom Installation Logic
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -332,6 +425,8 @@ example, the code
will print a message during installation.
+.. _install-export:
+
Installing Exports
^^^^^^^^^^^^^^^^^^
@@ -361,11 +456,24 @@ generated import file will reference only the matching target
configurations. The ``EXPORT_LINK_INTERFACE_LIBRARIES`` keyword, if
present, causes the contents of the properties matching
``(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?`` to be exported, when
-policy :policy:`CMP0022` is ``NEW``. If a ``COMPONENT`` option is
-specified that does not match that given to the targets associated with
-``<export-name>`` the behavior is undefined. If a library target is
-included in the export but a target to which it links is not included
-the behavior is unspecified.
+policy :policy:`CMP0022` is ``NEW``.
+
+When a ``COMPONENT`` option is given, the listed ``<component>`` implicitly
+depends on all components mentioned in the export set. The exported
+``<name>.cmake`` file will require each of the exported components to be
+present in order for dependent projects to build properly. For example, a
+project may define components ``Runtime`` and ``Development``, with shared
+libraries going into the ``Runtime`` component and static libraries and
+headers going into the ``Development`` component. The export set would also
+typically be part of the ``Development`` component, but it would export
+targets from both the ``Runtime`` and ``Development`` components. Therefore,
+the ``Runtime`` component would need to be installed if the ``Development``
+component was installed, but not vice versa. If the ``Development`` component
+was installed without the ``Runtime`` component, dependent projects that try
+to link against it would have build errors. Package managers, such as APT and
+RPM, typically handle this by listing the ``Runtime`` component as a dependency
+of the ``Development`` component in the package metadata, ensuring that the
+library is always installed if the headers and CMake export file are present.
In addition to cmake language files, the ``EXPORT_ANDROID_MK`` mode maybe
used to specify an export to the android ndk build system. This mode
diff --git a/Help/release/dev/namelink-component.rst b/Help/release/dev/namelink-component.rst
new file mode 100644
index 0000000..aaeb04f
--- /dev/null
+++ b/Help/release/dev/namelink-component.rst
@@ -0,0 +1,7 @@
+namelink-component
+------------------
+
+* The :command:`install` command learned an optional ``NAMELINK_COMPONENT``
+ parameter, which allows you to change the component for a shared library's
+ namelink. If none is specified, the value of ``COMPONENT`` is used by
+ default.
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index b5291a1..b325b0c 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -33,16 +33,17 @@ class cmExecutionStatus;
static cmInstallTargetGenerator* CreateInstallTargetGenerator(
cmTarget& target, const cmInstallCommandArguments& args, bool impLib,
- bool forceOpt = false)
+ bool forceOpt = false, bool namelink = false)
{
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(target.GetMakefile());
target.SetHaveInstallRule(true);
+ const char* component = namelink ? args.GetNamelinkComponent().c_str()
+ : args.GetComponent().c_str();
return new cmInstallTargetGenerator(
target.GetName(), args.GetDestination().c_str(), impLib,
- args.GetPermissions().c_str(), args.GetConfigurations(),
- args.GetComponent().c_str(), message, args.GetExcludeFromAll(),
- args.GetOptional() || forceOpt);
+ args.GetPermissions().c_str(), args.GetConfigurations(), component,
+ message, args.GetExcludeFromAll(), args.GetOptional() || forceOpt);
}
static cmInstallFilesGenerator* CreateInstallFilesGenerator(
@@ -313,6 +314,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
"The NAMELINK_SKIP option may be specified only following LIBRARY.");
return false;
}
+ if (archiveArgs.HasNamelinkComponent() ||
+ runtimeArgs.HasNamelinkComponent() ||
+ objectArgs.HasNamelinkComponent() ||
+ frameworkArgs.HasNamelinkComponent() ||
+ bundleArgs.HasNamelinkComponent() ||
+ privateHeaderArgs.HasNamelinkComponent() ||
+ publicHeaderArgs.HasNamelinkComponent() ||
+ resourceArgs.HasNamelinkComponent()) {
+ this->SetError(
+ "TARGETS given NAMELINK_COMPONENT option not in LIBRARY group. "
+ "The NAMELINK_COMPONENT option may be specified only following "
+ "LIBRARY.");
+ return false;
+ }
if (libraryArgs.GetNamelinkOnly() && libraryArgs.GetNamelinkSkip()) {
this->SetError("TARGETS given NAMELINK_ONLY and NAMELINK_SKIP. "
"At most one of these two options may be specified.");
@@ -377,6 +392,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
// any files of the given type.
bool installsArchive = false;
bool installsLibrary = false;
+ bool installsNamelink = false;
bool installsRuntime = false;
bool installsObject = false;
bool installsFramework = false;
@@ -391,6 +407,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
cmTarget& target = *ti;
cmInstallTargetGenerator* archiveGenerator = nullptr;
cmInstallTargetGenerator* libraryGenerator = nullptr;
+ cmInstallTargetGenerator* namelinkGenerator = nullptr;
cmInstallTargetGenerator* runtimeGenerator = nullptr;
cmInstallTargetGenerator* objectGenerator = nullptr;
cmInstallTargetGenerator* frameworkGenerator = nullptr;
@@ -453,9 +470,18 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
} else {
// The shared library uses the LIBRARY properties.
if (!libraryArgs.GetDestination().empty()) {
- libraryGenerator =
- CreateInstallTargetGenerator(target, libraryArgs, false);
- libraryGenerator->SetNamelinkMode(namelinkMode);
+ if (namelinkMode != cmInstallTargetGenerator::NamelinkModeOnly) {
+ libraryGenerator =
+ CreateInstallTargetGenerator(target, libraryArgs, false);
+ libraryGenerator->SetNamelinkMode(
+ cmInstallTargetGenerator::NamelinkModeSkip);
+ }
+ if (namelinkMode != cmInstallTargetGenerator::NamelinkModeSkip) {
+ namelinkGenerator = CreateInstallTargetGenerator(
+ target, libraryArgs, false, false, true);
+ namelinkGenerator->SetNamelinkMode(
+ cmInstallTargetGenerator::NamelinkModeOnly);
+ }
namelinkOnly =
(namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
} else {
@@ -684,6 +710,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
// Keep track of whether we're installing anything in each category
installsArchive = installsArchive || archiveGenerator != nullptr;
installsLibrary = installsLibrary || libraryGenerator != nullptr;
+ installsNamelink = installsNamelink || namelinkGenerator != nullptr;
installsRuntime = installsRuntime || runtimeGenerator != nullptr;
installsObject = installsObject || objectGenerator != nullptr;
installsFramework = installsFramework || frameworkGenerator != nullptr;
@@ -696,6 +723,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
this->Makefile->AddInstallGenerator(archiveGenerator);
this->Makefile->AddInstallGenerator(libraryGenerator);
+ this->Makefile->AddInstallGenerator(namelinkGenerator);
this->Makefile->AddInstallGenerator(runtimeGenerator);
this->Makefile->AddInstallGenerator(objectGenerator);
this->Makefile->AddInstallGenerator(frameworkGenerator);
@@ -735,6 +763,10 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
this->Makefile->GetGlobalGenerator()->AddInstallComponent(
libraryArgs.GetComponent().c_str());
}
+ if (installsNamelink) {
+ this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ libraryArgs.GetNamelinkComponent().c_str());
+ }
if (installsRuntime) {
this->Makefile->GetGlobalGenerator()->AddInstallComponent(
runtimeArgs.GetComponent().c_str());
diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx
index 7b79ab5..2d6dc12 100644
--- a/Source/cmInstallCommandArguments.cxx
+++ b/Source/cmInstallCommandArguments.cxx
@@ -21,6 +21,7 @@ cmInstallCommandArguments::cmInstallCommandArguments(
, ArgumentGroup()
, Destination(&Parser, "DESTINATION", &ArgumentGroup)
, Component(&Parser, "COMPONENT", &ArgumentGroup)
+ , NamelinkComponent(&Parser, "NAMELINK_COMPONENT", &ArgumentGroup)
, ExcludeFromAll(&Parser, "EXCLUDE_FROM_ALL", &ArgumentGroup)
, Rename(&Parser, "RENAME", &ArgumentGroup)
, Permissions(&Parser, "PERMISSIONS", &ArgumentGroup)
@@ -59,6 +60,14 @@ const std::string& cmInstallCommandArguments::GetComponent() const
return unspecifiedComponent;
}
+const std::string& cmInstallCommandArguments::GetNamelinkComponent() const
+{
+ if (!this->NamelinkComponent.GetString().empty()) {
+ return this->NamelinkComponent.GetString();
+ }
+ return this->GetComponent();
+}
+
const std::string& cmInstallCommandArguments::GetRename() const
{
if (!this->Rename.GetString().empty()) {
@@ -125,6 +134,17 @@ bool cmInstallCommandArguments::GetNamelinkSkip() const
return false;
}
+bool cmInstallCommandArguments::HasNamelinkComponent() const
+{
+ if (!this->NamelinkComponent.GetString().empty()) {
+ return true;
+ }
+ if (this->GenericArguments != nullptr) {
+ return this->GenericArguments->HasNamelinkComponent();
+ }
+ return false;
+}
+
const std::vector<std::string>& cmInstallCommandArguments::GetConfigurations()
const
{
diff --git a/Source/cmInstallCommandArguments.h b/Source/cmInstallCommandArguments.h
index a576e72..ee6e865 100644
--- a/Source/cmInstallCommandArguments.h
+++ b/Source/cmInstallCommandArguments.h
@@ -26,6 +26,7 @@ public:
const std::string& GetDestination() const;
const std::string& GetComponent() const;
+ const std::string& GetNamelinkComponent() const;
bool GetExcludeFromAll() const;
const std::string& GetRename() const;
const std::string& GetPermissions() const;
@@ -33,6 +34,7 @@ public:
bool GetOptional() const;
bool GetNamelinkOnly() const;
bool GetNamelinkSkip() const;
+ bool HasNamelinkComponent() const;
// once HandleDirectoryMode() is also switched to using
// cmInstallCommandArguments then these two functions can become non-static
@@ -45,6 +47,7 @@ private:
cmInstallCommandArguments(); // disabled
cmCAString Destination;
cmCAString Component;
+ cmCAString NamelinkComponent;
cmCAEnabler ExcludeFromAll;
cmCAString Rename;
cmCAStringVector Permissions;
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 6557cc4..690c5b4 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -338,7 +338,13 @@ add_RunCMake_test(CheckIPOSupported)
add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
add_RunCMake_test(CommandLineTar)
-add_RunCMake_test(install)
+if(CMAKE_PLATFORM_NO_VERSIONED_SONAME OR (NOT CMAKE_SHARED_LIBRARY_SONAME_FLAG AND NOT CMAKE_SHARED_LIBRARY_SONAME_C_FLAG))
+ set(NO_NAMELINK 1)
+else()
+ set(NO_NAMELINK 0)
+endif()
+
+add_RunCMake_test(install -DNO_NAMELINK=${NO_NAMELINK} -DCYGWIN=${CYGWIN})
add_RunCMake_test(CPackCommandLine)
add_RunCMake_test(CPackConfig)
add_RunCMake_test(CPackInstallProperties)
diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake
index 1a60f0c..f004ce9 100644
--- a/Tests/RunCMake/install/RunCMakeTest.cmake
+++ b/Tests/RunCMake/install/RunCMakeTest.cmake
@@ -21,6 +21,10 @@ function(run_install_test case)
# Check explicit component.
set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-exc)
run_cmake_command(${case}-exc ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -DCOMPONENT=exc -P cmake_install.cmake)
+ set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-lib)
+ run_cmake_command(${case}-lib ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -DCOMPONENT=lib -P cmake_install.cmake)
+ set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-dev)
+ run_cmake_command(${case}-dev ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -DCOMPONENT=dev -P cmake_install.cmake)
endif()
endfunction()
@@ -59,6 +63,8 @@ run_cmake(EXPORT-OldIFace)
run_cmake(CMP0062-OLD)
run_cmake(CMP0062-NEW)
run_cmake(CMP0062-WARN)
+run_cmake(TARGETS-NAMELINK_COMPONENT-bad-all)
+run_cmake(TARGETS-NAMELINK_COMPONENT-bad-exc)
if(NOT RunCMake_GENERATOR STREQUAL "Xcode" OR NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
run_install_test(FILES-TARGET_OBJECTS)
@@ -67,3 +73,4 @@ endif()
set(run_install_test_components 1)
run_install_test(FILES-EXCLUDE_FROM_ALL)
run_install_test(TARGETS-EXCLUDE_FROM_ALL)
+run_install_test(TARGETS-NAMELINK_COMPONENT)
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-all-check.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-all-check.cmake
new file mode 100644
index 0000000..bc9ebd1
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-all-check.cmake
@@ -0,0 +1,73 @@
+if(WIN32)
+ set(_check_files
+ [[lib]]
+ [[lib/(lib)?namelink-none\.dll]]
+ [[lib/(lib)?namelink-same\.dll]]
+ [[lib/(lib)?namelink-sep\.dll]]
+ [[lib/(lib)?namelink-skip\.dll]]
+ [[lib/(lib)?namelink-uns-dev\.dll]]
+ [[lib/(lib)?namelink-uns\.dll]]
+ )
+elseif(CYGWIN)
+ set(_check_files
+ [[lib]]
+ [[lib/cygnamelink-none\.dll]]
+ [[lib/cygnamelink-same-1\.dll]]
+ [[lib/cygnamelink-sep-1\.dll]]
+ [[lib/cygnamelink-skip-1\.dll]]
+ [[lib/cygnamelink-uns-1\.dll]]
+ [[lib/cygnamelink-uns-dev-1\.dll]]
+ )
+elseif(APPLE)
+ set(_check_files
+ [[lib]]
+ [[lib/libnamelink-none\.dylib]]
+ [[lib/libnamelink-only\.dylib]]
+ [[lib/libnamelink-same\.1\.0\.dylib]]
+ [[lib/libnamelink-same\.1\.dylib]]
+ [[lib/libnamelink-same\.dylib]]
+ [[lib/libnamelink-sep\.1\.0\.dylib]]
+ [[lib/libnamelink-sep\.1\.dylib]]
+ [[lib/libnamelink-sep\.dylib]]
+ [[lib/libnamelink-skip\.1\.0\.dylib]]
+ [[lib/libnamelink-skip\.1\.dylib]]
+ [[lib/libnamelink-uns-dev\.1\.0\.dylib]]
+ [[lib/libnamelink-uns-dev\.1\.dylib]]
+ [[lib/libnamelink-uns-dev\.dylib]]
+ [[lib/libnamelink-uns\.1\.0\.dylib]]
+ [[lib/libnamelink-uns\.1\.dylib]]
+ [[lib/libnamelink-uns\.dylib]]
+ )
+elseif(NO_NAMELINK)
+ set(_check_files
+ [[lib]]
+ [[lib/libnamelink-none\.so]]
+ [[lib/libnamelink-same\.so]]
+ [[lib/libnamelink-sep\.so]]
+ [[lib/libnamelink-skip\.so]]
+ [[lib/libnamelink-uns-dev\.so]]
+ [[lib/libnamelink-uns\.so]]
+ )
+else()
+ set(_check_files
+ [[lib]]
+ [[lib/libnamelink-none\.so]]
+ [[lib/libnamelink-only\.so]]
+ [[lib/libnamelink-same\.so]]
+ [[lib/libnamelink-same\.so\.1]]
+ [[lib/libnamelink-same\.so\.1\.0]]
+ [[lib/libnamelink-sep\.so]]
+ [[lib/libnamelink-sep\.so\.1]]
+ [[lib/libnamelink-sep\.so\.1\.0]]
+ [[lib/libnamelink-skip\.so\.1]]
+ [[lib/libnamelink-skip\.so\.1\.0]]
+ [[lib/libnamelink-uns-dev\.so]]
+ [[lib/libnamelink-uns-dev\.so\.1]]
+ [[lib/libnamelink-uns-dev\.so\.1\.0]]
+ [[lib/libnamelink-uns\.so]]
+ [[lib/libnamelink-uns\.so\.1]]
+ [[lib/libnamelink-uns\.so\.1\.0]]
+ )
+endif()
+
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all-result.txt b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all-stderr.txt b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all-stderr.txt
new file mode 100644
index 0000000..187a826
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TARGETS-NAMELINK_COMPONENT-bad-all\.cmake:5 \(install\):
+ install TARGETS given NAMELINK_COMPONENT option not in LIBRARY group\. The
+ NAMELINK_COMPONENT option may be specified only following LIBRARY\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)$
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all.cmake
new file mode 100644
index 0000000..701d093
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-all.cmake
@@ -0,0 +1,9 @@
+enable_language(C)
+
+add_library(namelink-lib empty.c)
+
+install(TARGETS namelink-lib
+ DESTINATION lib
+ COMPONENT lib
+ NAMELINK_COMPONENT dev
+)
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc-result.txt b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc-stderr.txt b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc-stderr.txt
new file mode 100644
index 0000000..d1002ba
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TARGETS-NAMELINK_COMPONENT-bad-exc\.cmake:5 \(install\):
+ install TARGETS given NAMELINK_COMPONENT option not in LIBRARY group\. The
+ NAMELINK_COMPONENT option may be specified only following LIBRARY\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)$
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc.cmake
new file mode 100644
index 0000000..19c12d4
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-bad-exc.cmake
@@ -0,0 +1,10 @@
+enable_language(C)
+
+add_executable(namelink-exc main.c)
+
+install(TARGETS namelink-exc
+ RUNTIME
+ DESTINATION bin
+ COMPONENT exc
+ NAMELINK_COMPONENT dev
+)
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-dev-check.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-dev-check.cmake
new file mode 100644
index 0000000..5396cdb
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-dev-check.cmake
@@ -0,0 +1,11 @@
+if(WIN32 OR CYGWIN OR NO_NAMELINK)
+ set(_check_files)
+else()
+ set(_check_files
+ [[lib]]
+ [[lib/libnamelink-only\.(so|dylib)]]
+ [[lib/libnamelink-sep\.(so|dylib)]]
+ [[lib/libnamelink-uns-dev\.(so|dylib)]]
+ )
+endif()
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-lib-check.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-lib-check.cmake
new file mode 100644
index 0000000..3f6be68
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-lib-check.cmake
@@ -0,0 +1,50 @@
+if(WIN32)
+ set(_check_files
+ [[lib]]
+ [[lib/(lib)?namelink-none\.dll]]
+ [[lib/(lib)?namelink-same\.dll]]
+ [[lib/(lib)?namelink-sep\.dll]]
+ [[lib/(lib)?namelink-skip\.dll]]
+ )
+elseif(CYGWIN)
+ set(_check_files
+ [[lib]]
+ [[lib/cygnamelink-none\.dll]]
+ [[lib/cygnamelink-same-1\.dll]]
+ [[lib/cygnamelink-sep-1\.dll]]
+ [[lib/cygnamelink-skip-1\.dll]]
+ )
+elseif(APPLE)
+ set(_check_files
+ [[lib]]
+ [[lib/libnamelink-none\.dylib]]
+ [[lib/libnamelink-same\.1\.0\.dylib]]
+ [[lib/libnamelink-same\.1\.dylib]]
+ [[lib/libnamelink-same\.dylib]]
+ [[lib/libnamelink-sep\.1\.0\.dylib]]
+ [[lib/libnamelink-sep\.1\.dylib]]
+ [[lib/libnamelink-skip\.1\.0\.dylib]]
+ [[lib/libnamelink-skip\.1\.dylib]]
+ )
+elseif(NO_NAMELINK)
+ set(_check_files
+ [[lib]]
+ [[lib/libnamelink-none\.so]]
+ [[lib/libnamelink-same\.so]]
+ [[lib/libnamelink-sep\.so]]
+ [[lib/libnamelink-skip\.so]]
+ )
+else()
+ set(_check_files
+ [[lib]]
+ [[lib/libnamelink-none\.so]]
+ [[lib/libnamelink-same\.so]]
+ [[lib/libnamelink-same\.so\.1]]
+ [[lib/libnamelink-same\.so\.1\.0]]
+ [[lib/libnamelink-sep\.so\.1]]
+ [[lib/libnamelink-sep\.so\.1\.0]]
+ [[lib/libnamelink-skip\.so\.1]]
+ [[lib/libnamelink-skip\.so\.1\.0]]
+ )
+endif()
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-uns-check.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-uns-check.cmake
new file mode 100644
index 0000000..0033c88
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-uns-check.cmake
@@ -0,0 +1,38 @@
+if(WIN32)
+ set(_check_files
+ [[lib]]
+ [[lib/(lib)?namelink-uns-dev\.dll]]
+ [[lib/(lib)?namelink-uns\.dll]]
+ )
+elseif(CYGWIN)
+ set(_check_files
+ [[lib]]
+ [[lib/cygnamelink-uns-1\.dll]]
+ [[lib/cygnamelink-uns-dev-1\.dll]]
+ )
+elseif(APPLE)
+ set(_check_files
+ [[lib]]
+ [[lib/libnamelink-uns-dev\.1\.0\.dylib]]
+ [[lib/libnamelink-uns-dev\.1\.dylib]]
+ [[lib/libnamelink-uns\.1\.0\.dylib]]
+ [[lib/libnamelink-uns\.1\.dylib]]
+ [[lib/libnamelink-uns\.dylib]]
+ )
+elseif(NO_NAMELINK)
+ set(_check_files
+ [[lib]]
+ [[lib/libnamelink-uns-dev\.so]]
+ [[lib/libnamelink-uns\.so]]
+ )
+else()
+ set(_check_files
+ [[lib]]
+ [[lib/libnamelink-uns-dev\.so\.1]]
+ [[lib/libnamelink-uns-dev\.so\.1\.0]]
+ [[lib/libnamelink-uns\.so]]
+ [[lib/libnamelink-uns\.so\.1]]
+ [[lib/libnamelink-uns\.so\.1\.0]]
+ )
+endif()
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT.cmake
new file mode 100644
index 0000000..0e684e1
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT.cmake
@@ -0,0 +1,68 @@
+enable_language(C)
+
+macro(add_versioned_library NAME)
+ add_library(${NAME} SHARED obj1.c)
+ set_target_properties(${NAME} PROPERTIES
+ VERSION 1.0
+ SOVERSION 1
+ )
+endmacro()
+
+add_versioned_library(namelink-sep)
+add_versioned_library(namelink-same)
+add_versioned_library(namelink-uns)
+add_versioned_library(namelink-uns-dev)
+add_versioned_library(namelink-only)
+add_versioned_library(namelink-skip)
+add_library(namelink-none SHARED obj1.c)
+
+install(TARGETS namelink-sep namelink-none
+ RUNTIME
+ DESTINATION lib
+ COMPONENT lib
+ LIBRARY
+ DESTINATION lib
+ COMPONENT lib
+ NAMELINK_COMPONENT dev
+)
+install(TARGETS namelink-same
+ RUNTIME
+ DESTINATION lib
+ COMPONENT lib
+ LIBRARY
+ DESTINATION lib
+ COMPONENT lib
+)
+install(TARGETS namelink-uns
+ RUNTIME
+ DESTINATION lib
+ LIBRARY
+ DESTINATION lib
+)
+install(TARGETS namelink-uns-dev
+ RUNTIME
+ DESTINATION lib
+ LIBRARY
+ DESTINATION lib
+ NAMELINK_COMPONENT dev
+)
+install(TARGETS namelink-only
+ RUNTIME
+ DESTINATION lib
+ COMPONENT lib
+ LIBRARY
+ DESTINATION lib
+ COMPONENT lib
+ NAMELINK_COMPONENT dev
+ NAMELINK_ONLY
+)
+install(TARGETS namelink-skip
+ RUNTIME
+ DESTINATION lib
+ COMPONENT lib
+ LIBRARY
+ DESTINATION lib
+ COMPONENT lib
+ NAMELINK_COMPONENT dev
+ NAMELINK_SKIP
+)