mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-22 14:23:10 -05:00
export: Factor out CMake-specific export generation (2/2)
In order to support generation of Common Package Specifications, the mechanisms CMake uses to export package information need to be made more abstract. The prior commits began this refactoring; this continues by (actually) restructuring the classes used to generate the actual export files. To minimize churn, this introduces virtual base classes and diamond inheritance in order to separate logic which is format-agnostic but depends on the export mode (build-tree versus install-tree) from logic which is format-specific but mode-agnostic. This could probably be refactored further to use helper classes instead, and a future commit may do that, however an initial attempt to do that was proving even more invasive, such that this approach was deemed more manageable. While we're at it, add 'const' in more places where possible.
This commit is contained in:
@@ -2,28 +2,50 @@
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmExportBuildAndroidMKGenerator.h"
|
||||
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <cmext/algorithm>
|
||||
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmLinkItem.h"
|
||||
#include "cmList.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmPolicies.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTarget.h"
|
||||
|
||||
cmExportBuildAndroidMKGenerator::cmExportBuildAndroidMKGenerator()
|
||||
cmExportBuildAndroidMKGenerator::cmExportBuildAndroidMKGenerator() = default;
|
||||
|
||||
bool cmExportBuildAndroidMKGenerator::GenerateMainFile(std::ostream& os)
|
||||
{
|
||||
this->LG = nullptr;
|
||||
this->ExportSet = nullptr;
|
||||
if (!this->CollectExports([&](cmGeneratorTarget const*) {})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create all the imported targets.
|
||||
for (auto const& exp : this->Exports) {
|
||||
cmGeneratorTarget* gte = exp.Target;
|
||||
|
||||
this->GenerateImportTargetCode(os, gte, this->GetExportTargetType(gte));
|
||||
|
||||
gte->Target->AppendBuildInterfaceIncludes();
|
||||
|
||||
ImportPropertyMap properties;
|
||||
if (!this->PopulateInterfaceProperties(gte, properties)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool const newCMP0022Behavior =
|
||||
gte->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
|
||||
gte->GetPolicyStatusCMP0022() != cmPolicies::OLD;
|
||||
if (newCMP0022Behavior) {
|
||||
this->PopulateInterfaceLinkLibrariesProperty(
|
||||
gte, cmGeneratorExpression::BuildInterface, properties);
|
||||
}
|
||||
|
||||
this->GenerateInterfaceProperties(gte, os, properties);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateImportHeaderCode(
|
||||
@@ -32,15 +54,6 @@ void cmExportBuildAndroidMKGenerator::GenerateImportHeaderCode(
|
||||
os << "LOCAL_PATH := $(call my-dir)\n\n";
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateImportFooterCode(std::ostream&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateExpectedTargetsCode(
|
||||
std::ostream&, std::string const&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode(
|
||||
std::ostream& os, cmGeneratorTarget const* target,
|
||||
cmStateEnums::TargetType /*targetType*/)
|
||||
@@ -55,143 +68,3 @@ void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode(
|
||||
cmSystemTools::ConvertToOutputPath(target->GetFullPath(noConfig));
|
||||
os << path << "\n";
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateImportPropertyCode(
|
||||
std::ostream&, std::string const&, std::string const&,
|
||||
cmGeneratorTarget const*, ImportPropertyMap const&, std::string const&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateMissingTargetsCheckCode(
|
||||
std::ostream&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
|
||||
cmGeneratorTarget const* target, std::ostream& os,
|
||||
ImportPropertyMap const& properties)
|
||||
{
|
||||
std::string config;
|
||||
if (!this->Configurations.empty()) {
|
||||
config = this->Configurations[0];
|
||||
}
|
||||
cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
|
||||
target, os, properties, cmExportBuildAndroidMKGenerator::BUILD, config);
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
|
||||
cmGeneratorTarget const* target, std::ostream& os,
|
||||
ImportPropertyMap const& properties, GenerateType type,
|
||||
std::string const& config)
|
||||
{
|
||||
bool const newCMP0022Behavior =
|
||||
target->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
|
||||
target->GetPolicyStatusCMP0022() != cmPolicies::OLD;
|
||||
if (!newCMP0022Behavior) {
|
||||
std::ostringstream w;
|
||||
if (type == cmExportBuildAndroidMKGenerator::BUILD) {
|
||||
w << "export(TARGETS ... ANDROID_MK) called with policy CMP0022";
|
||||
} else {
|
||||
w << "install( EXPORT_ANDROID_MK ...) called with policy CMP0022";
|
||||
}
|
||||
w << " set to OLD for target " << target->Target->GetName() << ". "
|
||||
<< "The export will only work with CMP0022 set to NEW.";
|
||||
target->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
|
||||
}
|
||||
if (!properties.empty()) {
|
||||
os << "LOCAL_CPP_FEATURES := rtti exceptions\n";
|
||||
for (auto const& property : properties) {
|
||||
if (property.first == "INTERFACE_COMPILE_OPTIONS") {
|
||||
os << "LOCAL_CPP_FEATURES += ";
|
||||
os << (property.second) << "\n";
|
||||
} else if (property.first == "INTERFACE_LINK_LIBRARIES") {
|
||||
std::string staticLibs;
|
||||
std::string sharedLibs;
|
||||
std::string ldlibs;
|
||||
cmLinkInterfaceLibraries const* linkIFace =
|
||||
target->GetLinkInterfaceLibraries(config, target,
|
||||
cmGeneratorTarget::UseTo::Link);
|
||||
for (cmLinkItem const& item : linkIFace->Libraries) {
|
||||
cmGeneratorTarget const* gt = item.Target;
|
||||
std::string const& lib = item.AsStr();
|
||||
if (gt) {
|
||||
|
||||
if (gt->GetType() == cmStateEnums::SHARED_LIBRARY ||
|
||||
gt->GetType() == cmStateEnums::MODULE_LIBRARY) {
|
||||
sharedLibs += " " + lib;
|
||||
} else {
|
||||
staticLibs += " " + lib;
|
||||
}
|
||||
} else {
|
||||
bool relpath = false;
|
||||
if (type == cmExportBuildAndroidMKGenerator::INSTALL) {
|
||||
relpath = cmHasLiteralPrefix(lib, "../");
|
||||
}
|
||||
// check for full path or if it already has a -l, or
|
||||
// in the case of an install check for relative paths
|
||||
// if it is full or a link library then use string directly
|
||||
if (cmSystemTools::FileIsFullPath(lib) ||
|
||||
cmHasLiteralPrefix(lib, "-l") || relpath) {
|
||||
ldlibs += " " + lib;
|
||||
// if it is not a path and does not have a -l then add -l
|
||||
} else if (!lib.empty()) {
|
||||
ldlibs += " -l" + lib;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!sharedLibs.empty()) {
|
||||
os << "LOCAL_SHARED_LIBRARIES :=" << sharedLibs << "\n";
|
||||
}
|
||||
if (!staticLibs.empty()) {
|
||||
os << "LOCAL_STATIC_LIBRARIES :=" << staticLibs << "\n";
|
||||
}
|
||||
if (!ldlibs.empty()) {
|
||||
os << "LOCAL_EXPORT_LDLIBS :=" << ldlibs << "\n";
|
||||
}
|
||||
} else if (property.first == "INTERFACE_INCLUDE_DIRECTORIES") {
|
||||
std::string includes = property.second;
|
||||
cmList includeList{ includes };
|
||||
os << "LOCAL_EXPORT_C_INCLUDES := ";
|
||||
std::string end;
|
||||
for (std::string const& i : includeList) {
|
||||
os << end << i;
|
||||
end = "\\\n";
|
||||
}
|
||||
os << "\n";
|
||||
} else if (property.first == "INTERFACE_LINK_OPTIONS") {
|
||||
os << "LOCAL_EXPORT_LDFLAGS := ";
|
||||
cmList linkFlagsList{ property.second };
|
||||
os << linkFlagsList.join(" ") << "\n";
|
||||
} else {
|
||||
os << "# " << property.first << " " << (property.second) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tell the NDK build system if prebuilt static libraries use C++.
|
||||
if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
|
||||
cmLinkImplementation const* li =
|
||||
target->GetLinkImplementation(config, cmGeneratorTarget::UseTo::Link);
|
||||
if (cm::contains(li->Languages, "CXX")) {
|
||||
os << "LOCAL_HAS_CPP := true\n";
|
||||
}
|
||||
}
|
||||
|
||||
switch (target->GetType()) {
|
||||
case cmStateEnums::SHARED_LIBRARY:
|
||||
case cmStateEnums::MODULE_LIBRARY:
|
||||
os << "include $(PREBUILT_SHARED_LIBRARY)\n";
|
||||
break;
|
||||
case cmStateEnums::STATIC_LIBRARY:
|
||||
os << "include $(PREBUILT_STATIC_LIBRARY)\n";
|
||||
break;
|
||||
case cmStateEnums::EXECUTABLE:
|
||||
case cmStateEnums::UTILITY:
|
||||
case cmStateEnums::OBJECT_LIBRARY:
|
||||
case cmStateEnums::GLOBAL_TARGET:
|
||||
case cmStateEnums::INTERFACE_LIBRARY:
|
||||
case cmStateEnums::UNKNOWN_LIBRARY:
|
||||
break;
|
||||
}
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user