Merge topic 'genex-target-prefix-suffix'

b70bac647d Genex: add $<TARGET_FILE_PREFIX:...> and $<TARGET_FILE_SUFFIX:...>
f65763fe9b Refactor: Add new methods to retrieve prefix and suffix

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3207
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index ec6cb9d..b42fe42 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -80,12 +80,17 @@
 within the project.  ``IMPORTED`` libraries are useful for convenient
 reference from commands like :command:`target_link_libraries`.  Details
 about the imported library are specified by setting properties whose names
-begin in ``IMPORTED_`` and ``INTERFACE_``.  The most important such
-property is :prop_tgt:`IMPORTED_LOCATION` (and its per-configuration
-variant :prop_tgt:`IMPORTED_LOCATION_<CONFIG>`) which specifies the
-location of the main library file on disk.  Or, for object libraries,
-:prop_tgt:`IMPORTED_OBJECTS` (and :prop_tgt:`IMPORTED_OBJECTS_<CONFIG>`)
-specifies the locations of object files on disk.
+begin in ``IMPORTED_`` and ``INTERFACE_``.
+
+The most important properties are:
+
+* :prop_tgt:`IMPORTED_LOCATION` (and its per-configuration
+  variant :prop_tgt:`IMPORTED_LOCATION_<CONFIG>`) which specifies the
+  location of the main library file on disk.
+* :prop_tgt:`IMPORTED_OBJECTS` (and :prop_tgt:`IMPORTED_OBJECTS_<CONFIG>`)
+  for object libraries, specifies the locations of object files on disk.
+* :prop_tgt:`PUBLIC_HEADER` files to be installed during :command:`install` invocation
+
 See documentation of the ``IMPORTED_*`` and ``INTERFACE_*`` properties
 for more information.
 
diff --git a/Help/command/install.rst b/Help/command/install.rst
index a4cee71..7571aae 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -148,13 +148,13 @@
   property are treated as ``FRAMEWORK`` targets on macOS.
 
 ``BUNDLE``
-  Executables marked with the ``MACOSX_BUNDLE`` property are treated as
+  Executables marked with the :prop_tgt:`MACOSX_BUNDLE` property are treated as
   ``BUNDLE`` targets on macOS.
 
 ``PUBLIC_HEADER``
-  Any ``PUBLIC_HEADER`` files associated with a library are installed in
+  Any :prop_tgt:`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``
+  platforms. Rules defined by this argument are ignored for :prop_tgt:`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.
diff --git a/Help/release/dev/iface-headers.rst b/Help/release/dev/iface-headers.rst
new file mode 100644
index 0000000..2e1de5e
--- /dev/null
+++ b/Help/release/dev/iface-headers.rst
@@ -0,0 +1,7 @@
+iface-headers
+-------------
+
+* ``INTERFACE`` library can now have :prop_tgt:`PUBLIC_HEADER` and
+  :prop_tgt:`PRIVATE_HEADER` properties set. The headers specified by those
+  properties can be installed using the :command:`install(TARGETS)` command by
+  passing the ``PUBLIC_HEADER`` and ``PRIVATE_HEADER`` arguments respectively.
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 4571566..70c44e1 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 14)
-set(CMake_VERSION_PATCH 20190410)
+set(CMake_VERSION_PATCH 20190412)
 #set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/bills-comments.txt b/Source/CPack/bills-comments.txt
