Đặt tùy chọn CFLAGS và CXXFLAGS bằng CMake


88

Tôi chỉ muốn gỡ lỗi một số mã chạy trên Linux và tôi cần một bản dựng gỡ lỗi ( -O0 -ggdb). Vì vậy, tôi đã thêm những thứ này vào CMakeLists.txt:

set(CMAKE_BUILD_TYPE DEBUG)
set(CMAKE_C_FLAGS "-O0 -ggdb")
set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb")
set(CMAKE_C_FLAGS_RELEASE "-O0 -ggdb")
set(CMAKE_CXX_FLAGS "-O0 -ggdb")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "-O0 -ggdb")

Khi tôi cố gắng biên dịch, tôi đã bật chi tiết bằng cách sử dụng make VERBOSE=1 Và tôi đã quan sát đầu ra, như thế này

... /usr/bin/c++ -D_BSD_SOURCE **-O0 -ggdb** -Wnon-virtual-dtor 
-Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W 
-Wpointer-arith -Wformat-security -fno-exceptions -DQT_NO_EXCEPTIONS 
-fno-check-new -fno-common -Woverloaded-virtual -fno-threadsafe-statics 
-fvisibility=hidden -fvisibility-inlines-hidden **-g -O2** 
-fno-reorder-blocks -fno-schedule-insns -fno-inline ...

Rõ ràng mã được biên dịch "-g -O2"và đây không phải là những gì tôi muốn. Làm thế nào tôi có thể buộc nó "-O0 -ggdb"chỉ sử dụng ?


1
Nếu bạn muốn một bản dựng có thể gỡ lỗi, chỉ cần thực hiện cấu hình gỡ lỗi tại dòng lệnh. "cmake -DCMAKE_BUILD_TYPE = Gỡ lỗi". Bản dựng kết quả sẽ có cờ gỡ lỗi bật cho hệ thống bản dựng đã cho. Không có lý do gì để sửa đổi chính tệp cmake. Bạn cũng có thể gửi giá trị CMAKE_C_FLAGS với đối số -D khác.
Atifm

Câu trả lời:


83

Bạn cần phải thiết lập các cờ sau khi các projectlệnh trong CMakeLists.txt của bạn.

Ngoài ra, nếu bạn đang gọi include(${QT_USE_FILE})hoặc add_definitions(${QT_DEFINITIONS}), bạn nên bao gồm các setlệnh này sau các lệnh Qt vì chúng sẽ gắn thêm các cờ. Nếu đó trường hợp, bạn có lẽ chỉ muốn gắn cờ của bạn với các Qt, vì vậy thay đổi ví dụ

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb")

Tôi đã đặt những cờ đó sau lệnh dự án. Nhưng đầu ra là như nhau.
majie

Tôi chỉ nhận thấy QT_NO_EXCEPTIONStrong cờ của bạn, vì vậy tôi đã mở rộng câu trả lời của mình một chút. Tôi đoán rằng điều đó ${QT_DEFINITIONS}đang thêm vào -g -O2.
Fraser

1
Vâng, Đây là nó. Đặt các setlệnh đó sau lệnh Qt sẽ giải quyết được vấn đề. Cảm ơn rât nhiều.
majie

18

Giải pháp dễ nhất hoạt động tốt đối với tôi là:

export CFLAGS=-ggdb
export CXXFLAGS=-ggdb

CMake sẽ nối chúng vào cờ của tất cả các cấu hình. Chỉ cần đảm bảo xóa bộ nhớ cache CMake.


3
Đặt cờ trong môi trường như thế này là cách duy nhất để làm điều đó mà không cần sửa đổi CMakeLists.txt của bạn. Lưu ý rằng giá trị môi trường chỉ được đọc trên cấu hình đầu tiên và sau đó được đưa vào bộ nhớ cache, vì vậy nếu bạn muốn thay đổi điều này, bạn cần xóa bộ nhớ cache CMake và chạy lại bước cấu hình với các giá trị mới trong env. Tài liệu: cmake.org/cmake/help/latest/envvar/CFLAGS.html cmake.org/cmake/help/latest/envvar/CXXFLAGS.html
bleater

3
Đó không phải là "dễ nhất", đó là cách duy nhất đúng để làm điều đó.
Slava

Lỗi nhỏ, nếu trình tạo đang định cấu hình một cờ cụ thể cho một kiểu xây dựng cụ thể (ví dụ: trong CMAKE_CXX_FLAGS_DEBUG v.v.), thì việc đưa nó vào CXXFLAGS(và do đó đưa nó vào CMAKE_CXX_FLAGS) thực sự không đủ để chuyển tùy chọn đến trình biên dịch. Cấu hình mỗi loại bản dựng được ưu tiên hơn so với đầu vào của người dùng.
Mở rộng 3h

15

Bạn phải thay đổi CỜ mặc định của cmake C / CXX.

Theo CMAKE_BUILD_TYPE={DEBUG/MINSIZEREL/RELWITHDEBINFO/RELEASE} đưa vào một trong những chính CMakeLists.txtcủa:

Đối với C

set(CMAKE_C_FLAGS_DEBUG "put your flags")
set(CMAKE_C_FLAGS_MINSIZEREL "put your flags")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "put your flags")
set(CMAKE_C_FLAGS_RELEASE "put your flags")

Đối với C ++

set(CMAKE_CXX_FLAGS_DEBUG "put your flags")
set(CMAKE_CXX_FLAGS_MINSIZEREL "put your flags")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "put your flags")
set(CMAKE_CXX_FLAGS_RELEASE "put your flags")

Điều này sẽ ghi đè các giá trị được xác định trong CMakeCache.txt


ghi đè các cờ cmake hiện tại của bạn. vì vậy nó sẽ phá vỡ gỡ lỗi trừ khi bạn tự thêm cờ -g (gcc)
activedecay

Có cùng suy nghĩ sử dụng cú pháp "Modern Cmake" không?
Sandburg

6

Trên các hệ thống Unix, đối với một số dự án, tôi đã thêm các dòng này vào CMakeLists.txt và nó đã được biên dịch thành công vì base ( / usr / include ) và local include ( / usr / local / include ) đi vào các thư mục riêng biệt:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/local/include -L/usr/local/lib")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/local/include")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")

Nó nối đúng thư mục, bao gồm các đường dẫn cho cờ trình biên dịch C và C ++ và đường dẫn thư mục chính xác cho cờ trình liên kết.

Lưu ý: Trình biên dịch C ++ (c ++) không hỗ trợ -L, vì vậy chúng tôi phải sử dụng CMAKE_EXE_LINKER_FLAGS


3
Nó không tốt hơn nếu sử dụng include_directoriesthay vì -Ilá cờ?
Tejas Kale

Cảm ơn bạn rất nhiều. Tôi đã đặt cờ trình liên kết của mình CMAKE_CXX_FLAGS, điều này khiến chúng bị bỏ qua. Bây giờ tôi đã đặt chúng CMAKE_EXE_LINKER_FLAGSdựa trên câu trả lời của bạn, chúng đang hoạt động tốt.
Nahiyan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.