mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
CPS: Add Symbolic Components
Adds support for "symbolic" components, which represent feature-level capabilities of a package that do not correspond to actual build targets. These are modeled as pseudo-targets, using the INTERFACE type as a base, and can be queried via: get_target_property(... <tgt> "SYMBOLIC") This enables consumers to declare requirements on optional features (e.g., SSL support) even when they do not map to concrete targets. Fixes: #27187
This commit is contained in:
@@ -196,6 +196,30 @@ Interface Libraries
|
||||
call are ``PRIVATE`` to the interface library and do not appear in its
|
||||
:prop_tgt:`INTERFACE_SOURCES` target property.
|
||||
|
||||
.. signature::
|
||||
add_library(<name> INTERFACE SYMBOLIC)
|
||||
:target: INTERFACE-SYMBOLIC
|
||||
|
||||
.. versionadded:: 4.2
|
||||
|
||||
Add a symbolic :ref:`Interface Library <Interface Libraries>` target.
|
||||
Symbolic interface libraries are useful for representing optional components
|
||||
or features in a package. They have no usage requirements, do not compile
|
||||
sources, and do not produce a library artifact on disk, but they may be
|
||||
exported and installed. They can also be tested for existence with the
|
||||
regular :command:`if(TARGET)` subcommand.
|
||||
|
||||
A symbolic interface library may be used as a linkable target to enforce the
|
||||
presence of optional components in a dependency. For example, if a library
|
||||
``libgui`` may or may not provide a feature ``widget``, a consumer package
|
||||
can link against ``widget`` to express that it requires this component to be
|
||||
available. This allows :command:`find_package` calls that declare required
|
||||
components to be validated by linking against the corresponding symbolic
|
||||
targets.
|
||||
|
||||
A symbolic interface library has the :prop_tgt:`SYMBOLIC` target property
|
||||
set to true.
|
||||
|
||||
.. _`add_library imported libraries`:
|
||||
|
||||
Imported Libraries
|
||||
|
@@ -417,6 +417,7 @@ Properties on Targets
|
||||
/prop_tgt/Swift_LANGUAGE_VERSION
|
||||
/prop_tgt/Swift_MODULE_DIRECTORY
|
||||
/prop_tgt/Swift_MODULE_NAME
|
||||
/prop_tgt/SYMBOLIC
|
||||
/prop_tgt/SYSTEM
|
||||
/prop_tgt/TEST_LAUNCHER
|
||||
/prop_tgt/TRANSITIVE_COMPILE_PROPERTIES
|
||||
|
11
Help/prop_tgt/SYMBOLIC.rst
Normal file
11
Help/prop_tgt/SYMBOLIC.rst
Normal file
@@ -0,0 +1,11 @@
|
||||
SYMBOLIC
|
||||
--------
|
||||
|
||||
.. versionadded:: 4.2
|
||||
|
||||
Read-only indication of whether a target is ``SYMBOLIC``.
|
||||
|
||||
Symbolic targets are created by calls to
|
||||
:command:`add_library(INTERFACE SYMBOLIC) <add_library(INTERFACE-SYMBOLIC)>`.
|
||||
They are useful for packages to represent additional **components** or
|
||||
**feature selectors** that consumers can request via ``find_package()``.
|
@@ -33,6 +33,7 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
|
||||
bool excludeFromAll = false;
|
||||
bool importTarget = false;
|
||||
bool importGlobal = false;
|
||||
bool symbolicTarget = false;
|
||||
|
||||
auto s = args.begin();
|
||||
|
||||
@@ -117,6 +118,9 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
|
||||
} else if (*s == "EXCLUDE_FROM_ALL") {
|
||||
++s;
|
||||
excludeFromAll = true;
|
||||
} else if (*s == "SYMBOLIC") {
|
||||
++s;
|
||||
symbolicTarget = true;
|
||||
} else if (*s == "IMPORTED") {
|
||||
++s;
|
||||
importTarget = true;
|
||||
@@ -223,9 +227,9 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
|
||||
}
|
||||
|
||||
/* ideally we should check whether for the linker language of the target
|
||||
CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to
|
||||
STATIC. But at this point we know only the name of the target, but not
|
||||
yet its linker language. */
|
||||
CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to
|
||||
STATIC. But at this point we know only the name of the target, but not
|
||||
yet its linker language. */
|
||||
if ((type == cmStateEnums::SHARED_LIBRARY ||
|
||||
type == cmStateEnums::MODULE_LIBRARY) &&
|
||||
!mf.GetState()->GetGlobalPropertyAsBool("TARGET_SUPPORTS_SHARED_LIBS")) {
|
||||
@@ -282,7 +286,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
|
||||
}
|
||||
|
||||
// Create the imported target.
|
||||
mf.AddImportedTarget(libName, type, importGlobal);
|
||||
cmTarget* target = mf.AddImportedTarget(libName, type, importGlobal);
|
||||
target->SetSymbolic(symbolicTarget);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -312,8 +317,15 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
|
||||
}
|
||||
}
|
||||
|
||||
if (symbolicTarget && type != cmStateEnums::INTERFACE_LIBRARY) {
|
||||
status.SetError(
|
||||
"SYMBOLIC option may only be used with INTERFACE libraries");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> srcs(s, args.end());
|
||||
mf.AddLibrary(libName, type, srcs, excludeFromAll);
|
||||
cmTarget* target = mf.AddLibrary(libName, type, srcs, excludeFromAll);
|
||||
target->SetSymbolic(symbolicTarget);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -292,7 +292,20 @@ void cmExportCMakeConfigGenerator::GenerateImportTargetCode(
|
||||
os << "add_library(" << targetName << " OBJECT IMPORTED)\n";
|
||||
break;
|
||||
case cmStateEnums::INTERFACE_LIBRARY:
|
||||
os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
|
||||
if (target->IsSymbolic()) {
|
||||
os << "if(CMAKE_VERSION VERSION_GREATER_EQUAL \""
|
||||
<< CMake_VERSION_DEVEL(4, 2)
|
||||
<< "\")\n"
|
||||
" add_library("
|
||||
<< targetName << " INTERFACE SYMBOLIC IMPORTED)\n"
|
||||
<< "elseif(CMAKE_VERSION VERSION_GREATER_EQUAL 3.2.0)\n"
|
||||
<< " add_library(" << targetName << " INTERFACE IMPORTED)\n"
|
||||
<< " set_target_properties(" << targetName
|
||||
<< " PROPERTIES SYMBOLIC TRUE)\n"
|
||||
<< "endif()\n";
|
||||
} else {
|
||||
os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
|
||||
}
|
||||
break;
|
||||
default: // should never happen
|
||||
break;
|
||||
|
@@ -182,6 +182,7 @@ Json::Value* cmExportPackageInfoGenerator::GenerateImportTarget(
|
||||
|
||||
Json::Value& component = components[name];
|
||||
Json::Value& type = component["type"];
|
||||
|
||||
switch (targetType) {
|
||||
case cmStateEnums::EXECUTABLE:
|
||||
type = "executable";
|
||||
@@ -196,7 +197,7 @@ Json::Value* cmExportPackageInfoGenerator::GenerateImportTarget(
|
||||
type = "module";
|
||||
break;
|
||||
case cmStateEnums::INTERFACE_LIBRARY:
|
||||
type = "interface";
|
||||
type = target->IsSymbolic() ? "symbolic" : "interface";
|
||||
break;
|
||||
default:
|
||||
type = "unknown";
|
||||
|
@@ -1153,6 +1153,11 @@ bool cmGeneratorTarget::IsImportedGloballyVisible() const
|
||||
return this->Target->IsImportedGloballyVisible();
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::IsSymbolic() const
|
||||
{
|
||||
return this->Target->IsSymbolic();
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::IsForeign() const
|
||||
{
|
||||
return this->Target->IsForeign();
|
||||
|
@@ -70,6 +70,7 @@ public:
|
||||
bool IsImported() const;
|
||||
bool IsImportedGloballyVisible() const;
|
||||
bool IsForeign() const;
|
||||
bool IsSymbolic() const;
|
||||
bool CanCompileSources() const;
|
||||
bool HasKnownRuntimeArtifactLocation(std::string const& config) const;
|
||||
std::string const& GetLocation(std::string const& config) const;
|
||||
|
@@ -773,7 +773,9 @@ bool cmPackageInfoReader::ImportTargets(cmMakefile* makefile,
|
||||
|
||||
cmTarget* target = nullptr;
|
||||
if (type == "symbolic"_s) {
|
||||
// TODO
|
||||
target = this->AddLibraryComponent(
|
||||
makefile, cmStateEnums::INTERFACE_LIBRARY, fullName, *ci, package);
|
||||
target->SetSymbolic(true);
|
||||
} else if (type == "dylib"_s) {
|
||||
target = this->AddLibraryComponent(
|
||||
makefile, cmStateEnums::SHARED_LIBRARY, fullName, *ci, package);
|
||||
|
@@ -634,7 +634,13 @@ bool HandleTargetMode(cmExecutionStatus& status,
|
||||
status.SetError("can not be used on an ALIAS target.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) {
|
||||
if (target->IsSymbolic()) {
|
||||
status.SetError("can not be used on a SYMBOLIC target.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle the current target.
|
||||
if (!HandleTarget(target, status.GetMakefile(), propertyName,
|
||||
propertyValue, appendAsString, appendMode, remove)) {
|
||||
|
@@ -40,6 +40,10 @@ bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args,
|
||||
return false;
|
||||
}
|
||||
if (cmTarget* target = mf.FindTargetToUse(tname)) {
|
||||
if (target->IsSymbolic()) {
|
||||
status.SetError("can not be used on a SYMBOLIC target.");
|
||||
return false;
|
||||
}
|
||||
// loop through all the props and set them
|
||||
for (auto k = propsIter + 1; k != args.end(); k += 2) {
|
||||
target->SetProperty(*k, *(k + 1));
|
||||
|
@@ -608,6 +608,7 @@ public:
|
||||
bool IsAndroid;
|
||||
bool BuildInterfaceIncludesAppended;
|
||||
bool PerConfig;
|
||||
bool IsSymbolic;
|
||||
cmTarget::Visibility TargetVisibility;
|
||||
std::set<BT<std::pair<std::string, bool>>> Utilities;
|
||||
std::set<std::string> CodegenDependencies;
|
||||
@@ -885,6 +886,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
|
||||
this->impl->IsAIX = false;
|
||||
this->impl->IsApple = false;
|
||||
this->impl->IsAndroid = false;
|
||||
this->impl->IsSymbolic = false;
|
||||
this->impl->TargetVisibility = vis;
|
||||
this->impl->BuildInterfaceIncludesAppended = false;
|
||||
this->impl->PerConfig = (perConfig == PerConfig::Yes);
|
||||
@@ -1946,6 +1948,7 @@ MAKE_PROP(LINK_LIBRARIES);
|
||||
MAKE_PROP(MANUALLY_ADDED_DEPENDENCIES);
|
||||
MAKE_PROP(NAME);
|
||||
MAKE_PROP(SOURCES);
|
||||
MAKE_PROP(SYMBOLIC);
|
||||
MAKE_PROP(TYPE);
|
||||
MAKE_PROP(BINARY_DIR);
|
||||
MAKE_PROP(SOURCE_DIR);
|
||||
@@ -2047,6 +2050,7 @@ bool IsSettableProperty(cmMakefile* context, cmTarget* target,
|
||||
{ "MANUALLY_ADDED_DEPENDENCIES", { ROC::All } },
|
||||
{ "NAME", { ROC::All } },
|
||||
{ "SOURCES", { ROC::Imported } },
|
||||
{ "SYMBOLIC", { ROC::All } },
|
||||
{ "TYPE", { ROC::All } },
|
||||
{ "ALIAS_GLOBAL", { ROC::All, cmPolicies::CMP0160 } },
|
||||
{ "BINARY_DIR", { ROC::All, cmPolicies::CMP0160 } },
|
||||
@@ -2067,6 +2071,11 @@ bool IsSettableProperty(cmMakefile* context, cmTarget* target,
|
||||
}
|
||||
}
|
||||
|
||||
void cmTarget::SetSymbolic(bool const value)
|
||||
{
|
||||
this->impl->IsSymbolic = value;
|
||||
}
|
||||
|
||||
void cmTarget::SetProperty(std::string const& prop, cmValue value)
|
||||
{
|
||||
if (!IsSettableProperty(this->impl->Makefile, this, prop)) {
|
||||
@@ -2606,6 +2615,7 @@ cmValue cmTarget::GetProperty(std::string const& prop) const
|
||||
propBINARY_DIR,
|
||||
propSOURCE_DIR,
|
||||
propSOURCES,
|
||||
propSYMBOLIC,
|
||||
propINTERFACE_LINK_LIBRARIES,
|
||||
propINTERFACE_LINK_LIBRARIES_DIRECT,
|
||||
propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE,
|
||||
@@ -2626,6 +2636,10 @@ cmValue cmTarget::GetProperty(std::string const& prop) const
|
||||
return cmValue(propertyIter->second.Value);
|
||||
}
|
||||
|
||||
if (prop == propSYMBOLIC) {
|
||||
return this->IsSymbolic() ? cmValue(propTRUE) : cmValue(propFALSE);
|
||||
}
|
||||
|
||||
UsageRequirementProperty const* usageRequirements[] = {
|
||||
&this->impl->IncludeDirectories,
|
||||
&this->impl->CompileOptions,
|
||||
@@ -2760,6 +2774,11 @@ bool cmTarget::IsApple() const
|
||||
return this->impl->IsApple;
|
||||
}
|
||||
|
||||
bool cmTarget::IsSymbolic() const
|
||||
{
|
||||
return this->impl->IsSymbolic;
|
||||
}
|
||||
|
||||
bool cmTarget::IsNormal() const
|
||||
{
|
||||
switch (this->impl->TargetVisibility) {
|
||||
|
@@ -193,6 +193,8 @@ public:
|
||||
//! Get the utilities used by this target
|
||||
std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
|
||||
|
||||
void SetSymbolic(bool value);
|
||||
|
||||
//! Set/Get a property of this target file
|
||||
void SetProperty(std::string const& prop, cmValue value);
|
||||
void SetProperty(std::string const& prop, std::nullptr_t)
|
||||
@@ -232,6 +234,7 @@ public:
|
||||
bool IsForeign() const;
|
||||
bool IsPerConfig() const;
|
||||
bool IsRuntimeBinary() const;
|
||||
bool IsSymbolic() const;
|
||||
bool CanCompileSources() const;
|
||||
|
||||
bool GetMappedConfig(std::string const& desiredConfig, cmValue& loc,
|
||||
|
@@ -102,6 +102,11 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target->IsSymbolic()) {
|
||||
status.SetError("can not be used on a SYMBOLIC target.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Having a UTILITY library on the LHS is a bug.
|
||||
if (target->GetType() == cmStateEnums::UTILITY) {
|
||||
mf.IssueMessage(
|
||||
|
@@ -42,6 +42,10 @@ bool cmTargetPropCommandBase::HandleArguments(
|
||||
this->HandleMissingTarget(args[0]);
|
||||
return false;
|
||||
}
|
||||
if (this->Target->IsSymbolic()) {
|
||||
this->SetError("can not be used on a SYMBOLIC target.");
|
||||
return false;
|
||||
}
|
||||
bool const isRegularTarget =
|
||||
(this->Target->GetType() == cmStateEnums::EXECUTABLE) ||
|
||||
(this->Target->GetType() == cmStateEnums::STATIC_LIBRARY) ||
|
||||
|
@@ -0,0 +1,5 @@
|
||||
add_library(gui INTERFACE)
|
||||
add_library(widget INTERFACE SYMBOLIC)
|
||||
|
||||
install(TARGETS gui widget EXPORT gui-targets)
|
||||
install(EXPORT gui-targets DESTINATION lib/cmake/gui FILE gui-config.cmake NAMESPACE gui::)
|
@@ -0,0 +1,6 @@
|
||||
enable_language(C)
|
||||
find_package(gui REQUIRED)
|
||||
|
||||
add_library(baz INTERFACE)
|
||||
|
||||
target_link_libraries(baz INTERFACE gui::gui gui::widget)
|
@@ -18,11 +18,14 @@ function(run_ExportImport_test case)
|
||||
run_cmake_with_options(${case}-import
|
||||
-Dfoo_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/foo
|
||||
-Dbar_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/bar
|
||||
-Dgui_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/gui
|
||||
)
|
||||
endfunction()
|
||||
|
||||
run_ExportImport_test(SharedDep)
|
||||
run_ExportImport_test(SpdxLicenseProperty)
|
||||
run_ExportImport_test(InterfaceWithSymbolic)
|
||||
|
||||
|
||||
function(run_ExportImportBuildInstall_test case)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-export-build)
|
||||
|
@@ -0,0 +1,7 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
|
||||
|
||||
set(out_dir "${RunCMake_BINARY_DIR}/ExportSymbolicComponent-build")
|
||||
|
||||
file(READ "${out_dir}/foo.cps" content)
|
||||
expect_value("${content}" "foo" "name")
|
||||
expect_value("${content}" "symbolic" "components" "foo" "type")
|
@@ -0,0 +1,4 @@
|
||||
add_library(foo INTERFACE SYMBOLIC)
|
||||
|
||||
install(TARGETS foo EXPORT foo DESTINATION .)
|
||||
export(EXPORT foo PACKAGE_INFO foo)
|
@@ -38,6 +38,7 @@ run_cmake(Minimal)
|
||||
run_cmake(MinimalVersion)
|
||||
run_cmake(LowerCaseFile)
|
||||
run_cmake(Requirements)
|
||||
run_cmake(ExportSymbolicComponent)
|
||||
run_cmake(TargetTypes)
|
||||
run_cmake(DependsMultiple)
|
||||
run_cmake(LinkOnly)
|
||||
@@ -46,3 +47,4 @@ run_cmake(EmptyConfig)
|
||||
run_cmake(FileSetHeaders)
|
||||
run_cmake(DependencyVersionCMake)
|
||||
run_cmake(DependencyVersionCps)
|
||||
run_cmake(TransitiveSymbolicComponent)
|
||||
|
@@ -0,0 +1,16 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
|
||||
|
||||
set(out_dir "${RunCMake_BINARY_DIR}/TransitiveSymbolicComponent-build")
|
||||
|
||||
|
||||
file(READ "${out_dir}/bar.cps" content)
|
||||
expect_value("${content}" "bar" "name")
|
||||
expect_array("${content}" 1 "requires" "Symbolic" "components")
|
||||
expect_value("${content}" "test" "requires" "Symbolic" "components" 0)
|
||||
expect_value("${content}" "1.0" "requires" "Symbolic" "version")
|
||||
expect_array("${content}" 1 "requires" "Symbolic" "hints")
|
||||
expect_value("${content}" "${CMAKE_CURRENT_LIST_DIR}/cps" "requires" "Symbolic" "hints" 0)
|
||||
|
||||
string(JSON component GET "${content}" "components" "bar")
|
||||
expect_array("${component}" 1 "requires")
|
||||
expect_value("${component}" "Symbolic:test" "requires" 0)
|
@@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 4.0)
|
||||
|
||||
add_library(bar INTERFACE)
|
||||
|
||||
find_package(Symbolic REQUIRED CONFIG
|
||||
COMPONENTS foo test
|
||||
NO_DEFAULT_PATH
|
||||
PATHS ${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(bar INTERFACE Symbolic::test)
|
||||
|
||||
install(TARGETS bar EXPORT bar DESTINATION .)
|
||||
export(EXPORT bar PACKAGE_INFO bar)
|
17
Tests/RunCMake/ExportPackageInfo/cps/symbolic.cps
Normal file
17
Tests/RunCMake/ExportPackageInfo/cps/symbolic.cps
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"components" :
|
||||
{
|
||||
"foo" :
|
||||
{
|
||||
"type" : "interface"
|
||||
},
|
||||
"test" :
|
||||
{
|
||||
"type" : "symbolic"
|
||||
}
|
||||
},
|
||||
"cps_path" : "@prefix@",
|
||||
"cps_version" : "0.13.0",
|
||||
"name" : "Symbolic",
|
||||
"version": "1.0"
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
|
||||
|
||||
set(out_dir "${RunCMake_BINARY_DIR}/InstallSymbolicComponent-build/CMakeFiles/Export/5058f1af8388633f609cadb75a75dc9d")
|
||||
|
||||
file(READ "${out_dir}/foo.cps" content)
|
||||
expect_value("${content}" "foo" "name")
|
||||
expect_value("${content}" "symbolic" "components" "foo" "type")
|
@@ -0,0 +1,4 @@
|
||||
add_library(foo INTERFACE SYMBOLIC)
|
||||
|
||||
install(TARGETS foo EXPORT foo)
|
||||
install(PACKAGE_INFO foo EXPORT foo DESTINATION .)
|
@@ -55,4 +55,6 @@ run_cmake(EmptyConfig)
|
||||
run_cmake(FileSetHeaders)
|
||||
run_cmake(DependencyVersionCMake)
|
||||
run_cmake(DependencyVersionCps)
|
||||
run_cmake(TransitiveSymbolicComponent)
|
||||
run_cmake(InstallSymbolicComponent)
|
||||
run_cmake_install(Destination)
|
||||
|
@@ -0,0 +1,15 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
|
||||
|
||||
set(out_dir "${RunCMake_BINARY_DIR}/TransitiveSymbolicComponent-build/CMakeFiles/Export/5058f1af8388633f609cadb75a75dc9d")
|
||||
|
||||
file(READ "${out_dir}/bar.cps" content)
|
||||
expect_value("${content}" "bar" "name")
|
||||
expect_array("${content}" 1 "requires" "Symbolic" "components")
|
||||
expect_value("${content}" "test" "requires" "Symbolic" "components" 0)
|
||||
expect_value("${content}" "1.0" "requires" "Symbolic" "version")
|
||||
expect_array("${content}" 1 "requires" "Symbolic" "hints")
|
||||
expect_value("${content}" "${CMAKE_CURRENT_LIST_DIR}/cps" "requires" "Symbolic" "hints" 0)
|
||||
|
||||
string(JSON component GET "${content}" "components" "bar")
|
||||
expect_array("${component}" 1 "requires")
|
||||
expect_value("${component}" "Symbolic:test" "requires" 0)
|
@@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 4.0)
|
||||
|
||||
add_library(bar INTERFACE)
|
||||
|
||||
find_package(Symbolic REQUIRED CONFIG
|
||||
COMPONENTS foo test
|
||||
NO_DEFAULT_PATH
|
||||
PATHS ${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(bar INTERFACE Symbolic::test)
|
||||
|
||||
install(TARGETS bar EXPORT bar)
|
||||
install(PACKAGE_INFO bar EXPORT bar DESTINATION .)
|
17
Tests/RunCMake/InstallPackageInfo/cps/symbolic.cps
Normal file
17
Tests/RunCMake/InstallPackageInfo/cps/symbolic.cps
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"components" :
|
||||
{
|
||||
"foo" :
|
||||
{
|
||||
"type" : "interface"
|
||||
},
|
||||
"test" :
|
||||
{
|
||||
"type" : "symbolic"
|
||||
}
|
||||
},
|
||||
"cps_path" : "@prefix@",
|
||||
"cps_version" : "0.13.0",
|
||||
"name" : "Symbolic",
|
||||
"version": "1.0"
|
||||
}
|
8
Tests/RunCMake/add_library/INTERFACEwithSYMBOLIC.cmake
Normal file
8
Tests/RunCMake/add_library/INTERFACEwithSYMBOLIC.cmake
Normal file
@@ -0,0 +1,8 @@
|
||||
add_library(TestSymbolicInterfaceLib INTERFACE SYMBOLIC)
|
||||
|
||||
get_target_property(IS_SYMBOLIC TestSymbolicInterfaceLib "SYMBOLIC")
|
||||
|
||||
if("${IS_SYMBOLIC}" STREQUAL "FALSE")
|
||||
string(APPEND RunCMake_TEST_FAILED "Target: \"TestSymbolicInterfaceLib\" does not have the SYMBOLIC property")
|
||||
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
|
||||
endif()
|
@@ -3,6 +3,7 @@ include(RunCMake)
|
||||
run_cmake(CMP0073)
|
||||
|
||||
run_cmake(INTERFACEwithNoSources)
|
||||
run_cmake(INTERFACEwithSYMBOLIC)
|
||||
run_cmake(OBJECTwithNoSources)
|
||||
run_cmake(STATICwithNoSources)
|
||||
run_cmake(SHAREDwithNoSources)
|
||||
@@ -19,6 +20,7 @@ run_cmake(UNKNOWNwithOnlyObjectSources)
|
||||
run_cmake(INTERFACEwithNoSourcesButLinkObjects)
|
||||
run_cmake(OBJECTwithNoSourcesButLinkObjects)
|
||||
run_cmake(STATICwithNoSourcesButLinkObjects)
|
||||
run_cmake(STATICwithSYMBOLIC)
|
||||
run_cmake(SHAREDwithNoSourcesButLinkObjects)
|
||||
run_cmake(MODULEwithNoSourcesButLinkObjects)
|
||||
run_cmake(UNKNOWNwithNoSourcesButLinkObjects)
|
||||
|
1
Tests/RunCMake/add_library/STATICwithSYMBOLIC-result.txt
Normal file
1
Tests/RunCMake/add_library/STATICwithSYMBOLIC-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
4
Tests/RunCMake/add_library/STATICwithSYMBOLIC-stderr.txt
Normal file
4
Tests/RunCMake/add_library/STATICwithSYMBOLIC-stderr.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
^CMake Error at STATICwithSYMBOLIC.cmake:[0-9]+ \(add_library\):
|
||||
add_library SYMBOLIC option may only be used with INTERFACE libraries
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)$
|
1
Tests/RunCMake/add_library/STATICwithSYMBOLIC.cmake
Normal file
1
Tests/RunCMake/add_library/STATICwithSYMBOLIC.cmake
Normal file
@@ -0,0 +1 @@
|
||||
add_library(TestStaticWithSymbolic STATIC SYMBOLIC)
|
@@ -27,3 +27,4 @@ run_cmake(FindDependencyExportStatic)
|
||||
run_cmake(FindDependencyExportShared)
|
||||
#FIXME(#26622): The FindDependencyExportFetchContent test case exposes an assertion failure.
|
||||
#run_cmake(FindDependencyExportFetchContent)
|
||||
run_cmake(SymbolicComponent)
|
||||
|
4
Tests/RunCMake/export/SymbolicComponent-check.cmake
Normal file
4
Tests/RunCMake/export/SymbolicComponent-check.cmake
Normal file
@@ -0,0 +1,4 @@
|
||||
file(READ "${RunCMake_TEST_BINARY_DIR}/foo.cmake" foo)
|
||||
if("${foo}" MATCHES "add_library\(foo INTERFACE SYMBOLIC IMPORTED\)")
|
||||
string(APPEND RunCMake_TEST_FAILED "Symbolic Component Foo was not exported\n")
|
||||
endif()
|
2
Tests/RunCMake/export/SymbolicComponent.cmake
Normal file
2
Tests/RunCMake/export/SymbolicComponent.cmake
Normal file
@@ -0,0 +1,2 @@
|
||||
add_library(foo INTERFACE SYMBOLIC)
|
||||
export(TARGETS foo FILE foo.cmake)
|
@@ -54,9 +54,4 @@ run_cmake(MissingComponentDependency)
|
||||
run_cmake(MissingTransitiveComponentCPS)
|
||||
run_cmake(MissingTransitiveComponentCMake)
|
||||
run_cmake(MissingTransitiveComponentDependency)
|
||||
|
||||
# Configuration selection tests
|
||||
run_cmake_build(ConfigDefault)
|
||||
run_cmake_build(ConfigFirst)
|
||||
run_cmake_build(ConfigMapped)
|
||||
run_cmake_build(ConfigMatchBuildType Test)
|
||||
run_cmake(SymbolicComponents)
|
||||
|
8
Tests/RunCMake/find_package-CPS/SymbolicComponents.cmake
Normal file
8
Tests/RunCMake/find_package-CPS/SymbolicComponents.cmake
Normal file
@@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION 4.0)
|
||||
|
||||
include(Setup.cmake)
|
||||
|
||||
add_library(bar INTERFACE)
|
||||
|
||||
find_package(Symbolic REQUIRED COMPONENTS foo test)
|
||||
target_link_libraries(bar INTERFACE Symbolic::foo Symbolic::test)
|
17
Tests/RunCMake/find_package-CPS/cps/symbolic.cps
Normal file
17
Tests/RunCMake/find_package-CPS/cps/symbolic.cps
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"components" :
|
||||
{
|
||||
"foo" :
|
||||
{
|
||||
"type" : "interface"
|
||||
},
|
||||
"test" :
|
||||
{
|
||||
"type" : "symbolic"
|
||||
}
|
||||
},
|
||||
"cps_path" : "@prefix@",
|
||||
"cps_version" : "0.13.0",
|
||||
"name" : "Symbolic",
|
||||
"version": "1.0"
|
||||
}
|
@@ -97,7 +97,7 @@ foreach(policy IN ITEMS NEW OLD WARN)
|
||||
run_install_test(CMP0177-${policy})
|
||||
run_cmake_with_options(CMP0177-${policy}-verify
|
||||
-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/CMP0177-${policy}-build/root-all
|
||||
)
|
||||
)
|
||||
endforeach()
|
||||
run_cmake(TARGETS-ImportedGlobal)
|
||||
run_cmake(TARGETS-NAMELINK_COMPONENT-bad-all)
|
||||
@@ -106,7 +106,7 @@ run_cmake(FILES-DESTINATION-TYPE)
|
||||
run_cmake(DIRECTORY-DESTINATION-TYPE)
|
||||
run_cmake(FILES-directory)
|
||||
if(NOT WIN32)
|
||||
run_cmake(FILES-symlink-to-directory)
|
||||
run_cmake(FILES-symlink-to-directory)
|
||||
endif()
|
||||
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_BUILD_TYPE:STRING=Debug")
|
||||
@@ -131,6 +131,7 @@ run_install_test(TARGETS-OPTIONAL)
|
||||
run_install_test(FILES-OPTIONAL)
|
||||
run_install_test(DIRECTORY-OPTIONAL)
|
||||
run_install_test(TARGETS-Defaults)
|
||||
run_install_test(TARGETS-SymbolicComponent)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
run_install_test(TARGETS-NAMELINK-No-Tweak)
|
||||
|
@@ -0,0 +1,5 @@
|
||||
file(READ "${RunCMake_TEST_BINARY_DIR}/root-all/foo.cmake" foo)
|
||||
|
||||
if("${foo}" MATCHES "add_library\(foo INTERFACE SYMBOLIC IMPORTED\)")
|
||||
string(APPEND RunCMake_TEST_FAILED "Symbolic Component Foo was not exported\n")
|
||||
endif()
|
3
Tests/RunCMake/install/TARGETS-SymbolicComponent.cmake
Normal file
3
Tests/RunCMake/install/TARGETS-SymbolicComponent.cmake
Normal file
@@ -0,0 +1,3 @@
|
||||
add_library(foo INTERFACE SYMBOLIC)
|
||||
install(TARGETS foo EXPORT foo)
|
||||
install(EXPORT foo DESTINATION . FILE foo.cmake)
|
Reference in New Issue
Block a user