deleted file mode 100644
index 1aaf9af..0000000
--- a/Source/CPack/bills-comments.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-cpack.cxx
-
-cmCPackGenerators  -- creates cmCPackGenericGenerator's via NewGenerator
-  - a cmCPackGenericGenerator factory
-
-
-cmCPackGenericGenerator::Initialize
-   this->InitializeInternal
-     CPACK_INCLUDE_TOPLEVEL_DIRECTORY = 0 turns off
-
-
-// binary package run
-cmCPackGenericGenerator::ProcessGenerator   // DoPackage
-  cmCPackGenericGenerator::PrepareNames  -- sets a bunch of CPACK_vars
-  cmCPackGenericGenerator::InstallProject
-     run preinstall  (make preinstall/fast)
-     call ReadListFile(cmake_install.cmake)
-  glob recurse in install directory to get list of files
-     this->CompressFiles with the list of files
-
-
-// source package run
-cmCPackGenericGenerator::ProcessGenerator   // DoPackage
-  cmCPackGenericGenerator::PrepareNames  -- sets a bunch of CPACK_vars
-  cmCPackGenericGenerator::InstallProject  -->
-     if set CPACK_INSTALLED_DIRECTORIES
-        glob the files in that directory
-        copy those files to the tmp install directory _CPack something
-  glob recurse in install directory to get list of files
-     this->CompressFiles with the list of files
-
-
-cmCPackGenericGenerator::InstallProject is used for both source and binary
-packages.  It is controlled based on values set in CPACK_ variables.
-
-
-InstallProject
-   1. CPACK_INSTALL_COMMANDS       - a list of commands used to install the package
-
-   2. CPACK_INSTALLED_DIRECTORIES  - copy this directory to CPACK_TEMPORARY_DIRECTORY
-
-   3. CPACK_INSTALL_CMAKE_PROJECTS - a cmake install script
-         - run make preinstall
-         - run cmake_install.cmake
-             - set CMAKE_INSTALL_PREFIX to the temp directory
-             - CPACK_BUILD_CONFIG check this and set the BUILD_TYPE to it
-              - ReadListFile on the install script  cmake_install.cmake
-         - run strip on the executables and libraries if CPACK_STRIP_FILES is TRUE
-
-Recommendations:
-
-rename cmCPackGenerators  to cmCPackGeneratorFactory
-
-rename cmCPackGenericGenerator  -->  cmCPackGenerator
-
-rename cmCPackGenericGenerator::ProcessGenerator  -> cmCPackGenerator::DoPackage
-
-
-break up cmCPackGenerator::InstallProject so it calls the following:
-
-// run user provided install commands
-  cmCPackGenerator::RunInstallCommands();
-// copy entire directories that need no processing like source trees
-  cmCPackGenerator::CopyPreInstalledDirectories();
-// run the cmake install scripts if provided
-  cmCPackGenerator::RunCMakeInstallScripts()
-
--
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 72cce9f..5f6ccca 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -303,7 +303,6 @@
 #ifdef QT_WINEXTRAS
   this->TaskbarButton = new QWinTaskbarButton(this);
   this->TaskbarButton->setWindow(this->windowHandle());
-  this->TaskbarButton->setOverlayIcon(QIcon(":/loading.png"));
 #endif
 }
 
diff --git a/Source/cmArgumentParser.cxx b/Source/cmArgumentParser.cxx
index 9a9932c..751d117 100644
--- a/Source/cmArgumentParser.cxx
+++ b/Source/cmArgumentParser.cxx
@@ -55,7 +55,7 @@
 void Instance::Bind(MultiStringList& val)
 {
   this->CurrentString = nullptr;
-  this->CurrentList = (val.emplace_back(), &val.back());
+  this->CurrentList = (static_cast<void>(val.emplace_back()), &val.back());
   this->ExpectValue = false;
 }
 
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 2fc6121..db673bb 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1146,6 +1146,13 @@
   // Add CMakeLists.txt file for user convenience.
   this->AddXCodeProjBuildRule(gtgt, classes);
 
+  // Add the Info.plist we are about to generate for an App Bundle.
+  if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
+    std::string plist = this->ComputeInfoPListLocation(gtgt);
+    cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(plist, true);
+    classes.push_back(sf);
+  }
+
   std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
 
   gtgt->ComputeObjectMapping();
@@ -2862,13 +2869,13 @@
         continue;
       }
 
-      // add the soon to be generated Info.plist file as a source for a
-      // MACOSX_BUNDLE file
-      if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
-        std::string plist = this->ComputeInfoPListLocation(gtgt);
-        mf->GetOrCreateSource(plist, true);
-        gtgt->AddSource(plist);
-      }
+      auto addSourceToGroup = [this, mf, gtgt,
+                               &sourceGroups](std::string const& source) {
+        cmSourceGroup* sourceGroup = mf->FindSourceGroup(source, sourceGroups);
+        cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(gtgt, sourceGroup);
+        std::string key = GetGroupMapKeyFromPath(gtgt, source);
+        this->GroupMap[key] = pbxgroup;
+      };
 
       // Put cmSourceFile instances in proper groups:
       for (auto const& si : gtgt->GetAllConfigSources()) {
@@ -2877,12 +2884,7 @@
           // Object library files go on the link line instead.
           continue;
         }
