1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmGlobalGenerator.cxx,v $
6 Date: $Date: 2009-03-09 16:19:27 $
7 Version: $Revision: 1.253 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #if defined(_WIN32) && !defined(__CYGWIN__)
18 #include "windows.h" // this must be first to define GetCurrentDirectory
21 #include "cmGlobalGenerator.h"
22 #include "cmLocalGenerator.h"
23 #include "cmExternalMakefileProjectGenerator.h"
25 #include "cmMakefile.h"
26 #include "cmSourceFile.h"
27 #include "cmVersion.h"
28 #include "cmExportInstallFileGenerator.h"
29 #include "cmComputeTargetDepends.h"
30 #include "cmGeneratedFileStream.h"
32 #include <cmsys/Directory.hxx>
34 #if defined(CMAKE_BUILD_WITH_CMAKE)
35 # include <cmsys/MD5.h>
38 #include <stdlib.h> // required for atof
42 cmGlobalGenerator::cmGlobalGenerator()
44 // By default the .SYMBOLIC dependency is not needed on symbolic rules.
45 this->NeedSymbolicMark
= false;
47 // by default use the native paths
48 this->ForceUnixPaths
= false;
50 // By default do not try to support color.
51 this->ToolSupportsColor
= false;
53 // By default do not use link scripts.
54 this->UseLinkScript
= false;
56 // Whether an install target is needed.
57 this->InstallTargetEnabled
= false;
59 // how long to let try compiles run
60 this->TryCompileTimeout
= 0;
62 this->ExtraGenerator
= 0;
63 this->CurrentLocalGenerator
= 0;
66 cmGlobalGenerator::~cmGlobalGenerator()
68 // Delete any existing cmLocalGenerators
69 for (unsigned int i
= 0; i
< this->LocalGenerators
.size(); ++i
)
71 delete this->LocalGenerators
[i
];
73 this->LocalGenerators
.clear();
75 if (this->ExtraGenerator
)
77 delete this->ExtraGenerator
;
80 this->ClearExportSets();
83 // Find the make program for the generator, required for try compiles
84 void cmGlobalGenerator::FindMakeProgram(cmMakefile
* mf
)
86 if(this->FindMakeProgramFile
.size() == 0)
89 "Generator implementation error, "
90 "all generators must specify this->FindMakeProgramFile");
92 if(!mf
->GetDefinition("CMAKE_MAKE_PROGRAM")
93 || cmSystemTools::IsOff(mf
->GetDefinition("CMAKE_MAKE_PROGRAM")))
95 std::string setMakeProgram
=
96 mf
->GetModulesFile(this->FindMakeProgramFile
.c_str());
97 if(setMakeProgram
.size())
99 mf
->ReadListFile(0, setMakeProgram
.c_str());
102 if(!mf
->GetDefinition("CMAKE_MAKE_PROGRAM")
103 || cmSystemTools::IsOff(mf
->GetDefinition("CMAKE_MAKE_PROGRAM")))
106 err
<< "CMake was unable to find a build program corresponding to \""
107 << this->GetName() << "\". CMAKE_MAKE_PROGRAM is not set. You "
108 << "probably need to select a different build tool.";
109 cmSystemTools::Error(err
.str().c_str());
110 cmSystemTools::SetFatalErrorOccured();
113 std::string makeProgram
= mf
->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
114 // if there are spaces in the make program use short path
115 // but do not short path the actual program name, as
116 // this can cause trouble with VSExpress
117 if(makeProgram
.find(' ') != makeProgram
.npos
)
121 cmSystemTools::SplitProgramPath(makeProgram
.c_str(),
123 std::string saveFile
= file
;
124 cmSystemTools::GetShortPath(makeProgram
.c_str(), makeProgram
);
125 cmSystemTools::SplitProgramPath(makeProgram
.c_str(),
129 makeProgram
+= saveFile
;
130 mf
->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram
.c_str(),
132 cmCacheManager::FILEPATH
);
135 if(makeProgram
.find("xcodebuild") != makeProgram
.npos
)
137 // due to the text file busy /bin/sh problem with xcodebuild
138 // use the cmakexbuild wrapper instead. This program
139 // will run xcodebuild and if it sees the error text file busy
140 // it will stop forwarding output, and let the build finish.
141 // Then it will retry the build. It will continue this
142 // untill no text file busy errors occur.
143 std::string cmakexbuild
=
144 this->CMakeInstance
->GetCacheManager()->GetCacheValue("CMAKE_COMMAND");
145 cmakexbuild
= cmakexbuild
.substr(0, cmakexbuild
.length()-5);
146 cmakexbuild
+= "cmakexbuild";
148 mf
->AddCacheDefinition("CMAKE_MAKE_PROGRAM",
151 cmCacheManager::FILEPATH
);
155 // enable the given language
157 // The following files are loaded in this order:
159 // First figure out what OS we are running on:
161 // CMakeSystem.cmake - configured file created by CMakeDetermineSystem.cmake
162 // CMakeDetermineSystem.cmake - figure out os info and create
163 // CMakeSystem.cmake IF CMAKE_SYSTEM
165 // CMakeSystem.cmake - configured file created by
166 // CMakeDetermineSystem.cmake IF CMAKE_SYSTEM_LOADED
168 // Next try and enable all languages found in the languages vector
170 // FOREACH LANG in languages
171 // CMake(LANG)Compiler.cmake - configured file create by
172 // CMakeDetermine(LANG)Compiler.cmake
173 // CMakeDetermine(LANG)Compiler.cmake - Finds compiler for LANG and
174 // creates CMake(LANG)Compiler.cmake
175 // CMake(LANG)Compiler.cmake - configured file created by
176 // CMakeDetermine(LANG)Compiler.cmake
178 // CMakeSystemSpecificInformation.cmake
179 // - includes Platform/${CMAKE_SYSTEM_NAME}.cmake
180 // may use compiler stuff
182 // FOREACH LANG in languages
183 // CMake(LANG)Information.cmake
184 // - loads Platform/${CMAKE_SYSTEM_NAME}-${COMPILER}.cmake
185 // CMakeTest(LANG)Compiler.cmake
186 // - Make sure the compiler works with a try compile if
187 // CMakeDetermine(LANG) was loaded
189 // Now load a few files that can override values set in any of the above
190 // (PROJECTNAME)Compatibility.cmake
191 // - load any backwards compatibility stuff for current project
192 // ${CMAKE_USER_MAKE_RULES_OVERRIDE}
193 // - allow users a chance to override system variables
198 cmGlobalGenerator::EnableLanguage(std::vector
<std::string
>const& languages
,
199 cmMakefile
*mf
, bool)
201 if(languages
.size() == 0)
203 cmSystemTools::Error("EnableLanguage must have a lang specified!");
204 cmSystemTools::SetFatalErrorOccured();
207 mf
->AddDefinition("RUN_CONFIGURE", true);
208 std::string rootBin
= mf
->GetHomeOutputDirectory();
209 rootBin
+= cmake::GetCMakeFilesDirectory();
211 // If the configuration files path has been set,
212 // then we are in a try compile and need to copy the enable language
213 // files from the parent cmake bin dir, into the try compile bin dir
214 if(this->ConfiguredFilesPath
.size())
216 for(std::vector
<std::string
>::const_iterator l
= languages
.begin();
217 l
!= languages
.end(); ++l
)
221 this->SetLanguageEnabled("NONE", mf
);
225 rootBin
= this->ConfiguredFilesPath
;
228 // set the dir for parent files so they can be used by modules
229 mf
->AddDefinition("CMAKE_PLATFORM_ROOT_BIN",rootBin
.c_str());
231 // find and make sure CMAKE_MAKE_PROGRAM is defined
232 this->FindMakeProgram(mf
);
234 // try and load the CMakeSystem.cmake if it is there
235 std::string fpath
= rootBin
;
236 if(!mf
->GetDefinition("CMAKE_SYSTEM_LOADED"))
238 fpath
+= "/CMakeSystem.cmake";
239 if(cmSystemTools::FileExists(fpath
.c_str()))
241 mf
->ReadListFile(0,fpath
.c_str());
244 // Load the CMakeDetermineSystem.cmake file and find out
245 // what platform we are running on
246 if (!mf
->GetDefinition("CMAKE_SYSTEM"))
248 #if defined(_WIN32) && !defined(__CYGWIN__)
249 /* Windows version number data. */
251 ZeroMemory(&osvi
, sizeof(osvi
));
252 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
253 GetVersionEx (&osvi
);
254 cmOStringStream windowsVersionString
;
255 windowsVersionString
<< osvi
.dwMajorVersion
<< "." << osvi
.dwMinorVersion
;
256 windowsVersionString
.str();
257 mf
->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
258 windowsVersionString
.str().c_str());
260 // Read the DetermineSystem file
261 std::string systemFile
= mf
->GetModulesFile("CMakeDetermineSystem.cmake");
262 mf
->ReadListFile(0, systemFile
.c_str());
263 // load the CMakeSystem.cmake from the binary directory
264 // this file is configured by the CMakeDetermineSystem.cmake file
266 fpath
+= "/CMakeSystem.cmake";
267 mf
->ReadListFile(0,fpath
.c_str());
269 std::map
<cmStdString
, bool> needTestLanguage
;
270 std::map
<cmStdString
, bool> needSetLanguageEnabledMaps
;
272 // load the CMakeDetermine(LANG)Compiler.cmake file to find
275 for(std::vector
<std::string
>::const_iterator l
= languages
.begin();
276 l
!= languages
.end(); ++l
)
278 const char* lang
= l
->c_str();
279 needSetLanguageEnabledMaps
[lang
] = false;
282 this->SetLanguageEnabled("NONE", mf
);
285 std::string loadedLang
= "CMAKE_";
287 loadedLang
+= "_COMPILER_LOADED";
288 // If the existing build tree was already configured with this
289 // version of CMake then try to load the configured file first
290 // to avoid duplicate compiler tests.
291 unsigned int cacheMajor
= mf
->GetCacheMajorVersion();
292 unsigned int cacheMinor
= mf
->GetCacheMinorVersion();
293 unsigned int selfMajor
= cmVersion::GetMajorVersion();
294 unsigned int selfMinor
= cmVersion::GetMinorVersion();
295 if((this->CMakeInstance
->GetIsInTryCompile() ||
296 (selfMajor
== cacheMajor
&& selfMinor
== cacheMinor
))
297 && !mf
->GetDefinition(loadedLang
.c_str()))
302 fpath
+= "Compiler.cmake";
303 if(cmSystemTools::FileExists(fpath
.c_str()))
305 if(!mf
->ReadListFile(0,fpath
.c_str()))
307 cmSystemTools::Error("Could not find cmake module file:",
310 // if this file was found then the language was already determined
312 needTestLanguage
[lang
] = false;
313 this->SetLanguageEnabledFlag(lang
, mf
);
314 needSetLanguageEnabledMaps
[lang
] = true;
315 // this can only be called after loading CMake(LANG)Compiler.cmake
319 if(!this->GetLanguageEnabled(lang
) )
321 if (this->CMakeInstance
->GetIsInTryCompile())
323 cmSystemTools::Error("This should not have happen. "
324 "If you see this message, you are probably "
325 "using a broken CMakeLists.txt file or a "
326 "problematic release of CMake");
328 // if the CMake(LANG)Compiler.cmake file was not found then
329 // load CMakeDetermine(LANG)Compiler.cmake
330 std::string determineCompiler
= "CMakeDetermine";
331 determineCompiler
+= lang
;
332 determineCompiler
+= "Compiler.cmake";
333 std::string determineFile
=
334 mf
->GetModulesFile(determineCompiler
.c_str());
335 if(!mf
->ReadListFile(0,determineFile
.c_str()))
337 cmSystemTools::Error("Could not find cmake module file:",
338 determineFile
.c_str());
340 needTestLanguage
[lang
] = true;
341 // Some generators like visual studio should not use the env variables
342 // So the global generator can specify that in this variable
343 if(!mf
->GetDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV"))
345 // put ${CMake_(LANG)_COMPILER_ENV_VAR}=${CMAKE_(LANG)_COMPILER
346 // into the environment, in case user scripts want to run
347 // configure, or sub cmakes
348 std::string compilerName
= "CMAKE_";
349 compilerName
+= lang
;
350 compilerName
+= "_COMPILER";
351 std::string compilerEnv
= "CMAKE_";
353 compilerEnv
+= "_COMPILER_ENV_VAR";
354 std::string envVar
= mf
->GetRequiredDefinition(compilerEnv
.c_str());
355 std::string envVarValue
=
356 mf
->GetRequiredDefinition(compilerName
.c_str());
357 std::string env
= envVar
;
360 cmSystemTools::PutEnv(env
.c_str());
363 // if determineLanguage was called then load the file it
364 // configures CMake(LANG)Compiler.cmake
368 fpath
+= "Compiler.cmake";
369 if(!mf
->ReadListFile(0,fpath
.c_str()))
371 cmSystemTools::Error("Could not find cmake module file:",
374 this->SetLanguageEnabledFlag(lang
, mf
);
375 needSetLanguageEnabledMaps
[lang
] = true;
376 // this can only be called after loading CMake(LANG)Compiler.cmake
377 // the language must be enabled for try compile to work, but we do
378 // not know if it is a working compiler yet so set the test language
380 needTestLanguage
[lang
] = true;
381 } // end if(!this->GetLanguageEnabled(lang) )
382 } // end loop over languages
384 // **** Load the system specific information if not yet loaded
385 if (!mf
->GetDefinition("CMAKE_SYSTEM_SPECIFIC_INFORMATION_LOADED"))
387 fpath
= mf
->GetModulesFile("CMakeSystemSpecificInformation.cmake");
388 if(!mf
->ReadListFile(0,fpath
.c_str()))
390 cmSystemTools::Error("Could not find cmake module file:",
394 // loop over languages again loading CMake(LANG)Information.cmake
396 for(std::vector
<std::string
>::const_iterator l
= languages
.begin();
397 l
!= languages
.end(); ++l
)
399 const char* lang
= l
->c_str();
402 this->SetLanguageEnabled("NONE", mf
);
405 std::string langLoadedVar
= "CMAKE_";
406 langLoadedVar
+= lang
;
407 langLoadedVar
+= "_INFORMATION_LOADED";
408 if (!mf
->GetDefinition(langLoadedVar
.c_str()))
412 fpath
+= "Information.cmake";
413 std::string informationFile
= mf
->GetModulesFile(fpath
.c_str());
414 if (informationFile
.empty())
416 cmSystemTools::Error("Could not find cmake module file:",
419 else if(!mf
->ReadListFile(0, informationFile
.c_str()))
421 cmSystemTools::Error("Could not process cmake module file:",
422 informationFile
.c_str());
425 if (needSetLanguageEnabledMaps
[lang
])
427 this->SetLanguageEnabledMaps(lang
, mf
);
430 std::string compilerName
= "CMAKE_";
431 compilerName
+= lang
;
432 compilerName
+= "_COMPILER";
433 std::string compilerLangFile
= rootBin
;
434 compilerLangFile
+= "/CMake";
435 compilerLangFile
+= lang
;
436 compilerLangFile
+= "Compiler.cmake";
437 // Test the compiler for the language just setup
438 // (but only if a compiler has been actually found)
439 // At this point we should have enough info for a try compile
440 // which is used in the backward stuff
441 // If the language is untested then test it now with a try compile.
442 if (!mf
->IsSet(compilerName
.c_str()))
444 // if the compiler did not work, then remove the
445 // CMake(LANG)Compiler.cmake file so that it will get tested the
446 // next time cmake is run
447 cmSystemTools::RemoveFile(compilerLangFile
.c_str());
449 else if(needTestLanguage
[lang
])
451 if (!this->CMakeInstance
->GetIsInTryCompile())
453 std::string testLang
= "CMakeTest";
455 testLang
+= "Compiler.cmake";
456 std::string ifpath
= mf
->GetModulesFile(testLang
.c_str());
457 if(!mf
->ReadListFile(0,ifpath
.c_str()))
459 cmSystemTools::Error("Could not find cmake module file:",
462 std::string compilerWorks
= "CMAKE_";
463 compilerWorks
+= lang
;
464 compilerWorks
+= "_COMPILER_WORKS";
465 // if the compiler did not work, then remove the
466 // CMake(LANG)Compiler.cmake file so that it will get tested the
467 // next time cmake is run
468 if(!mf
->IsOn(compilerWorks
.c_str()))
470 cmSystemTools::RemoveFile(compilerLangFile
.c_str());
474 // load backwards compatibility stuff for C and CXX
475 // for old versions of CMake ListFiles C and CXX had some
476 // backwards compatibility files they have to load
477 // These files have a bunch of try compiles in them so
478 // should only be done
479 if (mf
->NeedBackwardsCompatibility(1,4))
481 if(strcmp(lang
, "C") == 0)
484 mf
->GetModulesFile("CMakeBackwardCompatibilityC.cmake");
485 mf
->ReadListFile(0,ifpath
.c_str());
487 if(strcmp(lang
, "CXX") == 0)
490 mf
->GetModulesFile("CMakeBackwardCompatibilityCXX.cmake");
491 mf
->ReadListFile(0,ifpath
.c_str());
495 } // end if in try compile
496 } // end need test language
497 } // end for each language
499 // Now load files that can override any settings on the platform or for
500 // the project First load the project compatibility file if it is in
502 std::string projectCompatibility
= mf
->GetDefinition("CMAKE_ROOT");
503 projectCompatibility
+= "/Modules/";
504 projectCompatibility
+= mf
->GetSafeDefinition("PROJECT_NAME");
505 projectCompatibility
+= "Compatibility.cmake";
506 if(cmSystemTools::FileExists(projectCompatibility
.c_str()))
508 mf
->ReadListFile(0,projectCompatibility
.c_str());
512 //----------------------------------------------------------------------------
514 cmGlobalGenerator::GetLanguageOutputExtension(cmSourceFile
const& source
)
516 if(const char* lang
= source
.GetLanguage())
518 if(this->LanguageToOutputExtension
.count(lang
) > 0)
520 return this->LanguageToOutputExtension
[lang
].c_str();
525 // if no language is found then check to see if it is already an
526 // ouput extension for some language. In that case it should be ignored
527 // and in this map, so it will not be compiled but will just be used.
528 std::string
const& ext
= source
.GetExtension();
531 if(this->OutputExtensions
.count(ext
))
541 const char* cmGlobalGenerator::GetLanguageFromExtension(const char* ext
)
543 // if there is an extension and it starts with . then move past the
544 // . because the extensions are not stored with a . in the map
545 if(ext
&& *ext
== '.')
549 if(this->ExtensionToLanguage
.count(ext
) > 0)
551 return this->ExtensionToLanguage
[ext
].c_str();
556 /* SetLanguageEnabled() is now split in two parts:
557 at first the enabled-flag is set. This can then be used in EnabledLanguage()
558 for checking whether the language is already enabled. After setting this
559 flag still the values from the cmake variables have to be copied into the
560 internal maps, this is done in SetLanguageEnabledMaps() which is called
561 after the system- and compiler specific files have been loaded.
563 This split was done originally so that compiler-specific configuration
564 files could change the object file extension
565 (CMAKE_<LANG>_OUTPUT_EXTENSION) before the CMake variables were copied
568 void cmGlobalGenerator::SetLanguageEnabled(const char* l
, cmMakefile
* mf
)
570 this->SetLanguageEnabledFlag(l
, mf
);
571 this->SetLanguageEnabledMaps(l
, mf
);
574 void cmGlobalGenerator::SetLanguageEnabledFlag(const char* l
, cmMakefile
* mf
)
576 this->LanguageEnabled
[l
] = true;
578 // Fill the language-to-extension map with the current variable
579 // settings to make sure it is available for the try_compile()
580 // command source file signature. In SetLanguageEnabledMaps this
581 // will be done again to account for any compiler- or
582 // platform-specific entries.
583 this->FillExtensionToLanguageMap(l
, mf
);
586 void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l
, cmMakefile
* mf
)
588 // use LanguageToLinkerPreference to detect whether this functions has
590 if (this->LanguageToLinkerPreference
.find(l
) !=
591 this->LanguageToLinkerPreference
.end())
596 std::string linkerPrefVar
= std::string("CMAKE_") +
597 std::string(l
) + std::string("_LINKER_PREFERENCE");
598 const char* linkerPref
= mf
->GetDefinition(linkerPrefVar
.c_str());
602 if (sscanf(linkerPref
, "%d", &preference
)!=1)
604 // backward compatibility: before 2.6 LINKER_PREFERENCE
605 // was either "None" or "Prefered", and only the first character was
606 // tested. So if there is a custom language out there and it is
607 // "Prefered", set its preference high
608 if (linkerPref
[0]=='P')
621 std::string msg
= linkerPrefVar
;
622 msg
+= " is negative, adjusting it to 0";
623 cmSystemTools::Message(msg
.c_str(), "Warning");
627 this->LanguageToLinkerPreference
[l
] = preference
;
629 std::string outputExtensionVar
= std::string("CMAKE_") +
630 std::string(l
) + std::string("_OUTPUT_EXTENSION");
631 const char* outputExtension
= mf
->GetDefinition(outputExtensionVar
.c_str());
634 this->LanguageToOutputExtension
[l
] = outputExtension
;
635 this->OutputExtensions
[outputExtension
] = outputExtension
;
636 if(outputExtension
[0] == '.')
638 this->OutputExtensions
[outputExtension
+1] = outputExtension
+1;
642 // The map was originally filled by SetLanguageEnabledFlag, but
643 // since then the compiler- and platform-specific files have been
644 // loaded which might have added more entries.
645 this->FillExtensionToLanguageMap(l
, mf
);
647 std::string ignoreExtensionsVar
= std::string("CMAKE_") +
648 std::string(l
) + std::string("_IGNORE_EXTENSIONS");
649 std::string ignoreExts
= mf
->GetSafeDefinition(ignoreExtensionsVar
.c_str());
650 std::vector
<std::string
> extensionList
;
651 cmSystemTools::ExpandListArgument(ignoreExts
, extensionList
);
652 for(std::vector
<std::string
>::iterator i
= extensionList
.begin();
653 i
!= extensionList
.end(); ++i
)
655 this->IgnoreExtensions
[*i
] = true;
660 void cmGlobalGenerator::FillExtensionToLanguageMap(const char* l
,
663 std::string extensionsVar
= std::string("CMAKE_") +
664 std::string(l
) + std::string("_SOURCE_FILE_EXTENSIONS");
665 std::string exts
= mf
->GetSafeDefinition(extensionsVar
.c_str());
666 std::vector
<std::string
> extensionList
;
667 cmSystemTools::ExpandListArgument(exts
, extensionList
);
668 for(std::vector
<std::string
>::iterator i
= extensionList
.begin();
669 i
!= extensionList
.end(); ++i
)
671 this->ExtensionToLanguage
[*i
] = l
;
675 bool cmGlobalGenerator::IgnoreFile(const char* l
)
677 if(this->GetLanguageFromExtension(l
))
681 return (this->IgnoreExtensions
.count(l
) > 0);
684 bool cmGlobalGenerator::GetLanguageEnabled(const char* l
) const
686 return (this->LanguageEnabled
.find(l
)!= this->LanguageEnabled
.end());
689 void cmGlobalGenerator::ClearEnabledLanguages()
691 this->LanguageEnabled
.clear();
694 bool cmGlobalGenerator::IsDependedOn(const char* project
,
697 // Get all local gens for this project
698 std::vector
<cmLocalGenerator
*>* gens
= &this->ProjectMap
[project
];
699 // loop over local gens and get the targets for each one
700 for(unsigned int i
= 0; i
< gens
->size(); ++i
)
702 cmTargets
& targets
= (*gens
)[i
]->GetMakefile()->GetTargets();
703 for (cmTargets::iterator l
= targets
.begin();
704 l
!= targets
.end(); l
++)
706 cmTarget
& target
= l
->second
;
707 std::set
<cmStdString
>::const_iterator pos
=
708 target
.GetUtilities().find(targetIn
->GetName());
709 if(pos
!= target
.GetUtilities().end())
718 void cmGlobalGenerator::Configure()
720 this->FirstTimeProgress
= 0.0f
;
721 this->ClearExportSets();
722 // Delete any existing cmLocalGenerators
724 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
726 delete this->LocalGenerators
[i
];
728 this->LocalGenerators
.clear();
729 this->TargetDependencies
.clear();
730 this->TotalTargets
.clear();
731 this->LocalGeneratorToTargetMap
.clear();
732 this->ProjectMap
.clear();
733 this->RuleHashes
.clear();
734 this->DirectoryContentMap
.clear();
735 this->BinaryDirectories
.clear();
737 // start with this directory
738 cmLocalGenerator
*lg
= this->CreateLocalGenerator();
739 this->LocalGenerators
.push_back(lg
);
741 // set the Start directories
742 cmMakefile
* mf
= lg
->GetMakefile();
743 lg
->GetMakefile()->SetStartDirectory
744 (this->CMakeInstance
->GetStartDirectory());
745 lg
->GetMakefile()->SetStartOutputDirectory
746 (this->CMakeInstance
->GetStartOutputDirectory());
747 lg
->GetMakefile()->MakeStartDirectoriesCurrent();
749 this->BinaryDirectories
.insert(mf
->GetStartOutputDirectory());
754 // update the cache entry for the number of local generators, this is used
757 sprintf(num
,"%d",static_cast<int>(this->LocalGenerators
.size()));
758 this->GetCMakeInstance()->AddCacheEntry
759 ("CMAKE_NUMBER_OF_LOCAL_GENERATORS", num
,
760 "number of local generators", cmCacheManager::INTERNAL
);
762 // check for link libraries and include directories containing "NOTFOUND"
763 // and for infinite loops
764 this->CheckLocalGenerators();
766 // at this point this->LocalGenerators has been filled,
767 // so create the map from project name to vector of local generators
768 this->FillProjectMap();
770 if ( !this->CMakeInstance
->GetScriptMode() )
772 const char* msg
= "Configuring done";
773 if(cmSystemTools::GetErrorOccuredFlag())
775 msg
= "Configuring incomplete, errors occurred!";
777 this->CMakeInstance
->UpdateProgress(msg
, -1);
781 bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
783 // If the property is not enabled then okay.
784 if(!this->CMakeInstance
785 ->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
790 // This generator does not support duplicate custom targets.
792 e
<< "This project has enabled the ALLOW_DUPLICATE_CUSTOM_TARGETS "
793 << "global property. "
794 << "The \"" << this->GetName() << "\" generator does not support "
795 << "duplicate custom targets. "
796 << "Consider using a Makefiles generator or fix the project to not "
797 << "use duplicat target names.";
798 cmSystemTools::Error(e
.str().c_str());
802 void cmGlobalGenerator::Generate()
804 // Some generators track files replaced during the Generate.
805 // Start with an empty vector:
806 this->FilesReplacedDuringGenerate
.clear();
808 // Check whether this generator is allowed to run.
809 if(!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS())
814 // Check that all targets are valid.
815 if(!this->CheckTargets())
820 // For each existing cmLocalGenerator
823 // Consolidate global targets
824 cmTargets globalTargets
;
825 this->CreateDefaultGlobalTargets(&globalTargets
);
826 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
829 &(this->LocalGenerators
[i
]->GetMakefile()->GetTargets());
830 cmTargets::iterator tarIt
;
831 for ( tarIt
= targets
->begin(); tarIt
!= targets
->end(); ++ tarIt
)
833 if ( tarIt
->second
.GetType() == cmTarget::GLOBAL_TARGET
)
835 globalTargets
[tarIt
->first
] = tarIt
->second
;
839 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
841 cmMakefile
* mf
= this->LocalGenerators
[i
]->GetMakefile();
842 cmTargets
* targets
= &(mf
->GetTargets());
843 cmTargets::iterator tit
;
844 for ( tit
= globalTargets
.begin(); tit
!= globalTargets
.end(); ++ tit
)
846 (*targets
)[tit
->first
] = tit
->second
;
847 (*targets
)[tit
->first
].SetMakefile(mf
);
851 // Add generator specific helper commands
852 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
854 this->LocalGenerators
[i
]->AddHelperCommands();
857 // Trace the dependencies, after that no custom commands should be added
858 // because their dependencies might not be handled correctly
859 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
861 this->LocalGenerators
[i
]->TraceDependencies();
864 // Compute the manifest of main targets generated.
865 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
867 this->LocalGenerators
[i
]->GenerateTargetManifest();
870 // Compute the inter-target dependencies.
872 cmComputeTargetDepends
ctd(this);
877 std::vector
<cmTarget
*> const& targets
= ctd
.GetTargets();
878 for(std::vector
<cmTarget
*>::const_iterator ti
= targets
.begin();
879 ti
!= targets
.end(); ++ti
)
881 ctd
.GetTargetDirectDepends(*ti
, this->TargetDependencies
[*ti
]);
885 // Create a map from local generator to the complete set of targets
886 // it builds by default.
887 this->FillLocalGeneratorToTargetMap();
889 // Generate project files
890 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
892 this->SetCurrentLocalGenerator(this->LocalGenerators
[i
]);
893 this->LocalGenerators
[i
]->Generate();
894 this->LocalGenerators
[i
]->GenerateInstallRules();
895 this->LocalGenerators
[i
]->GenerateTestFiles();
896 this->CMakeInstance
->UpdateProgress("Generating",
897 (i
+1.0f
)/this->LocalGenerators
.size());
899 this->SetCurrentLocalGenerator(0);
901 // Update rule hashes.
902 this->CheckRuleHashes();
904 this->WriteSummary();
906 if (this->ExtraGenerator
!= 0)
908 this->ExtraGenerator
->Generate();
911 this->CMakeInstance
->UpdateProgress("Generating done", -1);
914 //----------------------------------------------------------------------------
915 bool cmGlobalGenerator::CheckTargets()
917 // Make sure all targets can find their source files.
918 for(unsigned int i
=0; i
< this->LocalGenerators
.size(); ++i
)
921 this->LocalGenerators
[i
]->GetMakefile()->GetTargets();
922 for(cmTargets::iterator ti
= targets
.begin();
923 ti
!= targets
.end(); ++ti
)
925 cmTarget
& target
= ti
->second
;
926 if(target
.GetType() == cmTarget::EXECUTABLE
||
927 target
.GetType() == cmTarget::STATIC_LIBRARY
||
928 target
.GetType() == cmTarget::SHARED_LIBRARY
||
929 target
.GetType() == cmTarget::MODULE_LIBRARY
||
930 target
.GetType() == cmTarget::UTILITY
)
932 if(!target
.FindSourceFiles())
942 void cmGlobalGenerator::CheckLocalGenerators()
944 std::map
<cmStdString
, cmStdString
> notFoundMap
;
945 // std::set<cmStdString> notFoundMap;
946 // after it is all done do a ConfigureFinalPass
947 cmCacheManager
* manager
= 0;
948 for (unsigned int i
= 0; i
< this->LocalGenerators
.size(); ++i
)
950 manager
= this->LocalGenerators
[i
]->GetMakefile()->GetCacheManager();
951 this->LocalGenerators
[i
]->ConfigureFinalPass();
952 const cmTargets
& targets
=
953 this->LocalGenerators
[i
]->GetMakefile()->GetTargets();
954 for (cmTargets::const_iterator l
= targets
.begin();
955 l
!= targets
.end(); l
++)
957 const cmTarget::LinkLibraryVectorType
& libs
=
958 l
->second
.GetOriginalLinkLibraries();
959 for(cmTarget::LinkLibraryVectorType::const_iterator lib
= libs
.begin();
960 lib
!= libs
.end(); ++lib
)
962 if(lib
->first
.size() > 9 &&
963 cmSystemTools::IsNOTFOUND(lib
->first
.c_str()))
965 std::string varName
= lib
->first
.substr(0, lib
->first
.size()-9);
966 cmCacheManager::CacheIterator it
=
967 manager
->GetCacheIterator(varName
.c_str());
968 if(it
.GetPropertyAsBool("ADVANCED"))
970 varName
+= " (ADVANCED)";
972 std::string text
= notFoundMap
[varName
];
973 text
+= "\n linked by target \"";
974 text
+= l
->second
.GetName();
975 text
+= "\" in directory ";
976 text
+=this->LocalGenerators
[i
]->GetMakefile()->GetCurrentDirectory();
977 notFoundMap
[varName
] = text
;
981 const std::vector
<std::string
>& incs
=
982 this->LocalGenerators
[i
]->GetMakefile()->GetIncludeDirectories();
984 for( std::vector
<std::string
>::const_iterator incDir
= incs
.begin();
985 incDir
!= incs
.end(); ++incDir
)
987 if(incDir
->size() > 9 &&
988 cmSystemTools::IsNOTFOUND(incDir
->c_str()))
990 std::string varName
= incDir
->substr(0, incDir
->size()-9);
991 cmCacheManager::CacheIterator it
=
992 manager
->GetCacheIterator(varName
.c_str());
993 if(it
.GetPropertyAsBool("ADVANCED"))
995 varName
+= " (ADVANCED)";
997 std::string text
= notFoundMap
[varName
];
998 text
+= "\n used as include directory in directory ";
999 text
+= this->LocalGenerators
[i
]->GetMakefile()->GetCurrentDirectory();
1000 notFoundMap
[varName
] = text
;
1003 this->CMakeInstance
->UpdateProgress
1004 ("Configuring", 0.9f
+0.1f
*(i
+1.0f
)/this->LocalGenerators
.size());
1007 if(notFoundMap
.size())
1009 std::string notFoundVars
;
1010 for(std::map
<cmStdString
, cmStdString
>::const_iterator
1011 ii
= notFoundMap
.begin();
1012 ii
!= notFoundMap
.end();
1015 notFoundVars
+= ii
->first
;
1016 notFoundVars
+= ii
->second
;
1017 notFoundVars
+= "\n";
1019 cmSystemTools::Error("The following variables are used in this project, "
1020 "but they are set to NOTFOUND.\n"
1021 "Please set them or make sure they are set and "
1022 "tested correctly in the CMake files:\n",
1023 notFoundVars
.c_str());
1027 int cmGlobalGenerator::TryCompile(const char *srcdir
, const char *bindir
,
1028 const char *projectName
,
1030 std::string
*output
, cmMakefile
*mf
)
1032 // if this is not set, then this is a first time configure
1033 // and there is a good chance that the try compile stuff will
1034 // take the bulk of the time, so try and guess some progress
1035 // by getting closer and closer to 100 without actually getting there.
1036 if (!this->CMakeInstance
->GetCacheManager()->GetCacheValue
1037 ("CMAKE_NUMBER_OF_LOCAL_GENERATORS"))
1039 // If CMAKE_NUMBER_OF_LOCAL_GENERATORS is not set
1040 // we are in the first time progress and we have no
1041 // idea how long it will be. So, just move 1/10th of the way
1042 // there each time, and don't go over 95%
1043 this->FirstTimeProgress
+= ((1.0f
- this->FirstTimeProgress
) /30.0f
);
1044 if(this->FirstTimeProgress
> 0.95f
)
1046 this->FirstTimeProgress
= 0.95f
;
1048 this->CMakeInstance
->UpdateProgress("Configuring",
1049 this->FirstTimeProgress
);
1052 std::string makeCommand
= this->CMakeInstance
->
1053 GetCacheManager()->GetCacheValue("CMAKE_MAKE_PROGRAM");
1054 if(makeCommand
.size() == 0)
1056 cmSystemTools::Error(
1057 "Generator cannot find the appropriate make command.");
1061 std::string newTarget
;
1062 if (target
&& strlen(target
))
1064 newTarget
+= target
;
1066 #if defined(_WIN32) || defined(__CYGWIN__)
1067 std::string tmp
= target
;
1068 // if the target does not already end in . something
1070 if(tmp
.size() < 4 || tmp
[tmp
.size()-4] != '.')
1072 newTarget
+= ".exe";
1077 const char* config
= mf
->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
1078 return this->Build(srcdir
,bindir
,projectName
,
1080 output
,makeCommand
.c_str(),config
,false,true,
1081 this->TryCompileTimeout
);
1084 std::string cmGlobalGenerator
1085 ::GenerateBuildCommand(const char* makeProgram
, const char *projectName
,
1086 const char* additionalOptions
, const char *targetName
,
1087 const char* config
, bool ignoreErrors
, bool)
1089 // Project name and config are not used yet.
1093 std::string makeCommand
=
1094 cmSystemTools::ConvertToUnixOutputPath(makeProgram
);
1096 // Since we have full control over the invocation of nmake, let us
1098 if ( strcmp(this->GetName(), "NMake Makefiles") == 0 )
1100 makeCommand
+= " /NOLOGO ";
1104 makeCommand
+= " -i";
1106 if ( additionalOptions
)
1109 makeCommand
+= additionalOptions
;
1114 makeCommand
+= targetName
;
1119 int cmGlobalGenerator::Build(
1120 const char *, const char *bindir
,
1121 const char *projectName
, const char *target
,
1122 std::string
*output
,
1123 const char *makeCommandCSTR
,
1125 bool clean
, bool fast
,
1128 const char* extraOptions
,
1129 std::vector
<std::string
> const& nativeOptions
)
1132 * Run an executable command and put the stdout in output.
1134 std::string cwd
= cmSystemTools::GetCurrentWorkingDirectory();
1135 cmSystemTools::ChangeDirectory(bindir
);
1138 *output
+= "Change Dir: ";
1144 bool hideconsole
= cmSystemTools::GetRunCommandHideConsole();
1145 cmSystemTools::SetRunCommandHideConsole(true);
1146 std::string outputBuffer
;
1147 std::string
* outputPtr
= 0;
1150 outputPtr
= &outputBuffer
;
1153 // should we do a clean first?
1156 std::string cleanCommand
=
1157 this->GenerateBuildCommand(makeCommandCSTR
, projectName
,
1158 0, "clean", config
, false, fast
);
1161 *output
+= "\nRun Clean Command:";
1162 *output
+= cleanCommand
;
1166 if (!cmSystemTools::RunSingleCommand(cleanCommand
.c_str(), outputPtr
,
1167 &retVal
, 0, verbose
, timeout
))
1169 cmSystemTools::SetRunCommandHideConsole(hideconsole
);
1170 cmSystemTools::Error("Generator: execution of make clean failed.");
1173 *output
+= *outputPtr
;
1174 *output
+= "\nGenerator: execution of make clean failed.\n";
1177 // return to the original directory
1178 cmSystemTools::ChangeDirectory(cwd
.c_str());
1183 *output
+= *outputPtr
;
1188 std::string makeCommand
=
1189 this->GenerateBuildCommand(makeCommandCSTR
, projectName
,
1190 extraOptions
, target
,
1191 config
, false, fast
);
1194 *output
+= "\nRun Build Command:";
1195 *output
+= makeCommand
;
1199 std::vector
<cmStdString
> command
=
1200 cmSystemTools::ParseArguments(makeCommand
.c_str());
1201 for(std::vector
<std::string
>::const_iterator ni
= nativeOptions
.begin();
1202 ni
!= nativeOptions
.end(); ++ni
)
1204 command
.push_back(*ni
);
1207 if (!cmSystemTools::RunSingleCommand(command
, outputPtr
,
1208 &retVal
, 0, verbose
, timeout
))
1210 cmSystemTools::SetRunCommandHideConsole(hideconsole
);
1211 cmSystemTools::Error
1212 ("Generator: execution of make failed. Make command was: ",
1213 makeCommand
.c_str());
1216 *output
+= *outputPtr
;
1217 *output
+= "\nGenerator: execution of make failed. Make command was: "
1218 + makeCommand
+ "\n";
1221 // return to the original directory
1222 cmSystemTools::ChangeDirectory(cwd
.c_str());
1227 *output
+= *outputPtr
;
1229 cmSystemTools::SetRunCommandHideConsole(hideconsole
);
1231 // The SGI MipsPro 7.3 compiler does not return an error code when
1232 // the source has a #error in it! This is a work-around for such
1234 if((retVal
== 0) && (output
->find("#error") != std::string::npos
))
1239 cmSystemTools::ChangeDirectory(cwd
.c_str());
1243 void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator
*lg
)
1245 this->LocalGenerators
.push_back(lg
);
1248 // estimate how many lg there will be
1249 const char *numGenC
=
1250 this->CMakeInstance
->GetCacheManager()->GetCacheValue
1251 ("CMAKE_NUMBER_OF_LOCAL_GENERATORS");
1255 // If CMAKE_NUMBER_OF_LOCAL_GENERATORS is not set
1256 // we are in the first time progress and we have no
1257 // idea how long it will be. So, just move half way
1258 // there each time, and don't go over 95%
1259 this->FirstTimeProgress
+= ((1.0f
- this->FirstTimeProgress
) /30.0f
);
1260 if(this->FirstTimeProgress
> 0.95f
)
1262 this->FirstTimeProgress
= 0.95f
;
1264 this->CMakeInstance
->UpdateProgress("Configuring",
1265 this->FirstTimeProgress
);
1269 int numGen
= atoi(numGenC
);
1270 float prog
= 0.9f
*this->LocalGenerators
.size()/numGen
;
1275 this->CMakeInstance
->UpdateProgress("Configuring", prog
);
1278 void cmGlobalGenerator::AddInstallComponent(const char* component
)
1280 if(component
&& *component
)
1282 this->InstallComponents
.insert(component
);
1286 void cmGlobalGenerator::AddTargetToExports(const char* exportSetName
,
1288 cmInstallTargetGenerator
* archive
,
1289 cmInstallTargetGenerator
* runTime
,
1290 cmInstallTargetGenerator
* library
,
1291 cmInstallTargetGenerator
* framework
,
1292 cmInstallTargetGenerator
* bundle
,
1293 cmInstallFilesGenerator
* headers
)
1295 if ((exportSetName
) && (*exportSetName
) && (target
))
1297 cmTargetExport
* te
= new cmTargetExport(target
, archive
, runTime
, library
,
1298 framework
, bundle
, headers
);
1299 this->ExportSets
[exportSetName
].push_back(te
);
1303 //----------------------------------------------------------------------------
1304 void cmGlobalGenerator::ClearExportSets()
1306 for(std::map
<cmStdString
, std::vector
<cmTargetExport
*> >::iterator
1307 setIt
= this->ExportSets
.begin();
1308 setIt
!= this->ExportSets
.end(); ++setIt
)
1310 for(unsigned int i
= 0; i
< setIt
->second
.size(); ++i
)
1312 delete setIt
->second
[i
];
1315 this->ExportSets
.clear();
1318 const std::vector
<cmTargetExport
*>* cmGlobalGenerator::GetExportSet(
1319 const char* name
) const
1321 std::map
<cmStdString
, std::vector
<cmTargetExport
*> >::const_iterator
1322 exportSetIt
= this->ExportSets
.find(name
);
1323 if (exportSetIt
!= this->ExportSets
.end())
1325 return &exportSetIt
->second
;
1332 void cmGlobalGenerator::EnableInstallTarget()
1334 this->InstallTargetEnabled
= true;
1337 cmLocalGenerator
*cmGlobalGenerator::CreateLocalGenerator()
1339 cmLocalGenerator
*lg
= new cmLocalGenerator
;
1340 lg
->SetGlobalGenerator(this);
1344 void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator
*gen
)
1346 std::string cfp
= gen
->GetCMakeInstance()->GetHomeOutputDirectory();
1347 cfp
+= cmake::GetCMakeFilesDirectory();
1348 this->SetConfiguredFilesPath(cfp
.c_str());
1350 gen
->GetCMakeInstance()->GetCacheDefinition("CMAKE_MAKE_PROGRAM");
1351 this->GetCMakeInstance()->AddCacheEntry("CMAKE_MAKE_PROGRAM", make
,
1353 cmCacheManager::FILEPATH
);
1354 // copy the enabled languages
1355 this->LanguageEnabled
= gen
->LanguageEnabled
;
1356 this->ExtensionToLanguage
= gen
->ExtensionToLanguage
;
1357 this->IgnoreExtensions
= gen
->IgnoreExtensions
;
1358 this->LanguageToOutputExtension
= gen
->LanguageToOutputExtension
;
1359 this->LanguageToLinkerPreference
= gen
->LanguageToLinkerPreference
;
1360 this->OutputExtensions
= gen
->OutputExtensions
;
1363 //----------------------------------------------------------------------------
1364 void cmGlobalGenerator::GetDocumentation(cmDocumentationEntry
& entry
) const
1366 entry
.Name
= this->GetName();
1371 bool cmGlobalGenerator::IsExcluded(cmLocalGenerator
* root
,
1372 cmLocalGenerator
* gen
)
1374 if(!gen
|| gen
== root
)
1376 // No directory excludes itself.
1380 if(gen
->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
1382 // This directory is excluded from its parent.
1386 // This directory is included in its parent. Check whether the
1387 // parent is excluded.
1388 return this->IsExcluded(root
, gen
->GetParent());
1391 bool cmGlobalGenerator::IsExcluded(cmLocalGenerator
* root
,
1394 if(target
.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
1396 // This target is excluded from its directory.
1401 // This target is included in its directory. Check whether the
1402 // directory is excluded.
1403 return this->IsExcluded(root
, target
.GetMakefile()->GetLocalGenerator());
1407 void cmGlobalGenerator::GetEnabledLanguages(std::vector
<std::string
>& lang
)
1409 for(std::map
<cmStdString
, bool>::iterator i
=
1410 this->LanguageEnabled
.begin(); i
!= this->LanguageEnabled
.end(); ++i
)
1412 lang
.push_back(i
->first
);
1416 int cmGlobalGenerator::GetLinkerPreference(const char* lang
)
1418 std::map
<cmStdString
, int>::const_iterator it
=
1419 this->LanguageToLinkerPreference
.find(lang
);
1420 if (it
!= this->LanguageToLinkerPreference
.end())
1427 void cmGlobalGenerator::FillProjectMap()
1429 this->ProjectMap
.clear(); // make sure we start with a clean map
1431 for(i
= 0; i
< this->LocalGenerators
.size(); ++i
)
1433 // for each local generator add all projects
1434 cmLocalGenerator
*lg
= this->LocalGenerators
[i
];
1438 if (name
!= lg
->GetMakefile()->GetProjectName())
1440 name
= lg
->GetMakefile()->GetProjectName();
1441 this->ProjectMap
[name
].push_back(this->LocalGenerators
[i
]);
1443 lg
= lg
->GetParent();
1450 // Build a map that contains a the set of targets used by each local
1451 // generator directory level.
1452 void cmGlobalGenerator::FillLocalGeneratorToTargetMap()
1454 this->LocalGeneratorToTargetMap
.clear();
1455 // Loop over all targets in all local generators.
1456 for(std::vector
<cmLocalGenerator
*>::const_iterator
1457 lgi
= this->LocalGenerators
.begin();
1458 lgi
!= this->LocalGenerators
.end(); ++lgi
)
1460 cmLocalGenerator
* lg
= *lgi
;
1461 cmMakefile
* mf
= lg
->GetMakefile();
1462 cmTargets
& targets
= mf
->GetTargets();
1463 for(cmTargets::iterator t
= targets
.begin(); t
!= targets
.end(); ++t
)
1465 cmTarget
& target
= t
->second
;
1467 // Consider the directory containing the target and all its
1468 // parents until something excludes the target.
1469 for(cmLocalGenerator
* clg
= lg
; clg
&& !this->IsExcluded(clg
, target
);
1470 clg
= clg
->GetParent())
1472 // This local generator includes the target.
1473 std::set
<cmTarget
*>& targetSet
=
1474 this->LocalGeneratorToTargetMap
[clg
];
1475 targetSet
.insert(&target
);
1477 // Add dependencies of the included target. An excluded
1478 // target may still be included if it is a dependency of a
1479 // non-excluded target.
1480 TargetDependSet
& tgtdeps
= this->GetTargetDirectDepends(target
);
1481 for(TargetDependSet::const_iterator ti
= tgtdeps
.begin();
1482 ti
!= tgtdeps
.end(); ++ti
)
1484 targetSet
.insert(*ti
);
1492 ///! Find a local generator by its startdirectory
1493 cmLocalGenerator
* cmGlobalGenerator::FindLocalGenerator(const char* start_dir
)
1495 std::vector
<cmLocalGenerator
*>* gens
= &this->LocalGenerators
;
1496 for(unsigned int i
= 0; i
< gens
->size(); ++i
)
1498 std::string sd
= (*gens
)[i
]->GetMakefile()->GetStartDirectory();
1499 if (sd
== start_dir
)
1508 //----------------------------------------------------------------------------
1510 cmGlobalGenerator::FindTarget(const char* project
, const char* name
)
1512 // if project specific
1515 std::vector
<cmLocalGenerator
*>* gens
= &this->ProjectMap
[project
];
1516 for(unsigned int i
= 0; i
< gens
->size(); ++i
)
1518 cmTarget
* ret
= (*gens
)[i
]->GetMakefile()->FindTarget(name
);
1525 // if all projects/directories
1528 std::map
<cmStdString
,cmTarget
*>::iterator i
=
1529 this->TotalTargets
.find ( name
);
1530 if ( i
!= this->TotalTargets
.end() )
1538 //----------------------------------------------------------------------------
1539 bool cmGlobalGenerator::NameResolvesToFramework(const std::string
& libname
)
1541 if(cmSystemTools::IsPathToFramework(libname
.c_str()))
1546 if(cmTarget
* tgt
= this->FindTarget(0, libname
.c_str()))
1548 if(tgt
->IsFrameworkOnApple())
1557 //----------------------------------------------------------------------------
1558 inline std::string
removeQuotes(const std::string
& s
)
1560 if(s
[0] == '\"' && s
[s
.size()-1] == '\"')
1562 return s
.substr(1, s
.size()-2);
1567 void cmGlobalGenerator::SetCMakeInstance(cmake
* cm
)
1569 // Store a pointer to the cmake object instance.
1570 this->CMakeInstance
= cm
;
1573 void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets
* targets
)
1575 cmMakefile
* mf
= this->LocalGenerators
[0]->GetMakefile();
1576 const char* cmakeCfgIntDir
= this->GetCMakeCFGInitDirectory();
1577 const char* cmakeCommand
= mf
->GetRequiredDefinition("CMAKE_COMMAND");
1580 std::string workingDir
= mf
->GetStartOutputDirectory();
1581 cmCustomCommandLines cpackCommandLines
;
1582 std::vector
<std::string
> depends
;
1583 cmCustomCommandLine singleLine
;
1584 singleLine
.push_back(this->GetCMakeInstance()->GetCPackCommand());
1585 if ( cmakeCfgIntDir
&& *cmakeCfgIntDir
&& cmakeCfgIntDir
[0] != '.' )
1587 singleLine
.push_back("-C");
1588 singleLine
.push_back(cmakeCfgIntDir
);
1590 singleLine
.push_back("--config");
1591 std::string configFile
= mf
->GetStartOutputDirectory();;
1592 configFile
+= "/CPackConfig.cmake";
1593 std::string relConfigFile
= "./CPackConfig.cmake";
1594 singleLine
.push_back(relConfigFile
);
1595 cpackCommandLines
.push_back(singleLine
);
1596 if ( this->GetPreinstallTargetName() )
1598 depends
.push_back(this->GetPreinstallTargetName());
1602 const char* noPackageAll
=
1603 mf
->GetDefinition("CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY");
1604 if(!noPackageAll
|| cmSystemTools::IsOff(noPackageAll
))
1606 depends
.push_back(this->GetAllTargetName());
1609 if(cmSystemTools::FileExists(configFile
.c_str()))
1611 (*targets
)[this->GetPackageTargetName()]
1612 = this->CreateGlobalTarget(this->GetPackageTargetName(),
1613 "Run CPack packaging tool...",
1614 &cpackCommandLines
, depends
,
1615 workingDir
.c_str());
1618 const char* packageSourceTargetName
= this->GetPackageSourceTargetName();
1619 if ( packageSourceTargetName
)
1621 cpackCommandLines
.erase(cpackCommandLines
.begin(),
1622 cpackCommandLines
.end());
1623 singleLine
.erase(singleLine
.begin(), singleLine
.end());
1624 depends
.erase(depends
.begin(), depends
.end());
1625 singleLine
.push_back(this->GetCMakeInstance()->GetCPackCommand());
1626 singleLine
.push_back("--config");
1627 configFile
= mf
->GetStartOutputDirectory();;
1628 configFile
+= "/CPackSourceConfig.cmake";
1629 relConfigFile
= "./CPackSourceConfig.cmake";
1630 singleLine
.push_back(relConfigFile
);
1631 if(cmSystemTools::FileExists(configFile
.c_str()))
1633 singleLine
.push_back(configFile
);
1634 cpackCommandLines
.push_back(singleLine
);
1635 (*targets
)[packageSourceTargetName
]
1636 = this->CreateGlobalTarget(packageSourceTargetName
,
1637 "Run CPack packaging tool for source...",
1638 &cpackCommandLines
, depends
,
1645 if(mf
->IsOn("CMAKE_TESTING_ENABLED"))
1647 cpackCommandLines
.erase(cpackCommandLines
.begin(),
1648 cpackCommandLines
.end());
1649 singleLine
.erase(singleLine
.begin(), singleLine
.end());
1650 depends
.erase(depends
.begin(), depends
.end());
1651 singleLine
.push_back(this->GetCMakeInstance()->GetCTestCommand());
1652 singleLine
.push_back("--force-new-ctest-process");
1653 if(cmakeCfgIntDir
&& *cmakeCfgIntDir
&& cmakeCfgIntDir
[0] != '.')
1655 singleLine
.push_back("-C");
1656 singleLine
.push_back(cmakeCfgIntDir
);
1658 else // TODO: This is a hack. Should be something to do with the generator
1660 singleLine
.push_back("$(ARGS)");
1662 cpackCommandLines
.push_back(singleLine
);
1663 (*targets
)[this->GetTestTargetName()]
1664 = this->CreateGlobalTarget(this->GetTestTargetName(),
1665 "Running tests...", &cpackCommandLines
, depends
, 0);
1669 const char* editCacheTargetName
= this->GetEditCacheTargetName();
1670 if ( editCacheTargetName
)
1672 cpackCommandLines
.erase(cpackCommandLines
.begin(),
1673 cpackCommandLines
.end());
1674 singleLine
.erase(singleLine
.begin(), singleLine
.end());
1675 depends
.erase(depends
.begin(), depends
.end());
1677 // Use CMAKE_EDIT_COMMAND for the edit_cache rule if it is defined.
1678 // Otherwise default to the interactive command-line interface.
1679 if(mf
->GetDefinition("CMAKE_EDIT_COMMAND"))
1681 singleLine
.push_back(mf
->GetDefinition("CMAKE_EDIT_COMMAND"));
1682 singleLine
.push_back("-H$(CMAKE_SOURCE_DIR)");
1683 singleLine
.push_back("-B$(CMAKE_BINARY_DIR)");
1684 cpackCommandLines
.push_back(singleLine
);
1685 (*targets
)[editCacheTargetName
] =
1686 this->CreateGlobalTarget(
1687 editCacheTargetName
, "Running CMake cache editor...",
1688 &cpackCommandLines
, depends
, 0);
1692 singleLine
.push_back(cmakeCommand
);
1693 singleLine
.push_back("-i");
1694 singleLine
.push_back(".");
1695 cpackCommandLines
.push_back(singleLine
);
1696 (*targets
)[editCacheTargetName
] =
1697 this->CreateGlobalTarget(
1698 editCacheTargetName
,
1699 "Running interactive CMake command-line interface...",
1700 &cpackCommandLines
, depends
, 0);
1705 const char* rebuildCacheTargetName
= this->GetRebuildCacheTargetName();
1706 if ( rebuildCacheTargetName
)
1708 cpackCommandLines
.erase(cpackCommandLines
.begin(),
1709 cpackCommandLines
.end());
1710 singleLine
.erase(singleLine
.begin(), singleLine
.end());
1711 depends
.erase(depends
.begin(), depends
.end());
1712 singleLine
.push_back(cmakeCommand
);
1713 singleLine
.push_back("-H$(CMAKE_SOURCE_DIR)");
1714 singleLine
.push_back("-B$(CMAKE_BINARY_DIR)");
1715 cpackCommandLines
.push_back(singleLine
);
1716 (*targets
)[rebuildCacheTargetName
] =
1717 this->CreateGlobalTarget(
1718 rebuildCacheTargetName
, "Running CMake to regenerate build system...",
1719 &cpackCommandLines
, depends
, 0);
1723 if(this->InstallTargetEnabled
)
1725 if(!cmakeCfgIntDir
|| !*cmakeCfgIntDir
|| cmakeCfgIntDir
[0] == '.')
1727 std::set
<cmStdString
>* componentsSet
= &this->InstallComponents
;
1728 cpackCommandLines
.erase(cpackCommandLines
.begin(),
1729 cpackCommandLines
.end());
1730 depends
.erase(depends
.begin(), depends
.end());
1731 cmOStringStream ostr
;
1732 if ( componentsSet
->size() > 0 )
1734 ostr
<< "Available install components are:";
1735 std::set
<cmStdString
>::iterator it
;
1737 it
= componentsSet
->begin();
1738 it
!= componentsSet
->end();
1741 ostr
<< " \"" << it
->c_str() << "\"";
1746 ostr
<< "Only default component available";
1748 singleLine
.push_back(ostr
.str().c_str());
1749 (*targets
)["list_install_components"]
1750 = this->CreateGlobalTarget("list_install_components",
1752 &cpackCommandLines
, depends
, 0);
1755 cpackCommandLines
.erase(cpackCommandLines
.begin(),
1756 cpackCommandLines
.end());
1757 singleLine
.erase(singleLine
.begin(), singleLine
.end());
1758 depends
.erase(depends
.begin(), depends
.end());
1759 if ( this->GetPreinstallTargetName() )
1761 depends
.push_back(this->GetPreinstallTargetName());
1766 mf
->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
1767 if(!noall
|| cmSystemTools::IsOff(noall
))
1769 depends
.push_back(this->GetAllTargetName());
1772 if(mf
->GetDefinition("CMake_BINARY_DIR"))
1774 // We are building CMake itself. We cannot use the original
1775 // executable to install over itself.
1776 cmd
= mf
->GetDefinition("EXECUTABLE_OUTPUT_PATH");
1777 if(cmakeCfgIntDir
&& *cmakeCfgIntDir
&& cmakeCfgIntDir
[0] != '.')
1780 cmd
+= cmakeCfgIntDir
;
1788 singleLine
.push_back(cmd
.c_str());
1789 if ( cmakeCfgIntDir
&& *cmakeCfgIntDir
&& cmakeCfgIntDir
[0] != '.' )
1791 std::string cfgArg
= "-DBUILD_TYPE=";
1792 cfgArg
+= mf
->GetDefinition("CMAKE_CFG_INTDIR");
1793 singleLine
.push_back(cfgArg
);
1795 singleLine
.push_back("-P");
1796 singleLine
.push_back("cmake_install.cmake");
1797 cpackCommandLines
.push_back(singleLine
);
1798 (*targets
)[this->GetInstallTargetName()] =
1799 this->CreateGlobalTarget(
1800 this->GetInstallTargetName(), "Install the project...",
1801 &cpackCommandLines
, depends
, 0);
1804 if(const char* install_local
= this->GetInstallLocalTargetName())
1806 cmCustomCommandLine localCmdLine
= singleLine
;
1808 localCmdLine
.insert(localCmdLine
.begin()+1,
1809 "-DCMAKE_INSTALL_LOCAL_ONLY=1");
1810 cpackCommandLines
.erase(cpackCommandLines
.begin(),
1811 cpackCommandLines
.end());
1812 cpackCommandLines
.push_back(localCmdLine
);
1814 (*targets
)[install_local
] =
1815 this->CreateGlobalTarget(
1816 install_local
, "Installing only the local directory...",
1817 &cpackCommandLines
, depends
, 0);
1821 const char* install_strip
= this->GetInstallStripTargetName();
1822 if((install_strip
!=0) && (mf
->IsSet("CMAKE_STRIP")))
1824 cmCustomCommandLine stripCmdLine
= singleLine
;
1826 stripCmdLine
.insert(stripCmdLine
.begin()+1,"-DCMAKE_INSTALL_DO_STRIP=1");
1827 cpackCommandLines
.erase(cpackCommandLines
.begin(),
1828 cpackCommandLines
.end());
1829 cpackCommandLines
.push_back(stripCmdLine
);
1831 (*targets
)[install_strip
] =
1832 this->CreateGlobalTarget(
1833 install_strip
, "Installing the project stripped...",
1834 &cpackCommandLines
, depends
, 0);
1839 cmTarget
cmGlobalGenerator::CreateGlobalTarget(
1840 const char* name
, const char* message
,
1841 const cmCustomCommandLines
* commandLines
,
1842 std::vector
<std::string
> depends
,
1843 const char* workingDirectory
,
1844 bool depends_on_all
/* = false */)
1848 target
.GetProperties().SetCMakeInstance(this->CMakeInstance
);
1849 target
.SetType(cmTarget::GLOBAL_TARGET
, name
);
1850 target
.SetProperty("EXCLUDE_FROM_ALL","TRUE");
1852 std::vector
<std::string
> no_outputs
;
1853 std::vector
<std::string
> no_depends
;
1854 // Store the custom command in the target.
1855 cmCustomCommand
cc(no_outputs
, no_depends
, *commandLines
, 0,
1857 target
.GetPostBuildCommands().push_back(cc
);
1858 target
.SetProperty("EchoString", message
);
1859 if ( depends_on_all
)
1861 target
.AddUtility("all");
1863 std::vector
<std::string
>::iterator dit
;
1864 for ( dit
= depends
.begin(); dit
!= depends
.end(); ++ dit
)
1866 target
.AddUtility(dit
->c_str());
1871 //----------------------------------------------------------------------------
1872 void cmGlobalGenerator::AppendDirectoryForConfig(const char*, const char*,
1873 const char*, std::string
&)
1875 // Subclasses that support multiple configurations should implement
1876 // this method to append the subdirectory for the given build
1880 //----------------------------------------------------------------------------
1881 cmGlobalGenerator::TargetDependSet
&
1882 cmGlobalGenerator::GetTargetDirectDepends(cmTarget
& target
)
1884 return this->TargetDependencies
[&target
];
1887 void cmGlobalGenerator::AddTarget(cmTargets::value_type
&v
)
1889 assert(!v
.second
.IsImported());
1890 this->TotalTargets
[v
.first
] = &v
.second
;
1893 void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
1894 cmExternalMakefileProjectGenerator
*extraGenerator
)
1896 this->ExtraGenerator
= extraGenerator
;
1897 if (this->ExtraGenerator
!=0)
1899 this->ExtraGenerator
->SetGlobalGenerator(this);
1903 const char* cmGlobalGenerator::GetExtraGeneratorName() const
1905 return this->ExtraGenerator
==0 ? 0 : this->ExtraGenerator
->GetName();
1908 void cmGlobalGenerator::FileReplacedDuringGenerate(const std::string
& filename
)
1910 this->FilesReplacedDuringGenerate
.push_back(filename
);
1915 ::GetFilesReplacedDuringGenerate(std::vector
<std::string
>& filenames
)
1919 this->FilesReplacedDuringGenerate
.begin(),
1920 this->FilesReplacedDuringGenerate
.end(),
1921 std::back_inserter(filenames
));
1926 ::GetTargetSets(cmGlobalGenerator::TargetDependSet
& projectTargets
,
1927 cmGlobalGenerator::TargetDependSet
& originalTargets
,
1928 cmLocalGenerator
* root
,
1929 std::vector
<cmLocalGenerator
*> const& generators
)
1931 // loop over all local generators
1932 for(std::vector
<cmLocalGenerator
*>::const_iterator i
= generators
.begin();
1933 i
!= generators
.end(); ++i
)
1935 // check to make sure generator is not excluded
1936 if(this->IsExcluded(root
, *i
))
1940 cmMakefile
* mf
= (*i
)->GetMakefile();
1941 // Get the targets in the makefile
1942 cmTargets
&tgts
= mf
->GetTargets();
1943 // loop over all the targets
1944 for (cmTargets::iterator l
= tgts
.begin(); l
!= tgts
.end(); ++l
)
1946 cmTarget
* target
= &l
->second
;
1947 // put the target in the set of original targets
1948 originalTargets
.insert(target
);
1949 // Get the set of targets that depend on target
1950 this->AddTargetDepends(target
,
1957 cmGlobalGenerator::AddTargetDepends(cmTarget
* target
,
1958 cmGlobalGenerator::TargetDependSet
&
1961 // add the target itself
1962 projectTargets
.insert(target
);
1963 // get the direct depends of target
1964 cmGlobalGenerator::TargetDependSet
const& tset
1965 = this->GetTargetDirectDepends(*target
);
1968 // if there are targets that depend on target
1969 // add them and their depends as well
1970 for(cmGlobalGenerator::TargetDependSet::const_iterator i
=
1971 tset
.begin(); i
!= tset
.end(); ++i
)
1973 cmTarget
* dtarget
= *i
;
1974 this->AddTargetDepends(dtarget
, projectTargets
);
1980 //----------------------------------------------------------------------------
1981 void cmGlobalGenerator::AddToManifest(const char* config
,
1982 std::string
const& f
)
1984 // Add to the main manifest for this configuration.
1985 this->TargetManifest
[config
].insert(f
);
1987 // Add to the content listing for the file's directory.
1988 std::string dir
= cmSystemTools::GetFilenamePath(f
);
1989 std::string file
= cmSystemTools::GetFilenameName(f
);
1990 this->DirectoryContentMap
[dir
].insert(file
);
1993 //----------------------------------------------------------------------------
1994 std::set
<cmStdString
> const&
1995 cmGlobalGenerator::GetDirectoryContent(std::string
const& dir
, bool needDisk
)
1997 DirectoryContent
& dc
= this->DirectoryContentMap
[dir
];
1998 if(needDisk
&& !dc
.LoadedFromDisk
)
2000 // Load the directory content from disk.
2002 if(d
.Load(dir
.c_str()))
2004 unsigned long n
= d
.GetNumberOfFiles();
2005 for(unsigned long i
= 0; i
< n
; ++i
)
2007 const char* f
= d
.GetFile(i
);
2008 if(strcmp(f
, ".") != 0 && strcmp(f
, "..") != 0)
2014 dc
.LoadedFromDisk
= true;
2019 //----------------------------------------------------------------------------
2021 cmGlobalGenerator::AddRuleHash(const std::vector
<std::string
>& outputs
,
2022 std::string
const& content
)
2024 #if defined(CMAKE_BUILD_WITH_CMAKE)
2025 // Ignore if there are no outputs.
2031 // Compute a hash of the rule.
2034 unsigned char const* data
=
2035 reinterpret_cast<unsigned char const*>(content
.c_str());
2036 int length
= static_cast<int>(content
.length());
2037 cmsysMD5
* sum
= cmsysMD5_New();
2038 cmsysMD5_Initialize(sum
);
2039 cmsysMD5_Append(sum
, data
, length
);
2040 cmsysMD5_FinalizeHex(sum
, hash
.Data
);
2041 cmsysMD5_Delete(sum
);
2044 // Shorten the output name (in expected use case).
2045 cmLocalGenerator
* lg
= this->GetLocalGenerators()[0];
2046 std::string fname
= lg
->Convert(outputs
[0].c_str(),
2047 cmLocalGenerator::HOME_OUTPUT
);
2049 // Associate the hash with this output.
2050 this->RuleHashes
[fname
] = hash
;
2057 //----------------------------------------------------------------------------
2058 void cmGlobalGenerator::CheckRuleHashes()
2060 #if defined(CMAKE_BUILD_WITH_CMAKE)
2061 std::string home
= this->GetCMakeInstance()->GetHomeOutputDirectory();
2062 std::string pfile
= home
;
2063 pfile
+= this->GetCMakeInstance()->GetCMakeFilesDirectory();
2064 pfile
+= "/CMakeRuleHashes.txt";
2066 #if defined(_WIN32) || defined(__CYGWIN__)
2067 std::ifstream
fin(pfile
.c_str(), std::ios::in
| std::ios::binary
);
2069 std::ifstream
fin(pfile
.c_str(), std::ios::in
);
2073 while(cmSystemTools::GetLineFromStream(fin
, line
))
2075 // Line format is a 32-byte hex string followed by a space
2076 // followed by a file name (with no escaping).
2078 // Skip blank and comment lines.
2079 if(line
.size() < 34 || line
[0] == '#')
2084 // Get the filename.
2085 fname
= line
.substr(33, line
.npos
);
2087 // Look for a hash for this file's rule.
2088 std::map
<cmStdString
, RuleHash
>::const_iterator rhi
=
2089 this->RuleHashes
.find(fname
);
2090 if(rhi
!= this->RuleHashes
.end())
2092 // Compare the rule hash in the file to that we were given.
2093 if(strncmp(line
.c_str(), rhi
->second
.Data
, 32) != 0)
2095 // The rule has changed. Delete the output so it will be
2097 fname
= cmSystemTools::CollapseFullPath(fname
.c_str(), home
.c_str());
2098 cmSystemTools::RemoveFile(fname
.c_str());
2103 // We have no hash for a rule previously listed. This may be a
2104 // case where a user has turned off a build option and might
2105 // want to turn it back on later, so do not delete the file.
2106 // Instead, we keep the rule hash as long as the file exists so
2107 // that if the feature is turned back on and the rule has
2108 // changed the file is still rebuilt.
2110 cmSystemTools::CollapseFullPath(fname
.c_str(), home
.c_str());
2111 if(cmSystemTools::FileExists(fpath
.c_str()))
2114 strncpy(hash
.Data
, line
.c_str(), 32);
2115 this->RuleHashes
[fname
] = hash
;
2120 // Now generate a new persistence file with the current hashes.
2121 if(this->RuleHashes
.empty())
2123 cmSystemTools::RemoveFile(pfile
.c_str());
2127 cmGeneratedFileStream
fout(pfile
.c_str());
2128 fout
<< "# Hashes of file build rules.\n";
2129 for(std::map
<cmStdString
, RuleHash
>::const_iterator
2130 rhi
= this->RuleHashes
.begin(); rhi
!= this->RuleHashes
.end(); ++rhi
)
2132 fout
.write(rhi
->second
.Data
, 32);
2133 fout
<< " " << rhi
->first
<< "\n";
2139 //----------------------------------------------------------------------------
2140 void cmGlobalGenerator::WriteSummary()
2142 cmMakefile
* mf
= this->LocalGenerators
[0]->GetMakefile();
2144 // Record all target directories in a central location.
2145 std::string fname
= mf
->GetHomeOutputDirectory();
2146 fname
+= cmake::GetCMakeFilesDirectory();
2147 fname
+= "/TargetDirectories.txt";
2148 cmGeneratedFileStream
fout(fname
.c_str());
2150 // Generate summary information files for each target.
2152 for(std::map
<cmStdString
,cmTarget
*>::const_iterator ti
=
2153 this->TotalTargets
.begin(); ti
!= this->TotalTargets
.end(); ++ti
)
2155 this->WriteSummary(ti
->second
);
2156 fout
<< ti
->second
->GetSupportDirectory() << "\n";
2160 //----------------------------------------------------------------------------
2161 void cmGlobalGenerator::WriteSummary(cmTarget
* target
)
2163 // Place the labels file in a per-target support directory.
2164 std::string dir
= target
->GetSupportDirectory();
2165 std::string file
= dir
;
2166 file
+= "/Labels.txt";
2168 // Check whether labels are enabled for this target.
2169 if(const char* value
= target
->GetProperty("LABELS"))
2171 cmSystemTools::MakeDirectory(dir
.c_str());
2172 cmGeneratedFileStream
fout(file
.c_str());
2174 // List the target-wide labels. All sources in the target get
2176 std::vector
<std::string
> labels
;
2177 cmSystemTools::ExpandListArgument(value
, labels
);
2180 fout
<< "# Target labels\n";
2181 for(std::vector
<std::string
>::const_iterator li
= labels
.begin();
2182 li
!= labels
.end(); ++li
)
2184 fout
<< " " << *li
<< "\n";
2188 // List the source files with any per-source labels.
2189 fout
<< "# Source files and their labels\n";
2190 std::vector
<cmSourceFile
*> const& sources
= target
->GetSourceFiles();
2191 for(std::vector
<cmSourceFile
*>::const_iterator si
= sources
.begin();
2192 si
!= sources
.end(); ++si
)
2194 cmSourceFile
* sf
= *si
;
2195 fout
<< sf
->GetFullPath() << "\n";
2196 if(const char* svalue
= sf
->GetProperty("LABELS"))
2199 cmSystemTools::ExpandListArgument(svalue
, labels
);
2200 for(std::vector
<std::string
>::const_iterator li
= labels
.begin();
2201 li
!= labels
.end(); ++li
)
2203 fout
<< " " << *li
<< "\n";
2210 cmSystemTools::RemoveFile(file
.c_str());