2013-06-12 39 views
5

Như đã trình bày trong Undocumented qmake, tôi tuyên bố một trình biên dịch thêm trong tập tin dự án qmake tôi:qmake thêm biên dịch với nhiều kết quả đầu ra cho mỗi tập tin

TEST = somefile.h 

test_c.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_1.cpp 
test_c.input = TEST 
test_c.commands = C:/somedir/some.exe /i ${QMAKE_FILE_IN} /o ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_1.cpp 
test_c.variable_out = SOURCES 
test_c.name = MyTestC 

QMAKE_EXTRA_COMPILERS += test_c 

Và điều này hoạt động tốt. Nhưng tôi cũng muốn tạo một tệp tiêu đề. Tôi có thể dễ dàng tạo một công cụ tùy chỉnh thứ hai để phân tích tệp này (hoặc các tệp, nếu> 1 sẽ ở trong TEST), nhưng tôi không muốn phân tích cú pháp từng tệp hai lần. Tôi đã thử:

test_c.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_1.cpp \ 
    ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_2.cpp 

Chỉ để kiểm tra xem trình biên dịch bổ sung có thể tạo hai tệp cho mỗi lần chạy hay không. Tôi mong đợi một số lỗi như "file somefile_2.cpp doesn't exist", nhưng dự án biên dịch mà không có lỗi và tệp đầu ra thứ hai bị bỏ qua. Trong Makefile somefile_2.cpp không có mặt.

Bây giờ tôi đang suy nghĩ về hai biến thể:

  1. Thực hiện một trình biên dịch bổ sung mà tạo ra một kho lưu trữ, nơi mà tất cả các file đầu ra cần thiết sẽ được lưu cùng một lúc. Đặt tool1.variable_out = TOOL_1_OUT và thêm hai trình biên dịch bổ sung với toolN.input = TOOL_1_OUT để chỉ "giải nén" các tệp đã lưu trữ (một tệp cho mỗi công cụ) và thêm chúng vào một số biến.

    Trong trường hợp này, ba lần thực thi sẽ được gọi cho mỗi tệp đầu vào. Đây không phải là tối ưu, nhưng ít nhất trình phân tích cú pháp sẽ chỉ chạy một lần cho mỗi tệp.

  2. Thử nghiệm với tùy chọn .output_function. Tạo hàm qmake trả về cùng tên với tên .output hiện tại, nhưng cũng thêm tên tệp thứ hai vào HEADERS.

P.S. Tôi đang sử dụng MinGW x32 4.7, QtCreator 2.7.1, Qt 5.1.0, C++ 11.

Trả lời

2

