diff options
47 files changed, 478 insertions, 0 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 65f9248..968a3b1 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/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 diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 8d20ae2..0b81677 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/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 diff --git a/Help/prop_tgt/VERIFY_HEADER_SETS.rst b/Help/prop_tgt/VERIFY_HEADER_SETS.rst new file mode 100644 index 0000000..cbfd51b --- /dev/null +++ b/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. diff --git a/Help/release/dev/verify-header-sets.rst b/Help/release/dev/verify-header-sets.rst new file mode 100644 index 0000000..7676382 --- /dev/null +++ b/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. diff --git a/Help/variable/CMAKE_VERIFY_HEADER_SETS.rst b/Help/variable/CMAKE_VERIFY_HEADER_SETS.rst new file mode 100644 index 0000000..8bd618a --- /dev/null +++ b/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. diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 1a13bdb..f1ab85c 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/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; +} diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 96e48a4..53844ae 100644 --- a/Source/cmGeneratorTarget.h +++ b/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); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index fb84cd1..3c31db1 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1501,6 +1501,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; @@ -1722,6 +1727,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) { diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index a4b2ae3..5965a16 100644 --- a/Source/cmGlobalGenerator.h +++ b/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, diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 4ca1b9b..e2314e2 100644 --- a/Source/cmTarget.cxx +++ b/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"); diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index e695844..dbff293 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -978,6 +978,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() diff --git a/Tests/RunCMake/VerifyHeaderSets/CMakeLists.txt b/Tests/RunCMake/VerifyHeaderSets/CMakeLists.txt new file mode 100644 index 0000000..5ff8d3e --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.23) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake b/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake new file mode 100644 index 0000000..06d48bf --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stderr.txt new file mode 100644 index 0000000..b78bc52 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stderr.txt @@ -0,0 +1 @@ +(TEST_A_H defined)? diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stdout.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stdout.txt new file mode 100644 index 0000000..b78bc52 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stdout.txt @@ -0,0 +1 @@ +(TEST_A_H defined)? diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-check.cmake b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-check.cmake new file mode 100644 index 0000000..44e028f --- /dev/null +++ b/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() diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stderr.txt new file mode 100644 index 0000000..eaa9a03 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stderr.txt @@ -0,0 +1 @@ +(Compiled in debug mode)? diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stdout.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stdout.txt new file mode 100644 index 0000000..eaa9a03 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stdout.txt @@ -0,0 +1 @@ +(Compiled in debug mode)? diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stderr.txt new file mode 100644 index 0000000..25699f9 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stderr.txt @@ -0,0 +1 @@ +(Compiled in release mode)? diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stdout.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stdout.txt new file mode 100644 index 0000000..25699f9 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stdout.txt @@ -0,0 +1 @@ +(Compiled in release mode)? diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stderr.txt new file mode 100644 index 0000000..27ef042 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stderr.txt @@ -0,0 +1 @@ +(TEST_DIR_C_H defined)? diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stdout.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stdout.txt new file mode 100644 index 0000000..27ef042 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stdout.txt @@ -0,0 +1 @@ +(TEST_DIR_C_H defined)? diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stderr.txt new file mode 100644 index 0000000..cd17d11 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stderr.txt @@ -0,0 +1 @@ +(TEST_DIR_CXX_H defined)? diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stdout.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stdout.txt new file mode 100644 index 0000000..cd17d11 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stdout.txt @@ -0,0 +1 @@ +(TEST_DIR_CXX_H defined)? diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-stderr.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-stderr.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-stderr.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-stderr.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-stderr.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-stderr.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake new file mode 100644 index 0000000..f515031 --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/VerifyHeaderSets/a.h b/Tests/RunCMake/VerifyHeaderSets/a.h new file mode 100644 index 0000000..8b17182 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/a.h @@ -0,0 +1,5 @@ +#ifdef TEST_A_H +# error "TEST_A_H defined" +#endif + +extern void a_h(void); diff --git a/Tests/RunCMake/VerifyHeaderSets/debug.h b/Tests/RunCMake/VerifyHeaderSets/debug.h new file mode 100644 index 0000000..4d4baa1 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/debug.h @@ -0,0 +1,3 @@ +#error "Compiled in debug mode" + +extern void debug_h(void); diff --git a/Tests/RunCMake/VerifyHeaderSets/dir/c.h b/Tests/RunCMake/VerifyHeaderSets/dir/c.h new file mode 100644 index 0000000..151cd81 --- /dev/null +++ b/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); diff --git a/Tests/RunCMake/VerifyHeaderSets/dir/cxx.h b/Tests/RunCMake/VerifyHeaderSets/dir/cxx.h new file mode 100644 index 0000000..255f61b --- /dev/null +++ b/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); diff --git a/Tests/RunCMake/VerifyHeaderSets/lang_test.h b/Tests/RunCMake/VerifyHeaderSets/lang_test.h new file mode 100644 index 0000000..633a2a4 --- /dev/null +++ b/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); diff --git a/Tests/RunCMake/VerifyHeaderSets/lib.c b/Tests/RunCMake/VerifyHeaderSets/lib.c new file mode 100644 index 0000000..6401eca --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/lib.c @@ -0,0 +1,6 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + void lib_c(void) +{ +} diff --git a/Tests/RunCMake/VerifyHeaderSets/lib.cxx b/Tests/RunCMake/VerifyHeaderSets/lib.cxx new file mode 100644 index 0000000..a0b3096 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/lib.cxx @@ -0,0 +1,6 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + void lib_cxx(void) +{ +} diff --git a/Tests/RunCMake/VerifyHeaderSets/main.c b/Tests/RunCMake/VerifyHeaderSets/main.c new file mode 100644 index 0000000..8a83e8c --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/main.c @@ -0,0 +1,11 @@ +int main(void) +{ + return 0; +} + +#ifdef _WIN32 +__declspec(dllexport) +#endif + void main_c(void) +{ +} diff --git a/Tests/RunCMake/VerifyHeaderSets/release.h b/Tests/RunCMake/VerifyHeaderSets/release.h new file mode 100644 index 0000000..7641988 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/release.h @@ -0,0 +1,3 @@ +#error "Compiled in release mode" + +extern void release_h(void); |