summaryrefslogtreecommitdiffstats
path: root/Source/cmExportTryCompileFileGenerator.cxx
blob: 948508b9d8bfcedefda8a12b6966bb16f30cf02b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*============================================================================
  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"
#include "cmGeneratorExpressionDAGChecker.h"

//----------------------------------------------------------------------------
bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
{
  std::set<cmTarget*> emitted;
  std::set<cmTarget*> emittedDeps;
  while(!this->Exports.empty())
    {
    cmTarget* te = this->Exports.back();
    this->Exports.pop_back();
    if (emitted.insert(te).second)
      {
      emittedDeps.insert(te);
      this->GenerateImportTargetCode(os, te);

      ImportPropertyMap properties;

      this->FindTargets("INTERFACE_INCLUDE_DIRECTORIES", te, emittedDeps);
      this->FindTargets("INTERFACE_COMPILE_DEFINITIONS", te, emittedDeps);

      this->PopulateProperties(te, properties, emittedDeps);

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

std::string cmExportTryCompileFileGenerator::FindTargets(const char *propName,
                                                cmTarget *tgt,
                                                std::set<cmTarget*> &emitted)
{
  const char *prop = tgt->GetProperty(propName);
  if(!prop)
    {
    return std::string();
    }

  cmListFileBacktrace lfbt;
  cmGeneratorExpression ge(lfbt);

  cmGeneratorExpressionDAGChecker dagChecker(lfbt,
                                      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());

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

  const std::set<cmTarget*> &allTargets = cge->GetAllTargetsSeen();
  for(std::set<cmTarget*>::const_iterator li = allTargets.begin();
      li != allTargets.end(); ++li)
    {
    if(emitted.insert(*li).second)
      {
      this->Exports.push_back(*li);
      }
    }
  return result;
}

//----------------------------------------------------------------------------
void
cmExportTryCompileFileGenerator::PopulateProperties(cmTarget* target,
                                                ImportPropertyMap& properties,
                                                std::set<cmTarget*> &emitted)
{
  cmPropertyMap props = target->GetProperties();
  for(cmPropertyMap::const_iterator i = props.begin(); i != props.end(); ++i)
    {
    properties[i->first] = i->second.GetValue();

    if(i->first.find("IMPORTED_LINK_INTERFACE_LIBRARIES") == 0)
      {
      const std::string libs = i->second.GetValue();

      std::string evalResult = this->FindTargets(i->first.c_str(),
                                                 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)
        {
        cmTarget *tgt = target->GetMakefile()->FindTargetToUse(li->c_str());
        if(tgt && emitted.insert(tgt).second)
          {
          this->Exports.push_back(tgt);
          }
        }
      }
    }
}
std::string
cmExportTryCompileFileGenerator::InstallNameDir(cmTarget* target,
                                                const std::string& config)
{
  std::string install_name_dir;

  cmMakefile* mf = target->GetMakefile();
  if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
    {
    install_name_dir =
      target->GetInstallNameDirForBuildTree(config.c_str());
    }

  return install_name_dir;
}