2010-08-20 11 views
10

मैं एक प्रोजेक्ट बनाने के लिए स्कैन का उपयोग कर रहा हूं और इसे एक फ़ाइल के लिए एक प्रतीकात्मक लिंक जोड़ने की जरूरत है जो इसे env.Install के माध्यम से स्थापित कर रहा है। कमांड लाइन पर कौन सा आदेश ln -s चलाने के बराबर होगा?स्कॉन्स के साथ एक प्रतीकात्मक लिंक कैसे बनाएं?

उत्तर

8

SCons एक समर्पित प्रतीकात्मक कड़ी आदेश नहीं है, लेकिन आप पायथन के os मॉड्यूल से os.symlink(src, dst) उपयोग कर सकते हैं:

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) 

यह विंडोज पर ठीक से काम नहीं हो सकता है, मैं केवल यह लिनक्स पर की कोशिश की है।

+0

किसी कारण जब एक subdir अंदर एक सिमलिंक बनाने का प्रयास कर यह काम नहीं करता, तो जैसे "env.Command (स्वाद + '/ संसाधन', 'src/Resources', SymLink)" जहां स्वाद 'डीबग' या 'रिलीज' है। – Septagram

+1

@Septagram कृपया मेरे संपादन को देखें –

+0

स्थापित फ़ाइलों के लिए काम नहीं करें – RzR

1

यह काम करने के लिए एक बिल्डर बनाता है:

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) 

फिर, यह समाधान लिनक्स के लिए है।

+1

दुर्भाग्यवश, यह निर्देशिकाओं पर अच्छी तरह से काम नहीं करता है: "TypeError: निर्देशिका/home/septi/Dropbox/code/StreetCleaner/src/Resources जहां फ़ाइल मिली अपेक्षित .: " – Septagram

+0

@ सप्तग्राम: निर्देशिका समस्या को कैसे ठीक करें? –

+0

@ Nordlöw, क्षमा करें, लेकिन यह थोड़ी देर हो गया है और मुझे नहीं पता :(कृपया कुछ जवाब दें और अगर आपको कुछ मिल जाए तो टिप्पणी करें। – Septagram

7

प्रतीकात्मक लिंक समर्थन के लिए स्कॉन्स कोर कोड में थोड़ा प्रगति प्रतीत होती है और मैं वेब पर मिलने वाले किसी भी समाधान से संतुष्ट नहीं था। यहां एक संभावित निर्माता है जो निक और रिचक के उत्तरों दोनों के पहलुओं को शामिल करता है। इसके अतिरिक्त, यह नाम परिवर्तन (एमिटर विधि के कारण) पकड़ लेगा और प्लेटफॉर्म-अज्ञेयवादी के रूप में मैं इसे प्राप्त कर सकता हूं।

मैं इस निर्माता को पसंद करता हूं क्योंकि यह उस निर्देशिका के सापेक्ष लिंक बनाएगा जिसमें वे स्थापित हैं। कोई भी मुझे लगता है कि पूर्ण होने के लिए लिंक को मजबूर करने के लिए एक विकल्प जोड़ सकता है, लेकिन मुझे इसकी आवश्यकता नहीं है या अभी तक चाहिए था।

वर्तमान में, यदि ओएस सिम्लिंक का समर्थन नहीं करता है, तो मैं बस पास करता हूं और कुछ भी नहीं करता हूं, लेकिन उदाहरण के लिए os.copytree() का उपयोग कर सकता है, हालांकि स्रोत एक निर्देशिका है तो एमिटर को गड़बड़ हो जाती है ताकि एमिटर को कुछ फैंसी करो। मैं यहां किसी भी सुझाव के लिए तैयार हूं।

एक निम्न कोड फ़ाइल में site_scons/site_tools/symlink.py (खाली साथ उपयुक्त स्थानों में फ़ाइलों _ _.py init) डाल सकते हैं। तब 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 
+0

target_factory तहत आदमी पृष्ठ देखें आप एक प्रश्न के लिखित है हार्ड लिंक के लिए संस्करण, साथ ही? मैं एक ही इंटरफ़ेस चाहता हूं जिसे 'इंस्टॉल' बनाया गया है जहां पहला तर्क निर्देशिका है। –

संबंधित मुद्दे