2012-06-06 3 views
21

CMake documentation tuyên bố rõ ràng rằng file(GLOB ...) không phải là được đề xuất để thu thập tệp nguồn cho một bản dựng, nhưng không đề cập đến phương pháp được đề xuất thực sự là gì.Làm thế nào để thu thập các tệp nguồn với CMake mà không cần sử dụng globbing?

Chỉ định mọi tệp nguồn theo cách thủ công có vẻ hơi quá thủ công đối với tôi. Vậy, phương pháp nào đúng để thu thập các tệp nguồn, nếu không phải là file(GLOB ...)?

+0

Bạn có thể sử dụng GLOB từ cmake trong một kịch bản và có mà thêm đổ ra tên tập tin. – Damian

Trả lời

17

Hướng dẫn sử dụng thực sự là phương pháp được khuyến nghị. Bằng cách giới thiệu chống lại việc sử dụng GLOB, tài liệu chỉ đơn giản là cảnh báo chống lại một hệ thống xây dựng phụ thuộc vào các tệp hiện tại. Ví dụ: bạn muốn thêm tệp thi hành thử nghiệm, do đó bạn tạo mytest.cpp. Rất tiếc. Bây giờ thư viện biên dịch của bạn bị hỏng. Các tài liệu cho AUX_SOURCE_DIRECTORY (mục đích tương tự như globbing cho cho các tập tin nguồn) cung cấp cho các cảnh báo sau đây:

Nó là hấp dẫn để sử dụng lệnh này để tránh phải viết danh sách các nguồn tập tin cho một thư viện hoặc mục tiêu thực thi. Trong khi điều này dường như làm việc, không có cách nào để CMake tạo ra một hệ thống xây dựng mà biết khi nào một tệp nguồn mới đã được thêm vào. Thông thường, hệ thống xây dựng được tạo ra sẽ biết khi nào cần chạy lại CMake vì tệp CMakeLists.txt là được sửa đổi để thêm nguồn mới. Khi nguồn chỉ được thêm vào thư mục mà không sửa đổi tệp này, một tệp sẽ phải theo cách thủ công chạy lại CMake để tạo hệ thống xây dựng kết hợp tệp mới.

Nếu bạn chắc chắn rằng bạn muốn tất cả nội dung của thư mục và không có kế hoạch thêm nội dung mới, thì bằng mọi cách, hãy sử dụng GLOB.

Ngoài ra, đừng quên các tệp danh sách theo cách thủ công không phải liên quan đến việc nhập tất cả tên tệp. Bạn có thể làm, ví dụ: ls *.cpp >> CMakeLists.txt, sau đó sử dụng trình chỉnh sửa của bạn để di chuyển danh sách tệp đến đúng vị trí trong tệp.

+0

Loại phụ thuộc vào IDE tbh. Trong Qt Creator, nó luôn chạy lại CMake để sử dụng GLOB không phải là vấn đề. – Lap

+2

'printf 'add_library (xxx $ (ls * .cpp))" >> CMakeLists.txt' phải đẹp quá! – Alex

+0

Tôi không nghĩ rằng biến chứng của bạn là hợp lệ, bởi vì kiểm tra thường nằm trong thư mục thử nghiệm và không nên lộn xộn cây nguồn. – Arne

12

tôi sử dụng GLOB cho chính xác điều đó và mỗi khi tôi thêm một tập tin tôi chạy

touch ../src/CMakeLists.txt 

Các make lệnh tiếp theo sẽ quét lại các thư mục.

"Không có cách nào để CMake tạo hệ thống xây dựng biết khi nào một tệp nguồn mới đã được thêm" Thật không? Ok, vì vậy, hãy cho biết!

Nó không phải là 100% tự động nhưng một cảnh chết tiệt dễ dàng hơn việc thêm tệp theo cách thủ công.

1

Tôi sử dụng cog, mô-đun python. Đây là một mẫu để thu thập tập tin cpp:

Các CMakeLists.txt:

set(SRC_FILES "") 

# [[[cog 
# import cog, glob 
# for src in glob.glob('*.cpp'): 
#  if "skeleton" in src: continue 
#  cog.outl("SET(SRC_FILES ${SRC_FILES} %s)" % src) 
# ]]] 
# [[[end]]] 

add_library(mylib STATIC ${SRC_FILES}) 

Và sau đó, hãy chạy:

python -m cogapp -r CMakeLists.txt 

File CMakeLists.txt sẽ được cập nhật tại chỗ.

Để biết cách cài đặt cog và cách sử dụng khác, vui lòng đọc the article from the author.

0

Tôi sử dụng CMakeLists.txt thông thường và tập lệnh python để cập nhật. Tôi chạy tập lệnh python theo cách thủ công sau khi thêm tệp.

import os 
import re  

def relFiles(base, sub): 
    fullSub = os.path.join(base,sub) 
    abs = [os.path.join(dp, f) for dp, dn, fn in os.walk(fullSub) for f in fn] 
    return [os.path.relpath(f, base) for f in abs] 

def updateAddLibrary(cmakelistsDir, subs): 
    cmakelists = os.path.join(cmakelistsDir, "CMakeLists.txt") 
    listings = [relFiles(cmakelistsDir, sub) for sub in subs] 
    files = [f for listing in listings for f in listing] #flatten 
    with open(cmakelists, 'r') as file: 
     text = file.read() 
    sources = "".join([" %s\n" % f.replace('\\', '/') for f in files]) 
    text = re.sub(r"add_library\s*\(\s*([^\s\)]+).*?\)", 
      r"add_library(\1\n%s)" % sources, 
      text, 1, re.DOTALL) 
    with open(cmakelists, "w") as file: 
     file.write(text) 

dir = os.path.dirname(os.path.abspath(__file__)) 
updateAddLibrary(dir, ['inc','src']) 

Ví dụ trước:

... 
add_library(MyLib 
    inc/a.h 
) 
... 

sau:

... 
add_library(MyLib 
    inc/a.h 
    inc/sub/b.h 
    src/a.cpp 
)   
...