Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There seems to be little advancement in the SCons core code for symbolic link support and I wasn't satisfied any one solution I found on the web. Here is a potential builder which incorporates aspects of both Nick's and richq's answers. Additionally, it will catch name changes (due to the emitter method) and is as platform-agnostic as I could get it.</p> <p>I prefer this builder because it will make links relative to the directory in which they are installed. One could add an option to force the link to be absolute I suppose, but I have not needed or wanted that yet.</p> <p>Currently, if the OS doesn't support symlinks, I just pass and do nothing, but one could use os.copytree() for example however the dependency becomes messy if the source is a directory so the emitter would need to do something fancy. I'm up for any suggestions here.</p> <p>One can put the following code into the file <strong>site_scons/site_tools/symlink.py</strong> (with blank <strong>_<em>init</em>_.py</strong> files in the appropriate places). Then do this in the SConstruct file:</p> <p>SConstruct:</p> <pre class="lang-python prettyprint-override"><code>env = Environment() env.Tool('symlink') env.SymLink('link_name.txt', 'real_file.txt') </code></pre> <p>symlink.py:</p> <pre class="lang-python prettyprint-override"><code>import os from os import path from SCons.Node import FS from SCons.Script import Action, Builder def generate(env): ''' SymLink(link_name,source) env.SymLink(link_name,source) Makes a symbolic link named "link_name" that points to the real file or directory "source". The link produced is always relative. ''' bldr = Builder(action = Action(symlink_builder,symlink_print), target_factory = FS.File, source_factory = FS.Entry, single_target = True, single_source = True, emitter = symlink_emitter) env.Append(BUILDERS = {'SymLink' : bldr}) def exists(env): ''' we could test if the OS supports symlinks here, or we could use copytree as an alternative in the builder. ''' return True def symlink_print(target, source, env): lnk = path.basename(target[0].abspath) src = path.basename(source[0].abspath) return 'Link: '+lnk+' points to '+src def symlink_emitter(target, source, env): ''' This emitter removes the link if the source file name has changed since scons does not seem to catch this case. ''' lnk = target[0].abspath src = source[0].abspath lnkdir,lnkname = path.split(lnk) srcrel = path.relpath(src,lnkdir) if int(env.get('verbose',0)) &gt; 3: ldir = path.relpath(lnkdir,env.Dir('#').abspath) if rellnkdir[:2] == '..': ldir = path.abspath(ldir) print ' symbolic link in directory: %s' % ldir print ' %s -&gt; %s' % (lnkname,srcrel) try: if path.exists(lnk): if os.readlink(lnk) != srcrel: os.remove(lnk) except AttributeError: # no symlink available, so we remove the whole tree? (or pass) #os.rmtree(lnk) print 'no os.symlink capability on this system?' return (target, source) def symlink_builder(target, source, env): lnk = target[0].abspath src = source[0].abspath lnkdir,lnkname = path.split(lnk) srcrel = path.relpath(src,lnkdir) if int(env.get('verbose',0)) &gt; 4: print 'target:', target print 'source:', source print 'lnk:', lnk print 'src:', src print 'lnkdir,lnkname:', lnkdir, lnkname print 'srcrel:', srcrel if int(env.get('verbose',0)) &gt; 4: print 'in directory: %s' % path.relpath(lnkdir,env.Dir('#').abspath) print ' symlink: %s -&gt; %s' % (lnkname,srcrel) try: os.symlink(srcrel,lnk) except AttributeError: # no symlink available, so we make a (deep) copy? (or pass) #os.copytree(srcrel,lnk) print 'no os.symlink capability on this system?' return None </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload