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