Lines 34-39
Link Here
|
34 |
|
34 |
|
35 |
import os |
35 |
import os |
36 |
import os.path |
36 |
import os.path |
|
|
37 |
import subprocess |
37 |
|
38 |
|
38 |
import SCons.Util |
39 |
import SCons.Util |
39 |
|
40 |
|
Lines 48-53
Link Here
|
48 |
return '-qtempinc=' + os.path.join(build_dir, 'tempinc') |
49 |
return '-qtempinc=' + os.path.join(build_dir, 'tempinc') |
49 |
return '' |
50 |
return '' |
50 |
|
51 |
|
|
|
52 |
def smart_rpath(target, source, env, for_signature): |
53 |
if not env.subst('$RPATH'): |
54 |
return None # let the -L arguments form the rpath |
55 |
# need the quotes, probably for issue#1123 |
56 |
return '"${vWl}-blibpath:${RPATH}:/usr/lib:/lib"' |
57 |
|
58 |
class vendor: |
59 |
def __init__(self, vendordict): |
60 |
self.vendordict = vendordict |
61 |
pass |
62 |
def __call__(self, target, source, env, for_signature = None): |
63 |
vendor = env.subst('$LINKVENDOR') |
64 |
result = self.vendordict.get(vendor,'') |
65 |
return result |
66 |
pass |
67 |
|
68 |
def getBits(target, source, env): |
69 |
"""Determine whether the first source object file this is 32 or 64 bits.""" |
70 |
with open(str(source[0]), "rb") as s: |
71 |
magic = s.read(2) |
72 |
if magic == '\x01\xdf': return 32 |
73 |
if magic == '\x01\xf7': return 64 |
74 |
raise SCons.Errors.BuildError( |
75 |
errstr='Cannot infer bitness, magic='+magic, |
76 |
node = target, filename = source[0], |
77 |
exc_info = exc_info, |
78 |
) |
79 |
|
80 |
def getShrBase(target, source, env, for_signature): |
81 |
"""Get the bits (32 or 64) from the first source object file.""" |
82 |
#if for_signature: |
83 |
# return 'shr' |
84 |
bits = getBits(target, source, env) |
85 |
if bits == 64: return 'shr_64' |
86 |
return 'shr' |
87 |
|
88 |
def parseLinkflags(flags, env): |
89 |
"""Find the soname in the linker flags, and fix scons-hardcoded flags for AIX linker.""" |
90 |
|
91 |
result = { 'soname': '', 'flags': SCons.Util.CLVar() } |
92 |
longopt = '' |
93 |
for flag in SCons.Util.CLVar(flags): |
94 |
if flag.startswith('"'): |
95 |
flag = flag.strip('"') |
96 |
if flag.startswith('-Wl,'): |
97 |
Wl = "${vWl}" |
98 |
ldflags = flag.split(',')[1:] # "-Wl,-flag1,-flag2" |
99 |
else: |
100 |
Wl = '' |
101 |
ldflags = [ flag ] |
102 |
for ldflag in ldflags: |
103 |
ldflag = longopt + ldflag |
104 |
longopt = '' |
105 |
if ldflag == '-soname': |
106 |
longopt = '-soname=' |
107 |
continue |
108 |
if ldflag.startswith('-soname='): |
109 |
result['soname'] = ldflag[8:] |
110 |
continue |
111 |
if ldflag == '-Bsymbolic': # hardcoded in Tool/__init__.py |
112 |
ldflag = '-bsymbolic' # TODO: identify whether ld is GNU |
113 |
# need the quotes, probably for issue#1123 |
114 |
result['flags'].append('"' + Wl + ldflag + '"') |
115 |
return result |
116 |
|
117 |
class linkflagsFilter: |
118 |
def __init__(self, linkflagsvar): |
119 |
self.linkflagsvar = linkflagsvar |
120 |
def __call__(self, target, source, env, for_signature): |
121 |
return parseLinkflags(env.subst('$'+self.linkflagsvar, target=target, source=source), env).get('flags', '') |
122 |
pass |
123 |
|
124 |
def createImportFile_str(importfile, linkflags, target, source, env): |
125 |
return 'CreateImportFile("%s")' % importfile |
126 |
|
127 |
def createImportFile_func(importfile, linkflags, target, source, env): |
128 |
|
129 |
shrbase = env.subst('$SHR', target=SCons.Util.CLVar(target), source=SCons.Util.CLVar(source)) |
130 |
|
131 |
bits = 32 |
132 |
if '64' in shrbase: |
133 |
bits = 64 |
134 |
|
135 |
soname = parseLinkflags(linkflags, env).get('soname', target) |
136 |
|
137 |
symbols = {} |
138 |
ignoreable = False |
139 |
# TODO: support GNU nm; this is native AIX nm |
140 |
symreader = SCons.Action._subproc(env, |
141 |
SCons.Util.CLVar("nm -X%d -PCpgl %s" % (bits, source)), |
142 |
error = 'raise', |
143 |
stdin = 'devnull', |
144 |
stderr = subprocess.PIPE, |
145 |
stdout = subprocess.PIPE) |
146 |
outlines, errlines = symreader.communicate() |
147 |
errors = '' |
148 |
for line in outlines.split('\n'): |
149 |
if not line or line.startswith('.') or line.endswith(':'): |
150 |
continue |
151 |
tokens = line.split() # symname type addr |
152 |
if len(tokens) < 3: |
153 |
continue |
154 |
if tokens[1] not in 'TDBWVZ': |
155 |
continue |
156 |
if tokens[1] in 'WVZ': |
157 |
tokens[0] += ' weak' |
158 |
symbols[tokens[0]] = None |
159 |
for line in errlines.split('\n'): |
160 |
if not line: |
161 |
continue |
162 |
if '0654-203' in line: # nm: lib.so[shr.imp]: 0654-203 Specify an XCOFF object module. |
163 |
ignoreable = True |
164 |
continue |
165 |
errors += line + '\n' |
166 |
if symreader.returncode and (not ignoreable or errors): |
167 |
# Import Files found as archive members trigger an error |
168 |
raise SCons.Errors.BuildError( |
169 |
errstr='Error %d from nm reading symbols from %s:\n%s' % ( symreader.returncode, source, errors ), |
170 |
node = target, filename = source[0], |
171 |
) |
172 |
|
173 |
with open(importfile, "wb") as imp: |
174 |
imp.write('#! %s(%s.o)\n# %d\n' % (soname, shrbase, bits)) |
175 |
for sym in symbols.keys(): |
176 |
imp.write(sym + '\n') |
177 |
pass |
178 |
|
51 |
def generate(env): |
179 |
def generate(env): |
52 |
""" |
180 |
""" |
53 |
Add Builders and construction variables for Visual Age linker to |
181 |
Add Builders and construction variables for Visual Age linker to |
Lines 56-68
Link Here
|
56 |
link.generate(env) |
184 |
link.generate(env) |
57 |
|
185 |
|
58 |
env['SMARTLINKFLAGS'] = smart_linkflags |
186 |
env['SMARTLINKFLAGS'] = smart_linkflags |
59 |
env['LINKFLAGS'] = SCons.Util.CLVar('$SMARTLINKFLAGS') |
187 |
env['_RPATH'] = smart_rpath |
60 |
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -qmkshrobj -qsuppress=1501-218') |
188 |
env['SHR'] = getShrBase |
61 |
env['SHLIBSUFFIX'] = '.a' |
189 |
env['EXPSYMFILE'] = '${TARGET}.d/${SHR}.imp' |
|
|
190 |
|
191 |
env['vLINKFLAGS'] = vendor({ 'XLC': '$SMARTLINKFLAGS -qsuppress=1501-218' }) |
192 |
env['vWl'] = vendor({ 'GNU': '-Wl,', '': '-Wl,' }) |
193 |
env['vShared'] = vendor({ 'GNU': '-shared' }) |
194 |
|
195 |
# need the quotes, probably for issue#1123 |
196 |
env['LINKFLAGS'] = '${vLINKFLAGS}' |
197 |
env['LINKCOM'] = '$LINK "${vWl}-brtl" -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' |
198 |
|
199 |
env['SHLINKFLAGS'] = "${LINKFLAGS}" |
200 |
|
201 |
CreateImportFile = SCons.Action.ActionFactory(createImportFile_func, createImportFile_str) |
202 |
|
203 |
env['SHLINKFLAGSfiltered'] = linkflagsFilter('SHLINKFLAGS') |
204 |
env['SHLINKCOM'] = [ |
205 |
SCons.Defaults.Delete('${TARGET}.d'), |
206 |
SCons.Defaults.Mkdir('${TARGET}.d'), |
207 |
CreateImportFile('$EXPSYMFILE', '$SHLINKFLAGS', '$TARGET', '$SOURCES', '$__env__'), |
208 |
# need the quotes, probably for issue#1123 |
209 |
'${SHLINK} ${vShared} "${vWl}-G" -o ${TARGET}.d/${SHR}.o "${vWl}-bexport:${EXPSYMFILE}" $SHLINKFLAGSfiltered $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS', |
210 |
# SCons.Defaults.Move('${TARGET}.d/${SHR}.o', '$TARGET'), |
211 |
'strip -e ${TARGET}.d/${SHR}.o', |
212 |
'$AR $ARFLAGS $TARGET ${TARGET}.d/${SHR}.o ${TARGET}.d/${SHR}.imp', |
213 |
SCons.Defaults.Delete('${TARGET}.d'), |
214 |
] |
215 |
|
216 |
env['LDMODULEFLAGSfiltered'] = linkflagsFilter('LDMODULEFLAGS') |
217 |
env['LDMODULECOM'] = [ |
218 |
SCons.Defaults.Delete('${TARGET}.d'), |
219 |
SCons.Defaults.Mkdir('${TARGET}.d'), |
220 |
CreateImportFile('$EXPSYMFILE', '$LDMODULEFLAGS', '$TARGET', '$SOURCES', '$__env__'), |
221 |
# need the quotes, probably for issue#1123 |
222 |
'$LDMODULE ${vShared} "${vWl}-G" -o ${TARGET}.d/${SHR}.o "${vWl}-bexport:${EXPSYMFILE}" $LDMODULEFLAGSfiltered $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS', |
223 |
'strip -e ${TARGET}.d/${SHR}.o', |
224 |
'$AR $ARFLAGS $TARGET ${TARGET}.d/${SHR}.o', |
225 |
SCons.Defaults.Delete('${TARGET}.d'), |
226 |
] |
62 |
|
227 |
|
63 |
def exists(env): |
228 |
def exists(env): |
64 |
# TODO: sync with link.smart_link() to choose a linker |
229 |
# TODO: sync with link.smart_link() to choose a linker |
65 |
linkers = { 'CXX': ['aixc++'], 'CC': ['aixcc'] } |
230 |
linkers = { 'CXX': ['aixc++', 'g++'], 'CC': ['aixcc', 'gcc'] } |
66 |
alltools = [] |
231 |
alltools = [] |
67 |
for langvar, linktools in linkers.items(): |
232 |
for langvar, linktools in linkers.items(): |
68 |
if langvar in env: # use CC over CXX when user specified CC but not CXX |
233 |
if langvar in env: # use CC over CXX when user specified CC but not CXX |