cmExportTryCompileFileGenerator.cxx 4.64 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2013 Stephen Kelly <steveire@gmail.com>

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/

#include "cmExportTryCompileFileGenerator.h"

#include "cmGeneratedFileStream.h"
16
#include "cmGlobalGenerator.h"
17
18
19
#include "cmGeneratorExpressionDAGChecker.h"

//----------------------------------------------------------------------------
20
21
22
23
24
25
cmExportTryCompileFileGenerator::cmExportTryCompileFileGenerator(
    cmGlobalGenerator* gg)
{
  gg->CreateGenerationObjects(cmGlobalGenerator::ImportedOnly);
}

26
27
bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
{
28
29
  std::set<cmTarget const*> emitted;
  std::set<cmTarget const*> emittedDeps;
30
31
  while(!this->Exports.empty())
    {
32
    cmTarget const* te = this->Exports.back();
33
34
35
36
37
38
39
40
    this->Exports.pop_back();
    if (emitted.insert(te).second)
      {
      emittedDeps.insert(te);
      this->GenerateImportTargetCode(os, te);

      ImportPropertyMap properties;

41
#define FIND_TARGETS(PROPERTY) \
42
      this->FindTargets("INTERFACE_" #PROPERTY, te, emittedDeps);
43
44

      CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(FIND_TARGETS)
45

46
47
#undef FIND_TARGETS

48
49
50
51
52
53
54
55
      this->PopulateProperties(te, properties, emittedDeps);

      this->GenerateInterfaceProperties(te, os, properties);
      }
    }
  return true;
}

56
57
58
std::string cmExportTryCompileFileGenerator::FindTargets(
                                          const std::string& propName,
                                          cmTarget const* tgt,
59
                                          std::set<cmTarget const*> &emitted)
60
61
62
63
64
65
66
{
  const char *prop = tgt->GetProperty(propName);
  if(!prop)
    {
    return std::string();
    }

67
  cmGeneratorExpression ge;
68

69
  cmGeneratorExpressionDAGChecker dagChecker(
70
71
72
73
74
75
76
77
78
                                      tgt->GetName(),
                                      propName, 0, 0);

  cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);

  cmTarget dummyHead;
  dummyHead.SetType(cmTarget::EXECUTABLE, "try_compile_dummy_exe");
  dummyHead.SetMakefile(tgt->GetMakefile());

79
80
81
82
83
84
  cmGeneratorTarget* gtgt =
      tgt->GetMakefile()->GetGlobalGenerator()->GetGeneratorTarget(tgt);

  std::string result = cge->Evaluate(gtgt->Target->GetMakefile(), this->Config,
                                     false, &dummyHead,
                                     gtgt->Target, &dagChecker);
85

86
87
  const std::set<cmTarget const*> &allTargets = cge->GetAllTargetsSeen();
  for(std::set<cmTarget const*>::const_iterator li = allTargets.begin();
88
89
90
91
92
93
94
95
96
97
98
99
      li != allTargets.end(); ++li)
    {
    if(emitted.insert(*li).second)
      {
      this->Exports.push_back(*li);
      }
    }
  return result;
}

//----------------------------------------------------------------------------
void
100
cmExportTryCompileFileGenerator::PopulateProperties(cmTarget const* target,
101
                                                ImportPropertyMap& properties,
102
                                          std::set<cmTarget const*> &emitted)
103
104
105
106
107
108
{
  cmPropertyMap props = target->GetProperties();
  for(cmPropertyMap::const_iterator i = props.begin(); i != props.end(); ++i)
    {
    properties[i->first] = i->second.GetValue();

109
    if(i->first.find("IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
110
111
        || i->first.find("IMPORTED_LINK_DEPENDENT_LIBRARIES") == 0
        || i->first.find("INTERFACE_LINK_LIBRARIES") == 0)
112
      {
Stephen Kelly's avatar
Stephen Kelly committed
113
      std::string evalResult = this->FindTargets(i->first,
114
115
116
117
118
119
120
                                                 target, emitted);

      std::vector<std::string> depends;
      cmSystemTools::ExpandListArgument(evalResult, depends);
      for(std::vector<std::string>::const_iterator li = depends.begin();
          li != depends.end(); ++li)
        {
121
        cmTarget *tgt = target->GetMakefile()->FindTargetToUse(*li);
122
123
124
125
126
127
128
129
        if(tgt && emitted.insert(tgt).second)
          {
          this->Exports.push_back(tgt);
          }
        }
      }
    }
}
130

131
std::string
132
cmExportTryCompileFileGenerator::InstallNameDir(cmGeneratorTarget* target,
133
134
135
136
                                                const std::string& config)
{
  std::string install_name_dir;

137
  cmMakefile* mf = target->Target->GetMakefile();
138
139
140
  if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
    {
    install_name_dir =
Stephen Kelly's avatar
Stephen Kelly committed
141
      target->GetInstallNameDirForBuildTree(config);
142
143
144
145
    }

  return install_name_dir;
}