Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / CPack / cpack.cxx
blob00d9dae54547569352196642fc3f93a87583d707
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cpack.cxx,v $
5 Language: C++
6 Date: $Date: 2009-01-22 18:56:13 $
7 Version: $Revision: 1.46 $
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 #include "cmSystemTools.h"
19 // Need these for documentation support.
20 #include "cmake.h"
21 #include "cmDocumentation.h"
22 #include "cmCPackGeneratorFactory.h"
23 #include "cmCPackGenerator.h"
24 #include "cmake.h"
25 #include "cmGlobalGenerator.h"
26 #include "cmLocalGenerator.h"
27 #include "cmMakefile.h"
29 #include "cmCPackLog.h"
31 #include <cmsys/CommandLineArguments.hxx>
32 #include <memory> // auto_ptr
34 //----------------------------------------------------------------------------
35 static const char * cmDocumentationName[][3] =
37 {0,
38 " cpack - Packaging driver provided by CMake.", 0},
39 {0,0,0}
42 //----------------------------------------------------------------------------
43 static const char * cmDocumentationUsage[][3] =
45 {0,
46 " cpack -G <generator> [options]",
47 0},
48 {0,0,0}
51 //----------------------------------------------------------------------------
52 static const char * cmDocumentationDescription[][3] =
54 {0,
55 "The \"cpack\" executable is the CMake packaging program. "
56 "CMake-generated build trees created for projects that use "
57 "the INSTALL_* commands have packaging support. "
58 "This program will generate the package.", 0},
59 CMAKE_STANDARD_INTRODUCTION,
60 {0,0,0}
63 //----------------------------------------------------------------------------
64 static const char * cmDocumentationOptions[][3] =
66 {"-G <generator>", "Use the specified generator to generate package.",
67 "CPack may support multiple native packaging systems on certain "
68 "platforms. A generator is responsible for generating input files for "
69 "particular system and invoking that systems. Possible generator names "
70 "are specified in the Generators section." },
71 {"-C <Configuration>", "Specify the project configuration",
72 "This option specifies the configuration that the project was build "
73 "with, for example 'Debug', 'Release'." },
74 {"-D <var>=<value>", "Set a CPack variable.", \
75 "Set a variable that can be used by the generator."}, \
76 {"--config <config file>", "Specify the config file.",
77 "Specify the config file to use to create the package. By default "
78 "CPackConfig.cmake in the current directory will be used." },
79 {0,0,0}
82 //----------------------------------------------------------------------------
83 static const char * cmDocumentationSeeAlso[][3] =
85 {0, "cmake", 0},
86 {0, "ccmake", 0},
87 {0, 0, 0}
90 //----------------------------------------------------------------------------
91 int cpackUnknownArgument(const char*, void*)
93 return 1;
96 //----------------------------------------------------------------------------
97 struct cpackDefinitions
99 typedef std::map<cmStdString, cmStdString> MapType;
100 MapType Map;
101 cmCPackLog *Log;
104 //----------------------------------------------------------------------------
105 int cpackDefinitionArgument(const char* argument, const char* cValue,
106 void* call_data)
108 (void)argument;
109 cpackDefinitions* def = static_cast<cpackDefinitions*>(call_data);
110 std::string value = cValue;
111 size_t pos = value.find_first_of("=");
112 if ( pos == std::string::npos )
114 cmCPack_Log(def->Log, cmCPackLog::LOG_ERROR,
115 "Please specify CPack definitions as: KEY=VALUE" << std::endl);
116 return 0;
118 std::string key = value.substr(0, pos);
119 value = value.c_str() + pos + 1;
120 def->Map[key] = value;
121 cmCPack_Log(def->Log, cmCPackLog::LOG_DEBUG, "Set CPack variable: "
122 << key.c_str() << " to \"" << value.c_str() << "\"" << std::endl);
123 return 1;
126 //----------------------------------------------------------------------------
127 // this is CPack.
128 int main (int argc, char *argv[])
130 cmSystemTools::FindExecutableDirectory(argv[0]);
131 cmCPackLog log;
132 log.SetErrorPrefix("CPack Error: ");
133 log.SetWarningPrefix("CPack Warning: ");
134 log.SetOutputPrefix("CPack: ");
135 log.SetVerbosePrefix("CPack Verbose: ");
137 cmSystemTools::EnableMSVCDebugHook();
139 if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
141 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
142 "Current working directory cannot be established." << std::endl);
145 std::string generator;
146 bool help = false;
147 bool helpVersion = false;
148 bool verbose = false;
149 bool debug = false;
150 std::string helpFull;
151 std::string helpMAN;
152 std::string helpHTML;
154 std::string cpackProjectName;
155 std::string cpackProjectDirectory
156 = cmsys::SystemTools::GetCurrentWorkingDirectory();
157 std::string cpackBuildConfig;
158 std::string cpackProjectVersion;
159 std::string cpackProjectPatch;
160 std::string cpackProjectVendor;
161 std::string cpackConfigFile;
163 cpackDefinitions definitions;
164 definitions.Log = &log;
166 cpackConfigFile = "";
168 cmDocumentation doc;
169 cmsys::CommandLineArguments arg;
170 arg.Initialize(argc, argv);
171 typedef cmsys::CommandLineArguments argT;
172 // Help arguments
173 arg.AddArgument("--help", argT::NO_ARGUMENT, &help, "CPack help");
174 arg.AddArgument("--help-full", argT::SPACE_ARGUMENT, &helpFull,
175 "CPack help");
176 arg.AddArgument("--help-html", argT::SPACE_ARGUMENT, &helpHTML,
177 "CPack help");
178 arg.AddArgument("--help-man", argT::SPACE_ARGUMENT, &helpMAN, "CPack help");
179 arg.AddArgument("--version", argT::NO_ARGUMENT, &helpVersion, "CPack help");
181 arg.AddArgument("-V", argT::NO_ARGUMENT, &verbose, "CPack verbose");
182 arg.AddArgument("--verbose", argT::NO_ARGUMENT, &verbose, "-V");
183 arg.AddArgument("--debug", argT::NO_ARGUMENT, &debug, "-V");
184 arg.AddArgument("--config", argT::SPACE_ARGUMENT, &cpackConfigFile,
185 "CPack configuration file");
186 arg.AddArgument("-C", argT::SPACE_ARGUMENT, &cpackBuildConfig,
187 "CPack build configuration");
188 arg.AddArgument("-G", argT::SPACE_ARGUMENT,
189 &generator, "CPack generator");
190 arg.AddArgument("-P", argT::SPACE_ARGUMENT,
191 &cpackProjectName, "CPack project name");
192 arg.AddArgument("-R", argT::SPACE_ARGUMENT,
193 &cpackProjectVersion, "CPack project version");
194 arg.AddArgument("-B", argT::SPACE_ARGUMENT,
195 &cpackProjectDirectory, "CPack project directory");
196 arg.AddArgument("--patch", argT::SPACE_ARGUMENT,
197 &cpackProjectPatch, "CPack project patch");
198 arg.AddArgument("--vendor", argT::SPACE_ARGUMENT,
199 &cpackProjectVendor, "CPack project vendor");
200 arg.AddCallback("-D", argT::SPACE_ARGUMENT,
201 cpackDefinitionArgument, &definitions, "CPack Definitions");
202 arg.SetUnknownArgumentCallback(cpackUnknownArgument);
204 // Parse command line
205 int parsed = arg.Parse();
207 // Setup logging
208 if ( verbose )
210 log.SetVerbose(verbose);
211 cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Verbse" << std::endl);
213 if ( debug )
215 log.SetDebug(debug);
216 cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Debug" << std::endl);
219 cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
220 "Read CPack config file: " << cpackConfigFile.c_str() << std::endl);
222 cmake cminst;
223 cminst.RemoveUnscriptableCommands();
224 cmGlobalGenerator cmgg;
225 cmgg.SetCMakeInstance(&cminst);
226 std::auto_ptr<cmLocalGenerator> cmlg(cmgg.CreateLocalGenerator());
227 cmMakefile* globalMF = cmlg->GetMakefile();
229 bool cpackConfigFileSpecified = true;
230 if ( cpackConfigFile.empty() )
232 cpackConfigFile = cmSystemTools::GetCurrentWorkingDirectory();
233 cpackConfigFile += "/CPackConfig.cmake";
234 cpackConfigFileSpecified = false;
237 cmCPackGeneratorFactory generators;
238 generators.SetLogger(&log);
239 cmCPackGenerator* cpackGenerator = 0;
241 if ( !helpFull.empty() || !helpMAN.empty() ||
242 !helpHTML.empty() || helpVersion )
244 help = true;
247 if ( parsed && !help )
249 // find out which system cpack is running on, so it can setup the search
250 // paths, so FIND_XXX() commands can be used in scripts
251 cminst.AddCMakePaths();
252 std::string systemFile =
253 globalMF->GetModulesFile("CMakeDetermineSystem.cmake");
254 if (!globalMF->ReadListFile(0, systemFile.c_str()))
256 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
257 "Error reading CMakeDetermineSystem.cmake" << std::endl);
258 return 1;
261 systemFile =
262 globalMF->GetModulesFile("CMakeSystemSpecificInformation.cmake");
263 if (!globalMF->ReadListFile(0, systemFile.c_str()))
265 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
266 "Error reading CMakeSystemSpecificInformation.cmake" << std::endl);
267 return 1;
270 if ( cmSystemTools::FileExists(cpackConfigFile.c_str()) )
272 cpackConfigFile =
273 cmSystemTools::CollapseFullPath(cpackConfigFile.c_str());
274 cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
275 "Read CPack configuration file: " << cpackConfigFile.c_str()
276 << std::endl);
277 if ( !globalMF->ReadListFile(0, cpackConfigFile.c_str()) )
279 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
280 "Problem reading CPack config file: \""
281 << cpackConfigFile.c_str() << "\"" << std::endl);
282 return 1;
285 else if ( cpackConfigFileSpecified )
287 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
288 "Cannot find CPack config file: \"" << cpackConfigFile.c_str()
289 << "\"" << std::endl);
290 return 1;
293 if ( !generator.empty() )
295 globalMF->AddDefinition("CPACK_GENERATOR", generator.c_str());
297 if ( !cpackProjectName.empty() )
299 globalMF->AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName.c_str());
301 if ( !cpackProjectVersion.empty() )
303 globalMF->AddDefinition("CPACK_PACKAGE_VERSION",
304 cpackProjectVersion.c_str());
306 if ( !cpackProjectVendor.empty() )
308 globalMF->AddDefinition("CPACK_PACKAGE_VENDOR",
309 cpackProjectVendor.c_str());
311 if ( !cpackProjectDirectory.empty() )
313 globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY",
314 cpackProjectDirectory.c_str());
316 if ( !cpackBuildConfig.empty() )
318 globalMF->AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str());
320 cpackDefinitions::MapType::iterator cdit;
321 for ( cdit = definitions.Map.begin();
322 cdit != definitions.Map.end();
323 ++cdit )
325 globalMF->AddDefinition(cdit->first.c_str(), cdit->second.c_str());
328 const char* cpackModulesPath =
329 globalMF->GetDefinition("CPACK_MODULE_PATH");
330 if ( cpackModulesPath )
332 globalMF->AddDefinition("CMAKE_MODULE_PATH", cpackModulesPath);
334 const char* genList = globalMF->GetDefinition("CPACK_GENERATOR");
335 if ( !genList )
337 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
338 "CPack generator not specified" << std::endl);
339 parsed = 0;
341 else
343 std::vector<std::string> generatorsVector;
344 cmSystemTools::ExpandListArgument(genList,
345 generatorsVector);
346 std::vector<std::string>::iterator it;
347 for ( it = generatorsVector.begin();
348 it != generatorsVector.end();
349 ++it )
351 const char* gen = it->c_str();
352 cmMakefile newMF(*globalMF);
353 cmMakefile* mf = &newMF;
354 cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
355 "Specified generator: " << gen << std::endl);
356 if ( parsed && !mf->GetDefinition("CPACK_PACKAGE_NAME") )
358 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
359 "CPack project name not specified" << std::endl);
360 parsed = 0;
362 if ( parsed && !(mf->GetDefinition("CPACK_PACKAGE_VERSION")
363 || mf->GetDefinition("CPACK_PACKAGE_VERSION_MAJOR") &&
364 mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR")
365 && mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH")) )
367 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
368 "CPack project version not specified" << std::endl
369 << "Specify CPACK_PACKAGE_VERSION, or "
370 "CPACK_PACKAGE_VERSION_MAJOR, "
371 "CPACK_PACKAGE_VERSION_MINOR, and CPACK_PACKAGE_VERSION_PATCH."
372 << std::endl);
373 parsed = 0;
375 if ( parsed )
377 cpackGenerator = generators.NewGenerator(gen);
378 if ( !cpackGenerator )
380 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
381 "Cannot initialize CPack generator: "
382 << gen << std::endl);
383 parsed = 0;
385 if ( parsed && !cpackGenerator->Initialize(gen, mf) )
387 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
388 "Cannot initialize the generator " << gen << std::endl);
389 parsed = 0;
392 if ( !mf->GetDefinition("CPACK_INSTALL_COMMANDS") &&
393 !mf->GetDefinition("CPACK_INSTALLED_DIRECTORIES") &&
394 !mf->GetDefinition("CPACK_INSTALL_CMAKE_PROJECTS") )
396 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
397 "Please specify build tree of the project that uses CMake "
398 "using CPACK_INSTALL_CMAKE_PROJECTS, specify "
399 "CPACK_INSTALL_COMMANDS, or specify "
400 "CPACK_INSTALLED_DIRECTORIES."
401 << std::endl);
402 parsed = 0;
404 if ( parsed )
406 #ifdef _WIN32
407 std::string comspec = "cmw9xcom.exe";
408 cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str());
409 #endif
411 const char* projName = mf->GetDefinition("CPACK_PACKAGE_NAME");
412 cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "Use generator: "
413 << cpackGenerator->GetNameOfClass() << std::endl);
414 cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "For project: "
415 << projName << std::endl);
417 const char* projVersion =
418 mf->GetDefinition("CPACK_PACKAGE_VERSION");
419 if ( !projVersion )
421 const char* projVersionMajor
422 = mf->GetDefinition("CPACK_PACKAGE_VERSION_MAJOR");
423 const char* projVersionMinor
424 = mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR");
425 const char* projVersionPatch
426 = mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH");
427 cmOStringStream ostr;
428 ostr << projVersionMajor << "." << projVersionMinor << "."
429 << projVersionPatch;
430 mf->AddDefinition("CPACK_PACKAGE_VERSION",
431 ostr.str().c_str());
434 int res = cpackGenerator->DoPackage();
435 if ( !res )
437 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
438 "Error when generating package: " << projName << std::endl);
439 return 1;
447 if ( help )
449 doc.CheckOptions(argc, argv);
450 // Construct and print requested documentation.
451 doc.SetName("cpack");
452 doc.SetSection("Name",cmDocumentationName);
453 doc.SetSection("Usage",cmDocumentationUsage);
454 doc.SetSection("Description",cmDocumentationDescription);
455 doc.SetSection("Options",cmDocumentationOptions);
457 std::vector<cmDocumentationEntry> v;
458 cmCPackGeneratorFactory::DescriptionsMap::const_iterator generatorIt;
459 for( generatorIt = generators.GetGeneratorsList().begin();
460 generatorIt != generators.GetGeneratorsList().end();
461 ++ generatorIt )
463 cmDocumentationEntry e;
464 e.Name = generatorIt->first.c_str();
465 e.Brief = generatorIt->second.c_str();
466 e.Full = "";
467 v.push_back(e);
469 doc.SetSection("Generators",v);
471 doc.SetSeeAlsoList(cmDocumentationSeeAlso);
472 #undef cout
473 return doc.PrintRequestedDocumentation(std::cout)? 0:1;
474 #define cout no_cout_use_cmCPack_Log
477 if (cmSystemTools::GetErrorOccuredFlag())
479 return 1;
482 return 0;