packaging: Initial packaging
[platform/upstream/cmake.git] / Source / cmBuildCommand.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
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 "cmBuildCommand.h"
13
14 #include "cmLocalGenerator.h"
15 #include "cmGlobalGenerator.h"
16
17 //----------------------------------------------------------------------
18 bool cmBuildCommand
19 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
20 {
21   // Support the legacy signature of the command:
22   //
23   if(2 == args.size())
24     {
25     return this->TwoArgsSignature(args);
26     }
27
28   return this->MainSignature(args);
29 }
30
31 //----------------------------------------------------------------------
32 bool cmBuildCommand
33 ::MainSignature(std::vector<std::string> const& args)
34 {
35   if(args.size() < 1)
36     {
37     this->SetError("requires at least one argument naming a CMake variable");
38     return false;
39     }
40
41   // The cmake variable in which to store the result.
42   const char* variable = args[0].c_str();
43
44   // Parse remaining arguments.
45   const char* configuration = 0;
46   const char* project_name = 0;
47   const char* target = 0;
48   enum Doing { DoingNone, DoingConfiguration, DoingProjectName, DoingTarget };
49   Doing doing = DoingNone;
50   for(unsigned int i=1; i < args.size(); ++i)
51     {
52     if(args[i] == "CONFIGURATION")
53       {
54       doing = DoingConfiguration;
55       }
56     else if(args[i] == "PROJECT_NAME")
57       {
58       doing = DoingProjectName;
59       }
60     else if(args[i] == "TARGET")
61       {
62       doing = DoingTarget;
63       }
64     else if(doing == DoingConfiguration)
65       {
66       doing = DoingNone;
67       configuration = args[i].c_str();
68       }
69     else if(doing == DoingProjectName)
70       {
71       doing = DoingNone;
72       project_name = args[i].c_str();
73       }
74     else if(doing == DoingTarget)
75       {
76       doing = DoingNone;
77       target = args[i].c_str();
78       }
79     else
80       {
81       cmOStringStream e;
82       e << "unknown argument \"" << args[i] << "\"";
83       this->SetError(e.str().c_str());
84       return false;
85       }
86     }
87
88   const char* makeprogram
89     = this->Makefile->GetDefinition("CMAKE_MAKE_PROGRAM");
90   if(!makeprogram)
91     {
92     this->Makefile->IssueMessage(
93       cmake::FATAL_ERROR,
94       "build_command() requires CMAKE_MAKE_PROGRAM to be defined.  "
95       "Call project() or enable_language() first.");
96     return true;
97     }
98
99   // If null/empty CONFIGURATION argument, GenerateBuildCommand uses 'Debug'
100   // in the currently implemented multi-configuration global generators...
101   // so we put this code here to end up with the same default configuration
102   // as the original 2-arg build_command signature:
103   //
104   if(!configuration || !*configuration)
105     {
106     configuration = getenv("CMAKE_CONFIG_TYPE");
107     }
108   if(!configuration || !*configuration)
109     {
110     configuration = "Release";
111     }
112
113   // If null/empty PROJECT_NAME argument, use the Makefile's project name:
114   //
115   if(!project_name || !*project_name)
116     {
117     project_name = this->Makefile->GetProjectName();
118     }
119
120   // If null/empty TARGET argument, GenerateBuildCommand omits any mention
121   // of a target name on the build command line...
122   //
123   std::string makecommand = this->Makefile->GetLocalGenerator()
124     ->GetGlobalGenerator()->GenerateBuildCommand
125     (makeprogram, project_name, 0, 0, target, configuration, true, false);
126
127   this->Makefile->AddDefinition(variable, makecommand.c_str());
128
129   return true;
130 }
131
132 //----------------------------------------------------------------------
133 bool cmBuildCommand
134 ::TwoArgsSignature(std::vector<std::string> const& args)
135 {
136   if(args.size() < 2 )
137     {
138     this->SetError("called with less than two arguments");
139     return false;
140     }
141
142   const char* define = args[0].c_str();
143   const char* cacheValue
144     = this->Makefile->GetDefinition(define);
145   std::string makeprogram = args[1];
146
147   std::string configType = "Release";
148   const char* cfg = getenv("CMAKE_CONFIG_TYPE");
149   if ( cfg )
150     {
151     configType = cfg;
152     }
153
154   std::string makecommand = this->Makefile->GetLocalGenerator()
155     ->GetGlobalGenerator()->GenerateBuildCommand
156     (makeprogram.c_str(), this->Makefile->GetProjectName(), 0, 0,
157      0, configType.c_str(), true, false);
158
159   if(cacheValue)
160     {
161     return true;
162     }
163   this->Makefile->AddCacheDefinition(define,
164                                  makecommand.c_str(),
165                                  "Command used to build entire project "
166                                  "from the command line.",
167                                  cmCacheManager::STRING);
168   return true;
169 }