Estoy usando SCons para construir un proyecto y necesito agregar un enlace simbólico a un archivo que está instalando a través de env.Install. ¿Qué comando (s) hará un enlace que es equivalente a ejecutar ln -s
en la línea de comando?¿Cómo crear un enlace simbólico con SCons?
Respuesta
SCons no tiene un comando de enlace simbólico dedicado, pero se puede utilizar os.symlink(src, dst)
desde el módulo de Python os
:
import os
env = Environment()
def SymLink(target, source, env):
os.symlink(os.path.abspath(str(source[0])), os.path.abspath(str(target[0])))
env.Command("file.out", "file.in", SymLink)
Esto puede no funcionar correctamente en Windows, sólo he probado en Linux.
Esto crea un constructor para realizar el trabajo:
mylib = env.SharedLibrary("foobar", SRCS)
builder = Builder(action = "ln -s ${SOURCE.file} ${TARGET.file}", chdir = True)
env.Append(BUILDERS = {"Symlink" : builder})
mylib_link = env.Symlink("_foobar.so", mylib)
env.Default(mylib)
env.Default(mylib_link)
Una vez más, esta solución es para Linux.
Desafortunadamente, no funciona bien (en absoluto) en los directorios: "TypeError: Directory/home/septi/Dropbox/Code/StreetCleaner/src/Resources found where file esperado .: " – Septagram
@Septagram: ¿Cómo se soluciona el problema del directorio? –
@ Nordlöw, lo siento, pero ha pasado un tiempo y no sé :(Por favor, intente con otras respuestas y comente si encuentra algo. – Septagram
Parece haber pocos avances en el código básico de SCons para la compatibilidad con enlaces simbólicos y no estaba satisfecho con ninguna solución que encontré en la web. Aquí hay un generador potencial que incorpora aspectos de las respuestas de Nick y Richq. Además, detectará los cambios de nombre (debido al método del emisor) y es tan independiente de la plataforma como podría obtenerlo.
Prefiero este constructor porque creará enlaces relativos al directorio en el que están instalados. Se podría agregar una opción para forzar que el enlace sea absoluto, supongo, pero aún no lo he necesitado ni lo deseo.
Actualmente, si el sistema operativo no admite enlaces simbólicos, simplemente paso y no hago nada, pero se podría usar os.copytree(), por ejemplo, pero la dependencia se vuelve desordenada si el origen es un directorio por lo que el emisor necesitaría hacer algo elegante Estoy a la altura de cualquier sugerencia aquí.
Uno puede poner el código siguiente en el archivo site_scons/site_tools/symlink.py (con blanco _ init _.py archivos en los lugares apropiados). Luego de hacer esto en el archivo SConstruct:
SConstruct:
env = Environment()
env.Tool('symlink')
env.SymLink('link_name.txt', 'real_file.txt')
symlink.py:
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)) > 3:
ldir = path.relpath(lnkdir,env.Dir('#').abspath)
if rellnkdir[:2] == '..':
ldir = path.abspath(ldir)
print ' symbolic link in directory: %s' % ldir
print ' %s -> %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)) > 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)) > 4:
print 'in directory: %s' % path.relpath(lnkdir,env.Dir('#').abspath)
print ' symlink: %s -> %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
¿usted ha escrito una variante para enlaces duros, ¿así? Quiero la misma interfaz que builtin 'Install' donde el primer argumento es un directorio. –
- 1. .htaccess o enlace simbólico (enlace simbólico)
- 2. ¿Cómo elimino un enlace simbólico?
- 3. archivo de reglas de Debian crear un enlace simbólico
- 4. Crear un enlace simbólico relativo en Python sin usar os.chdir()
- 5. ¿Cómo muevo un enlace simbólico relativo?
- 6. Homebrew enlace simbólico error
- 7. android: determinar un enlace simbólico
- 8. enlace gcc contra enlace simbólico
- 9. Cómo comprobar si existe un enlace simbólico
- 10. ¿Cómo eliminar un enlace simbólico en python?
- 11. Crear un enlace simbólico del directorio en Ubuntu
- 12. Modificando un enlace simbólico en python
- 13. Buscar el enlace simbólico
- 14. Cómo hacer un enlace simbólico con cygwin en Windows 7
- 15. ¿Cómo creo un enlace simbólico en Windows Vista?
- 16. Reemplazar el enlace simbólico importante 'con seguridad'
- 17. Detección de un enlace simbólico en Java
- 18. Enlace simbólico en Windows XP
- 19. copia de Linux enlace simbólico
- 20. Enlace simbólico a un gancho en git
- 21. Copiando un enlace simbólico en Python
- 22. ¿Tiene algún efecto secundario la creación de un enlace simbólico a otro enlace simbólico?
- 23. ¿Cómo tratar un enlace simbólico como un directorio en Mercurial?
- 24. ¿Puedo Traverse directorios en Ruby con un enlace simbólico "**" pegote?
- 25. Crear una compilación jerárquica con SCons
- 26. ¿Cómo crear un enlace cliqueable con GWT?
- 27. Cómo acceder a ctime, mtime, ... de un enlace simbólico?
- 28. ¿Cómo obtengo el objetivo de un enlace simbólico?
- 29. Averigüe si un archivo es un enlace simbólico en PowerShell
- 30. ¿Es posible crear un enlace simbólico al último archivo en un directorio?
Por alguna razón no funciona cuando se trata de crear un enlace simbólico dentro de un subdirectorio, como "env.Command (flavor + '/ Resources', 'src/Resources', SymLink)" donde el sabor es 'depurar' o 'liberar'. – Septagram
@Septagram por favor vea mi edición –
No funcionará para los archivos instalados – RzR