diff options
Diffstat (limited to 'Source/CPack/cpack.cxx')
-rw-r--r-- | Source/CPack/cpack.cxx | 486 |
1 files changed, 486 insertions, 0 deletions
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx new file mode 100644 index 0000000..26bf607 --- /dev/null +++ b/Source/CPack/cpack.cxx @@ -0,0 +1,486 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmSystemTools.h" + +// Need these for documentation support. +#include "cmake.h" +#include "cmDocumentation.h" +#include "cmCPackGeneratorFactory.h" +#include "cmCPackGenerator.h" +#include "cmake.h" +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" +#include "cmMakefile.h" + +#include "cmCPackLog.h" + +#include <cmsys/CommandLineArguments.hxx> +#include <cmsys/SystemTools.hxx> +#include <cmsys/Encoding.hxx> +#include <locale.h> + +//---------------------------------------------------------------------------- +static const char * cmDocumentationName[][2] = +{ + {0, + " cpack - Packaging driver provided by CMake."}, + {0,0} +}; + +//---------------------------------------------------------------------------- +static const char * cmDocumentationUsage[][2] = +{ + {0, + " cpack -G <generator> [options]"}, + {0,0} +}; + +//---------------------------------------------------------------------------- +static const char * cmDocumentationOptions[][2] = +{ + {"-G <generator>", "Use the specified generator to generate package."}, + {"-C <Configuration>", "Specify the project configuration"}, + {"-D <var>=<value>", "Set a CPack variable."}, + {"--config <config file>", "Specify the config file."}, + {"--verbose,-V","enable verbose output"}, + {"--debug","enable debug output (for CPack developers)"}, + {"-P <package name>","override/define CPACK_PACKAGE_NAME"}, + {"-R <package version>","override/define CPACK_PACKAGE_VERSION"}, + {"-B <package directory>","override/define CPACK_PACKAGE_DIRECTORY"}, + {"--vendor <vendor name>","override/define CPACK_PACKAGE_VENDOR"}, + {0,0} +}; + +//---------------------------------------------------------------------------- +int cpackUnknownArgument(const char*, void*) +{ + return 1; +} + +//---------------------------------------------------------------------------- +struct cpackDefinitions +{ + typedef std::map<std::string, std::string> MapType; + MapType Map; + cmCPackLog *Log; +}; + +//---------------------------------------------------------------------------- +int cpackDefinitionArgument(const char* argument, const char* cValue, + void* call_data) +{ + (void)argument; + cpackDefinitions* def = static_cast<cpackDefinitions*>(call_data); + std::string value = cValue; + size_t pos = value.find_first_of("="); + if ( pos == std::string::npos ) + { + cmCPack_Log(def->Log, cmCPackLog::LOG_ERROR, + "Please specify CPack definitions as: KEY=VALUE" << std::endl); + return 0; + } + std::string key = value.substr(0, pos); + value = value.c_str() + pos + 1; + def->Map[key] = value; + cmCPack_Log(def->Log, cmCPackLog::LOG_DEBUG, "Set CPack variable: " + << key << " to \"" << value << "\"" << std::endl); + return 1; +} + + +//---------------------------------------------------------------------------- +// this is CPack. +int main (int argc, char const* const* argv) +{ + setlocale(LC_CTYPE, ""); + cmsys::Encoding::CommandLineArguments args = + cmsys::Encoding::CommandLineArguments::Main(argc, argv); + argc = args.argc(); + argv = args.argv(); + + cmSystemTools::FindCMakeResources(argv[0]); + cmCPackLog log; + + log.SetErrorPrefix("CPack Error: "); + log.SetWarningPrefix("CPack Warning: "); + log.SetOutputPrefix("CPack: "); + log.SetVerbosePrefix("CPack Verbose: "); + + cmSystemTools::EnableMSVCDebugHook(); + + if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 ) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "Current working directory cannot be established." << std::endl); + return 1; + } + + std::string generator; + bool help = false; + bool helpVersion = false; + bool verbose = false; + bool debug = false; + std::string helpFull; + std::string helpMAN; + std::string helpHTML; + + std::string cpackProjectName; + std::string cpackProjectDirectory; + std::string cpackBuildConfig; + std::string cpackProjectVersion; + std::string cpackProjectPatch; + std::string cpackProjectVendor; + std::string cpackConfigFile; + + cpackDefinitions definitions; + definitions.Log = &log; + + cpackConfigFile = ""; + + cmsys::CommandLineArguments arg; + arg.Initialize(argc, argv); + typedef cmsys::CommandLineArguments argT; + // Help arguments + arg.AddArgument("--help", argT::NO_ARGUMENT, &help, "CPack help"); + arg.AddArgument("--help-full", argT::SPACE_ARGUMENT, &helpFull, + "CPack help"); + arg.AddArgument("--help-html", argT::SPACE_ARGUMENT, &helpHTML, + "CPack help"); + arg.AddArgument("--help-man", argT::SPACE_ARGUMENT, &helpMAN, "CPack help"); + arg.AddArgument("--version", argT::NO_ARGUMENT, &helpVersion, "CPack help"); + + arg.AddArgument("-V", argT::NO_ARGUMENT, &verbose, "CPack verbose"); + arg.AddArgument("--verbose", argT::NO_ARGUMENT, &verbose, "-V"); + arg.AddArgument("--debug", argT::NO_ARGUMENT, &debug, "-V"); + arg.AddArgument("--config", argT::SPACE_ARGUMENT, &cpackConfigFile, + "CPack configuration file"); + arg.AddArgument("-C", argT::SPACE_ARGUMENT, &cpackBuildConfig, + "CPack build configuration"); + arg.AddArgument("-G", argT::SPACE_ARGUMENT, + &generator, "CPack generator"); + arg.AddArgument("-P", argT::SPACE_ARGUMENT, + &cpackProjectName, "CPack project name"); + arg.AddArgument("-R", argT::SPACE_ARGUMENT, + &cpackProjectVersion, "CPack project version"); + arg.AddArgument("-B", argT::SPACE_ARGUMENT, + &cpackProjectDirectory, "CPack project directory"); + arg.AddArgument("--patch", argT::SPACE_ARGUMENT, + &cpackProjectPatch, "CPack project patch"); + arg.AddArgument("--vendor", argT::SPACE_ARGUMENT, + &cpackProjectVendor, "CPack project vendor"); + arg.AddCallback("-D", argT::SPACE_ARGUMENT, + cpackDefinitionArgument, &definitions, "CPack Definitions"); + arg.SetUnknownArgumentCallback(cpackUnknownArgument); + + // Parse command line + int parsed = arg.Parse(); + + // Setup logging + if ( verbose ) + { + log.SetVerbose(verbose); + cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Verbose" << std::endl); + } + if ( debug ) + { + log.SetDebug(debug); + cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Debug" << std::endl); + } + + cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, + "Read CPack config file: " << cpackConfigFile << std::endl); + + cmake cminst; + cminst.RemoveUnscriptableCommands(); + cmGlobalGenerator cmgg; + cmgg.SetCMakeInstance(&cminst); + cmsys::auto_ptr<cmLocalGenerator> cmlg(cmgg.CreateLocalGenerator()); + cmMakefile* globalMF = cmlg->GetMakefile(); + + bool cpackConfigFileSpecified = true; + if ( cpackConfigFile.empty() ) + { + cpackConfigFile = cmSystemTools::GetCurrentWorkingDirectory(); + cpackConfigFile += "/CPackConfig.cmake"; + cpackConfigFileSpecified = false; + } + + cmCPackGeneratorFactory generators; + generators.SetLogger(&log); + cmCPackGenerator* cpackGenerator = 0; + + cmDocumentation doc; + doc.addCPackStandardDocSections(); + /* Were we invoked to display doc or to do some work ? + * Unlike cmake launching cpack with zero argument + * should launch cpack using "cpackConfigFile" if it exists + * in the current directory. + */ + if((doc.CheckOptions(argc, argv,"-G")) && !(argc==1)) + { + help = true; + } + else + { + help = false; + } + + // This part is used for cpack documentation lookup as well. + cminst.AddCMakePaths(); + + if ( parsed && !help ) + { + // find out which system cpack is running on, so it can setup the search + // paths, so FIND_XXX() commands can be used in scripts + std::string systemFile = + globalMF->GetModulesFile("CMakeDetermineSystem.cmake"); + if (!globalMF->ReadListFile(0, systemFile.c_str())) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "Error reading CMakeDetermineSystem.cmake" << std::endl); + return 1; + } + + systemFile = + globalMF->GetModulesFile("CMakeSystemSpecificInformation.cmake"); + if (!globalMF->ReadListFile(0, systemFile.c_str())) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "Error reading CMakeSystemSpecificInformation.cmake" << std::endl); + return 1; + } + + if ( !cpackBuildConfig.empty() ) + { + globalMF->AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str()); + } + + if ( cmSystemTools::FileExists(cpackConfigFile.c_str()) ) + { + cpackConfigFile = + cmSystemTools::CollapseFullPath(cpackConfigFile); + cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, + "Read CPack configuration file: " << cpackConfigFile + << std::endl); + if ( !globalMF->ReadListFile(0, cpackConfigFile.c_str()) ) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "Problem reading CPack config file: \"" + << cpackConfigFile << "\"" << std::endl); + return 1; + } + } + else if ( cpackConfigFileSpecified ) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "Cannot find CPack config file: \"" << + cpackConfigFile << "\"" << std::endl); + return 1; + } + + if ( !generator.empty() ) + { + globalMF->AddDefinition("CPACK_GENERATOR", generator.c_str()); + } + if ( !cpackProjectName.empty() ) + { + globalMF->AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName.c_str()); + } + if ( !cpackProjectVersion.empty() ) + { + globalMF->AddDefinition("CPACK_PACKAGE_VERSION", + cpackProjectVersion.c_str()); + } + if ( !cpackProjectVendor.empty() ) + { + globalMF->AddDefinition("CPACK_PACKAGE_VENDOR", + cpackProjectVendor.c_str()); + } + // if this is not empty it has been set on the command line + // go for it. Command line override values set in config file. + if ( !cpackProjectDirectory.empty() ) + { + globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY", + cpackProjectDirectory.c_str()); + } + // The value has not been set on the command line + else + { + // get a default value (current working directory) + cpackProjectDirectory = cmsys::SystemTools::GetCurrentWorkingDirectory(); + // use default value iff no value has been provided by the config file + if (!globalMF->IsSet("CPACK_PACKAGE_DIRECTORY")) + { + globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY", + cpackProjectDirectory.c_str()); + } + } + cpackDefinitions::MapType::iterator cdit; + for ( cdit = definitions.Map.begin(); + cdit != definitions.Map.end(); + ++cdit ) + { + globalMF->AddDefinition(cdit->first, cdit->second.c_str()); + } + + const char* cpackModulesPath = + globalMF->GetDefinition("CPACK_MODULE_PATH"); + if ( cpackModulesPath ) + { + globalMF->AddDefinition("CMAKE_MODULE_PATH", cpackModulesPath); + } + const char* genList = globalMF->GetDefinition("CPACK_GENERATOR"); + if ( !genList ) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "CPack generator not specified" << std::endl); + } + else + { + std::vector<std::string> generatorsVector; + cmSystemTools::ExpandListArgument(genList, + generatorsVector); + std::vector<std::string>::iterator it; + for ( it = generatorsVector.begin(); + it != generatorsVector.end(); + ++it ) + { + const char* gen = it->c_str(); + cmMakefile newMF(*globalMF); + cmMakefile* mf = &newMF; + cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, + "Specified generator: " << gen << std::endl); + if ( parsed && !mf->GetDefinition("CPACK_PACKAGE_NAME") ) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "CPack project name not specified" << std::endl); + parsed = 0; + } + if (parsed && + !(mf->GetDefinition("CPACK_PACKAGE_VERSION") || + (mf->GetDefinition("CPACK_PACKAGE_VERSION_MAJOR") && + mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR") && + mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH")))) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "CPack project version not specified" << std::endl + << "Specify CPACK_PACKAGE_VERSION, or " + "CPACK_PACKAGE_VERSION_MAJOR, " + "CPACK_PACKAGE_VERSION_MINOR, and CPACK_PACKAGE_VERSION_PATCH." + << std::endl); + parsed = 0; + } + if ( parsed ) + { + cpackGenerator = generators.NewGenerator(gen); + if ( !cpackGenerator ) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "Cannot initialize CPack generator: " + << gen << std::endl); + parsed = 0; + } + if ( parsed && !cpackGenerator->Initialize(gen, mf) ) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "Cannot initialize the generator " << gen << std::endl); + parsed = 0; + } + + if ( !mf->GetDefinition("CPACK_INSTALL_COMMANDS") && + !mf->GetDefinition("CPACK_INSTALLED_DIRECTORIES") && + !mf->GetDefinition("CPACK_INSTALL_CMAKE_PROJECTS") ) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "Please specify build tree of the project that uses CMake " + "using CPACK_INSTALL_CMAKE_PROJECTS, specify " + "CPACK_INSTALL_COMMANDS, or specify " + "CPACK_INSTALLED_DIRECTORIES." + << std::endl); + parsed = 0; + } + if ( parsed ) + { + const char* projName = mf->GetDefinition("CPACK_PACKAGE_NAME"); + cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "Use generator: " + << cpackGenerator->GetNameOfClass() << std::endl); + cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "For project: " + << projName << std::endl); + + const char* projVersion = + mf->GetDefinition("CPACK_PACKAGE_VERSION"); + if ( !projVersion ) + { + const char* projVersionMajor + = mf->GetDefinition("CPACK_PACKAGE_VERSION_MAJOR"); + const char* projVersionMinor + = mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR"); + const char* projVersionPatch + = mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH"); + cmOStringStream ostr; + ostr << projVersionMajor << "." << projVersionMinor << "." + << projVersionPatch; + mf->AddDefinition("CPACK_PACKAGE_VERSION", + ostr.str().c_str()); + } + + int res = cpackGenerator->DoPackage(); + if ( !res ) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "Error when generating package: " << projName << std::endl); + return 1; + } + } + } + } + } + } + + /* In this case we are building the documentation object + * instance in order to create appropriate structure + * in order to satisfy the appropriate --help-xxx request + */ + if ( help ) + { + // Construct and print requested documentation. + + doc.SetName("cpack"); + doc.SetSection("Name",cmDocumentationName); + doc.SetSection("Usage",cmDocumentationUsage); + doc.PrependSection("Options",cmDocumentationOptions); + + std::vector<cmDocumentationEntry> v; + cmCPackGeneratorFactory::DescriptionsMap::const_iterator generatorIt; + for( generatorIt = generators.GetGeneratorsList().begin(); + generatorIt != generators.GetGeneratorsList().end(); + ++ generatorIt ) + { + cmDocumentationEntry e; + e.Name = generatorIt->first.c_str(); + e.Brief = generatorIt->second.c_str(); + v.push_back(e); + } + doc.SetSection("Generators",v); + +#undef cout + return doc.PrintRequestedDocumentation(std::cout)? 0:1; +#define cout no_cout_use_cmCPack_Log + } + + if (cmSystemTools::GetErrorOccuredFlag()) + { + return 1; + } + + return 0; +} |