parent
fdbef2a2be
commit
c798744f81
@ -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
|
||||
|
@ -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
Help/prop_tgt/VERIFY_HEADER_SETS.rst
Normal file
24
Help/prop_tgt/VERIFY_HEADER_SETS.rst
Normal file
@ -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
Help/release/dev/verify-header-sets.rst
Normal file
7
Help/release/dev/verify-header-sets.rst
Normal file
@ -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
Help/variable/CMAKE_VERIFY_HEADER_SETS.rst
Normal file
17
Help/variable/CMAKE_VERIFY_HEADER_SETS.rst
Normal file
@ -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.
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -573,6 +573,8 @@ protected:
|
||||
/// @return true on success
|
||||
bool QtAutoGen();
|
||||
|
||||
bool AddHeaderSetVerification();
|
||||
|
||||
bool AddAutomaticSources();
|
||||
|
||||
std::string SelectMakeProgram(const std::string& makeProgram,
|
||||
|
@ -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");
|
||||
|
@ -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
Tests/RunCMake/VerifyHeaderSets/CMakeLists.txt
Normal file
3
Tests/RunCMake/VerifyHeaderSets/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
42
Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake
Normal file
42
Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake
Normal file
@ -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)
|
@ -0,0 +1 @@
|
||||
[^0]
|
@ -0,0 +1 @@
|
||||
(TEST_A_H defined)?
|
@ -0,0 +1 @@
|
||||
(TEST_A_H defined)?
|
33
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-check.cmake
Normal file
33
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-check.cmake
Normal file
@ -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()
|
@ -0,0 +1 @@
|
||||
[^0]
|
@ -0,0 +1 @@
|
||||
(Compiled in debug mode)?
|
@ -0,0 +1 @@
|
||||
(Compiled in debug mode)?
|
@ -0,0 +1 @@
|
||||
[^0]
|
@ -0,0 +1 @@
|
||||
(Compiled in release mode)?
|
@ -0,0 +1 @@
|
||||
(Compiled in release mode)?
|
@ -0,0 +1 @@
|
||||
[^0]
|
@ -0,0 +1 @@
|
||||
(TEST_DIR_C_H defined)?
|
@ -0,0 +1 @@
|
||||
(TEST_DIR_C_H defined)?
|
@ -0,0 +1 @@
|
||||
[^0]
|
@ -0,0 +1 @@
|
||||
(TEST_DIR_CXX_H defined)?
|
@ -0,0 +1 @@
|
||||
(TEST_DIR_CXX_H defined)?
|
@ -0,0 +1 @@
|
||||
[^0]
|
@ -0,0 +1 @@
|
||||
.*
|
@ -0,0 +1 @@
|
||||
[^0]
|
@ -0,0 +1 @@
|
||||
.*
|
@ -0,0 +1 @@
|
||||
[^0]
|
@ -0,0 +1 @@
|
||||
.*
|
@ -0,0 +1 @@
|
||||
[^0]
|
@ -0,0 +1 @@
|
||||
.*
|
60
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake
Normal file
60
Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake
Normal file
@ -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
Tests/RunCMake/VerifyHeaderSets/a.h
Normal file
5
Tests/RunCMake/VerifyHeaderSets/a.h
Normal file
@ -0,0 +1,5 @@
|
||||
#ifdef TEST_A_H
|
||||
# error "TEST_A_H defined"
|
||||
#endif
|
||||
|
||||
extern void a_h(void);
|
3
Tests/RunCMake/VerifyHeaderSets/debug.h
Normal file
3
Tests/RunCMake/VerifyHeaderSets/debug.h
Normal file
@ -0,0 +1,3 @@
|
||||
#error "Compiled in debug mode"
|
||||
|
||||
extern void debug_h(void);
|
8
Tests/RunCMake/VerifyHeaderSets/dir/c.h
Normal file
8
Tests/RunCMake/VerifyHeaderSets/dir/c.h
Normal file
@ -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
Tests/RunCMake/VerifyHeaderSets/dir/cxx.h
Normal file
8
Tests/RunCMake/VerifyHeaderSets/dir/cxx.h
Normal file
@ -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
Tests/RunCMake/VerifyHeaderSets/lang_test.h
Normal file
8
Tests/RunCMake/VerifyHeaderSets/lang_test.h
Normal file
@ -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
Tests/RunCMake/VerifyHeaderSets/lib.c
Normal file
6
Tests/RunCMake/VerifyHeaderSets/lib.c
Normal file
@ -0,0 +1,6 @@
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void lib_c(void)
|
||||
{
|
||||
}
|
6
Tests/RunCMake/VerifyHeaderSets/lib.cxx
Normal file
6
Tests/RunCMake/VerifyHeaderSets/lib.cxx
Normal file
@ -0,0 +1,6 @@
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void lib_cxx(void)
|
||||
{
|
||||
}
|
11
Tests/RunCMake/VerifyHeaderSets/main.c
Normal file
11
Tests/RunCMake/VerifyHeaderSets/main.c
Normal file
@ -0,0 +1,11 @@
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void main_c(void)
|
||||
{
|
||||
}
|
3
Tests/RunCMake/VerifyHeaderSets/release.h
Normal file
3
Tests/RunCMake/VerifyHeaderSets/release.h
Normal file
@ -0,0 +1,3 @@
|
||||
#error "Compiled in release mode"
|
||||
|
||||
extern void release_h(void);
|
Loading…
Reference in New Issue
Block a user