Please note:The SCons wiki is in read-only mode due to ongoing spam/DoS issues. Also, new account creation is currently disabled. We are looking into alternative wiki hosts.

Goal: to have a more flexible LINKCOM, so that we can put options in any order. Right now, we are force to have LINKFLAGS LIBPATH LIBS. In particular, if we want to put linkflags between libs, this is not possible right now wo rewrwiting link actions.

None of below is meant as a prototype: this is just to show the basic concept.

   1 import SCons                                                                              
   2 from SCons.Defaults import _stripixes, _concat                                            
   3                                                                                           
   4 # This dict of func is just a (really) poor-man replacement for  scons                    
   5 # interpolation. In real life, of course, the scons scheme should be used.                
   6 def interpolate_lib(libs, env):                                                           
   7     return _stripixes(env['LIBLINKPREFIX'], libs,                                         
   8                       env['LIBLINKSUFFIX'], env['LIBPREFIXES'],                           
   9                       env['LIBSUFFIXES'], env)                                            
  10                                                                                           
  11 def interpolate_libpath(libpaths, env):                                                   
  12     return _concat(env['LIBDIRPREFIX'], libpaths, env['LIBDIRSUFFIX'], env,               
  13                       env['RDirs'], None, None)                                           
  14                                                                                           
  15 _INTERPOLATE = {'LIBS' : interpolate_lib,                                                 
  16         'LIBPATH': interpolate_libpath,                                                   
  17         'LINKFLAGS': lambda x, y: x}                                                      
  18                                                                                           
  19 class Framework:                                                                          
  20     _keys = {'LIBPATH': None, 'LIBS': None, 'LINKFLAGS': None}                            
  21     def __init__(self):                                                                   
  22         self._data = []                                                                   
  23                                                                                           
  24     def append(self, key, value):                                                         
  25         # XXX: handling non valid construction variables ?                                
  26         assert key in self._keys                                                          
  27                                                                                           
  28         # XXX: of course, this should be handled correctly too                            
  29         assert SCons.Util.is_List(value)                                                  
  30                                                                                           
  31         self._data.append((key, value))                                                   
  32                                                                                           
  33     def subst(self, env):                                                                 
  34         intp = []                                                                         
  35         # XXX: I should see how scons interpolation works                                 
  36         for item in self._data:                                                           
  37             key = item[0]                                                                 
  38             val = item[1]                                                                 
  39             intp.extend(_INTERPOLATE[key](val, env))                                      
  40                                                                                           
  41         return ' '.join(intp)                                                             
  42                                                                                           
  43 class Bstatic:                                                                            
  44     def __init__(self, lib):                                                              
  45         f = Framework()                                                                   
  46                                                                                           
  47         # XXX: This is tool specific (e.g. gnu ld here)                                   
  48         # Maybe this could be handled at the tool level, be defining pre/post             
  49         # flag ? But does this catpure all way of doing it (MS platforms ?) ?             
  50         f.append('LINKFLAGS', ['-Wl,-Bstatic'])                                           
  51         f.append('LIBS', lib)                                                             
  52         f.append('LINKFLAGS', ['-Wl,-Bshared'])                                           
  53                                                                                           
  54         self._f = f                                                                       
  55                                                                                           
  56     def subst(self, env):                                                                 
  57         return self._f.subst(env)                                                         
  58 ~                                             

Which would be used in :

   1 from framework import interpolate_lib, interpolate_libpath, Framework, Bstatic
   2 
   3 env = Environment()
   4 
   5 # Simple example with libpath + lib (not useful here, but anyway)
   6 f1 = Framework()
   7 
   8 f1.append('LIBPATH', ['/opt/bar'])
   9 f1.append('LIBS', ['bar'])
  10 
  11 print f1.subst(env)
  12 
  13 # Simple example to wrap a lib to link statically
  14 f2 = Bstatic(["foo"])
  15 
  16 print f2.subst(env)
  17 
  18 # Simple example to add two libraries: this way, of foo in present in /opt/bar
  19 # and /opt/foo, foo in /opt/foo will be picked up first
  20 f3 = Framework()
  21 f3.append('LIBPATH', ['/opt/foo'])
  22 f3.append('LIBS', ['foo'])
  23 f3.append('LIBPATH', ['/opt/bar'])
  24 f3.append('LIBS', ['bar'])
  25 
  26 print f3.subst(env)
  27 
  28 # More complicated example
  29 f4 = Framework()
  30 f4.append('LIBPATH', ['/opt/foo'])
  31 f4.append('LINKFLAGS', ['-Wl,--rpath-link=/opt/foo'])
  32 f4.append('LIBS', ['foo'])
  33 f4.append('LIBPATH', ['/opt/bar'])
  34 f4.append('LINKFLAGS', ['-Wl,--rpath-link=/opt/bar'])
  35 f4.append('LIBS', ['bar'])
  36 f4.append('LINKFLAGS', ['-xlic_lib=foobar'])
  37 
  38 print f4.subst(env)

Which would print:

-L/opt/bar -lbar
-Wl,-Bstatic -lfoo -Wl,-Bshared
-L/opt/foo -lfoo -L/opt/bar -lbar
-L/opt/foo -Wl,--rpath-link=/opt/foo -lfoo -L/opt/bar -Wl,--rpath-link=/opt/bar -lbar -xlic_lib=foobar

FlexibleLinkCom (last edited 2010-01-17 06:49:27 by s235-200)