]>
Commit | Line | Data |
---|---|---|
07a756b9 | 1 | ## @file BuildEnv.py\r |
2 | # Initialize Environment for building\r | |
3 | #\r | |
4 | # Copyright (c) 2007, Intel Corporation\r | |
5 | #\r | |
6 | # All rights reserved. This program and the accompanying materials\r | |
7 | # are licensed and made available under the terms and conditions of the BSD License\r | |
8 | # which accompanies this distribution. The full text of the license may be found at\r | |
9 | # http://opensource.org/licenses/bsd-license.php\r | |
10 | #\r | |
11 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
12 | # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
13 | #\r | |
14 | \r | |
15 | ##\r | |
16 | # Import Modules\r | |
17 | #\r | |
18 | import os\r | |
19 | import os.path\r | |
20 | import pickle\r | |
21 | import shutil\r | |
22 | import sys\r | |
23 | \r | |
24 | from optparse import OptionParser\r | |
25 | \r | |
26 | # Version and Copyright\r | |
27 | VersionNumber = "0.01"\r | |
28 | __version__ = "%prog Version " + VersionNumber\r | |
29 | __copyright__ = "Copyright (c) 2007, Intel Corporation All rights reserved."\r | |
30 | \r | |
31 | class SetupBuildEnvironmentApp:\r | |
32 | \r | |
33 | def __init__(self):\r | |
34 | (self.Opt, self.Args) = self.ProcessCommandLine()\r | |
35 | self.SetupDefaults()\r | |
36 | self.DetermineEnvironment()\r | |
8625864e | 37 | self.DeleteEnvironmentConfigurationScript()\r |
07a756b9 | 38 | self.CopyTemplates()\r |
39 | self.WriteEnvironmentConfigurationScript()\r | |
40 | \r | |
41 | def SetupDefaults(self):\r | |
42 | self.itemsToConfigure = (\r | |
43 | 'compiler',\r | |
8625864e | 44 | #'compiler-prefix',\r |
45 | 'templates',\r | |
07a756b9 | 46 | )\r |
47 | \r | |
48 | self.defaults = {\r | |
49 | 'compiler': {\r | |
50 | 'options': ('gcc', 'icc'),\r | |
51 | 'default': 'gcc',\r | |
52 | },\r | |
53 | 'compiler-prefix': {\r | |
54 | 'options': ('/usr/bin', '/usr/bin/x86_64-pc-mingw32-'),\r | |
55 | 'freeform': True,\r | |
56 | },\r | |
8625864e | 57 | 'templates': {\r |
58 | 'description': 'templates and Conf directory',\r | |
07a756b9 | 59 | 'options': (\r |
60 | 'copy once (no-overwrite)',\r | |
61 | 'copy with overwrite',\r | |
62 | 'symlink to templates',\r | |
63 | 'do nothing',\r | |
64 | ),\r | |
65 | 'default': 'copy once (no-overwrite)',\r | |
66 | },\r | |
67 | }\r | |
68 | \r | |
69 | def ProcessCommandLine(self):\r | |
6e98e263 | 70 | Parser = OptionParser(description=__copyright__,version=__version__,prog="BaseTools/BuildEnv")\r |
07a756b9 | 71 | Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r |
72 | Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\\r | |
73 | "including library instances selected, final dependency expression, "\\r | |
74 | "and warning messages, etc.")\r | |
75 | Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r | |
76 | \r | |
77 | if os.environ.has_key('WORKSPACE'):\r | |
78 | default = os.environ['WORKSPACE']\r | |
79 | else:\r | |
80 | default = os.getcwd()\r | |
81 | Parser.add_option("--workspace", action="store", type="string", help="Base director of tree to configure", default=default)\r | |
82 | \r | |
83 | (Opt, Args)=Parser.parse_args()\r | |
84 | Parser.print_version()\r | |
85 | \r | |
86 | return (Opt, Args)\r | |
87 | \r | |
88 | def DetermineEnvironment(self):\r | |
89 | confFilename = os.path.join(os.path.expanduser('~'), '.edk-build-env.pickle')\r | |
90 | try:\r | |
91 | confFile = open(confFilename, 'r')\r | |
92 | conf = pickle.load(confFile)\r | |
93 | confFile.close()\r | |
94 | except Exception:\r | |
95 | conf = {}\r | |
96 | self.conf = conf\r | |
97 | \r | |
98 | for item in self.itemsToConfigure:\r | |
99 | if not conf.has_key(item):\r | |
100 | self.AskForValueOfOption(item)\r | |
101 | \r | |
102 | while True:\r | |
103 | self.SummarizeCurrentState()\r | |
104 | \r | |
105 | if not self.Opt.quiet:\r | |
106 | response = raw_input('Would you like to change anything? (default=no): ')\r | |
107 | response = response.strip()\r | |
108 | else:\r | |
109 | response = ''\r | |
110 | \r | |
111 | if response.lower() in ('', 'n', 'no'):\r | |
112 | break\r | |
113 | \r | |
114 | for item in self.itemsToConfigure:\r | |
115 | self.AskForValueOfOption(item)\r | |
116 | \r | |
117 | confFile = open(confFilename, 'w')\r | |
118 | pickle.dump(conf, confFile)\r | |
119 | confFile.close()\r | |
120 | \r | |
07a756b9 | 121 | def AskForValueOfOption(self, option):\r |
8625864e | 122 | \r |
07a756b9 | 123 | options = self.defaults[option]['options']\r |
8625864e | 124 | \r |
07a756b9 | 125 | if self.defaults[option].has_key('default'):\r |
126 | default = self.defaults[option]['default']\r | |
127 | else:\r | |
128 | default = None\r | |
8625864e | 129 | \r |
07a756b9 | 130 | if self.defaults[option].has_key('freeform'):\r |
131 | freeform = self.defaults[option]['freeform']\r | |
132 | else:\r | |
133 | freeform = False\r | |
07a756b9 | 134 | \r |
8625864e | 135 | if self.defaults[option].has_key('description'):\r |
136 | description = self.defaults[option]['description']\r | |
137 | else:\r | |
138 | description = option\r | |
139 | \r | |
07a756b9 | 140 | conf = self.conf\r |
8625864e | 141 | if conf.has_key(option):\r |
142 | default = conf[option]\r | |
07a756b9 | 143 | options = list(options) # in case options came in as a tuple\r |
144 | assert((default == '') or (default is None) or ('' not in options))\r | |
145 | if (default is not None) and (default not in options):\r | |
146 | options.append(default)\r | |
147 | if (freeform and ('' not in options)):\r | |
148 | options.append('')\r | |
149 | options.sort()\r | |
150 | while True:\r | |
151 | print\r | |
152 | if len(options) > 0:\r | |
8625864e | 153 | print 'Options for', description\r |
07a756b9 | 154 | for i in range(len(options)):\r |
155 | print ' %d.' % (i + 1),\r | |
156 | if options[i] != '':\r | |
157 | print options[i],\r | |
158 | else:\r | |
159 | print '(empty string)',\r | |
160 | if options[i] == default:\r | |
161 | print '(default)'\r | |
162 | else:\r | |
163 | print\r | |
164 | \r | |
165 | if len(options) > 0:\r | |
166 | prompt = 'Select number or type value: '\r | |
167 | else:\r | |
8625864e | 168 | prompt = 'Type value: '\r |
07a756b9 | 169 | response = raw_input(prompt)\r |
170 | response = response.strip()\r | |
171 | \r | |
172 | if response.isdigit():\r | |
173 | response = int(response)\r | |
174 | if response > len(options):\r | |
175 | print 'ERROR: Invalid number selection!'\r | |
176 | continue\r | |
177 | response = options[response - 1]\r | |
178 | elif (response == '') and (default is not None):\r | |
179 | response = default\r | |
180 | \r | |
181 | if (not freeform) and (response not in options):\r | |
182 | print 'ERROR: Invalid selection! (must be from list)'\r | |
183 | continue\r | |
184 | \r | |
185 | break\r | |
186 | \r | |
8625864e | 187 | conf[option] = response\r |
188 | print 'Using', conf[option], 'for', description\r | |
07a756b9 | 189 | \r |
190 | def SummarizeCurrentState(self):\r | |
191 | print\r | |
192 | print 'Current configuration:'\r | |
193 | conf = self.conf\r | |
194 | for item in self.itemsToConfigure:\r | |
195 | value = conf[item]\r | |
196 | if value == '': value = '(empty string)'\r | |
197 | print ' ', item, '->', value\r | |
198 | \r | |
199 | def CopyTemplates(self):\r | |
8625864e | 200 | todo = self.conf['templates']\r |
07a756b9 | 201 | workspace = os.path.realpath(self.Opt.workspace)\r |
202 | templatesDir = \\r | |
8625864e | 203 | os.path.join(workspace, 'BaseTools', 'Conf')\r |
07a756b9 | 204 | confDir = \\r |
205 | os.path.join(workspace, 'Conf')\r | |
206 | print\r | |
207 | print 'Templates & Conf directory'\r | |
208 | print ' Templates dir:', self.RelativeToWorkspace(templatesDir)\r | |
209 | for filename in os.listdir(templatesDir):\r | |
8625864e | 210 | if not filename.endswith('.template'): continue\r |
07a756b9 | 211 | \r |
212 | srcFilename = os.path.join(templatesDir, filename)\r | |
8625864e | 213 | destFilename = os.path.join(confDir, filename[:-len('template')] + 'txt')\r |
07a756b9 | 214 | print ' ', self.RelativeToWorkspace(destFilename),\r |
215 | \r | |
216 | if todo == 'copy once (no-overwrite)':\r | |
217 | if os.path.exists(destFilename):\r | |
218 | print '[skipped, already exists]'\r | |
219 | else:\r | |
220 | shutil.copy(srcFilename, destFilename)\r | |
221 | print '[copied]'\r | |
222 | elif todo == 'copy with overwrite':\r | |
223 | overwrite = ''\r | |
224 | if os.path.exists(destFilename):\r | |
225 | os.remove(destFilename)\r | |
226 | overwrite = ', overwritten'\r | |
227 | shutil.copy(srcFilename, destFilename)\r | |
228 | print '[copied' + overwrite + ']'\r | |
229 | elif todo == 'symlink to templates':\r | |
8625864e | 230 | if os.path.islink(destFilename) or os.path.exists(destFilename):\r |
07a756b9 | 231 | if not os.path.islink(destFilename):\r |
232 | raise Exception, '%s is not a symlink! (remove file if you want to start using symlinks)' % \\r | |
233 | (self.RelativeToWorkspace(destFilename))\r | |
234 | os.remove(destFilename)\r | |
8625864e | 235 | os.symlink(os.path.join('..', self.RelativeToWorkspace(srcFilename)), destFilename)\r |
07a756b9 | 236 | print '[symlinked]'\r |
237 | elif todo == 'do nothing':\r | |
238 | print '[skipped by user request]'\r | |
239 | else:\r | |
240 | raise Exception, 'Unknown action for templates&conf: %s' % todo\r | |
241 | \r | |
8625864e | 242 | def DeleteEnvironmentConfigurationScript(self):\r |
243 | workspace = os.path.realpath(self.Opt.workspace)\r | |
244 | scriptFilename = os.path.join(workspace, 'Conf', 'BuildEnv.sh')\r | |
245 | if os.path.exists(scriptFilename):\r | |
246 | os.remove(scriptFilename)\r | |
247 | \r | |
07a756b9 | 248 | def WriteEnvironmentConfigurationScript(self):\r |
249 | workspace = os.path.realpath(self.Opt.workspace)\r | |
250 | scriptFilename = os.path.join(workspace, 'Conf', 'BuildEnv.sh')\r | |
251 | print\r | |
252 | print 'Storing environment configuration into',\r | |
253 | print self.RelativeToWorkspace(scriptFilename)\r | |
254 | script = open(scriptFilename, 'w')\r | |
255 | \r | |
256 | print >> script, 'export WORKSPACE="%s"' % workspace\r | |
257 | print >> script, 'export TOOLCHAIN="%s"' % self.conf['compiler']\r | |
8625864e | 258 | #print >> script, 'export COMPILER_SUITE_PATH_PREFIX="%s"' % self.conf['compiler-prefix']\r |
07a756b9 | 259 | \r |
6e98e263 | 260 | EDK_TOOLS_PATH = os.path.join(workspace, 'BaseTools')\r |
261 | print >> script, 'if [ $EDK_TOOLS_PATH=="" ]'\r | |
262 | print >> script, 'then'\r | |
263 | print >> script, ' export EDK_TOOLS_PATH="%s"' % EDK_TOOLS_PATH\r | |
264 | print >> script, 'fi'\r | |
265 | \r | |
07a756b9 | 266 | #\r |
267 | # Change PATH variable\r | |
268 | #\r | |
269 | newPath = os.environ['PATH'].split(os.path.pathsep)\r | |
270 | binDir = \\r | |
6e98e263 | 271 | os.path.join(workspace, 'BaseTools', 'Bin', sys.platform.title())\r |
07a756b9 | 272 | if binDir not in newPath:\r |
273 | newPath.append(binDir)\r | |
274 | newPath = os.path.pathsep.join(newPath)\r | |
275 | print >> script, 'export PATH=%s' % newPath\r | |
276 | \r | |
277 | script.close()\r | |
278 | \r | |
279 | def RelativeToWorkspace(self, path):\r | |
280 | workspace = os.path.realpath(self.Opt.workspace)\r | |
281 | for prefix in (workspace + os.path.sep, workspace):\r | |
282 | if path.startswith(prefix):\r | |
283 | return path[len(prefix):]\r | |
07a756b9 | 284 | \r |
285 | if __name__ == '__main__':\r | |
286 | SetupBuildEnvironmentApp()\r | |
287 | \r |