1
0
Эх сурвалжийг харах

FILE_SET: Add VERIFY_HEADER_SETS target property

Fixes: #23338
Kyle Edwards 3 жил өмнө
parent
commit
c798744f81
47 өөрчлөгдсөн 478 нэмэгдсэн , 0 устгасан
  1. 1 0
      Help/manual/cmake-properties.7.rst
  2. 1 0
      Help/manual/cmake-variables.7.rst
  3. 24 0
      Help/prop_tgt/VERIFY_HEADER_SETS.rst
  4. 7 0
      Help/release/dev/verify-header-sets.rst
  5. 17 0
      Help/variable/CMAKE_VERIFY_HEADER_SETS.rst
  6. 173 0
      Source/cmGeneratorTarget.cxx
  7. 5 0
      Source/cmGeneratorTarget.h
  8. 26 0
      Source/cmGlobalGenerator.cxx
  9. 2 0
      Source/cmGlobalGenerator.h
  10. 1 0
      Source/cmTarget.cxx
  11. 2 0
      Tests/RunCMake/CMakeLists.txt
  12. 3 0
      Tests/RunCMake/VerifyHeaderSets/CMakeLists.txt
  13. 42 0
      Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake
  14. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt
  15. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stderr.txt
  16. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stdout.txt
  17. 33 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-check.cmake
  18. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-result.txt
  19. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stderr.txt
  20. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stdout.txt
  21. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-result.txt
  22. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stderr.txt
  23. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stdout.txt
  24. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-result.txt
  25. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stderr.txt
  26. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stdout.txt
  27. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-result.txt
  28. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stderr.txt
  29. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stdout.txt
  30. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-result.txt
  31. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt
  32. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-result.txt
  33. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-stderr.txt
  34. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-result.txt
  35. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-stderr.txt
  36. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-result.txt
  37. 1 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-stderr.txt
  38. 60 0
      Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake
  39. 5 0
      Tests/RunCMake/VerifyHeaderSets/a.h
  40. 3 0
      Tests/RunCMake/VerifyHeaderSets/debug.h
  41. 8 0
      Tests/RunCMake/VerifyHeaderSets/dir/c.h
  42. 8 0
      Tests/RunCMake/VerifyHeaderSets/dir/cxx.h
  43. 8 0
      Tests/RunCMake/VerifyHeaderSets/lang_test.h
  44. 6 0
      Tests/RunCMake/VerifyHeaderSets/lib.c
  45. 6 0
      Tests/RunCMake/VerifyHeaderSets/lib.cxx
  46. 11 0
      Tests/RunCMake/VerifyHeaderSets/main.c
  47. 3 0
      Tests/RunCMake/VerifyHeaderSets/release.h

+ 1 - 0
Help/manual/cmake-properties.7.rst

@@ -380,6 +380,7 @@ Properties on Targets
    /prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE
    /prop_tgt/UNITY_BUILD_MODE
    /prop_tgt/UNITY_BUILD_UNIQUE_ID
+   /prop_tgt/VERIFY_HEADER_SETS
    /prop_tgt/VERSION
    /prop_tgt/VISIBILITY_INLINES_HIDDEN
    /prop_tgt/VS_CONFIGURATION_TYPE

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -503,6 +503,7 @@ Variables that Control the Build
    /variable/CMAKE_UNITY_BUILD_BATCH_SIZE
    /variable/CMAKE_UNITY_BUILD_UNIQUE_ID
    /variable/CMAKE_USE_RELATIVE_PATHS
+   /variable/CMAKE_VERIFY_HEADER_SETS
    /variable/CMAKE_VISIBILITY_INLINES_HIDDEN
    /variable/CMAKE_VS_GLOBALS
    /variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD

+ 24 - 0
Help/prop_tgt/VERIFY_HEADER_SETS.rst

