parent
c7173f18f8
commit
f59bab006d
@ -34,9 +34,9 @@ PkgConfig Targets
|
||||
|
||||
``cmake_pkg_config`` may recursively generate target-like names in the global
|
||||
scope in order to resolve a package ``IMPORT`` or ``POPULATE`` command. These
|
||||
names take the form of ``@foreign_pkgcfg::<package>`` and are exposed via the
|
||||
:prop_tgt:`INTERFACE_LINK_LIBRARIES` target property of an ``IMPORT``-generated
|
||||
target.
|
||||
names take the form of ``@foreign_pkgcfg::[<prefix>_]<package>`` and are exposed
|
||||
via the :prop_tgt:`INTERFACE_LINK_LIBRARIES` target property of an
|
||||
``IMPORT``-generated target.
|
||||
|
||||
It is not possible to modify or address these pkg-config native targets via
|
||||
normal target-based commands. Limited control over their generation is possible
|
||||
@ -180,9 +180,16 @@ common between them. They are:
|
||||
#. If no top build directory path is available, the ``pc_top_builddir``
|
||||
package variable is not set
|
||||
|
||||
``BIND_PC_REQUIRES``
|
||||
A list of ``<Name>=<Target>`` pairs, the ``Name`` is a package name as it
|
||||
appears in the ``Requires`` list of a pkg-config file and the ``Target`` is a
|
||||
``PREFIX <name>``
|
||||
Specifying a prefix creates an independent collection of pkg-config targets
|
||||
separate from previously populated targets. This enables multiple version of
|
||||
a given package to co-exist, for example packages from different sysroots.
|
||||
|
||||
The default prefix is an empty string.
|
||||
|
||||
``BIND_PC_REQUIRES <<name>=<target>>...``
|
||||
A list of ``<name>=<target>`` pairs, the ``name`` is a package name as it
|
||||
appears in the ``Requires`` list of a pkg-config file and the ``target`` is a
|
||||
CMake-native target name (not a pkg-config target).
|
||||
|
||||
When a given package name appears in the ``Requires`` list of a package, it
|
||||
@ -311,6 +318,7 @@ The following variables will be populated from the contents of package file:
|
||||
|
||||
cmake_pkg_config(POPULATE <package> [<version>]
|
||||
[REQUIRED] [EXACT] [QUIET]
|
||||
[PREFIX <prefix>]
|
||||
[BIND_PC_REQUIRES <<name>=<target>>...]
|
||||
[STRICTNESS <mode>]
|
||||
[ENV_MODE <mode>]
|
||||
@ -339,6 +347,8 @@ package was found.
|
||||
|
||||
cmake_pkg_config(IMPORT <package> [<version>]
|
||||
[REQUIRED] [EXACT] [QUIET]
|
||||
[NAME <name>]
|
||||
[PREFIX <prefix>]
|
||||
[BIND_PC_REQUIRES <<name>=<target>>...]
|
||||
[STRICTNESS <mode>]
|
||||
[ENV_MODE <mode>]
|
||||
@ -350,7 +360,11 @@ package was found.
|
||||
|
||||
Creates a native CMake ``IMPORTED`` target that can be linked to via
|
||||
:command:`target_link_libraries`. This new target is named
|
||||
``PkgConfig::<package>``.
|
||||
``PkgConfig::<package>`` by default.
|
||||
|
||||
A ``PKGCONFIG_<package>_FOUND`` variable will be set to indicate whether the
|
||||
package was found.
|
||||
|
||||
``NAME``
|
||||
Overrides the name of the created CMake target to ``PkgConfig::<name>``. This
|
||||
*does not* affect the ``PKGCONFIG_<package>_FOUND`` variable.
|
||||
|
@ -37,6 +37,7 @@
|
||||
namespace {
|
||||
struct ExtractArguments;
|
||||
struct PopulateArguments;
|
||||
struct ImportArguments;
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -797,10 +798,11 @@ bool HandleExtractCommand(std::vector<std::string> const& args,
|
||||
using pkgStack = std::unordered_map<std::string, std::vector<pkgStackEntry>>;
|
||||
using pkgProviders = std::unordered_map<std::string, std::string>;
|
||||
|
||||
cmTarget* CreateCMakeTarget(std::string const& name, cmPkgConfigResult& pkg,
|
||||
pkgProviders& providers, cmMakefile& mf)
|
||||
cmTarget* CreateCMakeTarget(std::string const& name, std::string const& prefix,
|
||||
cmPkgConfigResult& pkg, pkgProviders& providers,
|
||||
cmMakefile& mf)
|
||||
{
|
||||
auto* tgt = mf.AddForeignTarget("pkgcfg", name);
|
||||
auto* tgt = mf.AddForeignTarget("pkgcfg", cmStrCat(prefix, name));
|
||||
|
||||
tgt->AppendProperty("VERSION", pkg.Version());
|
||||
|
||||
@ -829,13 +831,14 @@ cmTarget* CreateCMakeTarget(std::string const& name, cmPkgConfigResult& pkg,
|
||||
}
|
||||
|
||||
tgt->AppendProperty("INTERFACE_LINK_LIBRARIES",
|
||||
cmStrCat("@foreign_pkgcfg::", dep.Name));
|
||||
cmStrCat("@foreign_pkgcfg::", prefix, dep.Name));
|
||||
}
|
||||
return tgt;
|
||||
}
|
||||
|
||||
bool CheckPackageDependencies(
|
||||
std::string const& name, cmPkgConfigResult& pkg, pkgStack& inStack,
|
||||
std::string const& name, std::string const& prefix, cmPkgConfigResult& pkg,
|
||||
pkgStack& inStack,
|
||||
std::unordered_map<std::string, cmPkgConfigResult>& outStack,
|
||||
pkgProviders& providers, ImportEnv& imEnv)
|
||||
{
|
||||
@ -846,7 +849,7 @@ bool CheckPackageDependencies(
|
||||
}
|
||||
|
||||
auto* tgt = imEnv.status.GetMakefile().FindTargetToUse(
|
||||
cmStrCat("@foreign_pkgcfg::", dep.Name),
|
||||
cmStrCat("@foreign_pkgcfg::", prefix, dep.Name),
|
||||
cmStateEnums::TargetDomain::FOREIGN);
|
||||
if (tgt) {
|
||||
auto ver = tgt->GetProperty("VERSION");
|
||||
@ -882,17 +885,23 @@ bool CheckPackageDependencies(
|
||||
|
||||
struct PopulateArguments : CommonArguments
|
||||
{
|
||||
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> providers;
|
||||
cm::optional<std::string> Prefix;
|
||||
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Providers;
|
||||
};
|
||||
|
||||
auto const PopulateParser =
|
||||
BIND_COMMON(PopulateArguments)
|
||||
.Bind("BIND_PC_REQUIRES"_s, &PopulateArguments::providers);
|
||||
#define BIND_POPULATE(argtype) \
|
||||
BIND_COMMON(argtype) \
|
||||
.Bind("PREFIX"_s, &argtype::Prefix) \
|
||||
.Bind("BIND_PC_REQUIRES"_s, &argtype::Providers)
|
||||
|
||||
auto const PopulateParser = BIND_POPULATE(PopulateArguments);
|
||||
|
||||
std::pair<bool, bool> PopulatePCTarget(PopulateArguments& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
|
||||
std::string prefix = args.Prefix ? cmStrCat(*args.Prefix, "_"_s) : "";
|
||||
|
||||
auto& mf = status.GetMakefile();
|
||||
auto maybeEnv = HandleCommon(args, status);
|
||||
|
||||
@ -903,8 +912,8 @@ std::pair<bool, bool> PopulatePCTarget(PopulateArguments& args,
|
||||
auto& imEnv = maybeEnv->second;
|
||||
|
||||
pkgProviders providers;
|
||||
if (args.providers) {
|
||||
for (auto const& provider_str : *args.providers) {
|
||||
if (args.Providers) {
|
||||
for (auto const& provider_str : *args.Providers) {
|
||||
auto assignment = provider_str.find('=');
|
||||
if (assignment != std::string::npos) {
|
||||
providers.emplace(provider_str.substr(0, assignment),
|
||||
@ -927,7 +936,7 @@ std::pair<bool, bool> PopulatePCTarget(PopulateArguments& args,
|
||||
}
|
||||
imEnv.exact = false;
|
||||
|
||||
if (!CheckPackageDependencies(*args.Package, *maybePackage, inStack,
|
||||
if (!CheckPackageDependencies(*args.Package, prefix, *maybePackage, inStack,
|
||||
outStack, providers, imEnv)) {
|
||||
return { !args.Required, false };
|
||||
}
|
||||
@ -940,8 +949,8 @@ std::pair<bool, bool> PopulatePCTarget(PopulateArguments& args,
|
||||
if (!maybePackage) {
|
||||
return { !args.Required, false };
|
||||
}
|
||||
if (!CheckPackageDependencies(name, *maybePackage, inStack, outStack,
|
||||
providers, imEnv)) {
|
||||
if (!CheckPackageDependencies(name, prefix, *maybePackage, inStack,
|
||||
outStack, providers, imEnv)) {
|
||||
return { !args.Required, false };
|
||||
}
|
||||
inStack.erase(name);
|
||||
@ -949,7 +958,7 @@ std::pair<bool, bool> PopulatePCTarget(PopulateArguments& args,
|
||||
}
|
||||
|
||||
for (auto& entry : outStack) {
|
||||
CreateCMakeTarget(entry.first, entry.second, providers, mf);
|
||||
CreateCMakeTarget(entry.first, prefix, entry.second, providers, mf);
|
||||
}
|
||||
|
||||
return { true, true };
|
||||
@ -961,7 +970,11 @@ bool HandlePopulateCommand(std::vector<std::string> const& args,
|
||||
std::vector<std::string> unparsed;
|
||||
auto parsedArgs = PopulateParser.Parse(args, &unparsed);
|
||||
|
||||
auto foreign_name = cmStrCat("@foreign_pkgcfg::", *parsedArgs.Package);
|
||||
std::string prefix =
|
||||
parsedArgs.Prefix ? cmStrCat(*parsedArgs.Prefix, "_"_s) : "";
|
||||
|
||||
auto foreign_name =
|
||||
cmStrCat("@foreign_pkgcfg::", prefix, *parsedArgs.Package);
|
||||
auto found_var = cmStrCat("PKGCONFIG_", *parsedArgs.Package, "_FOUND");
|
||||
|
||||
auto& mf = status.GetMakefile();
|
||||
@ -976,13 +989,27 @@ bool HandlePopulateCommand(std::vector<std::string> const& args,
|
||||
return result.first;
|
||||
}
|
||||
|
||||
struct ImportArguments : PopulateArguments
|
||||
{
|
||||
cm::optional<std::string> Name;
|
||||
};
|
||||
|
||||
auto const ImportParser =
|
||||
BIND_POPULATE(ImportArguments).Bind("NAME"_s, &ImportArguments::Name);
|
||||
|
||||
bool HandleImportCommand(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
std::vector<std::string> unparsed;
|
||||
auto parsedArgs = PopulateParser.Parse(args, &unparsed);
|
||||
auto foreign_name = cmStrCat("@foreign_pkgcfg::", *parsedArgs.Package);
|
||||
auto local_name = cmStrCat("PkgConfig::", *parsedArgs.Package);
|
||||
auto parsedArgs = ImportParser.Parse(args, &unparsed);
|
||||
|
||||
std::string prefix =
|
||||
parsedArgs.Prefix ? cmStrCat(*parsedArgs.Prefix, "_"_s) : "";
|
||||
|
||||
auto foreign_name =
|
||||
cmStrCat("@foreign_pkgcfg::", prefix, *parsedArgs.Package);
|
||||
auto local_name =
|
||||
cmStrCat("PkgConfig::", parsedArgs.Name.value_or(*parsedArgs.Package));
|
||||
auto found_var = cmStrCat("PKGCONFIG_", *parsedArgs.Package, "_FOUND");
|
||||
|
||||
auto& mf = status.GetMakefile();
|
||||
|
13
Tests/RunCMake/cmake_pkg_config/ImportName.cmake
Normal file
13
Tests/RunCMake/cmake_pkg_config/ImportName.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
set(CMAKE_PKG_CONFIG_PC_PATH ${CMAKE_CURRENT_LIST_DIR}/PackageRoot/RequiresPackages)
|
||||
|
||||
cmake_pkg_config(IMPORT alpha REQUIRED
|
||||
NAME moe
|
||||
)
|
||||
|
||||
if(TARGET PkgConfig::alpha)
|
||||
message("cmake_pkg_config target rename created PkgConfig::<package> target")
|
||||
endif()
|
||||
|
||||
if(NOT TARGET PkgConfig::moe)
|
||||
message("cmake_pkg_config target rename failed to create PkgConfig::<name> target")
|
||||
endif()
|
13
Tests/RunCMake/cmake_pkg_config/ImportPrefix-check.cmake
Normal file
13
Tests/RunCMake/cmake_pkg_config/ImportPrefix-check.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
set(expected
|
||||
"larry: Alpha
|
||||
curly: Alpha
|
||||
moe: AltAlpha
|
||||
shemp: AltAlpha
|
||||
"
|
||||
)
|
||||
|
||||
file(READ "${RunCMake_TEST_BINARY_DIR}/import-prefix.txt" actual)
|
||||
|
||||
if(NOT(expected STREQUAL actual))
|
||||
set(RunCMake_TEST_FAILED "cmake_pkg_config import-prefix.txt does not match expected:\n${actual}")
|
||||
endif()
|
33
Tests/RunCMake/cmake_pkg_config/ImportPrefix.cmake
Normal file
33
Tests/RunCMake/cmake_pkg_config/ImportPrefix.cmake
Normal file
@ -0,0 +1,33 @@
|
||||
set(CMAKE_PKG_CONFIG_PC_PATH ${CMAKE_CURRENT_LIST_DIR}/PackageRoot/RequiresPackages)
|
||||
|
||||
cmake_pkg_config(IMPORT alpha REQUIRED
|
||||
NAME larry
|
||||
)
|
||||
|
||||
set(CMAKE_PKG_CONFIG_PC_PATH ${CMAKE_CURRENT_LIST_DIR}/PackageRoot/AltRequiresPackages)
|
||||
|
||||
cmake_pkg_config(IMPORT alpha REQUIRED
|
||||
NAME curly
|
||||
)
|
||||
|
||||
cmake_pkg_config(IMPORT alpha REQUIRED
|
||||
NAME moe
|
||||
PREFIX moe
|
||||
)
|
||||
|
||||
set(CMAKE_PKG_CONFIG_PC_PATH ${CMAKE_CURRENT_LIST_DIR}/PackageRoot/RequiresPackages)
|
||||
|
||||
cmake_pkg_config(IMPORT alpha REQUIRED
|
||||
NAME shemp
|
||||
PREFIX moe
|
||||
)
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT import-prefix.txt
|
||||
CONTENT
|
||||
"larry: $<TARGET_PROPERTY:PkgConfig::larry,INTERFACE_COMPILE_OPTIONS>
|
||||
curly: $<TARGET_PROPERTY:PkgConfig::curly,INTERFACE_COMPILE_OPTIONS>
|
||||
moe: $<TARGET_PROPERTY:PkgConfig::moe,INTERFACE_COMPILE_OPTIONS>
|
||||
shemp: $<TARGET_PROPERTY:PkgConfig::shemp,INTERFACE_COMPILE_OPTIONS>
|
||||
"
|
||||
)
|
@ -0,0 +1,5 @@
|
||||
Name: AltAlpha
|
||||
Description: AltAlpha
|
||||
Version: 1.0.0
|
||||
|
||||
Cflags: AltAlpha
|
@ -16,8 +16,10 @@ run_cmake(ExtractRequired)
|
||||
run_cmake(ExtractReroot)
|
||||
run_cmake(ExtractUninstalled)
|
||||
run_cmake(ExtractVersion)
|
||||
run_cmake(ImportSimple)
|
||||
run_cmake(ImportName)
|
||||
run_cmake(ImportPrefix)
|
||||
run_cmake(ImportRequires)
|
||||
run_cmake(ImportSimple)
|
||||
run_cmake(ImportTransitiveFail)
|
||||
run_cmake(ImportTransitiveVersion)
|
||||
run_cmake(ImportTransitiveVersionFail)
|
||||
|
Loading…
Reference in New Issue
Block a user