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 ============================================================================*/
16 #include "cmSystemTools.h"
17 #include "cmPropertyDefinitionMap.h"
18 #include "cmPropertyMap.h"
20 class cmGlobalGeneratorFactory;
21 class cmGlobalGenerator;
22 class cmLocalGenerator;
26 class cmVariableWatch;
27 class cmFileTimeComparison;
28 class cmExternalMakefileProjectGenerator;
29 class cmDocumentationSection;
31 class cmListFileBacktrace;
33 class cmGeneratedFileStream;
35 /** \brief Represents a cmake invocation.
37 * This class represents a cmake invocation. It is the top level class when
38 * running cmake. Most cmake based GUIs should primarily create an instance
39 * of this class and communicate with it.
41 * The basic process for a GUI is as follows:
43 * -# Create a cmake instance
44 * -# Set the Home & Start directories, generator, and cmake command. this
45 * can be done using the Set methods or by using SetArgs and passing in
46 * command line arguments.
47 * -# Load the cache by calling LoadCache (duh)
48 * -# if you are using command line arguments with -D or -C flags then
49 * call SetCacheArgs (or if for some other reason you want to modify the
51 * -# Finally call Configure
52 * -# Let the user change values and go back to step 5
55 * If your GUI allows the user to change the start & home directories then
56 * you must at a minimum redo steps 2 through 7.
72 /** \brief Describes the working modes of cmake */
75 NORMAL_MODE, ///< Cmake runs to create project files
76 /** \brief Script mode (started by using -P).
78 * In script mode there is no generator and no cache. Also,
79 * languages are not enabled, so add_executable and things do
83 /** \brief A pkg-config like mode
85 * In this mode cmake just searches for a package and prints the results to
86 * stdout. This is similar to SCRIPT_MODE, but commands like add_library()
87 * work too, since they may be used e.g. in exported target files. Started
92 typedef std::map<cmStdString, cmCommand*> RegisteredCommandsMap;
94 /// Default constructor
99 static const char *GetCMakeFilesDirectory() {return "/CMakeFiles";};
100 static const char *GetCMakeFilesDirectoryPostSlash() {
101 return "CMakeFiles/";};
105 * Set/Get the home directory (or output directory) in the project. The
106 * home directory is the top directory of the project. It is the
107 * path-to-source cmake was run with. Remember that CMake processes
108 * CMakeLists files by recursing up the tree starting at the StartDirectory
109 * and going up until it reaches the HomeDirectory.
111 void SetHomeDirectory(const char* dir);
112 const char* GetHomeDirectory() const
114 return this->cmHomeDirectory.c_str();
116 void SetHomeOutputDirectory(const char* lib);
117 const char* GetHomeOutputDirectory() const
119 return this->HomeOutputDirectory.c_str();
125 * Set/Get the start directory (or output directory). The start directory
126 * is the directory of the CMakeLists.txt file that started the current
127 * round of processing. Remember that CMake processes CMakeLists files by
128 * recursing up the tree starting at the StartDirectory and going up until
129 * it reaches the HomeDirectory.
131 void SetStartDirectory(const char* dir)
133 this->cmStartDirectory = dir;
134 cmSystemTools::ConvertToUnixSlashes(this->cmStartDirectory);
136 const char* GetStartDirectory() const
138 return this->cmStartDirectory.c_str();
140 void SetStartOutputDirectory(const char* lib)
142 this->StartOutputDirectory = lib;
143 cmSystemTools::ConvertToUnixSlashes(this->StartOutputDirectory);
145 const char* GetStartOutputDirectory() const
147 return this->StartOutputDirectory.c_str();
152 * Handle a command line invocation of cmake.
154 int Run(const std::vector<std::string>&args)
155 { return this->Run(args, false); }
156 int Run(const std::vector<std::string>&args, bool noconfigure);
159 * Run the global generator Generate step.
164 * Configure the cmMakefiles. This routine will create a GlobalGenerator if
165 * one has not already been set. It will then Call Configure on the
166 * GlobalGenerator. This in turn will read in an process all the CMakeList
167 * files for the tree. It will not produce any actual Makefiles, or
168 * workspaces. Generate does that. */
170 int ActualConfigure();
173 void PreLoadCMakeFiles();
175 ///! Create a GlobalGenerator
176 cmGlobalGenerator* CreateGlobalGenerator(const char* name);
178 ///! Return the global generator assigned to this instance of cmake
179 cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; }
180 ///! Return the global generator assigned to this instance of cmake, const
181 const cmGlobalGenerator* GetGlobalGenerator() const
182 { return this->GlobalGenerator; }
184 ///! Return the global generator assigned to this instance of cmake
185 void SetGlobalGenerator(cmGlobalGenerator *);
187 ///! Get the names of the current registered generators
188 void GetRegisteredGenerators(std::vector<std::string>& names);
190 ///! Set the name of the selected generator-specific toolset.
191 void SetGeneratorToolset(std::string const& ts)
192 { this->GeneratorToolset = ts; }
194 ///! Get the name of the selected generator-specific toolset.
195 std::string const& GetGeneratorToolset() const
196 { return this->GeneratorToolset; }
198 ///! get the cmCachemManager used by this invocation of cmake
199 cmCacheManager *GetCacheManager() { return this->CacheManager; }
201 ///! set the cmake command this instance of cmake should use
202 void SetCMakeCommand(const char* cmd) { this->CMakeCommand = cmd; }
205 * Given a variable name, return its value (as a string).
207 const char* GetCacheDefinition(const char*) const;
208 ///! Add an entry into the cache
209 void AddCacheEntry(const char* key, const char* value,
210 const char* helpString,
213 * Execute commands during the build process. Supports options such
214 * as echo, remove file etc.
216 static int ExecuteCMakeCommand(std::vector<std::string>&);
219 * Get the system information and write it to the file specified
221 int GetSystemInformation(std::vector<std::string>&);
224 * Add a command to this cmake instance
226 void AddCommand(cmCommand* );
227 void RenameCommand(const char* oldName, const char* newName);
228 void RemoveCommand(const char* name);
229 void RemoveUnscriptableCommands();
232 * Get a command by its name
234 cmCommand *GetCommand(const char *name);
236 /** Get list of all commands */
237 RegisteredCommandsMap* GetCommands() { return &this->Commands; }
239 /** Check if a command exists. */
240 bool CommandExists(const char* name) const;
242 ///! Parse command line arguments
243 void SetArgs(const std::vector<std::string>&,
244 bool directoriesSetBefore = false);
246 ///! Is this cmake running as a result of a TRY_COMPILE command
247 bool GetIsInTryCompile() { return this->InTryCompile; }
249 ///! Is this cmake running as a result of a TRY_COMPILE command
250 void SetIsInTryCompile(bool i) { this->InTryCompile = i; }
252 ///! Parse command line arguments that might set cache values
253 bool SetCacheArgs(const std::vector<std::string>&);
255 typedef void (*ProgressCallbackType)
256 (const char*msg, float progress, void *);
258 * Set the function used by GUIs to receive progress updates
259 * Function gets passed: message as a const char*, a progress
260 * amount ranging from 0 to 1.0 and client data. The progress
261 * number provided may be negative in cases where a message is
262 * to be displayed without any progress percentage.
264 void SetProgressCallback(ProgressCallbackType f, void* clientData=0);
266 ///! this is called by generators to update the progress
267 void UpdateProgress(const char *msg, float prog);
269 ///! get the cmake policies instance
270 cmPolicies *GetPolicies() {return this->Policies;} ;
272 ///! Get the variable watch object
273 cmVariableWatch* GetVariableWatch() { return this->VariableWatch; }
275 /** Get the documentation entries for the supported commands.
276 * If withCurrentCommands is true, the documentation for the
277 * recommended set of commands is included.
278 * If withCompatCommands is true, the documentation for discouraged
279 * (compatibility) commands is included.
280 * You probably don't want to set both to false.
282 void GetCommandDocumentation(std::vector<cmDocumentationEntry>& entries,
283 bool withCurrentCommands = true,
284 bool withCompatCommands = true) const;
285 void GetPropertiesDocumentation(std::map<std::string,
286 cmDocumentationSection *>&);
287 void GetGeneratorDocumentation(std::vector<cmDocumentationEntry>&);
288 void GetPolicyDocumentation(std::vector<cmDocumentationEntry>& entries);
290 ///! Set/Get a property of this target file
291 void SetProperty(const char *prop, const char *value);
292 void AppendProperty(const char *prop, const char *value,bool asString=false);
293 const char *GetProperty(const char *prop);
294 const char *GetProperty(const char *prop, cmProperty::ScopeType scope);
295 bool GetPropertyAsBool(const char *prop);
297 // Get the properties
298 cmPropertyMap &GetProperties() { return this->Properties; };
300 ///! Do all the checks before running configure
301 int DoPreConfigureChecks();
303 void SetWorkingMode(WorkingMode mode) { this->CurrentWorkingMode = mode; }
304 WorkingMode GetWorkingMode() { return this->CurrentWorkingMode; }
306 ///! Debug the try compile stuff by not deleting the files
307 bool GetDebugTryCompile(){return this->DebugTryCompile;}
308 void DebugTryCompileOn(){this->DebugTryCompile = true;}
311 * Generate CMAKE_ROOT and CMAKE_COMMAND cache entries
316 * Get the file comparison class
318 cmFileTimeComparison* GetFileComparison() { return this->FileComparison; }
321 * Get the path to ctest
323 const char* GetCTestCommand();
324 const char* GetCPackCommand();
325 const char* GetCMakeCommand();
327 // Do we want debug output during the cmake run.
328 bool GetDebugOutput() { return this->DebugOutput; }
329 void SetDebugOutputOn(bool b) { this->DebugOutput = b;}
331 // Do we want trace output during the cmake run.
332 bool GetTrace() { return this->Trace;}
333 void SetTrace(bool b) { this->Trace = b;}
334 bool GetWarnUninitialized() { return this->WarnUninitialized;}
335 void SetWarnUninitialized(bool b) { this->WarnUninitialized = b;}
336 bool GetWarnUnused() { return this->WarnUnused;}
337 void SetWarnUnused(bool b) { this->WarnUnused = b;}
338 bool GetWarnUnusedCli() { return this->WarnUnusedCli;}
339 void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b;}
340 bool GetCheckSystemVars() { return this->CheckSystemVars;}
341 void SetCheckSystemVars(bool b) { this->CheckSystemVars = b;}
343 void MarkCliAsUsed(const std::string& variable);
346 void DefineProperty(const char *name, cmProperty::ScopeType scope,
347 const char *ShortDescription,
348 const char *FullDescription,
350 const char *variableGroup = 0);
352 bool GetIsPropertyDefined(const char *name, cmProperty::ScopeType scope);
354 // get property definition
355 cmPropertyDefinition *GetPropertyDefinition
356 (const char *name, cmProperty::ScopeType scope);
358 // Is a property defined?
359 bool IsPropertyDefined(const char *name, cmProperty::ScopeType scope);
360 bool IsPropertyChained(const char *name, cmProperty::ScopeType scope);
362 /** Get the list of configurations (in upper case) considered to be
363 debugging configurations.*/
364 std::vector<std::string> const& GetDebugConfigs();
366 // record accesses of properties and variables
367 void RecordPropertyAccess(const char *name, cmProperty::ScopeType scope);
368 void ReportUndefinedPropertyAccesses(const char *filename);
370 // Define the properties
371 static void DefineProperties(cmake *cm);
373 void SetCMakeEditCommand(const char* s)
375 this->CMakeEditCommand = s;
377 void SetSuppressDevWarnings(bool v)
379 this->SuppressDevWarnings = v;
380 this->DoSuppressDevWarnings = true;
383 /** Display a message to the user. */
384 void IssueMessage(cmake::MessageType t, std::string const& text,
385 cmListFileBacktrace const& backtrace);
386 ///! run the --build option
387 int Build(const std::string& dir,
388 const std::string& target,
389 const std::string& config,
390 const std::vector<std::string>& nativeOptions,
392 cmSystemTools::OutputOption outputflag);
394 void UnwatchUnusedCli(const char* var);
395 void WatchUnusedCli(const char* var);
397 void RunCheckForUnusedVariables();
398 void InitializeProperties();
399 int HandleDeleteCacheVariables(const char* var);
400 cmPropertyMap Properties;
401 std::set<std::pair<cmStdString,cmProperty::ScopeType> > AccessedProperties;
403 std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>
407 cmExternalMakefileProjectGenerator* (*CreateExtraGeneratorFunctionType)();
408 typedef std::map<cmStdString,
409 CreateExtraGeneratorFunctionType> RegisteredExtraGeneratorsMap;
410 typedef std::vector<cmGlobalGeneratorFactory*> RegisteredGeneratorsVector;
411 RegisteredCommandsMap Commands;
412 RegisteredGeneratorsVector Generators;
413 RegisteredExtraGeneratorsMap ExtraGenerators;
414 void AddDefaultCommands();
415 void AddDefaultGenerators();
416 void AddDefaultExtraGenerators();
417 void AddExtraGenerator(const char* name,
418 CreateExtraGeneratorFunctionType newFunction);
420 cmPolicies *Policies;
421 cmGlobalGenerator *GlobalGenerator;
422 cmCacheManager *CacheManager;
423 std::string cmHomeDirectory;
424 std::string HomeOutputDirectory;
425 std::string cmStartDirectory;
426 std::string StartOutputDirectory;
427 bool SuppressDevWarnings;
428 bool DoSuppressDevWarnings;
429 std::string GeneratorToolset;
431 ///! read in a cmake list file to initialize the cache
432 void ReadListFile(const std::vector<std::string>& args, const char *path);
433 bool FindPackage(const std::vector<std::string>& args);
435 ///! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file.
436 /// If it is set, truncate it to 50kb
437 void TruncateOutputLog(const char* fname);
440 * Method called to check build system integrity at build time.
441 * Returns 1 if CMake should rerun and 0 otherwise.
443 int CheckBuildSystem();
445 void SetDirectoriesFromFile(const char* arg);
447 //! Make sure all commands are what they say they are and there is no
449 void CleanupCommandsAndMacros();
451 void GenerateGraphViz(const char* fileName) const;
453 static int SymlinkLibrary(std::vector<std::string>& args);
454 static int SymlinkExecutable(std::vector<std::string>& args);
455 static bool SymlinkInternal(std::string const& file,
456 std::string const& link);
457 static int ExecuteEchoColor(std::vector<std::string>& args);
458 static int ExecuteLinkScript(std::vector<std::string>& args);
459 static int WindowsCEEnvironment(const char* version,
460 const std::string& name);
461 static int VisualStudioLink(std::vector<std::string>& args, int type);
462 static int VisualStudioLinkIncremental(std::vector<std::string>& args,
465 static int VisualStudioLinkNonIncremental(std::vector<std::string>& args,
469 static int ParseVisualStudioLinkCommand(std::vector<std::string>& args,
470 std::vector<cmStdString>& command,
471 std::string& targetName);
472 static bool RunCommand(const char* comment,
473 std::vector<cmStdString>& command,
475 int* retCodeOut = 0);
476 cmVariableWatch* VariableWatch;
478 ///! Find the full path to one of the cmake programs like ctest, cpack, etc.
479 std::string FindCMakeProgram(const char* name) const;
481 cmake(const cmake&); // Not implemented.
482 void operator=(const cmake&); // Not implemented.
483 ProgressCallbackType ProgressCallback;
484 void* ProgressCallbackClientData;
487 WorkingMode CurrentWorkingMode;
490 bool WarnUninitialized;
493 bool CheckSystemVars;
494 std::map<cmStdString, bool> UsedCliVariables;
495 std::string CMakeEditCommand;
496 std::string CMakeCommand;
497 std::string CXXEnvironment;
498 std::string CCEnvironment;
499 std::string CheckBuildSystemArgument;
500 std::string CheckStampFile;
501 std::string CheckStampList;
502 std::string VSSolutionFile;
503 std::string CTestCommand;
504 std::string CPackCommand;
505 bool ClearBuildSystem;
506 bool DebugTryCompile;
507 cmFileTimeComparison* FileComparison;
508 std::string GraphVizFile;
509 std::vector<std::string> DebugConfigs;
511 void UpdateConversionPathTable();
514 #define CMAKE_STANDARD_OPTIONS_TABLE \
515 {"-C <initial-cache>", "Pre-load a script to populate the cache.", \
516 "When cmake is first run in an empty build tree, it creates a " \
517 "CMakeCache.txt file and populates it with customizable settings " \
518 "for the project. This option may be used to specify a file from " \
519 "which to load cache entries before the first pass through " \
520 "the project's cmake listfiles. The loaded entries take priority " \
521 "over the project's default values. The given file should be a CMake " \
522 "script containing SET commands that use the CACHE option, " \
523 "not a cache-format file."}, \
524 {"-D <var>:<type>=<value>", "Create a cmake cache entry.", \
525 "When cmake is first run in an empty build tree, it creates a " \
526 "CMakeCache.txt file and populates it with customizable settings " \
527 "for the project. This option may be used to specify a setting " \
528 "that takes priority over the project's default value. The option " \
529 "may be repeated for as many cache entries as desired."}, \
530 {"-U <globbing_expr>", "Remove matching entries from CMake cache.", \
531 "This option may be used to remove one or more variables from the " \
532 "CMakeCache.txt file, globbing expressions using * and ? are supported. "\
533 "The option may be repeated for as many cache entries as desired.\n" \
534 "Use with care, you can make your CMakeCache.txt non-working."}, \
535 {"-G <generator-name>", "Specify a build system generator.", \
536 "CMake may support multiple native build systems on certain platforms. " \
537 "A generator is responsible for generating a particular build " \
538 "system. Possible generator names are specified in the Generators " \
540 {"-T <toolset-name>", "Specify toolset name if supported by generator.", \
541 "Some CMake generators support a toolset name to be given to the " \
542 "native build system to choose a compiler. " \
543 "This is supported only on specific generators:\n" \
544 " Visual Studio >= 10\n" \
546 "See native build system documentation for allowed toolset names."}, \
547 {"-Wno-dev", "Suppress developer warnings.",\
548 "Suppress warnings that are meant for the author"\
549 " of the CMakeLists.txt files."},\
550 {"-Wdev", "Enable developer warnings.",\
551 "Enable warnings that are meant for the author"\
552 " of the CMakeLists.txt files."}
555 #define CMAKE_STANDARD_INTRODUCTION \
557 "CMake is a cross-platform build system generator. Projects " \
558 "specify their build process with platform-independent CMake listfiles " \
559 "included in each directory of a source tree with the name " \
561 "Users build a project by using CMake to generate a build system " \
562 "for a native tool on their platform.", 0}