cmake/Source/cmExportTryCompileFileGenerator.cxx

168 lines
5.4 KiB
C++
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
2013-03-16 19:13:01 +02:00
#include "cmExportTryCompileFileGenerator.h"
2020-02-01 23:06:01 +01:00
#include <map>
#include <utility>
2021-09-14 00:13:48 +02:00
#include <cm/memory>
2022-03-29 21:10:50 +02:00
#include "cmFileSet.h"
2016-10-30 18:24:19 +01:00
#include "cmGeneratorExpression.h"
2016-07-09 11:21:54 +02:00
#include "cmGeneratorExpressionDAGChecker.h"
2016-10-30 18:24:19 +01:00
#include "cmGeneratorTarget.h"
2015-11-17 17:22:37 +01:00
#include "cmGlobalGenerator.h"
2023-07-02 19:51:09 +02:00
#include "cmList.h"
2022-03-29 21:10:50 +02:00
#include "cmListFileCache.h"
2016-03-13 13:35:51 +01:00
#include "cmLocalGenerator.h"
2016-10-30 18:24:19 +01:00
#include "cmMakefile.h"
2022-03-29 21:10:50 +02:00
#include "cmOutputConverter.h"
2017-04-14 19:02:05 +02:00
#include "cmStateTypes.h"
2020-02-01 23:06:01 +01:00
#include "cmStringAlgorithms.h"
2016-10-30 18:24:19 +01:00
#include "cmTarget.h"
2021-11-20 13:41:27 +01:00
#include "cmValue.h"
2016-10-30 18:24:19 +01:00
2022-03-29 21:10:50 +02:00
class cmTargetExport;
2015-11-17 17:22:37 +01:00
cmExportTryCompileFileGenerator::cmExportTryCompileFileGenerator(
2016-07-09 11:21:54 +02:00
cmGlobalGenerator* gg, const std::vector<std::string>& targets,
2018-04-23 21:13:27 +02:00
cmMakefile* mf, std::set<std::string> const& langs)
: Languages(langs.begin(), langs.end())
2015-11-17 17:22:37 +01:00
{
2016-03-13 13:35:51 +01:00
gg->CreateImportedGenerationObjects(mf, targets, this->Exports);
2015-11-17 17:22:37 +01:00
}
2013-03-16 19:13:01 +02:00
bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
{
2016-03-13 13:35:51 +01:00
std::set<cmGeneratorTarget const*> emitted;
std::set<cmGeneratorTarget const*> emittedDeps;
2016-07-09 11:21:54 +02:00
while (!this->Exports.empty()) {
2016-03-13 13:35:51 +01:00
cmGeneratorTarget const* te = this->Exports.back();
2013-03-16 19:13:01 +02:00
this->Exports.pop_back();
2016-07-09 11:21:54 +02:00
if (emitted.insert(te).second) {
2013-03-16 19:13:01 +02:00
emittedDeps.insert(te);
2018-08-09 18:06:22 +02:00
this->GenerateImportTargetCode(os, te, te->GetType());
2013-03-16 19:13:01 +02:00
ImportPropertyMap properties;
2018-04-23 21:13:27 +02:00
for (std::string const& lang : this->Languages) {
2016-07-09 11:21:54 +02:00
#define FIND_TARGETS(PROPERTY) \
2018-04-23 21:13:27 +02:00
this->FindTargets("INTERFACE_" #PROPERTY, te, lang, emittedDeps);
2013-11-03 12:27:13 +02:00
2018-04-23 21:13:27 +02:00
CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(FIND_TARGETS)
2013-03-16 19:13:01 +02:00
2014-08-03 19:52:23 +02:00
#undef FIND_TARGETS
2018-04-23 21:13:27 +02:00
}
2014-08-03 19:52:23 +02:00
2013-03-16 19:13:01 +02:00
this->PopulateProperties(te, properties, emittedDeps);
this->GenerateInterfaceProperties(te, os, properties);
}
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
return true;
}
2015-04-27 22:25:09 +02:00
std::string cmExportTryCompileFileGenerator::FindTargets(
2016-07-09 11:21:54 +02:00
const std::string& propName, cmGeneratorTarget const* tgt,
2018-04-23 21:13:27 +02:00
std::string const& language, std::set<cmGeneratorTarget const*>& emitted)
2013-03-16 19:13:01 +02:00
{
2021-11-20 13:41:27 +01:00
cmValue prop = tgt->GetProperty(propName);
2016-07-09 11:21:54 +02:00
if (!prop) {
2013-03-16 19:13:01 +02:00
return std::string();
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
2023-05-23 16:38:00 +02:00
cmGeneratorExpression ge(*tgt->Makefile->GetCMakeInstance());
2013-03-16 19:13:01 +02:00
2021-09-14 00:13:48 +02:00
std::unique_ptr<cmGeneratorExpressionDAGChecker> parentDagChecker;
if (propName == "INTERFACE_LINK_OPTIONS") {
// To please constraint checks of DAGChecker, this property must have
// LINK_OPTIONS property as parent
parentDagChecker = cm::make_unique<cmGeneratorExpressionDAGChecker>(
tgt, "LINK_OPTIONS", nullptr, nullptr);
}
cmGeneratorExpressionDAGChecker dagChecker(tgt, propName, nullptr,
parentDagChecker.get());
2013-03-16 19:13:01 +02:00
2020-08-30 11:54:41 +02:00
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*prop);
2013-03-16 19:13:01 +02:00
2017-04-14 19:02:05 +02:00
cmTarget dummyHead("try_compile_dummy_exe", cmStateEnums::EXECUTABLE,
2023-07-02 19:51:09 +02:00
cmTarget::Visibility::Normal, tgt->Target->GetMakefile(),
2020-08-30 11:54:41 +02:00
cmTarget::PerConfig::Yes);
2013-03-16 19:13:01 +02:00
2016-03-13 13:35:51 +01:00
cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
2013-03-16 19:13:01 +02:00
2020-02-01 23:06:01 +01:00
std::string result = cge->Evaluate(tgt->GetLocalGenerator(), this->Config,
&gDummyHead, &dagChecker, tgt, language);
2016-07-09 11:21:54 +02:00
const std::set<cmGeneratorTarget const*>& allTargets =
cge->GetAllTargetsSeen();
2018-01-26 17:06:56 +01:00
for (cmGeneratorTarget const* target : allTargets) {
if (emitted.insert(target).second) {
this->Exports.push_back(target);
2013-03-16 19:13:01 +02:00
}
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
return result;
}
2016-07-09 11:21:54 +02:00
void cmExportTryCompileFileGenerator::PopulateProperties(
const cmGeneratorTarget* target, ImportPropertyMap& properties,
std::set<cmGeneratorTarget const*>& emitted)
2013-03-16 19:13:01 +02:00
{
2022-03-29 21:10:50 +02:00
// Look through all non-special properties.
2016-03-13 13:35:51 +01:00
std::vector<std::string> props = target->GetPropertyKeys();
2022-03-29 21:10:50 +02:00
// Include special properties that might be relevant here.
props.emplace_back("INTERFACE_LINK_LIBRARIES");
2022-08-04 22:12:04 +02:00
props.emplace_back("INTERFACE_LINK_LIBRARIES_DIRECT");
props.emplace_back("INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE");
2018-01-26 17:06:56 +01:00
for (std::string const& p : props) {
2022-03-29 21:10:50 +02:00
cmValue v = target->GetProperty(p);
if (!v) {
continue;
}
properties[p] = *v;
2016-03-13 13:35:51 +01:00
2020-08-30 11:54:41 +02:00
if (cmHasLiteralPrefix(p, "IMPORTED_LINK_INTERFACE_LIBRARIES") ||
cmHasLiteralPrefix(p, "IMPORTED_LINK_DEPENDENT_LIBRARIES") ||
cmHasLiteralPrefix(p, "INTERFACE_LINK_LIBRARIES")) {
2018-04-23 21:13:27 +02:00
std::string evalResult =
this->FindTargets(p, target, std::string(), emitted);
2013-03-16 19:13:01 +02:00
2023-07-02 19:51:09 +02:00
cmList depends{ evalResult };
2018-01-26 17:06:56 +01:00
for (std::string const& li : depends) {
2016-07-09 11:21:54 +02:00
cmGeneratorTarget* tgt =
2018-01-26 17:06:56 +01:00
target->GetLocalGenerator()->FindGeneratorTargetToUse(li);
2016-07-09 11:21:54 +02:00
if (tgt && emitted.insert(tgt).second) {
2013-03-16 19:13:01 +02:00
this->Exports.push_back(tgt);
}
}
}
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
}
2015-11-17 17:22:37 +01:00
2016-07-09 11:21:54 +02:00
std::string cmExportTryCompileFileGenerator::InstallNameDir(
2021-11-20 13:41:27 +01:00
cmGeneratorTarget const* target, const std::string& config)
2013-11-03 12:27:13 +02:00
{
std::string install_name_dir;
2015-11-17 17:22:37 +01:00
cmMakefile* mf = target->Target->GetMakefile();
2016-07-09 11:21:54 +02:00
if (mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
install_name_dir = target->GetInstallNameDirForBuildTree(config);
}
2013-11-03 12:27:13 +02:00
return install_name_dir;
}
2022-03-29 21:10:50 +02:00
std::string cmExportTryCompileFileGenerator::GetFileSetDirectories(
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/)
{
return cmOutputConverter::EscapeForCMake(
cmJoin(fileSet->GetDirectoryEntries(), ";"));
}
std::string cmExportTryCompileFileGenerator::GetFileSetFiles(
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/)
{
return cmOutputConverter::EscapeForCMake(
cmJoin(fileSet->GetFileEntries(), ";"));
}