Resync.
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / CPack / cpack.cxx
blob724fcde4b11293533ccfb65c58af9b8577c00322
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cpack.cxx,v $
5 Language: C++
6 Date: $Date: 2007/12/13 22:56:49 $
7 Version: $Revision: 1.42 $
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>
33 //----------------------------------------------------------------------------
34 static const char * cmDocumentationName[][3] =
36 {0,
37 " cpack - Packaging driver provided by CMake.", 0},
38 {0,0,0}
41 //----------------------------------------------------------------------------
42 static const char * cmDocumentationUsage[][3] =
44 {0,
45 " cpack -G <generator> [options]",
46 0},
47 {0,0,0}
50 //----------------------------------------------------------------------------
51 static const char * cmDocumentationDescription[][3] =
53 {0,
54 "The \"cpack\" executable is the CMake packaging program. "
55 "CMake-generated build trees created for projects that use "
56 "the INSTALL_* commands have packaging support. "
57 "This program will generate the package.", 0},
58 CMAKE_STANDARD_INTRODUCTION,
59 {0,0,0}
62 //----------------------------------------------------------------------------
63 static const char * cmDocumentationOptions[][3] =
65 {"-G <generator>", "Use the specified generator to generate package.",
66 "CPack may support multiple native packaging systems on certain "
67 "platforms. A generator is responsible for generating input files for "
68 "particular system and invoking that systems. Possible generator names "
69 "are specified in the Generators section." },
70 {"-C <Configuration>", "Specify the project configuration",
71 "This option specifies the configuration that the project was build "
72 "with, for example 'Debug', 'Release'." },
73 {"-D <var>=<value>", "Set a CPack variable.", \
74 "Set a variable that can be used by the generator."}, \
75 {"--config <config file>", "Specify the config file.",
76 "Specify the config file to use to create the package. By default "
77 "CPackConfig.cmake in the current directory will be used." },
78 {0,0,0}
81 //----------------------------------------------------------------------------
82 static const char * cmDocumentationSeeAlso[][3] =
84 {0, "cmake", 0},
85 {0, "ccmake", 0},
86 {0, 0, 0}
89 //----------------------------------------------------------------------------
90 int cpackUnknownArgument(const char*, void*)
92 return 1;
95 //----------------------------------------------------------------------------
96 struct cpackDefinitions
98 typedef std::map<cmStdString, cmStdString> MapType;
99 MapType Map;
100 cmCPackLog *Log;
103 //----------------------------------------------------------------------------
104 int cpackDefinitionArgument(const char* argument, const char* cValue,
105 void* call_data)
107 (void)argument;
108 cpackDefinitions* def = static_cast<cpackDefinitions*>(call_data);
109 std::string value = cValue;
110 size_t pos = value.find_first_of("=");
111 if ( pos == std::string::npos )
113 cmCPack_Log(def->Log, cmCPackLog::LOG_ERROR,
114 "Please specify CPack definitions as: KEY=VALUE" << std::endl);
115 return 0;
117 std::string key = value.substr(0, pos);
118 value = value.c_str() + pos + 1;
119 def->Map[key] = value;
120 cmCPack_Log(def->Log, cmCPackLog::LOG_DEBUG, "Set CPack variable: "
121 << key.c_str() << " to \"" << value.c_str() << "\"" << std::endl);
122 return 1;
125 //----------------------------------------------------------------------------
126 // this is CPack.
127 int main (int argc, char *argv[])
129 cmSystemTools::FindExecutableDirectory(argv[0]);
130 cmCPackLog log;
131 log.SetErrorPrefix("CPack Error: ");
132 log.SetWarningPrefix("CPack Warning: ");
133 log.SetOutputPrefix("CPack: ");
134 log.SetVerbosePrefix("CPack Verbose: ");
136 cmSystemTools::EnableMSVCDebugHook();
138 if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
140 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
141 "Current working directory cannot be established." << std::endl);
144 std::string generator;
145 bool help = false;
146 bool helpVersion = false;
147 bool verbose = false;
148 bool debug = false;
149 std::string helpFull;
150 std::string helpMAN;
151 std::string helpHTML;
153 std::string cpackProjectName;
154 std::string cpackProjectDirectory
155 = cmsys::SystemTools::GetCurrentWorkingDirectory();
156 std::string cpackBuildConfig;
157 std::string cpackProjectVersion;
158 std::string cpackProjectPatch;
159 std::string cpackProjectVendor;
160 std::string cpackConfigFile;
162 cpackDefinitions definitions;
163 definitions.Log = &log;
165 cpackConfigFile = "";
167 cmDocumentation doc;
168 cmsys::CommandLineArguments arg;
169 arg.Initialize(argc, argv);
170 typedef cmsys::CommandLineArguments argT;
171 // Help arguments
172 arg.AddArgument("--help", argT::NO_ARGUMENT, &help, "CPack help");
173 arg.AddArgument("--help-full", argT::SPACE_ARGUMENT, &helpFull,
174 "CPack help");
175 arg.AddArgument("--help-html", argT::SPACE_ARGUMENT, &helpHTML,
176 "CPack help");
177 arg.AddArgument("--help-man", argT::SPACE_ARGUMENT, &helpMAN, "CPack help");
178 arg.AddArgument("--version", argT::NO_ARGUMENT, &helpVersion, "CPack help");
180 arg.AddArgument("-V", argT::NO_ARGUMENT, &verbose, "CPack verbose");
181 arg.AddArgument("--verbose", argT::NO_ARGUMENT, &verbose, "-V");
182 arg.AddArgument("--debug", argT::NO_ARGUMENT, &debug, "-V");
183 arg.AddArgument("--config", argT::SPACE_ARGUMENT, &cpackConfigFile,
184 "CPack configuration file");
185 arg.AddArgument("-C", argT::SPACE_ARGUMENT, &cpackBuildConfig,
186 "CPack build configuration");
187 arg.AddArgument("-G", argT::SPACE_ARGUMENT,
188 &generator, "CPack generator");
189 arg.AddArgument("-P", argT::SPACE_ARGUMENT,
190 &cpackProjectName, "CPack project name");
191 arg.AddArgument("-R", argT::SPACE_ARGUMENT,
192 &cpackProjectVersion, "CPack project version");
193 arg.AddArgument("-B", argT::SPACE_ARGUMENT,
194 &cpackProjectDirectory, "CPack project directory");
195 arg.AddArgument("--patch", argT::SPACE_ARGUMENT,
196 &cpackProjectPatch, "CPack project patch");
197 arg.AddArgument("--vendor", argT::SPACE_ARGUMENT,
198 &cpackProjectVendor, "CPack project vendor");
199 arg.AddCallback("-D", argT::SPACE_ARGUMENT,
200 cpackDefinitionArgument, &definitions, "CPack Definitions");
201 arg.SetUnknownArgumentCallback(cpackUnknownArgument);
203 // Parse command line
204 int parsed = arg.Parse();
206 // Setup logging
207 if ( verbose )
209 log.SetVerbose(verbose);
210 cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Verbse" << std::endl);
212 if ( debug )
214 log.SetDebug(debug);
215 cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Debug" << std::endl);
218 cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
219 "Read CPack config file: " << cpackConfigFile.c_str() << std::endl);
221 cmake cminst;
222 cminst.RemoveUnscriptableCommands();
223 cmGlobalGenerator cmgg;
224 cmgg.SetCMakeInstance(&cminst);
225 cmLocalGenerator* cmlg = cmgg.CreateLocalGenerator();
226 cmMakefile* globalMF = cmlg->GetMakefile();
228 bool cpackConfigFileSpecified = true;
229 if ( cpackConfigFile.empty() )
231 cpackConfigFile = cmSystemTools::GetCurrentWorkingDirectory();
232 cpackConfigFile += "/CPackConfig.cmake";
233 cpackConfigFileSpecified = false;
236 cmCPackGeneratorFactory generators;
237 generators.SetLogger(&log);
238 cmCPackGenerator* cpackGenerator = 0;
240 if ( !helpFull.empty() || !helpMAN.empty() ||
241 !helpHTML.empty() || helpVersion )
243 help = true;
246 if ( parsed && !help )
248 // find out which system cpack is running on, so it can setup the search
249 // paths, so FIND_XXX() commands can be used in scripts
250 cminst.AddCMakePaths();
251 std::string systemFile =
252 globalMF->GetModulesFile("CMakeDetermineSystem.cmake");
253 if (!globalMF->ReadListFile(0, systemFile.c_str()))
255 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
256 "Error reading CMakeDetermineSystem.cmake" << std::endl);
257 return 1;
260 systemFile =
261 globalMF->GetModulesFile("CMakeSystemSpecificInformation.cmake");
262 if (!globalMF->ReadListFile(0, systemFile.c_str()))
264 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
265 "Error reading CMakeSystemSpecificInformation.cmake" << std::endl);
266 return 1;
269 if ( cmSystemTools::FileExists(cpackConfigFile.c_str()) )
271 cpackConfigFile =
272 cmSystemTools::CollapseFullPath(cpackConfigFile.c_str());
273 cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
274 "Read CPack configuration file: " << cpackConfigFile.c_str()
275 << std::endl);
276 if ( !globalMF->ReadListFile(0, cpackConfigFile.c_str()) )
278 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
279 "Problem reading CPack config file: \""
280 << cpackConfigFile.c_str() << "\"" << std::endl);
281 return 1;
284 else if ( cpackConfigFileSpecified )
286 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
287 "Cannot find CPack config file: \"" << cpackConfigFile.c_str()
288 << "\"" << std::endl);
289 return 1;
292 if ( !generator.empty() )
294 globalMF->AddDefinition("CPACK_GENERATOR", generator.c_str());
296 if ( !cpackProjectName.empty() )
298 globalMF->AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName.c_str());
300 if ( !cpackProjectVersion.empty() )
302 globalMF->AddDefinition("CPACK_PACKAGE_VERSION",
303 cpackProjectVersion.c_str());
305 if ( !cpackProjectVendor.empty() )
307 globalMF->AddDefinition("CPACK_PACKAGE_VENDOR",
308 cpackProjectVendor.c_str());
310 if ( !cpackProjectDirectory.empty() )
312 globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY",
313 cpackProjectDirectory.c_str());
315 if ( !cpackBuildConfig.empty() )
317 globalMF->AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str());
319 cpackDefinitions::MapType::iterator cdit;
320 for ( cdit = definitions.Map.begin();
321 cdit != definitions.Map.end();
322 ++cdit )
324 globalMF->AddDefinition(cdit->first.c_str(), cdit->second.c_str());
327 const char* cpackModulesPath =
328 globalMF->GetDefinition("CPACK_MODULE_PATH");
329 if ( cpackModulesPath )
331 globalMF->AddDefinition("CMAKE_MODULE_PATH", cpackModulesPath);
333 const char* genList = globalMF->GetDefinition("CPACK_GENERATOR");
334 if ( !genList )
336 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
337 "CPack generator not specified" << std::endl);
338 parsed = 0;
340 else
342 std::vector<std::string> generatorsVector;
343 cmSystemTools::ExpandListArgument(genList,
344 generatorsVector);
345 std::vector<std::string>::iterator it;
346 for ( it = generatorsVector.begin();
347 it != generatorsVector.end();
348 ++it )
350 const char* gen = it->c_str();
351 cmMakefile newMF(*globalMF);
352 cmMakefile* mf = &newMF;
353 cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
354 "Specified generator: " << gen << std::endl);
355 if ( parsed && !mf->GetDefinition("CPACK_PACKAGE_NAME") )
357 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
358 "CPack project name not specified" << std::endl);
359 parsed = 0;
361 if ( parsed && !(mf->GetDefinition("CPACK_PACKAGE_VERSION")
362 || mf->GetDefinition("CPACK_PACKAGE_VERSION_MAJOR") &&
363 mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR")
364 && mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH")) )
366 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
367 "CPack project version not specified" << std::endl
368 << "Specify CPACK_PACKAGE_VERSION, or "
369 "CPACK_PACKAGE_VERSION_MAJOR, "
370 "CPACK_PACKAGE_VERSION_MINOR, and CPACK_PACKAGE_VERSION_PATCH."
371 << std::endl);
372 parsed = 0;
374 if ( parsed )
376 cpackGenerator = generators.NewGenerator(gen);
377 if ( !cpackGenerator )
379 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
380 "Cannot initialize CPack generator: "
381 << gen << std::endl);
382 parsed = 0;
384 if ( parsed && !cpackGenerator->Initialize(gen, mf, argv[0]) )
386 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
387 "Cannot initialize the generator " << gen << std::endl);
388 parsed = 0;
391 if ( !mf->GetDefinition("CPACK_INSTALL_COMMANDS") &&
392 !mf->GetDefinition("CPACK_INSTALLED_DIRECTORIES") &&
393 !mf->GetDefinition("CPACK_INSTALL_CMAKE_PROJECTS") )
395 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
396 "Please specify build tree of the project that uses CMake "
397 "using CPACK_INSTALL_CMAKE_PROJECTS, specify "
398 "CPACK_INSTALL_COMMANDS, or specify "
399 "CPACK_INSTALLED_DIRECTORIES."
400 << std::endl);
401 parsed = 0;
403 if ( parsed )
405 #ifdef _WIN32
406 std::string comspec = "cmw9xcom.exe";
407 cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str());
408 #endif
410 const char* projName = mf->GetDefinition("CPACK_PACKAGE_NAME");
411 cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "Use generator: "
412 << cpackGenerator->GetNameOfClass() << std::endl);
413 cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "For project: "
414 << projName << std::endl);
416 const char* projVersion =
417 mf->GetDefinition("CPACK_PACKAGE_VERSION");
418 if ( !projVersion )
420 const char* projVersionMajor
421 = mf->GetDefinition("CPACK_PACKAGE_VERSION_MAJOR");
422 const char* projVersionMinor
423 = mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR");
424 const char* projVersionPatch
425 = mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH");
426 cmOStringStream ostr;
427 ostr << projVersionMajor << "." << projVersionMinor << "."
428 << projVersionPatch;
429 mf->AddDefinition("CPACK_PACKAGE_VERSION",
430 ostr.str().c_str());
433 int res = cpackGenerator->DoPackage();
434 if ( !res )
436 cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
437 "Error when generating package: " << projName << std::endl);
438 return 1;
446 if ( help )
448 doc.CheckOptions(argc, argv);
449 // Construct and print requested documentation.
450 doc.SetName("cpack");
451 doc.SetSection("Name",cmDocumentationName);
452 doc.SetSection("Usage",cmDocumentationUsage);
453 doc.SetSection("Description",cmDocumentationDescription);
454 doc.SetSection("Options",cmDocumentationOptions);
456 std::vector<cmDocumentationEntry> v;
457 cmCPackGeneratorFactory::DescriptionsMap::const_iterator generatorIt;
458 for( generatorIt = generators.GetGeneratorsList().begin();
459 generatorIt != generators.GetGeneratorsList().end();
460 ++ generatorIt )
462 cmDocumentationEntry e;
463 e.Name = generatorIt->first.c_str();
464 e.Brief = generatorIt->second.c_str();
465 e.Full = "";
466 v.push_back(e);
468 doc.SetSection("Generators",v);
470 doc.SetSeeAlsoList(cmDocumentationSeeAlso);
471 #undef cout
472 return doc.PrintRequestedDocumentation(std::cout)? 0:1;
473 #define cout no_cout_use_cmCPack_Log
476 return 0;