2012-03-21 28 views
7

Chúng tôi đang đánh giá scons là một hệ thống xây dựng, và tôi đang gặp vấn đề với hệ thống cũ của chúng tôi. Trong một số thư mục con mã nguồn của chúng ta, chúng ta có một tệp "sources.lib" liệt kê tên của các tệp C++ cần được biên dịch để lắp ráp thư viện đích của thư mục đó. Tuy nhiên, có thêm các tệp C++ trong cùng một thư mục, vì vậy tôi không thể chỉ sử dụng Glob() để tìm các tệp thích hợp.Các scon có biết trong thư mục nào có tệp SConscript không?

Làm cách nào để tìm ra thư mục chứa tệp SConscript nào? os.getcwd() luôn trả về thư mục build. Mặc dù tài liệu nói rằng các đường dẫn trong một SConscript có liên quan đến thư mục nguồn (hoặc khác Glob ('*. Cpp') sẽ không hoạt động), chỉ cần mở ('sources.lib') không thành công vì nó tìm kiếm trong thư mục xây dựng. Cuối cùng, môi trường xây dựng trong tệp SConscript đó không chứa thư mục nguồn hiện tại thực sự.

Sửa Từ this reply nó trông giống như

File('sources.lib').srcnode().abspath 

trả về tên tập tin thích hợp và thư mục, nhưng nó sẽ không cho bạn biết nếu nó tồn tại (phải sử dụng os.path.isfile cho điều đó). Nó cũng xuất hiện rằng

Dir('.').srcnode().abspath 

sẽ cho bạn biết nơi tệp SConstruct cư trú.

Ví dụ Khi xác định mà nguồn tập tin để biên dịch cho một thư viện, tôi không muốn sử dụng

lib = env.SharedLibrary('mylib', Glob('*.cpp')) 

nhưng thay vì thà xây dựng một hàm rằng séc đầu tiên cho sự tồn tại của "sources.lib "và nếu nó không tồn tại, sử dụng globbing. Vì vậy, tôi xác định thư viện của tôi như vậy

lib = env.SharedLibrary('mylib', env.getSources('*.cpp')) 

và thực hiện một chức năng mà đọc các tập tin nếu nó tồn tại

def getSources(self, pattern): 

    # list of source files to assign to a target 
    sources = [] 
    # srcFile = 'sources.lib' # failed 
    # srcFile = os.path.join(os.getcwd(), 'sources.lib') # failed 
    srcFile = File('sources.lib').srcnode().abspath # works 

    # look for sources.lib 
    try: 
     infile = open(srcFile,'r') 
    except IOError: 
     #print "Globbing to get sources" 
     sources = Glob(pattern, strings=True) 
    else: 
     #print "Reading sources.lib" 
     for line in infile.readlines(): 
      line = line.rstrip('\n\r') 
      if line != '': 
       sources.append(line) 

    return sources 

buildEnv.AddMethod(getSources)

Điều này dường như làm việc. Tôi không biết về File.srcnode(). Abspath cho đến ngày hôm nay.

+0

Để xác định xem một tập tin tồn tại, bạn có thể sử dụng os.path.exists() – Brady

+0

Tôi không hiểu vấn đề của bạn, tạo ra ví dụ nhỏ minh họa nó. – Torsten

+0

Câu hỏi của bạn đã lưu cho tôi :) 'Dir ('.'). Srcnode(). Abspath' làm việc cho tôi. Tôi sử dụng tùy chọn này 'env.SConscriptChdir (0) 'để tránh thư mục" trang trình bày ". Cảm ơn! – Destroyica

Trả lời

2

Có 3 loại đường dẫn trong SCons:

  1. So với các SConstruct gốc prepending '#' để con đường
  2. So với các SConscript không sử dụng '#'.
  3. Đường dẫn tuyệt đối.Tôi nghĩ rằng đây là tự giải thích :)

Nếu bạn cần để đối phó với những con đường bên ngoài của thư mục chứa SConscript là, bạn nên sử dụng '#'

Nó sẽ làm việc cả hai cách trong ví dụ này , nhưng con đường với '#' dường như rõ ràng hơn và trực quan với tôi:

./SConstruct 
./dirA/SConscript - use '#dirA/sources.lib' OR 'sources.lib' 
./dirB/SConscript - use '#dirB/sources.lib' OR 'sources.lib' 

Hope this helps,

Brady

+0

Theo tài liệu hướng dẫn đường dẫn tương đối mặc định là tập tin SConstruct curretn và không đến nơi scons được thực hiện. –

+0

Bạn hoàn toàn đúng, tôi cũng đã thử nghiệm nó. Xin lỗi vì sự nhầm lẫn, tôi sẽ sửa câu trả lời của tôi. Tôi đã có một vấn đề với điều này một lần và đã được thuyết phục rằng nó đã liên quan đến từ nơi scons đã được thực hiện, ví dụ nếu bạn đang ở trong một subdir và sử dụng 'scons -u', nhưng điều đó dường như không phải là trường hợp. Cảm ơn vì sự đúng đắn của bạn. – Brady

+1

Nhưng những gì về * hiện tại * SConscript, như trái ngược với SConscript mà thực sự gọi một nhà xây dựng? Trong trường hợp của tôi, tôi đang cố gắng thiết lập môi trường chung được nhiều mô-đun phụ sử dụng - điều này bao gồm thêm một thư mục 'include /' trong thư mục SConscript hiện tại vào CPPPATH. –

4

tôi sử dụng đoạn mã sau:

this_sconscript_file = (lambda x:x).func_code.co_filename 
code_base = os.path.dirname(this_sconscript_file) 
+0

Không phải là 'os.path.dirname (__ file __) 'làm điều tương tự? – tutuca

+2

Không, bởi vì các scons bao gồm các bản ghi SCS bằng cách nào đó, rằng '__file__' luôn đề cập đến tập lệnh gốc, ngay cả trong các kịch bản kèm theo. – olpa

+0

Giải pháp thay thế tốt. Tôi vẫn nghĩ rằng 'Dir ('. '). Srcnode(). Abspath' là một giải pháp đẹp hơn. – gg349

Các vấn đề liên quan