-        // Add the file to the list of sources.
-        std::string const& source = sf->GetFullPath();
-        cmSourceGroup* sourceGroup = mf->FindSourceGroup(source, sourceGroups);
-        cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(gtgt, sourceGroup);
-        std::string key = GetGroupMapKeyFromPath(gtgt, source);
-        this->GroupMap[key] = pbxgroup;
+        addSourceToGroup(sf->GetFullPath());
       }
 
       // Add CMakeLists.txt file for user convenience.
@@ -2891,11 +2893,14 @@
           gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
         listfile += "/CMakeLists.txt";
         cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(listfile);
-        std::string const& source = sf->GetFullPath();
-        cmSourceGroup* sourceGroup = mf->FindSourceGroup(source, sourceGroups);
-        cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(gtgt, sourceGroup);
-        std::string key = GetGroupMapKeyFromPath(gtgt, source);
-        this->GroupMap[key] = pbxgroup;
+        addSourceToGroup(sf->GetFullPath());
+      }
+
+      // Add the Info.plist we are about to generate for an App Bundle.
+      if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
+        std::string plist = this->ComputeInfoPListLocation(gtgt);
+        cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(plist, true);
+        addSourceToGroup(sf->GetFullPath());
       }
     }
   }
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 9736b41..dba4bbb 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -666,8 +666,7 @@
     // generators for them.
     bool createInstallGeneratorsForTargetFileSets = true;
 
-    if (target.IsFrameworkOnApple() ||
-        target.GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (target.IsFrameworkOnApple()) {
       createInstallGeneratorsForTargetFileSets = false;
     }
 
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index d201061..212608d 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -3023,6 +3023,12 @@
 {
   errno = 0;
   char* endp;
+  while (isspace(*str)) {
+    ++str;
+  }
+  if (*str == '-') {
+    return false;
+  }
   *value = strtoul(str, &endp, 10);
   return (*endp == '\0') && (endp != str) && (errno == 0);
 }
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index d2c3496..994fcf7 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -67,6 +67,8 @@
     builtIns.insert("IMPORTED_GLOBAL");
     builtIns.insert("MANUALLY_ADDED_DEPENDENCIES");
     builtIns.insert("NAME");
+    builtIns.insert("PRIVATE_HEADER");
+    builtIns.insert("PUBLIC_HEADER");
     builtIns.insert("TYPE");
   }
 
diff --git a/Tests/BundleTest/BundleSubDir/CMakeLists.txt b/Tests/BundleTest/BundleSubDir/CMakeLists.txt
index 43c366a..2f7f2c4 100644
--- a/Tests/BundleTest/BundleSubDir/CMakeLists.txt
+++ b/Tests/BundleTest/BundleSubDir/CMakeLists.txt
@@ -1,3 +1,5 @@
+project(BundleSubDir)
+
 add_custom_command(
   OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
   COMMAND /bin/cp
@@ -34,3 +36,8 @@
 # bundle does not respect the name.  Also the executable will not be found by
 # the test driver if this does not work.
 set_target_properties(SecondBundle PROPERTIES OUTPUT_NAME SecondBundleExe)
+
+# Express one app bundle in terms of another's SOURCES to verify that
+# the generators do not expose the Info.plist of one to the other.
+add_executable(SubdirBundle1 MACOSX_BUNDLE EXCLUDE_FROM_ALL ../BundleTest.cxx)
+add_executable(SubdirBundle2 MACOSX_BUNDLE EXCLUDE_FROM_ALL $<TARGET_PROPERTY:SubdirBundle1,SOURCES>)
diff --git a/Tests/CMakeLib/testSystemTools.cxx b/Tests/CMakeLib/testSystemTools.cxx
index 96a4819..121e639 100644
--- a/Tests/CMakeLib/testSystemTools.cxx
+++ b/Tests/CMakeLib/testSystemTools.cxx
@@ -93,5 +93,22 @@
   if (!failed) {
     cmPassed("cmSystemTools::strverscmp working");
   }
+
+  // ----------------------------------------------------------------------
+  // Test cmSystemTools::StringToULong
+  {
+    unsigned long value;
+    cmAssert(cmSystemTools::StringToULong("1", &value) && value == 1,
+             "StringToULong parses a decimal integer.");
+    cmAssert(cmSystemTools::StringToULong(" 1", &value) && value == 1,
+             "StringToULong parses a decimal integer after whitespace.");
+    cmAssert(!cmSystemTools::StringToULong("-1", &value),
+             "StringToULong rejects a negative number.");
+    cmAssert(!cmSystemTools::StringToULong(" -1", &value),
+             "StringToULong rejects a negative number after whitespace.");
+    cmAssert(!cmSystemTools::StringToULong("1x", &value),
+             "StringToULong rejects trailing content.");
+  }
+
   return failed;
 }
