diff options
author | Brad King <brad.king@kitware.com> | 2018-05-03 12:11:02 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2018-05-03 12:11:20 (GMT) |
commit | 7c2866ec6094cc4d423469f8399c1a34d36ed5c3 (patch) | |
tree | 8212293f78b96646c7ce55dfcbdcdf7fee6b3289 | |
parent | 1e788a964d198fc3c135afd053afdefc531bf369 (diff) | |
parent | 7e8046e20b766b5363bc91a1bcae4eae2fc9263b (diff) | |
download | CMake-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
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 +) |