này hoạt động ok (biến thể # 1):

MY_COMP = src/precompiled.h \ 
    src/file2.h 

GENERATE_FOLDER = generated/ 

# build package file 
my_build.clean = $${GENERATE_FOLDER}gen_${QMAKE_FILE_BASE}.pack 
my_build.depends = [somepath]/my_precompiler.exe 
my_build.output = $${GENERATE_FOLDER}gen_${QMAKE_FILE_BASE}.pack 
my_build.input = MY_COMP 
my_build.commands = [somepath]/my_precompiler.exe /i ${QMAKE_FILE_IN} /o $${GENERATE_FOLDER}gen_${QMAKE_FILE_BASE}.pack 
my_build.variable_out = MY_PACKAGES 
my_build.name = "package build" 

# unpack cpp 
my_unpack_cpp.clean = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.cpp 
my_unpack_cpp.depends = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h 
my_unpack_cpp.output = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.cpp 
my_unpack_cpp.input = MY_PACKAGES 
my_unpack_cpp.commands = [somepath]/my_precompiler.exe /unpack cpp /i ${QMAKE_FILE_IN} /o $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.cpp 
my_unpack_cpp.variable_out = GENERATED_SOURCES 
my_unpack_cpp.dependency_type = TYPE_C 
my_unpack_cpp.name = "unpack code" 
my_unpack_cpp.CONFIG = no_link 

# unpack header 
my_unpack_h.clean = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h 
my_unpack_h.output = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h 
my_unpack_h.input = MY_PACKAGES 
my_unpack_h.commands = [somepath]/my_precompiler.exe /unpack h /i ${QMAKE_FILE_IN} /o $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h 
my_unpack_h.variable_out = HEADERS 
my_unpack_h.name = "unpack header" 
my_unpack_h.CONFIG = no_link 

QMAKE_EXTRA_COMPILERS += my_build my_unpack_h my_unpack_cpp 

Với số kỹ thuật này các tập tin đầu ra trên một phân tích cú pháp có thể khác nhau, nhưng có thể liên tục cho tất cả các file trong dự án, tất nhiên.

Trong my_precompiler Tôi phân tích cú pháp tệp nếu tùy chọn unpack không được giữ nguyên và tạo hai tệp (cpp + h) thành hai QBuffers. Sau đó tôi chỉ đơn giản là ghi dữ liệu builded để QFile:

QDataStream ds(&file); 
ds.setVersion(QDataStream::Qt_5_1); 

ds << qCompress(output_cpp.data(), 9); 
ds << qCompress(output_h.data(), 9); 

file.close(); 

Trong thực tế, bây giờ qCompress là không có lợi nhuận, vì tạo ra các file quá nhỏ để kích thước nén vượt quá kích thước của tiêu đề zlib - sizeof (.pack)> kích thước (.h + .h).

Tháo bao bì:

QByteArray ba; 

QDataStream ds(&file); 
ds.setVersion(QDataStream::Qt_5_1); 

ds >> ba; 

if(unpack != "cpp") 
{ 
ds >> ba; 
} 
file.close(); 

ba = qUncompress(ba); 

file.setFileName(output); 
if(!file.open(QFile::WriteOnly | QFile::Truncate)) return 1; 

file.write(ba); 
file.close(); 

Khi tạo:

  1. Viết #include "ban đầu" trong bắt đầu header tạo
  2. Viết #include "tạo tiêu đề" ở bắt đầu của mã được tạo ra

Vì vậy, tôi đặt điều này:

my_unpack_cpp.depends = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h 

Vì vậy, giải nén cpp (và, do đó, xây dựng) thực hiện sau khi tạo tệp tiêu đề cần thiết. Và điều này:

my_build.depends = [somepath]/my_precompiler.exe 

Sets builded gói (và, do đó, tạo ra cpp + h) phụ thuộc vào my_precompiler, vì vậy tất cả sẽ được rebuilded nếu tôi sửa đổi và xây dựng lại tiền biên dịch.

P.S. IMHO những dòng này phải hoạt động như chất tẩy rửa trước khi xây dựng lại:

my_build.clean = $${GENERATE_FOLDER}gen_${QMAKE_FILE_BASE}.pack 
my_unpack_cpp.clean = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.cpp 
my_unpack_h.clean = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h 

Nhưng họ không nhất :(Hiện nay tôi bỏ qua điều đó, nhưng bây giờ nếu xây dựng .pack được thất bại hơn builded trước gói-file được sử dụng

2

Biến thể # 2 của bạn là ý tưởng đúng. Này làm việc cho tôi:

defineReplace(addToHeaders) { 
    source = $$1 
    source_split = $$split(source, ".") 
    source_without_extension = $$first(source_split) 
    HEADERS += ${QMAKE_VAR_OBJECTS_DIR}$${source_without_extension}_1.h 
    return(${QMAKE_VAR_OBJECTS_DIR}$${source_without_extension}_1.cpp) 
} 
defineReplace(FILE_IN_addToHeaders) { 
    # qmake emits a warning unless this function is defined; not sure why. 
} 

TEST = somefile.h 

test_c.output_function = addToHeaders 
test_c.input = TEST 
test_c.commands = cp ${QMAKE_FILE_IN} ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_1.cpp ; cp ${QMAKE_FILE_IN} ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_1.h 
test_c.variable_out = SOURCES 
test_c.name = MyTestC 

QMAKE_EXTRA_COMPILERS += test_c 

Nó tạo ra một Makefile trong đó xây dựng somefile_1.cpp và somefile_1.h, với somefile_1.cpp thêm vào NGUỒN và somefile_1.h thêm vào tiêu đề.

+0

tôi Tôi không thể biến phiên bản này thành công, tôi đã sửa đổi điều này cho các nhu cầu của mình và không thể làm cho nó hoạt động được. Và tôi lo lắng về biến thể # 2, nghĩ rằng đây là hack.Tôi nghi ngờ rằng qmake có thể biết rằng đầu tiên (file_1.cpp) phụ thuộc từ nguồn (file.h) vì giá trị trả về output_function của công cụ tùy chỉnh, nhưng điều này không giải quyết thứ hai (file_1.h) Và Makefile có thể cố gắng xây dựng thứ gì đó phụ thuộc từ tệp_1.h trước khi tạo tệp_1.h – user2271079

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