2012-11-30 22 views
73

Tôi muốn sử dụng một bộ toàn cầu của cờ cho soạn thảo một dự án, có nghĩa là ở tập tin CMakeLists.txt cấp cao nhất của tôi, tôi đã xác định:Override biên dịch những lá cờ cho các tập tin đơn

ADD_DEFINITIONS (-Wall -Weffc++ -pedantic -std=c++0x) 

Tuy nhiên, đối với một tập tin cụ thể (giả sử "foo.cpp") trong thư mục con, tôi muốn chuyển các cờ biên dịch thành không áp dụng -WeffC++ (bao gồm thư viện thương mại mà tôi không thể thay đổi). Để đơn giản hóa tình huống chỉ sử dụng -Wall, tôi đã thử:

SET_SOURCE_FILES_PROPERTIES(foo.cpp PROPERTIES COMPILE_FLAGS -Wall) 
ADD_EXECUTABLE(foo foo.cpp) 

, không hoạt động. Tôi cũng đã cố gắng

SET_PROPERTY(SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall) 
ADD_EXECUTABLE(foo foo.cpp) 

ADD_EXECUTABLE(foo foo.cpp) 
SET_TARGET_PROPERTIES(foo PROPERTIES COMPILE_FLAGS -Wall) 

, trong đó không phải làm việc.

Cuối cùng, tôi đã cố gắng loại bỏ defintion này:

REMOVE_DEFINITIONS(-Weffc++) 
ADD_EXECUTABLE(foo foo.cpp) 
ADD_DEFINITIONS(-Weffc++) 

, mà cũng không làm việc (có nghĩa là, tôi nhận được rất nhiều lời cảnh báo phong cách về thư viện thương mại). (** Lưu ý:. Các cảnh báo được ức chế nếu tôi KHÔNG tái bao gồm -WeffC++ chỉ thị sau khi thực thi được xây dựng)

Tôi cũng đã cố gắng tạm thời loại bỏ những lá cờ biên dịch: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , nhưng điều đó không Cứu giúp.

Không có giải pháp thanh lịch cho điều này?

+1

Đợi, nếu lần cuối bạn làm việc, nhưng chỉ sau khi nó được tạo, có thể đây không phải là vấn đề về bộ nhớ đệm? Hãy thử xóa CMakeCache sau khi thực hiện (các) thay đổi của bạn. – Cameron

+0

Liên quan, hãy xem [Làm thế nào để thay đổi cờ trình biên dịch chỉ cho một thực thi trong CMake?] (Https://stackoverflow.com/q/24238937/608639) Câu trả lời của Andre cho thấy những gì dường như là một cách để thay thế các tùy chọn hiện tại bằng các tùy chọn mới . – jww

Trả lời

87

Nỗ lực của bạn ở trên đang thêm cờ thêm vào tệp/mục tiêu của bạn thay vì ghi đè như bạn mong đợi. Ví dụ: từ tài liệu cho Properties on Source Files - COMPILE_FLAGS:

Những cờ này sẽ được thêm vào danh sách cờ biên dịch khi tệp nguồn này được tạo.

Bạn sẽ có thể hồi lại các -Weffc++ cờ cho Foo.cpp bằng cách làm

set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++) 

này nên có tác dụng bổ sung -Wno-effc++ sau -Weffc++ trong lệnh biên dịch, và chiến thắng thiết lập sau. Để xem toàn bộ chỉ huy và kiểm tra rằng đây thực sự là trường hợp, bạn có thể làm

make VERBOSE=1 

Là một sang một bên, một trong các nhà bảo trì của GNU C++ thư viện chuẩn trình bày một quan điểm khá tiêu cực đối với -Weffc++ trong this answer.

Một điểm khác là bạn đang lạm dụng add_definitions theo nghĩa là bạn đang sử dụng điều này cho cờ trình biên dịch thay vì định nghĩa tiền xử lý dự định.

Nó sẽ là thích hợp hơn để sử dụng add_compile_options

add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x) 

hoặc cho các phiên bản CMake < 3.0 để làm một cái gì đó giống như:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x") 

Đáp lại tiếp tục câu hỏi trong các ý kiến ​​dưới đây, tôi tin rằng nó không thể đáng tin cậy loại bỏ một lá cờ trên một tập tin duy nhất. Lý do là đối với bất kỳ tệp nguồn cụ thể nào, nó có một mục tiêu được áp dụng trong bất kỳ thuộc tính nào cho tệp nguồn đó là COMPILE_OPTIONSCOMPILE_FLAGS .

Bạn có thể xem tước cờ vấn đề khỏi mục tiêu COMPILE_OPTIONS, sau đó áp dụng nó cho từng nguồn của mục tiêu riêng lẻ, bỏ qua nguồn đó từ tệp nguồn cụ thể theo yêu cầu.

Tuy nhiên, mặc dù điều này có thể hoạt động trong nhiều trường hợp, nhưng có một số vấn đề.

Đầu tiên - source files' properties không bao gồm COMPILE_OPTIONS, chỉ COMPILE_FLAGS. Đây là vấn đề bởi vì COMPILE_OPTIONS của một mục tiêu có thể bao gồm generator expressions, nhưng COMPILE_FLAGS không hỗ trợ chúng. Vì vậy, bạn phải thích ứng với biểu thức trình phát khi tìm kiếm cờ của mình và thực sự bạn có thể phải "phân tích cú pháp" biểu thức trình phát nếu cờ của bạn được chứa trong một hoặc nhiều để xem liệu nó có được áp dụng lại cho cờ còn lại hay không tệp nguồn.

Thứ hai - kể từ CMake v3.0, mục tiêu có thể chỉ định INTERFACE_COMPILE_OPTIONS. Điều này có nghĩa là sự phụ thuộc của mục tiêu của bạn có thể thêm hoặc ghi đè mục tiêu của bạn là COMPILE_OPTIONS thông qua INTERFACE_COMPILE_OPTIONS của mục tiêu. Vì vậy, bạn phải tiếp tục lặp lại thông qua tất cả các phụ thuộc của mục tiêu (không phải là nhiệm vụ đặc biệt dễ dàng vì danh sách LINK_LIBRARIES cho mục tiêu cũng có thể chứa biểu thức trình phát) để tìm bất kỳ từ nào đang áp dụng cờ vấn đề và thử gỡ bỏ nó các mục tiêu đó 'INTERFACE_COMPILE_OPTIONS cũng vậy.

Ở giai đoạn phức tạp này, tôi sẽ tìm cách gửi bản vá cho CMake để cung cấp chức năng xóa cờ cụ thể vô điều kiện khỏi tệp nguồn.


1: Lưu ý rằng không giống như các COMPILE_FLAGS tài sản trên các tập tin nguồn, COMPILE_FLAGS tài sản vào các mục tiêu bị phản đối.

+5

Nhưng làm thế nào để bạn thực sự thiết lập các cờ biên dịch cho các tệp riêng biệt mà không cần thêm chúng. Ví dụ tôi muốn sử dụng các cờ biên dịch khác nhau cho mục tiêu kết quả hơn cho các tệp nhưng vì chúng được nối thêm, tôi sẽ phải loại bỏ chúng theo cách thủ công. Không có thuộc tính nào không chắp thêm nhưng thực sự đặt chúng chỉ cho tệp/đích được chỉ định? –

+2

Chúng ta có thể làm gì khi -fno-flag không khả dụng (và đặt -fflag)? – gnzlbg

+0

@ Baradé Bạn không thể - không phải cho tệp nguồn. – Fraser

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