mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
Move some target related enumeration types from `cmStateTypes.h` to a new header, as these really aren't "state" types. Also, make `TargetType` a strongly-typed enumeration.
167 lines
5.0 KiB
C++
167 lines
5.0 KiB
C++
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
file LICENSE.rst or https://cmake.org/licensing for details. */
|
|
#include "cmExportBuildPackageInfoGenerator.h"
|
|
|
|
#include <cassert>
|
|
#include <functional>
|
|
#include <map>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include <cmext/string_view>
|
|
|
|
#include <cm3p/json/value.h>
|
|
|
|
#include "cmAlgorithms.h"
|
|
#include "cmDiagnosticContext.h"
|
|
#include "cmDiagnostics.h"
|
|
#include "cmGenExContext.h"
|
|
#include "cmGeneratorExpression.h"
|
|
#include "cmGeneratorFileSet.h"
|
|
#include "cmGeneratorTarget.h"
|
|
#include "cmList.h"
|
|
#include "cmPackageInfoArguments.h"
|
|
#include "cmStringAlgorithms.h"
|
|
#include "cmTargetTypes.h"
|
|
|
|
cmExportBuildPackageInfoGenerator::cmExportBuildPackageInfoGenerator(
|
|
cmPackageInfoArguments arguments, cmDiagnosticContext context)
|
|
: cmExportBuildFileGenerator(std::move(context))
|
|
, cmExportPackageInfoGenerator(std::move(arguments))
|
|
{
|
|
this->SetNamespace(cmStrCat(this->GetPackageName(), "::"_s));
|
|
}
|
|
|
|
bool cmExportBuildPackageInfoGenerator::GenerateMainFile(std::ostream& os)
|
|
{
|
|
if (!this->CollectExports([&](cmGeneratorTarget const*) {})) {
|
|
return false;
|
|
}
|
|
|
|
if (!this->CheckPackage()) {
|
|
return false;
|
|
}
|
|
|
|
Json::Value root = this->GeneratePackageInfo();
|
|
root["cps_path"] = "@prefix@";
|
|
|
|
Json::Value& components = root["components"];
|
|
|
|
// Create all the imported targets.
|
|
for (auto const& exp : this->Exports) {
|
|
cmGeneratorTarget* const target = exp.Target;
|
|
cm::TargetType targetType = this->GetExportTargetType(target);
|
|
|
|
Json::Value* const component =
|
|
this->GenerateImportTarget(components, target, targetType);
|
|
if (!component) {
|
|
return false;
|
|
}
|
|
|
|
ImportPropertyMap properties;
|
|
if (!this->PopulateInterfaceProperties(target, properties)) {
|
|
return false;
|
|
}
|
|
this->PopulateInterfaceLinkLibrariesProperty(
|
|
target, cmGeneratorExpression::InstallInterface, properties);
|
|
|
|
if (targetType != cm::TargetType::INTERFACE_LIBRARY) {
|
|
auto configurations = Json::Value{ Json::objectValue };
|
|
|
|
// Add per-configuration properties.
|
|
for (std::string const& c : this->Configurations) {
|
|
this->GenerateInterfacePropertiesConfig(configurations, target, c);
|
|
}
|
|
|
|
if (!configurations.empty()) {
|
|
(*component)["configurations"] = configurations;
|
|
}
|
|
}
|
|
|
|
// De-duplicate include directories prior to generation.
|
|
auto it = properties.find("INTERFACE_INCLUDE_DIRECTORIES");
|
|
if (it != properties.end()) {
|
|
auto list = cmList{ it->second };
|
|
list = cmList{ list.begin(), cmRemoveDuplicates(list) };
|
|
properties["INTERFACE_INCLUDE_DIRECTORIES"] = list.to_string();
|
|
}
|
|
|
|
// Set configuration-agnostic properties for component.
|
|
this->GenerateInterfaceProperties(*component, target, properties);
|
|
this->GenerateTargetFileSets(*component, target);
|
|
}
|
|
|
|
this->GeneratePackageRequires(root);
|
|
|
|
// Write the primary packing information file.
|
|
this->WritePackageInfo(root, os);
|
|
|
|
bool result = true;
|
|
|
|
return result;
|
|
}
|
|
|
|
void cmExportBuildPackageInfoGenerator::GenerateInterfacePropertiesConfig(
|
|
Json::Value& configurations, cmGeneratorTarget* target,
|
|
std::string const& config)
|
|
{
|
|
std::string const& suffix = PropertyConfigSuffix(config);
|
|
|
|
ImportPropertyMap properties;
|
|
|
|
assert(this->GetExportTargetType(target) !=
|
|
cm::TargetType::INTERFACE_LIBRARY);
|
|
this->SetImportLocationProperty(config, suffix, target, properties);
|
|
if (properties.empty()) {
|
|
return;
|
|
}
|
|
|
|
this->SetImportDetailProperties(config, suffix, target, properties);
|
|
|
|
// TODO: PUBLIC_HEADER_LOCATION
|
|
|
|
Json::Value component =
|
|
this->GenerateInterfaceConfigProperties(suffix, properties);
|
|
|
|
this->GenerateCxxModules(component, target, this->FileDir, config);
|
|
|
|
if (!component.empty()) {
|
|
configurations[config.empty() ? std::string{ "noconfig" } : config] =
|
|
std::move(component);
|
|
}
|
|
}
|
|
|
|
void cmExportBuildPackageInfoGenerator::GenerateTargetFileSets(
|
|
Json::Value& fileSets, cmGeneratorTarget const* target,
|
|
cmGeneratorFileSet const* fileSet, cmTargetExport const* /*targetExport*/,
|
|
std::string const& type) const
|
|
{
|
|
cm::GenEx::Context context{ target->LocalGenerator, {} };
|
|
|
|
std::map<std::string, std::vector<std::string>> files;
|
|
auto eval = [&files](std::string&& baseDir, std::string&& relPath,
|
|
std::string&& /*file*/) {
|
|
files[std::move(baseDir)].emplace_back(std::move(relPath));
|
|
};
|
|
|
|
if (fileSet->EvaluateFiles(context, target, eval)) {
|
|
this->IssueDiagnostic(
|
|
cmDiagnostics::CMD_AUTHOR,
|
|
cmStrCat("The \""_s, target->GetName(),
|
|
"\" target's interface file set \""_s, fileSet->GetName(),
|
|
"\" of type \""_s, fileSet->GetType(),
|
|
"\" contains context-sensitive information, which is not "
|
|
"supported. The file set will not be exported."_s));
|
|
return;
|
|
}
|
|
|
|
for (auto const& i : files) {
|
|
this->GenerateTargetFileSet(fileSets, fileSet, type, i.first, i.second);
|
|
}
|
|
}
|
|
|
|
std::string cmExportBuildPackageInfoGenerator::GetCxxModulesDirectory() const
|
|
{
|
|
return this->CxxModulesDirectory;
|
|
}
|