diff --git a/Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt b/Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt
index cff7022..81fd8db 100644
--- a/Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt
+++ b/Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt
@@ -69,6 +69,9 @@
 message("___ Configuring GAT project ___")
 execute_process(
     COMMAND "${CMAKE_COMMAND}" "${GAT_SDIR}"
+        -G "${CMAKE_GENERATOR}"
+        -A "${CMAKE_GENERATOR_PLATFORM}"
+        -T "${CMAKE_GENERATOR_TOOLSET}"
         "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
         "-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}"
         "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
diff --git a/Tests/RunCMake/CommandLine/ExplicitDirs/CMakeLists.txt b/Tests/RunCMake/CommandLine/ExplicitDirs/CMakeLists.txt
index 0ca5a0a..fc62914 100644
--- a/Tests/RunCMake/CommandLine/ExplicitDirs/CMakeLists.txt
+++ b/Tests/RunCMake/CommandLine/ExplicitDirs/CMakeLists.txt
@@ -1,4 +1,5 @@
-cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.14)
+project(ExplicitDirs NONE)
 add_custom_command(
   OUTPUT output.txt
   COMMAND ${CMAKE_COMMAND} -E echo CustomCommand > output.txt
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 3deabd0..ea749ea 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -82,23 +82,27 @@
   set(source_dir ${RunCMake_SOURCE_DIR}/ExplicitDirs)
   set(binary_dir ${RunCMake_BINARY_DIR}/ExplicitDirs-build)
 
+  set(RunCMake_TEST_SOURCE_DIR "${source_dir}")
+  set(RunCMake_TEST_BINARY_DIR "${binary_dir}")
+  set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake_TEST_NO_SOURCE_DIR 1)
+
   file(REMOVE_RECURSE "${binary_dir}")
-  file(MAKE_DIRECTORY "${binary_dir}")
-  run_cmake_command(S-arg ${CMAKE_COMMAND} -S ${source_dir} ${binary_dir})
-  run_cmake_command(S-arg-reverse-order ${CMAKE_COMMAND} ${binary_dir} -S${source_dir} )
-  run_cmake_command(S-no-arg ${CMAKE_COMMAND} -S )
-  run_cmake_command(S-no-arg2 ${CMAKE_COMMAND} -S -T)
-  run_cmake_command(S-B ${CMAKE_COMMAND} -S ${source_dir} -B ${binary_dir})
+  run_cmake_with_options(S-arg -S ${source_dir} ${binary_dir})
+  run_cmake_with_options(S-arg-reverse-order ${binary_dir} -S${source_dir} )
+  run_cmake_with_options(S-no-arg -S )
+  run_cmake_with_options(S-no-arg2 -S -T)
+  run_cmake_with_options(S-B -S ${source_dir} -B ${binary_dir})
 
   # make sure that -B can explicitly construct build directories
   file(REMOVE_RECURSE "${binary_dir}")
-  run_cmake_command(B-arg ${CMAKE_COMMAND} -B ${binary_dir} ${source_dir})
+  run_cmake_with_options(B-arg -B ${binary_dir} ${source_dir})
   file(REMOVE_RECURSE "${binary_dir}")
-  run_cmake_command(B-arg-reverse-order ${CMAKE_COMMAND} ${source_dir} -B${binary_dir})
-  run_cmake_command(B-no-arg ${CMAKE_COMMAND} -B )
-  run_cmake_command(B-no-arg2 ${CMAKE_COMMAND} -B -T)
+  run_cmake_with_options(B-arg-reverse-order ${source_dir} -B${binary_dir})
+  run_cmake_with_options(B-no-arg -B )
+  run_cmake_with_options(B-no-arg2 -B -T)
   file(REMOVE_RECURSE "${binary_dir}")
-  run_cmake_command(B-S ${CMAKE_COMMAND} -B${binary_dir} -S${source_dir})
+  run_cmake_with_options(B-S -B${binary_dir} -S${source_dir})
 
 endfunction()
 run_ExplicitDirs()
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index ce71677..ad3f8f6 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -98,8 +98,14 @@
     else()
       set(_D_CMAKE_GENERATOR_INSTANCE "")
     endif()
