Skip to content

Commit cb9181e

Browse files
authored
Merge pull request #19 from loicgelle/master
Add store feature
2 parents bee2583 + 6ef80a2 commit cb9181e

File tree

5 files changed

+46
-58
lines changed

5 files changed

+46
-58
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ As of August 2016 WLLVM is now a pip package. You can just do:
4040

4141
pip install wllvm
4242

43-
or
43+
or
4444

4545
sudo pip install wllvm
4646

@@ -222,8 +222,14 @@ Building a bitcode archive then extracting the bitcode
222222
llvm-ar x libjansson.bca
223223
ls -la
224224

225-
226225

226+
Put the bitcode files in a store
227+
--------------------------------
228+
229+
Sometimes it can be useful to put the bitcode files out of the build folder, to prevent
230+
deletion or to retrieve it later. If the environment variable `WLLVM_BC_STORE` is set to
231+
an existing directory, then WLLVM will copy the produced bitcode file into that directory,
232+
using a hash of the path to the original bitcode file as a name for the stored copy.
227233

228234

229235
Debugging

wllvm/arglistfilter.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ def __init__(self, inputList, exactMatches={}, patternMatches={}):
264264
self._inputArgs = collections.deque(inputList)
265265

266266
#iam: parse the cmd line, bailing if we discover that there will be no second phase.
267-
while (len(self._inputArgs) > 0 and
267+
while (self._inputArgs and
268268
not (self.isAssembly or
269269
self.isAssembleOnly or
270270
self.isPreprocessOnly)):
@@ -397,8 +397,7 @@ def getOutputFilename(self):
397397
(_, base) = os.path.split(self.inputFiles[0])
398398
(root, _) = os.path.splitext(base)
399399
return '{0}.o'.format(root)
400-
else:
401-
return 'a.out'
400+
return 'a.out'
402401

403402
# iam: returns a pair [objectFilename, bitcodeFilename] i.e .o and .bc.
404403
# the hidden flag determines whether the objectFile is hidden like the

wllvm/checker.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ def checkSwitch(self):
121121
return (1, '\n{0} we are using clang.\n'.format(vmsg))
122122
elif compiler_type == 'dragonegg':
123123
return (2, '\n{0} we are using dragonegg.\n'.format(vmsg))
124-
else:
125-
return (0, explain_LLVM_COMPILER)
124+
return (0, explain_LLVM_COMPILER)
126125

127126

128127
def checkClang(self):
@@ -184,9 +183,8 @@ def checkCompiler(self):
184183
elif code == 2:
185184
print(comment)
186185
return self.checkDragonegg()
187-
else:
188-
print('Insane')
189-
return False
186+
print('Insane')
187+
return False
190188

191189

192190

@@ -229,8 +227,7 @@ def checkExecutable(self, exe, version_switch='-v'):
229227
return (False, '{0} not executable'.format(exe))
230228
elif e.errno == errno.ENOENT:
231229
return (False, '{0} not found'.format(exe))
232-
else:
233-
return (False, '{0} not sure why, errno is {1}'.format(exe, e.errno))
230+
return (False, '{0} not sure why, errno is {1}'.format(exe, e.errno))
234231
else:
235232
return (True, compilerOutput)
236233

@@ -274,5 +271,4 @@ def extractLine(version, n):
274271
lines = version.split('\n')
275272
if n < len(lines):
276273
return lines[n]
277-
else:
278-
return lines[-1]
274+
return lines[-1]

wllvm/compilers.py

Lines changed: 16 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import os
66
import sys
77
import tempfile
8+
import hashlib
89

10+
from shutil import copyfile
911
from .filetype import FileType
1012
from .popenwrapper import Popen
1113
from .arglistfilter import ArgumentListFilter
@@ -120,6 +122,13 @@ def attachBitcodePathToObject(bcPath, outFileName):
120122
_logger.error('objcopy failed with %s', orc)
121123
sys.exit(-1)
122124

125+
# loicg: If the environment variable WLLVM_BC_STORE is set, copy the bitcode
126+
# file to that location, using a hash of the original bitcode path as a name
127+
storeEnv = os.getenv('WLLVM_BC_STORE')
128+
if storeEnv:
129+
hashName = hashlib.sha256(absBcPath).hexdigest()
130+
copyfile(absBcPath, os.path.join(storeEnv, hashName))
131+
123132
class BuilderBase(object):
124133
def __init__(self, cmd, isCxx, prefixPath=None):
125134
self.cmd = cmd
@@ -140,16 +149,7 @@ def __init__(self, cmd, isCxx, prefixPath=None):
140149
else:
141150
self.prefixPath = ''
142151

143-
#clang and dragonegg share the same taste in bitcode filenames.
144-
def getBitcodeFileName(self, argFilter):
145-
(dirs, baseFile) = os.path.split(argFilter.getOutputFilename())
146-
bcfilename = os.path.join(dirs, '.{0}.bc'.format(baseFile))
147-
return bcfilename
148-
149152
class ClangBuilder(BuilderBase):
150-
def __init__(self, cmd, isCxx, prefixPath=None):
151-
super(ClangBuilder, self).__init__(cmd, isCxx, prefixPath)
152-
153153
def getBitcodeCompiler(self):
154154
cc = self.getCompiler()
155155
return cc + ['-emit-llvm']
@@ -159,31 +159,16 @@ def getCompiler(self):
159159
cxx = os.getenv('LLVM_CXX_NAME')
160160
if cxx:
161161
return ['{0}{1}'.format(self.prefixPath, cxx)]
162-
else:
163-
return ['{0}clang++'.format(self.prefixPath)]
164-
else:
165-
cc = os.getenv('LLVM_CC_NAME')
166-
if cc:
167-
return ['{0}{1}'.format(self.prefixPath, cc)]
168-
else:
169-
return ['{0}clang'.format(self.prefixPath)]
162+
return ['{0}clang++'.format(self.prefixPath)]
163+
cc = os.getenv('LLVM_CC_NAME')
164+
if cc:
165+
return ['{0}{1}'.format(self.prefixPath, cc)]
166+
return ['{0}clang'.format(self.prefixPath)]
170167

171168
def getBitcodeArglistFilter(self):
172169
return ClangBitcodeArgumentListFilter(self.cmd)
173170

174-
def extraBitcodeArgs(self, argFilter):
175-
bcPath = self.getBitcodeFileName(argFilter)
176-
return ['-o', bcPath]
177-
178-
def attachBitcode(self, argFilter):
179-
bcname = self.getBitcodeFileName(argFilter)
180-
outFile = argFilter.getOutputFilename()
181-
attachBitcodePathToObject(bcname, outFile)
182-
183171
class DragoneggBuilder(BuilderBase):
184-
def __init__(self, cmd, isCxx, prefixPath=None):
185-
super(DragoneggBuilder, self).__init__(cmd, isCxx, prefixPath)
186-
187172
def getBitcodeCompiler(self):
188173
pth = os.getenv('LLVM_DRAGONEGG_PLUGIN')
189174
cc = self.getCompiler()
@@ -201,21 +186,11 @@ def getCompiler(self):
201186

202187
if self.isCxx:
203188
return ['{0}{1}g++'.format(self.prefixPath, pfx)]
204-
else:
205-
return ['{0}{1}gcc'.format(self.prefixPath, pfx)]
189+
return ['{0}{1}gcc'.format(self.prefixPath, pfx)]
206190

207191
def getBitcodeArglistFilter(self):
208192
return ArgumentListFilter(self.cmd)
209193

210-
# Don't need to do anything since the -B flag in the bitcode
211-
# compiler and the assembly stub handles it
212-
def attachBitcode(self, argFilter):
213-
pass
214-
215-
def extraBitcodeArgs(self, _):
216-
return []
217-
218-
219194
def getBuilder(cmd, isCxx):
220195
compilerEnv = 'LLVM_COMPILER'
221196
cstring = os.getenv(compilerEnv)
@@ -251,7 +226,7 @@ def buildAndAttachBitcode(builder):
251226

252227
af = builder.getBitcodeArglistFilter()
253228

254-
if len(af.inputFiles) == 0 or af.isEmitLLVM or af.isAssembly or af.isAssembleOnly or (af.isDependencyOnly and not af.isCompileOnly) or af.isPreprocessOnly:
229+
if not af.inputFiles or af.isEmitLLVM or af.isAssembly or af.isAssembleOnly or (af.isDependencyOnly and not af.isCompileOnly) or af.isPreprocessOnly:
255230
_logger.debug('No work to do')
256231
_logger.debug(af.__dict__)
257232
return
@@ -271,9 +246,6 @@ def buildAndAttachBitcode(builder):
271246
# maybe python-magic is in our future ...
272247
srcFile = af.inputFiles[0]
273248
(objFile, bcFile) = af.getArtifactNames(srcFile, hidden)
274-
if af.outputFilename is not None:
275-
objFile = af.outputFilename
276-
bcFile = builder.getBitcodeFileName(af)
277249
buildBitcodeFile(builder, srcFile, bcFile)
278250
attachBitcodePathToObject(bcFile, objFile)
279251

wllvm/extraction.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import tempfile
99
import shutil
1010
import argparse
11+
import hashlib
1112

1213
from .popenwrapper import Popen
1314

@@ -148,12 +149,26 @@ def extract_section_linux(inputFile):
148149
_logger.error('%s contained no %s. section is empty', inputFile, elfSectionName)
149150
return contents
150151

152+
# loicg: This function checks if the given path points to an existing bitcode file.
153+
# If it does not, it tries to look for the bitcode file in the store directory given
154+
# by the environment variable WLLVM_BC_STORE
155+
def getBitcodePath(bcPath):
156+
if not bcPath or os.path.isfile(bcPath):
157+
return bcPath
158+
storeEnv = os.getenv('WLLVM_BC_STORE')
159+
if storeEnv:
160+
hashName = hashlib.sha256(bcPath).hexdigest()
161+
hashPath = os.path.join(storeEnv, hashName)
162+
if os.path.isfile(hashPath):
163+
return hashPath
164+
return bcPath
151165

152166
def linkFiles(pArgs, fileNames):
153167
linkCmd = [pArgs.llvmLinker, '-v'] if pArgs.verboseFlag else [pArgs.llvmLinker]
154168

155169
linkCmd.append('-o={0}'.format(pArgs.outputFile))
156170

171+
fileNames = map(getBitcodePath, fileNames)
157172
linkCmd.extend([x for x in fileNames if x != ''])
158173
_logger.info('Writing output to %s', pArgs.outputFile)
159174
try:

0 commit comments

Comments
 (0)