@@ -0,0 +1,24 @@
+VERIFY_HEADER_SETS
+------------------
+
+.. versionadded:: 3.24
+
+Used to verify that all headers in a target's header sets can be included on
+their own.
+
+When this property is set to true, and the target is an object library, static
+library, shared library, or executable with exports enabled, and the target
+has one or more header sets, an object library target named
+``<target_name>_verify_header_sets`` is created. This verification target has
+one source file per header in the header sets. Each source file only includes
+its associated header file. The verification target links against the original
+target to get all of its usage requirements. The verification target has its
+:prop_tgt:`EXCLUDE_FROM_ALL` and :prop_tgt:`DISABLE_PRECOMPILE_HEADERS`
+properties set to true, and its :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTORCC`,
+:prop_tgt:`AUTOUIC`, and :prop_tgt:`UNITY_BUILD` properties set to false.
+
+If the header's :prop_sf:`LANGUAGE` property is set, the value of that property
+is used to determine the language with which to compile the header file.
+Otherwise, if the target has any C++ sources, the header is compiled as C++.
+Otherwise, if the target has any C sources, the header is compiled as C.
+Otherwise, the header file is not compiled.

+ 7 - 0
Help/release/dev/verify-header-sets.rst

@@ -0,0 +1,7 @@
+verify-header-sets
+------------------
+
+* A new :prop_tgt:`VERIFY_HEADER_SETS` target property was added, which can be
+  used to verify that all headers in header sets can be used on their own.
+* A new :variable:`CMAKE_VERIFY_HEADER_SETS` variable was added, which is used
+  to initialize the :prop_tgt:`VERIFY_HEADER_SETS` target property.

+ 17 - 0
Help/variable/CMAKE_VERIFY_HEADER_SETS.rst

@@ -0,0 +1,17 @@
+CMAKE_VERIFY_HEADER_SETS
+------------------------
+
+.. versionadded:: 3.24
+
+This variable is used to initialize the :prop_tgt:`VERIFY_HEADER_SETS`
+property of targets when they are created.  Setting it to true
+enables header set verification.
+
+Projects should not set this variable, it is intended as a developer
+control to be set on the :manual:`cmake(1)` command line or other
+equivalent methods.  The developer must have the ability to enable or
+disable header set verification according to the capabilities of their own
+machine and compiler.
+
+By default, this variable is not set, which will result in header set
+verification being disabled.

+ 173 - 0
Source/cmGeneratorTarget.cxx

@@ -8522,3 +8522,176 @@ cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType(
   // has to be set manually for C# targets.
   return this->IsCSharpOnly() ? ManagedType::Managed : ManagedType::Native;
 }
+
+bool cmGeneratorTarget::AddHeaderSetVerification()
+{
+  if (!this->GetPropertyAsBool("VERIFY_HEADER_SETS")) {
+    return true;
+  }
+
+  if (this->GetType() != cmStateEnums::STATIC_LIBRARY &&
+      this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+      this->GetType() != cmStateEnums::UNKNOWN_LIBRARY &&
+      this->GetType() != cmStateEnums::OBJECT_LIBRARY &&
+      this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
+      !this->IsExecutableWithExports()) {
+    return true;
+  }
+
+  cmTarget* verifyTarget = nullptr;
+
+  auto interfaceFileSetEntries = this->Target->GetInterfaceHeaderSetsEntries();
+
+  std::set<cmFileSet*> fileSets;
+  auto const addFileSets = [&fileSets, this](const cmBTStringRange& entries) {
+    for (auto const& entry : entries) {
+      for (auto const& name : cmExpandedList(entry.Value)) {
+        fileSets.insert(this->Target->GetFileSet(name));
+      }
+    }
+  };
+  addFileSets(interfaceFileSetEntries);
+
+  cm::optional<std::set<std::string>> languages;
+  for (auto* fileSet : fileSets) {
+    auto dirCges = fileSet->CompileDirectoryEntries();
+    auto fileCges = fileSet->CompileFileEntries();
+
+    static auto const contextSensitive =
+      [](const std::unique_ptr<cmCompiledGeneratorExpression>& cge) {
+        return cge->GetHadContextSensitiveCondition();
+      };
+    bool dirCgesContextSensitive = false;
+    bool fileCgesContextSensitive = false;
+
+    std::vector<std::string> dirs;
+    std::map<std::string, std::vector<std::string>> filesPerDir;
+    bool first = true;
+    for (auto const& config : this->Makefile->GetGeneratorConfigs(
+           cmMakefile::GeneratorConfigQuery::IncludeEmptyConfig)) {
+      if (first || dirCgesContextSensitive) {
+        dirs = fileSet->EvaluateDirectoryEntries(dirCges, this->LocalGenerator,
+                                                 config, this);
+        dirCgesContextSensitive =
+          std::any_of(dirCges.begin(), dirCges.end(), contextSensitive);
+      }
+      if (first || fileCgesContextSensitive) {
+        filesPerDir.clear();
+        for (auto const& fileCge : fileCges) {
+          fileSet->EvaluateFileEntry(dirs, filesPerDir, fileCge,
+                                     this->LocalGenerator, config, this);
+          if (fileCge->GetHadContextSensitiveCondition()) {
+            fileCgesContextSensitive = true;
+          }
+        }
+      }
+
+      for (auto const& files : filesPerDir) {
+        for (auto const& file : files.second) {
+          std::string filename = this->GenerateHeaderSetVerificationFile(
+            *this->Makefile->GetOrCreateSource(file), files.first, languages);
+          if (filename.empty()) {
+            continue;
+          }
+
+          if (!verifyTarget) {
+            {
+              cmMakefile::PolicyPushPop polScope(this->Makefile);
+              this->Makefile->SetPolicy(cmPolicies::CMP0119, cmPolicies::NEW);
+              verifyTarget = this->Makefile->AddLibrary(
+                cmStrCat(this->GetName(), "_verify_header_sets"),
+                cmStateEnums::OBJECT_LIBRARY, {}, true);
+            }
+
+            verifyTarget->AddLinkLibrary(
+              *this->Makefile, this->GetName(),
+              cmTargetLinkLibraryType::GENERAL_LibraryType);
+            verifyTarget->SetProperty("AUTOMOC", "OFF");
+            verifyTarget->SetProperty("AUTORCC", "OFF");
+            verifyTarget->SetProperty("AUTOUIC", "OFF");
+            verifyTarget->SetProperty("DISABLE_PRECOMPILE_HEADERS", "ON");
+            verifyTarget->SetProperty("UNITY_BUILD", "OFF");
+          }
+
+          if (fileCgesContextSensitive) {
+            filename = cmStrCat("$<$<CONFIG:", config, ">:", filename, ">");
+          }
+          verifyTarget->AddSource(filename);
+        }
+      }
+
+      if (!dirCgesContextSensitive && !fileCgesContextSensitive) {
+        break;
+      }
+      first = false;
+    }
+  }
+
+  if (verifyTarget) {
+    this->LocalGenerator->AddGeneratorTarget(
+      cm::make_unique<cmGeneratorTarget>(verifyTarget, this->LocalGenerator));
+  }
+
+  return true;
+}
+
+std::string cmGeneratorTarget::GenerateHeaderSetVerificationFile(
+  cmSourceFile& source, const std::string& dir,
+  cm::optional<std::set<std::string>>& languages) const
+{
+  std::string extension;
+  std::string language = source.GetOrDetermineLanguage();
+
+  if (language.empty()) {
+    if (!languages) {
+      languages.emplace();
+      for (auto const& tgtSource : this->GetAllConfigSources()) {
+        auto const& tgtSourceLanguage =
+          tgtSource.Source->GetOrDetermineLanguage();
+        if (tgtSourceLanguage == "CXX") {
+          languages->insert("CXX");
+          break; // C++ overrides everything else, so we don't need to keep
+                 // checking.
+        }
+        if (tgtSourceLanguage == "C") {
+          languages->insert("C");
+        }
+      }
+    }
+
+    if (languages->count("CXX")) {
+      language = "CXX";
+    } else if (languages->count("C")) {
+      language = "C";
+    }
+  }
+
+  if (language == "C") {
+    extension = ".c";
+  } else if (language == "CXX") {
+    extension = ".cxx";
+  } else {
+    return "";
+  }
+
+  std::string headerFilename = dir;
+  if (!headerFilename.empty()) {
+    headerFilename += '/';
+  }
+  headerFilename += source.GetLocation().GetName();
+
+  auto filename = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
+                           '/', this->GetName(), "_verify_header_sets/",
+                           headerFilename, extension);
+  auto* verificationSource = this->Makefile->GetOrCreateSource(filename);
+  verificationSource->SetProperty("LANGUAGE", language);
+
+  cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(filename));
+
+  cmGeneratedFileStream fout(filename);
+  fout.SetCopyIfDifferent(true);
+  fout << "#include <" << headerFilename << ">\n";
+  fout.close();
+
+  return filename;
+}

+ 5 - 0
Source/cmGeneratorTarget.h

@@ -868,6 +868,11 @@ public:
   std::vector<std::string> GetGeneratedISPCObjects(
     std::string const& config) const;
 
+  bool AddHeaderSetVerification();
+  std::string GenerateHeaderSetVerificationFile(
+    cmSourceFile& source, const std::string& dir,
+    cm::optional<std::set<std::string>>& languages) const;
+
 private:
   void AddSourceCommon(const std::string& src, bool before = false);
 

+ 26 - 0
Source/cmGlobalGenerator.cxx

@@ -1499,6 +1499,11 @@ bool cmGlobalGenerator::Compute()
     return false;
   }
 
+  // Iterate through all targets and add verification targets for header sets
+  if (!this->AddHeaderSetVerification()) {
+    return false;
+  }
+
   // Iterate through all targets and set up AUTOMOC, AUTOUIC and AUTORCC
   if (!this->QtAutoGen()) {
     return false;
@@ -1720,6 +1725,27 @@ bool cmGlobalGenerator::QtAutoGen()
 #endif
 }
 
+bool cmGlobalGenerator::AddHeaderSetVerification()
+{
+  for (auto const& gen : this->LocalGenerators) {
+    // Because AddHeaderSetVerification() adds generator targets, we need to
+    // cache the existing list of generator targets before starting.
+    std::vector<cmGeneratorTarget*> genTargets;
+    genTargets.reserve(gen->GetGeneratorTargets().size());
+    for (auto const& tgt : gen->GetGeneratorTargets()) {
+      genTargets.push_back(tgt.get());
+    }
+
+    for (auto* tgt : genTargets) {
+      if (!tgt->AddHeaderSetVerification()) {
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
 bool cmGlobalGenerator::AddAutomaticSources()
 {
   for (const auto& lg : this->LocalGenerators) {

+ 2 - 0
Source/cmGlobalGenerator.h

@@ -573,6 +573,8 @@ protected:
   /// @return true on success
   bool QtAutoGen();
 
+  bool AddHeaderSetVerification();
+
   bool AddAutomaticSources();
 
   std::string SelectMakeProgram(const std::string& makeProgram,

+ 1 - 0
Source/cmTarget.cxx

@@ -425,6 +425,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
   }
 
   initProp("FOLDER");
+  initProp("VERIFY_HEADER_SETS");
 
   if (this->GetGlobalGenerator()->IsXcode()) {
     initProp("XCODE_GENERATE_SCHEME");

+ 2 - 0
Tests/RunCMake/CMakeLists.txt

@@ -970,6 +970,8 @@ add_RunCMake_test(CMakePresetsTest
   -DCMake_TEST_JSON_SCHEMA=${CMake_TEST_JSON_SCHEMA}
   )
 
+add_RunCMake_test(VerifyHeaderSets)
+
 if(${CMAKE_GENERATOR} MATCHES "Make|Ninja")
   add_RunCMake_test(TransformDepfile)
 endif()

+ 3 - 0
Tests/RunCMake/VerifyHeaderSets/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.23)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 42 - 0
Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake

@@ -0,0 +1,42 @@
+include(RunCMake)
+
+function(run_cmake_build name target)
+  if(NOT BUILD_CONFIG)
+    set(BUILD_CONFIG Debug)
+  endif()
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(${name}-${target}-${BUILD_CONFIG}-build ${CMAKE_COMMAND} --build . --config ${BUILD_CONFIG} --target ${target})
+endfunction()
+
+set(RunCMake_TEST_OPTIONS -DCMAKE_VERIFY_HEADER_SETS=ON)
+if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+endif()
+run_cmake(VerifyHeaderSets)
+unset(RunCMake_TEST_OPTIONS)
+
+run_cmake_build(VerifyHeaderSets static_verify_header_sets)
+run_cmake_build(VerifyHeaderSets shared_verify_header_sets)
+run_cmake_build(VerifyHeaderSets object_verify_header_sets)
+run_cmake_build(VerifyHeaderSets interface_verify_header_sets)
+run_cmake_build(VerifyHeaderSets exe_verify_header_sets)
+run_cmake_build(VerifyHeaderSets export_exe_verify_header_sets)
+run_cmake_build(VerifyHeaderSets none_verify_header_sets)
+run_cmake_build(VerifyHeaderSets property_off_verify_header_sets)
+run_cmake_build(VerifyHeaderSets private_verify_header_sets)
+run_cmake_build(VerifyHeaderSets a_h_verify_header_sets)
+run_cmake_build(VerifyHeaderSets dir_c_h_verify_header_sets)
+run_cmake_build(VerifyHeaderSets dir_cxx_h_verify_header_sets)
+
+if(NOT RunCMake_GENERATOR STREQUAL "Xcode")
+  run_cmake_build(VerifyHeaderSets config_verify_header_sets)
+  if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(BUILD_CONFIG Release)
+    run_cmake_build(VerifyHeaderSets config_verify_header_sets)
+    unset(BUILD_CONFIG)
+  endif()
+endif()
+
+run_cmake_build(VerifyHeaderSets lang_test_c_verify_header_sets)
+run_cmake_build(VerifyHeaderSets lang_test_cxx_verify_header_sets)

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stderr.txt

@@ -0,0 +1 @@
+(TEST_A_H defined)?

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stdout.txt

@@ -0,0 +1 @@
+(TEST_A_H defined)?

+ 33 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-check.cmake

@@ -0,0 +1,33 @@
+function(check_file target filename)
+  set(full_filename "${RunCMake_TEST_BINARY_DIR}/${target}_verify_header_sets/${filename}")
+  if(NOT EXISTS "${full_filename}")
+    string(APPEND RunCMake_TEST_FAILED "File ${full_filename} should exist but does not\n")
+    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+    return()
+  endif()
+
+  if(filename MATCHES "^(.*)(\\.[a-z]+)$")
+    set(header_filename "${CMAKE_MATCH_1}")
+  endif()
+  set(expected_contents "#include <${header_filename}>\n")
+  file(READ "${full_filename}" actual_contents)
+
+  if(NOT actual_contents STREQUAL expected_contents)
+    string(REPLACE "\n" "\n  " expected_contents_formatted "${expected_contents}")
+    string(REPLACE "\n" "\n  " actual_contents_formatted "${actual_contents}")
+    string(APPEND RunCMake_TEST_FAILED "Expected contents of ${full_filename}:\n  ${expected_contents_formatted}\nActual contents:\n  ${actual_contents_formatted}\n")
+    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+    return()
+  endif()
+endfunction()
+
+check_file(static a.h.c)
+check_file(static dir/c.h.c)
+check_file(static dir/cxx.h.cxx)
+
+if(NOT RunCMake_GENERATOR STREQUAL "Xcode")
+  check_file(config debug.h.c)
+  if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    check_file(config release.h.c)
+  endif()
+endif()

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stderr.txt

@@ -0,0 +1 @@
+(Compiled in debug mode)?

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stdout.txt

@@ -0,0 +1 @@
+(Compiled in debug mode)?

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stderr.txt

@@ -0,0 +1 @@
+(Compiled in release mode)?

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stdout.txt

@@ -0,0 +1 @@
+(Compiled in release mode)?

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stderr.txt

@@ -0,0 +1 @@
+(TEST_DIR_C_H defined)?

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stdout.txt

@@ -0,0 +1 @@
+(TEST_DIR_C_H defined)?

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stderr.txt

@@ -0,0 +1 @@
+(TEST_DIR_CXX_H defined)?

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stdout.txt

@@ -0,0 +1 @@
+(TEST_DIR_CXX_H defined)?

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt

@@ -0,0 +1 @@
+.*

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-stderr.txt

@@ -0,0 +1 @@
+.*

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-stderr.txt

@@ -0,0 +1 @@
+.*

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-stderr.txt

@@ -0,0 +1 @@
+.*

+ 60 - 0
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake

@@ -0,0 +1,60 @@
+enable_language(C CXX)
+
+set_property(SOURCE a.h PROPERTY LANGUAGE C)
+set_property(SOURCE dir/c.h PROPERTY LANGUAGE C)
+set_property(SOURCE dir/cxx.h PROPERTY LANGUAGE CXX)
+
+add_library(static STATIC lib.c)
+target_sources(static INTERFACE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
+
+add_library(shared SHARED lib.c)
+target_sources(shared INTERFACE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
+
+add_library(object OBJECT lib.c)
+target_sources(object INTERFACE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
+
+add_library(interface INTERFACE)
+target_sources(interface INTERFACE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
+
+add_executable(exe main.c)
+target_sources(exe INTERFACE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
+
+add_executable(export_exe main.c)
+set_property(TARGET export_exe PROPERTY ENABLE_EXPORTS TRUE)
+target_sources(export_exe INTERFACE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
+
+add_library(none STATIC lib.c)
+
+add_library(property_off STATIC lib.c)
+target_sources(property_off INTERFACE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
+set_property(TARGET property_off PROPERTY VERIFY_HEADER_SETS OFF)
+
+add_library(private STATIC lib.c)
+target_sources(private PRIVATE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
+
+add_library(a_h STATIC lib.c)
+target_compile_definitions(a_h INTERFACE TEST_A_H)
+target_sources(a_h INTERFACE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
+
+add_library(dir_c_h STATIC lib.c)
+target_compile_definitions(dir_c_h INTERFACE TEST_DIR_C_H)
+target_sources(dir_c_h INTERFACE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
+
+add_library(dir_cxx_h STATIC lib.c)
+target_compile_definitions(dir_cxx_h INTERFACE TEST_DIR_CXX_H)
+target_sources(dir_cxx_h INTERFACE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
+
+set_property(SOURCE debug.h PROPERTY LANGUAGE C)
+set_property(SOURCE release.h PROPERTY LANGUAGE C)
+
+if(NOT CMAKE_GENERATOR STREQUAL "Xcode")
+  add_library(config STATIC lib.c)
+  target_sources(config INTERFACE FILE_SET HEADERS FILES $<IF:$<CONFIG:Debug>,debug.h,release.h>)
+endif()
+
+add_library(lang_test_c STATIC lib.c)
+target_sources(lang_test_c INTERFACE FILE_SET HEADERS FILES lang_test.h)
+
+add_library(lang_test_cxx STATIC lib.c lib.cxx)
+target_compile_definitions(lang_test_cxx INTERFACE EXPECT_CXX)
+target_sources(lang_test_cxx INTERFACE FILE_SET HEADERS FILES lang_test.h)

+ 5 - 0
Tests/RunCMake/VerifyHeaderSets/a.h

@@ -0,0 +1,5 @@
+#ifdef TEST_A_H
+#  error "TEST_A_H defined"
+#endif
+
+extern void a_h(void);

+ 3 - 0
Tests/RunCMake/VerifyHeaderSets/debug.h

@@ -0,0 +1,3 @@
+#error "Compiled in debug mode"
+
+extern void debug_h(void);

+ 8 - 0
Tests/RunCMake/VerifyHeaderSets/dir/c.h

@@ -0,0 +1,8 @@
+#ifdef TEST_DIR_C_H
+#  error "TEST_DIR_C_H defined"
+#endif
+#ifdef __cplusplus
+#  error "__cplusplus defined"
+#endif
+
+extern void dir_c_h(void);

+ 8 - 0
Tests/RunCMake/VerifyHeaderSets/dir/cxx.h

@@ -0,0 +1,8 @@
+#ifdef TEST_DIR_CXX_H
+#  error "TEST_DIR_CXX_H defined"
+#endif
+#ifndef __cplusplus
+#  error "__cplusplus not defined"
+#endif
+
+extern void dir_cxx_h(void);

+ 8 - 0
Tests/RunCMake/VerifyHeaderSets/lang_test.h

@@ -0,0 +1,8 @@
+#if defined(__cplusplus) && !defined(EXPECT_CXX)
+#  error "__cplusplus defined but EXPECT_CXX not defined"
+#endif
+#if !defined(__cplusplus) && defined(EXPECT_CXX)
+#  error "__cplusplus not defined but EXPECT_CXX defined"
+#endif
+
+extern void lang_test_h(void);

+ 6 - 0
Tests/RunCMake/VerifyHeaderSets/lib.c

@@ -0,0 +1,6 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+  void lib_c(void)
+{
+}

+ 6 - 0
Tests/RunCMake/VerifyHeaderSets/lib.cxx

@@ -0,0 +1,6 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+  void lib_cxx(void)
+{
+}

+ 11 - 0
Tests/RunCMake/VerifyHeaderSets/main.c

@@ -0,0 +1,11 @@
+int main(void)
+{
+  return 0;
+}
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+  void main_c(void)
+{
+}

+ 3 - 0
Tests/RunCMake/VerifyHeaderSets/release.h

@@ -0,0 +1,3 @@
+#error "Compiled in release mode"
+
+extern void release_h(void);