+    if(NOT RunCMake_TEST_NO_SOURCE_DIR)
+      set(maybe_source_dir "${RunCMake_TEST_SOURCE_DIR}")
+    else()
+      set(maybe_source_dir "")
+    endif()
     execute_process(
-      COMMAND ${CMAKE_COMMAND} "${RunCMake_TEST_SOURCE_DIR}"
+      COMMAND ${CMAKE_COMMAND}
+                ${maybe_source_dir}
                 -G "${RunCMake_GENERATOR}"
                 -A "${RunCMake_GENERATOR_PLATFORM}"
                 -T "${RunCMake_GENERATOR_TOOLSET}"
@@ -182,5 +188,10 @@
   run_cmake(${test})
 endfunction()
 
+function(run_cmake_with_options test)
+  set(RunCMake_TEST_OPTIONS "${ARGN}")
+  run_cmake(${test})
+endfunction()
+
 # Protect RunCMake tests from calling environment.
 unset(ENV{MAKEFLAGS})
diff --git a/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake b/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake
index c41cb2a..15335b2 100644
--- a/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake
+++ b/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake
@@ -4,6 +4,8 @@
     [[bin/exe\.exe]]
     [[bin/(lib)?lib1\.dll]]
     [[include]]
+    [[include/obj1\.h]]
+    [[include/obj2\.h]]
     [[include/obj4\.h]]
     [[include/obj5\.h]]
     [[lib]]
@@ -20,6 +22,8 @@
     [[bin/cyglib1\.dll]]
     [[bin/exe\.exe]]
     [[include]]
+    [[include/obj1\.h]]
+    [[include/obj2\.h]]
     [[include/obj4\.h]]
     [[include/obj5\.h]]
     [[lib]]
@@ -35,6 +39,8 @@
     [[bin]]
     [[bin/exe]]
     [[include]]
+    [[include/obj1\.h]]
+    [[include/obj2\.h]]
     [[include/obj4\.h]]
     [[include/obj5\.h]]
     [[lib]]
diff --git a/Tests/RunCMake/install/TARGETS-Defaults.cmake b/Tests/RunCMake/install/TARGETS-Defaults.cmake
index bfd8c2c..324aa11 100644
--- a/Tests/RunCMake/install/TARGETS-Defaults.cmake
+++ b/Tests/RunCMake/install/TARGETS-Defaults.cmake
@@ -8,6 +8,11 @@
 add_library(lib4 SHARED obj5.c)
 set_property(TARGET lib4 PROPERTY PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj5.h)
 
+add_library(iface INTERFACE)
+set_target_properties(iface PROPERTIES
+  PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj1.h
+  PRIVATE_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj2.h)
+
 install(TARGETS exe lib1 lib2)
 install(TARGETS lib3
   LIBRARY DESTINATION lib3
@@ -17,3 +22,6 @@
   LIBRARY DESTINATION lib4
   RUNTIME DESTINATION lib4
   )
+install(TARGETS iface
+  PUBLIC_HEADER DESTINATION include
+  PRIVATE_HEADER DESTINATION include)
diff --git a/Tests/RunCMake/install/obj2.h b/Tests/RunCMake/install/obj2.h
new file mode 100644
index 0000000..90bcd34
--- /dev/null
+++ b/Tests/RunCMake/install/obj2.h
@@ -0,0 +1,6 @@
+#ifndef OBJ2_H
+#define OBJ2_H
+
+int obj2(void);
+
+#endif /* OBJ2_H */
diff --git a/Tests/RunCMake/interface_library/whitelist.cmake b/Tests/RunCMake/interface_library/whitelist.cmake
index bf64f01..0db6375 100644
--- a/Tests/RunCMake/interface_library/whitelist.cmake
+++ b/Tests/RunCMake/interface_library/whitelist.cmake
@@ -14,3 +14,12 @@
 set_property(TARGET iface PROPERTY "custom_property" output)
 set_property(TARGET iface APPEND PROPERTY "custom_property" append)
 get_target_property(outname iface "custom_property")
+
+# PUBLIC_HEADER / PRIVATE_HEADER properties are allowed
+set_property(TARGET iface PROPERTY PUBLIC_HEADER foo.h)
+set_property(TARGET iface APPEND PROPERTY PUBLIC_HEADER bar.h)
+get_target_property(outname iface PUBLIC_HEADER)
+
+set_property(TARGET iface PROPERTY PRIVATE_HEADER foo.h)
+set_property(TARGET iface APPEND PROPERTY PRIVATE_HEADER bar.h)
+get_target_property(outname iface PRIVATE_HEADER)