1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #include "cmExportBuildFileGenerator.h"
14 #include "cmExportCommand.h"
16 //----------------------------------------------------------------------------
17 cmExportBuildFileGenerator::cmExportBuildFileGenerator()
19 this->ExportCommand = 0;
22 //----------------------------------------------------------------------------
23 bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
25 std::vector<cmTarget*> allTargets;
27 std::string expectedTargets;
29 for(std::vector<cmTarget*>::const_iterator
30 tei = this->Exports->begin();
31 tei != this->Exports->end(); ++tei)
33 expectedTargets += sep + this->Namespace + (*tei)->GetExportName();
36 if(this->ExportedTargets.insert(te).second)
38 allTargets.push_back(te);
42 if(this->ExportCommand && this->ExportCommand->ErrorMessage.empty())
45 e << "given target \"" << te->GetName() << "\" more than once.";
46 this->ExportCommand->ErrorMessage = e.str();
52 this->GenerateExpectedTargetsCode(os, expectedTargets);
55 std::vector<std::string> missingTargets;
57 // Create all the imported targets.
58 for(std::vector<cmTarget*>::const_iterator
59 tei = allTargets.begin();
60 tei != allTargets.end(); ++tei)
63 this->GenerateImportTargetCode(os, te);
65 te->AppendBuildInterfaceIncludes();
67 ImportPropertyMap properties;
69 this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,
70 cmGeneratorExpression::BuildInterface,
71 properties, missingTargets);
72 this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te,
73 cmGeneratorExpression::BuildInterface,
74 properties, missingTargets);
75 this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", te,
76 cmGeneratorExpression::BuildInterface,
77 properties, missingTargets);
78 this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
80 const bool newCMP0022Behavior =
81 te->GetPolicyStatusCMP0022() != cmPolicies::WARN
82 && te->GetPolicyStatusCMP0022() != cmPolicies::OLD;
83 if (newCMP0022Behavior)
85 this->PopulateInterfaceLinkLibrariesProperty(te,
86 cmGeneratorExpression::BuildInterface,
87 properties, missingTargets);
89 this->PopulateCompatibleInterfaceProperties(te, properties);
91 this->GenerateInterfaceProperties(te, os, properties);
94 // Generate import file content for each configuration.
95 for(std::vector<std::string>::const_iterator
96 ci = this->Configurations.begin();
97 ci != this->Configurations.end(); ++ci)
99 this->GenerateImportConfig(os, ci->c_str(), missingTargets);
102 this->GenerateMissingTargetsCheckCode(os, missingTargets);
107 //----------------------------------------------------------------------------
109 cmExportBuildFileGenerator
110 ::GenerateImportTargetsConfig(std::ostream& os,
111 const char* config, std::string const& suffix,
112 std::vector<std::string> &missingTargets)
114 for(std::vector<cmTarget*>::const_iterator
115 tei = this->Exports->begin();
116 tei != this->Exports->end(); ++tei)
118 // Collect import properties for this target.
119 cmTarget* target = *tei;
120 ImportPropertyMap properties;
121 this->SetImportLocationProperty(config, suffix, target, properties);
122 if(!properties.empty())
124 // Get the rest of the target details.
125 this->SetImportDetailProperties(config, suffix,
126 target, properties, missingTargets);
127 this->SetImportLinkInterface(config, suffix,
128 cmGeneratorExpression::BuildInterface,
129 target, properties, missingTargets);
132 // TOOD: PUBLIC_HEADER_LOCATION
133 // This should wait until the build feature propagation stuff
134 // is done. Then this can be a propagated include directory.
135 // this->GenerateImportProperty(config, te->HeaderGenerator,
138 // Generate code in the export file.
139 this->GenerateImportPropertyCode(os, config, target, properties);
144 //----------------------------------------------------------------------------
146 cmExportBuildFileGenerator
147 ::SetImportLocationProperty(const char* config, std::string const& suffix,
148 cmTarget* target, ImportPropertyMap& properties)
150 // Get the makefile in which to lookup target information.
151 cmMakefile* mf = target->GetMakefile();
153 // Add the main target file.
155 std::string prop = "IMPORTED_LOCATION";
158 if(target->IsAppBundleOnApple())
160 value = target->GetFullPath(config, false);
164 value = target->GetFullPath(config, false, true);
166 properties[prop] = value;
169 // Check whether this is a DLL platform.
171 (mf->IsOn("WIN32") || mf->IsOn("CYGWIN") || mf->IsOn("MINGW"));
173 // Add the import library for windows DLLs.
175 (target->GetType() == cmTarget::SHARED_LIBRARY ||
176 target->IsExecutableWithExports()) &&
177 mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
179 std::string prop = "IMPORTED_IMPLIB";
181 std::string value = target->GetFullPath(config, true);
182 target->GetImplibGNUtoMS(value, value,
183 "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
184 properties[prop] = value;
188 //----------------------------------------------------------------------------
190 cmExportBuildFileGenerator::HandleMissingTarget(
191 std::string& link_libs, std::vector<std::string>&,
192 cmMakefile*, cmTarget* depender, cmTarget* dependee)
194 // The target is not in the export.
195 if(!this->AppendMode)
197 // We are not appending, so all exported targets should be
198 // known here. This is probably user-error.
199 this->ComplainAboutMissingTarget(depender, dependee);
201 // Assume the target will be exported by another command.
202 // Append it with the export namespace.
203 link_libs += this->Namespace;
204 link_libs += dependee->GetExportName();
207 //----------------------------------------------------------------------------
209 cmExportBuildFileGenerator
210 ::ComplainAboutMissingTarget(cmTarget* depender,
213 if(!this->ExportCommand || !this->ExportCommand->ErrorMessage.empty())
219 e << "called with target \"" << depender->GetName()
220 << "\" which requires target \"" << dependee->GetName()
221 << "\" that is not in the export list.\n"
222 << "If the required target is not easy to reference in this call, "
223 << "consider using the APPEND option with multiple separate calls.";
224 this->ExportCommand->ErrorMessage = e.str();
228 cmExportBuildFileGenerator::InstallNameDir(cmTarget* target,
229 const std::string& config)
231 std::string install_name_dir;
233 cmMakefile* mf = target->GetMakefile();
234 if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
237 target->GetInstallNameDirForBuildTree(config.c_str());
240 return install_name_dir;