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 these first, otherwise there will be problems on Windows
13 // with GetCurrentDirectory() being redefined
14 #ifdef CMAKE_BUILD_WITH_CMAKE
15 #include "cmDynamicLoader.h"
16 #include "cmDocumentation.h"
20 #include "cmCacheManager.h"
21 #include "cmListFileCache.h"
22 #include "cmakewizard.h"
23 #include "cmSourceFile.h"
24 #include "cmGlobalGenerator.h"
25 #include "cmLocalGenerator.h"
26 #include "cmMakefile.h"
28 #ifdef CMAKE_BUILD_WITH_CMAKE
29 //----------------------------------------------------------------------------
30 static const char * cmDocumentationName[][3] =
33 " cmake - Cross-Platform Makefile Generator.", 0},
37 //----------------------------------------------------------------------------
38 static const char * cmDocumentationUsage[][3] =
41 " cmake [options] <path-to-source>\n"
42 " cmake [options] <path-to-existing-build>", 0},
46 //----------------------------------------------------------------------------
47 static const char * cmDocumentationDescription[][3] =
50 "The \"cmake\" executable is the CMake command-line interface. It may "
51 "be used to configure projects in scripts. Project configuration "
53 "may be specified on the command line with the -D option. The -i option "
54 "will cause cmake to interactively prompt for such settings.", 0},
55 CMAKE_STANDARD_INTRODUCTION,
59 #define CMAKE_BUILD_OPTIONS \
60 " <dir> = Project binary directory to be built.\n" \
61 " --target <tgt> = Build <tgt> instead of default targets.\n" \
62 " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \
63 " --clean-first = Build target 'clean' first, then build.\n" \
64 " (To clean only, use --target 'clean'.)\n" \
65 " --use-stderr = Don't merge stdout/stderr output and pass the\n" \
66 " original stdout/stderr handles to the native\n" \
67 " tool so it can use the capabilities of the\n" \
68 " calling terminal (e.g. colored output).\n" \
69 " -- = Pass remaining options to the native tool.\n"
71 //----------------------------------------------------------------------------
72 static const char * cmDocumentationOptions[][3] =
74 CMAKE_STANDARD_OPTIONS_TABLE,
75 {"-E", "CMake command mode.",
76 "For true platform independence, CMake provides a list of commands "
77 "that can be used on all systems. Run with -E help for the usage "
78 "information. Commands available are: chdir, compare_files, copy, "
79 "copy_directory, copy_if_different, echo, echo_append, environment, "
80 "make_directory, md5sum, remove, remove_directory, rename, tar, time, "
81 "touch, touch_nocreate. In addition, some platform specific commands "
83 "On Windows: comspec, delete_regv, write_regv. "
84 "On UNIX: create_symlink."},
85 {"-i", "Run in wizard mode.",
86 "Wizard mode runs cmake interactively without a GUI. The user is "
87 "prompted to answer questions about the project configuration. "
88 "The answers are used to set cmake cache values."},
89 {"-L[A][H]", "List non-advanced cached variables.",
90 "List cache variables will run CMake and list all the variables from the "
91 "CMake cache that are not marked as INTERNAL or ADVANCED. This will "
92 "effectively display current CMake settings, which can then be changed "
93 "with -D option. Changing some of the variables may result in more "
94 "variables being created. If A is specified, then it will display also "
95 "advanced variables. If H is specified, it will also display help for "
97 {"--build <dir>", "Build a CMake-generated project binary tree.",
98 "This abstracts a native build tool's command-line interface with the "
99 "following options:\n"
101 "Run cmake --build with no options for quick help."},
102 {"-N", "View mode only.",
103 "Only load the cache. Do not actually run configure and generate steps."},
104 {"-P <file>", "Process script mode.",
105 "Process the given cmake file as a script written in the CMake language. "
106 "No configure or generate step is performed and the cache is not"
107 " modified. If variables are defined using -D, this must be done "
108 "before the -P argument."},
109 {"--find-package", "Run in pkg-config like mode.",
110 "Search a package using find_package() and print the resulting flags "
111 "to stdout. This can be used to use cmake instead of pkg-config to find "
112 "installed libraries in plain Makefile-based projects or in "
113 "autoconf-based projects (via share/aclocal/cmake.m4)."},
114 {"--graphviz=[file]", "Generate graphviz of dependencies, see "
115 "CMakeGraphVizOptions.cmake for more.",
116 "Generate a graphviz input file that will contain all the library and "
117 "executable dependencies in the project. See the documentation for "
118 "CMakeGraphVizOptions.cmake for more details. "},
119 {"--system-information [file]", "Dump information about this system.",
120 "Dump a wide range of information about the current system. If run "
121 "from the top of a binary tree for a CMake project it will dump "
122 "additional information such as the cache, log files etc."},
123 {"--debug-trycompile", "Do not delete the try_compile build tree. Only "
124 "useful on one try_compile at a time.",
125 "Do not delete the files and directories created for try_compile calls. "
126 "This is useful in debugging failed try_compiles. It may however "
127 "change the results of the try-compiles as old junk from a previous "
128 "try-compile may cause a different test to either pass or fail "
129 "incorrectly. This option is best used for one try-compile at a time, "
130 "and only when debugging." },
131 {"--debug-output", "Put cmake in a debug mode.",
132 "Print extra stuff during the cmake run like stack traces with "
133 "message(send_error ) calls."},
134 {"--trace", "Put cmake in trace mode.",
135 "Print a trace of all calls made and from where with "
136 "message(send_error ) calls."},
137 {"--warn-uninitialized", "Warn about uninitialized values.",
138 "Print a warning when an uninitialized variable is used."},
139 {"--warn-unused-vars", "Warn about unused variables.",
140 "Find variables that are declared or set, but not used."},
141 {"--no-warn-unused-cli", "Don't warn about command line options.",
142 "Don't find variables that are declared on the command line, but not "
144 {"--check-system-vars", "Find problems with variable usage in system "
145 "files.", "Normally, unused and uninitialized variables are searched for "
146 "only in CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR. This flag tells CMake to "
147 "warn about other files as well."},
148 {"--help-command cmd [file]", "Print help for a single command and exit.",
149 "Full documentation specific to the given command is displayed. "
150 "If a file is specified, the documentation is written into and the output "
151 "format is determined depending on the filename suffix. Supported are man "
152 "page, HTML, DocBook and plain text."},
153 {"--help-command-list [file]", "List available listfile commands and exit.",
154 "The list contains all commands for which help may be obtained by using "
155 "the --help-command argument followed by a command name. "
156 "If a file is specified, the documentation is written into and the output "
157 "format is determined depending on the filename suffix. Supported are man "
158 "page, HTML, DocBook and plain text."},
159 {"--help-commands [file]", "Print help for all commands and exit.",
160 "Full documentation specific for all current commands is displayed."
161 "If a file is specified, the documentation is written into and the output "
162 "format is determined depending on the filename suffix. Supported are man "
163 "page, HTML, DocBook and plain text."},
164 {"--help-compatcommands [file]", "Print help for compatibility commands. ",
165 "Full documentation specific for all compatibility commands is displayed."
166 "If a file is specified, the documentation is written into and the output "
167 "format is determined depending on the filename suffix. Supported are man "
168 "page, HTML, DocBook and plain text."},
169 {"--help-module module [file]", "Print help for a single module and exit.",
170 "Full documentation specific to the given module is displayed."
171 "If a file is specified, the documentation is written into and the output "
172 "format is determined depending on the filename suffix. Supported are man "
173 "page, HTML, DocBook and plain text."},
174 {"--help-module-list [file]", "List available modules and exit.",
175 "The list contains all modules for which help may be obtained by using "
176 "the --help-module argument followed by a module name. "
177 "If a file is specified, the documentation is written into and the output "
178 "format is determined depending on the filename suffix. Supported are man "
179 "page, HTML, DocBook and plain text."},
180 {"--help-modules [file]", "Print help for all modules and exit.",
181 "Full documentation for all modules is displayed. "
182 "If a file is specified, the documentation is written into and the output "
183 "format is determined depending on the filename suffix. Supported are man "
184 "page, HTML, DocBook and plain text."},
185 {"--help-custom-modules [file]" , "Print help for all custom modules and "
187 "Full documentation for all custom modules is displayed. "
188 "If a file is specified, the documentation is written into and the output "
189 "format is determined depending on the filename suffix. Supported are man "
190 "page, HTML, DocBook and plain text."},
191 {"--help-policy cmp [file]",
192 "Print help for a single policy and exit.",
193 "Full documentation specific to the given policy is displayed."
194 "If a file is specified, the documentation is written into and the output "
195 "format is determined depending on the filename suffix. Supported are man "
196 "page, HTML, DocBook and plain text."},
197 {"--help-policies [file]", "Print help for all policies and exit.",
198 "Full documentation for all policies is displayed."
199 "If a file is specified, the documentation is written into and the output "
200 "format is determined depending on the filename suffix. Supported are man "
201 "page, HTML, DocBook and plain text."},
202 {"--help-property prop [file]",
203 "Print help for a single property and exit.",
204 "Full documentation specific to the given property is displayed."
205 "If a file is specified, the documentation is written into and the output "
206 "format is determined depending on the filename suffix. Supported are man "
207 "page, HTML, DocBook and plain text."},
208 {"--help-property-list [file]", "List available properties and exit.",
209 "The list contains all properties for which help may be obtained by using "
210 "the --help-property argument followed by a property name. If a file is "
211 "specified, the help is written into it."
212 "If a file is specified, the documentation is written into and the output "
213 "format is determined depending on the filename suffix. Supported are man "
214 "page, HTML, DocBook and plain text."},
215 {"--help-properties [file]", "Print help for all properties and exit.",
216 "Full documentation for all properties is displayed."
217 "If a file is specified, the documentation is written into and the output "
218 "format is determined depending on the filename suffix. Supported are man "
219 "page, HTML, DocBook and plain text."},
220 {"--help-variable var [file]",
221 "Print help for a single variable and exit.",
222 "Full documentation specific to the given variable is displayed."
223 "If a file is specified, the documentation is written into and the output "
224 "format is determined depending on the filename suffix. Supported are man "
225 "page, HTML, DocBook and plain text."},
226 {"--help-variable-list [file]", "List documented variables and exit.",
227 "The list contains all variables for which help may be obtained by using "
228 "the --help-variable argument followed by a variable name. If a file is "
229 "specified, the help is written into it."
230 "If a file is specified, the documentation is written into and the output "
231 "format is determined depending on the filename suffix. Supported are man "
232 "page, HTML, DocBook and plain text."},
233 {"--help-variables [file]", "Print help for all variables and exit.",
234 "Full documentation for all variables is displayed."
235 "If a file is specified, the documentation is written into and the output "
236 "format is determined depending on the filename suffix. Supported are man "
237 "page, HTML, DocBook and plain text."},
241 //----------------------------------------------------------------------------
242 static const char * cmDocumentationSeeAlso[][3] =
247 {0, "cmakecommands", 0},
248 {0, "cmakecompat", 0},
249 {0, "cmakemodules", 0},
250 {0, "cmakeprops", 0},
255 //----------------------------------------------------------------------------
256 static const char * cmDocumentationNOTE[][3] =
259 "CMake no longer configures a project when run with no arguments. "
260 "In order to configure the project in the current directory, run\n"
266 int do_cmake(int ac, char** av);
267 static int do_build(int ac, char** av);
269 static cmMakefile* cmakemainGetMakefile(void *clientdata)
271 cmake* cm = (cmake *)clientdata;
272 if(cm && cm->GetDebugOutput())
274 cmGlobalGenerator* gg=cm->GetGlobalGenerator();
277 cmLocalGenerator* lg=gg->GetCurrentLocalGenerator();
280 cmMakefile* mf = lg->GetMakefile();
288 static std::string cmakemainGetStack(void *clientdata)
291 cmMakefile* mf=cmakemainGetMakefile(clientdata);
294 msg = mf->GetListFileStack();
297 msg = "\n Called from: " + msg;
304 static void cmakemainErrorCallback(const char* m, const char*, bool&,
307 std::cerr << m << cmakemainGetStack(clientdata) << std::endl << std::flush;
310 static void cmakemainProgressCallback(const char *m, float prog,
313 cmMakefile* mf = cmakemainGetMakefile(clientdata);
315 if ((mf) && (strstr(m, "Configuring")==m) && (prog<0))
318 dir += mf->GetCurrentDirectory();
320 else if ((mf) && (strstr(m, "Generating")==m))
323 dir += mf->GetCurrentOutputDirectory();
326 if ((prog < 0) || (!dir.empty()))
328 std::cout << "-- " << m << dir << cmakemainGetStack(clientdata)<<std::endl;
335 int main(int ac, char** av)
337 cmSystemTools::EnableMSVCDebugHook();
338 cmSystemTools::FindExecutableDirectory(av[0]);
339 if(ac > 1 && strcmp(av[1], "--build") == 0)
341 return do_build(ac, av);
343 int ret = do_cmake(ac, av);
344 #ifdef CMAKE_BUILD_WITH_CMAKE
345 cmDynamicLoader::FlushCache();
350 int do_cmake(int ac, char** av)
352 if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
354 std::cerr << "Current working directory cannot be established."
359 #ifdef CMAKE_BUILD_WITH_CMAKE
361 doc.addCMakeStandardDocSections();
362 if(doc.CheckOptions(ac, av, "-E"))
364 // Construct and print requested documentation.
367 doc.SetCMakeRoot(hcm.GetCacheDefinition("CMAKE_ROOT"));
369 // the command line args are processed here so that you can do
370 // -DCMAKE_MODULE_PATH=/some/path and have this value accessible here
371 std::vector<std::string> args;
372 for(int i =0; i < ac; ++i)
374 args.push_back(av[i]);
376 hcm.SetCacheArgs(args);
377 const char* modulePath = hcm.GetCacheDefinition("CMAKE_MODULE_PATH");
380 doc.SetCMakeModulePath(modulePath);
383 std::vector<cmDocumentationEntry> commands;
384 std::vector<cmDocumentationEntry> policies;
385 std::vector<cmDocumentationEntry> compatCommands;
386 std::vector<cmDocumentationEntry> generators;
387 std::map<std::string,cmDocumentationSection *> propDocs;
389 hcm.GetPolicyDocumentation(policies);
390 hcm.GetCommandDocumentation(commands, true, false);
391 hcm.GetCommandDocumentation(compatCommands, false, true);
392 hcm.GetPropertiesDocumentation(propDocs);
393 hcm.GetGeneratorDocumentation(generators);
395 doc.SetName("cmake");
396 doc.SetSection("Name",cmDocumentationName);
397 doc.SetSection("Usage",cmDocumentationUsage);
398 doc.SetSection("Description",cmDocumentationDescription);
399 doc.AppendSection("Generators",generators);
400 doc.PrependSection("Options",cmDocumentationOptions);
401 doc.SetSection("Commands",commands);
402 doc.SetSection("Policies",policies);
403 doc.AppendSection("Compatibility Commands",compatCommands);
404 doc.SetSections(propDocs);
406 cmDocumentationEntry e;
408 "variables defined by cmake, that give information about the project, "
410 doc.PrependSection("Variables that Provide Information",e);
412 doc.SetSeeAlsoList(cmDocumentationSeeAlso);
413 int result = doc.PrintRequestedDocumentation(std::cout)? 0:1;
415 // If we were run with no arguments, but a CMakeLists.txt file
416 // exists, the user may have been trying to use the old behavior
417 // of cmake to build a project in-source. Print a message
418 // explaining the change to standard error and return an error
419 // condition in case the program is running from a script.
420 if((ac == 1) && cmSystemTools::FileExists("CMakeLists.txt"))
423 doc.SetSection("NOTE", cmDocumentationNOTE);
424 doc.Print(cmDocumentation::UsageForm, 0, std::cerr);
433 "Bootstrap CMake should not be used outside CMake build process."
440 bool sysinfo = false;
441 bool command = false;
442 bool list_cached = false;
443 bool list_all_cached = false;
444 bool list_help = false;
445 bool view_only = false;
446 cmake::WorkingMode workingMode = cmake::NORMAL_MODE;
447 std::vector<std::string> args;
448 for(int i =0; i < ac; ++i)
450 if(!command && strcmp(av[i], "-i") == 0)
454 else if(!command && strcmp(av[i], "--system-information") == 0)
458 // if command has already been set, then
460 else if (!command && strcmp(av[i], "-E") == 0)
464 else if (!command && strcmp(av[i], "-N") == 0)
468 else if (!command && strcmp(av[i], "-L") == 0)
472 else if (!command && strcmp(av[i], "-LA") == 0)
474 list_all_cached = true;
476 else if (!command && strcmp(av[i], "-LH") == 0)
481 else if (!command && strcmp(av[i], "-LAH") == 0)
483 list_all_cached = true;
486 else if (!command && strncmp(av[i], "-P", strlen("-P")) == 0)
490 cmSystemTools::Error("No script specified for argument -P");
494 workingMode = cmake::SCRIPT_MODE;
495 args.push_back(av[i]);
497 args.push_back(av[i]);
500 else if (!command && strncmp(av[i], "--find-package",
501 strlen("--find-package")) == 0)
503 workingMode = cmake::FIND_PACKAGE_MODE;
504 args.push_back(av[i]);
508 args.push_back(av[i]);
513 int ret = cmake::ExecuteCMakeCommand(args);
519 return wizard.RunWizard(args);
524 int ret = cm.GetSystemInformation(args);
528 cmSystemTools::SetErrorCallback(cmakemainErrorCallback, (void *)&cm);
529 cm.SetProgressCallback(cmakemainProgressCallback, (void *)&cm);
530 cm.SetWorkingMode(workingMode);
532 int res = cm.Run(args, view_only);
533 if ( list_cached || list_all_cached )
535 cmCacheManager::CacheIterator it =
536 cm.GetCacheManager()->GetCacheIterator();
537 std::cout << "-- Cache values" << std::endl;
538 for ( it.Begin(); !it.IsAtEnd(); it.Next() )
540 cmCacheManager::CacheEntryType t = it.GetType();
541 if ( t != cmCacheManager::INTERNAL && t != cmCacheManager::STATIC &&
542 t != cmCacheManager::UNINITIALIZED )
544 bool advanced = it.PropertyExists("ADVANCED");
545 if ( list_all_cached || !advanced)
549 std::cout << "// " << it.GetProperty("HELPSTRING") << std::endl;
551 std::cout << it.GetName() << ":" <<
552 cmCacheManager::TypeToString(it.GetType())
553 << "=" << it.GetValue() << std::endl;
556 std::cout << std::endl;
563 // Always return a non-negative value. Windows tools do not always
564 // interpret negative return values as errors.
575 //----------------------------------------------------------------------------
576 static int do_build(int ac, char** av)
578 #ifndef CMAKE_BUILD_WITH_CMAKE
579 std::cerr << "This cmake does not support --build\n";
583 std::string config = "Debug";
585 std::vector<std::string> nativeOptions;
587 cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_MERGE;
589 enum Doing { DoingNone, DoingDir, DoingTarget, DoingConfig, DoingNative};
590 Doing doing = DoingDir;
591 for(int i=2; i < ac; ++i)
593 if(doing == DoingNative)
595 nativeOptions.push_back(av[i]);
597 else if(strcmp(av[i], "--target") == 0)
601 else if(strcmp(av[i], "--config") == 0)
605 else if(strcmp(av[i], "--clean-first") == 0)
610 else if(strcmp(av[i], "--use-stderr") == 0)
612 outputflag = cmSystemTools::OUTPUT_PASSTHROUGH;
614 else if(strcmp(av[i], "--") == 0)
635 std::cerr << "Unknown argument " << av[i] << std::endl;
644 "Usage: cmake --build <dir> [options] [-- [native-options]]\n"
651 // Hack for vs6 that passes ".\Debug" as "$(IntDir)" value:
653 if (cmSystemTools::StringStartsWith(config.c_str(), ".\\"))
655 config = config.substr(2);
659 return cm.Build(dir, target, config, nativeOptions, clean, outputflag);