CMAKE_BUILD_TYPE không được sử dụng trong CMakeLists.txt


79

Tôi đang gặp sự cố khi đặt cấu hình bản dựng mặc định của mình thành Bản phát hành. Trong tệp CMakeLists.txt của mình, tôi đặt CMAKE_BUILD_TYPE ở đầu tệp với:

#enable Release ALWAYS, configure vars
set(CMAKE_BUILD_TYPE Release)
set(EXECUTABLE_NAME "ParticleSimulator")
set(VERSION_MAJOR 0)
set(VERSION_MINOR 2)

Nhưng khi xây dựng dự án và mở giải pháp, tôi luôn ở chế độ Gỡ lỗi, trái ngược với những gì tôi đã chỉ định trong tệp CMakeLists của mình. Tôi đang làm gì sai?

Tôi đã xem một số câu hỏi khác trên đó, nhưng tôi không thấy bất kỳ điều gì cụ thể cho câu hỏi này.

Ý chính của CMakeLists.txt .


Bạn đã xóa bộ nhớ cache CMake của mình chưa? cmake.org/pipermail/cmake/2008-September/023808.html
usr1234567

@ usr1234567 Có, và tôi cũng đã đọc qua tệp đó. Tôi phải làm gì đó ngu ngốc đó là ngăn chặn CMAKE_BUILD_TYPEtừ làm việc ...
cú pháp Fructose

@ usr1234567 Vẫn không có may mắn ... Cũng đã cố gắng set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Configuration type" FORCE)mà không làm việc
cú pháp Fructose

4
Lần thứ 3 trong 2 ngày qua)) set(CMAKE_BUILD_TYPE Release)Đây không phải là cách nó hoạt động. Tình cờ điều này sẽ hoạt động đối với trình Makefiletạo, đối với IDE như Xcode và Visual Studio, dòng này sẽ bị bỏ qua vì Release / Debug đã chuyển đổi nội bộ. Tài liệu là khá rõ ràng về điều đó. Nếu bạn muốn giới hạn các biến thể bản dựng của mình, bạn cần đặt CMAKE_CONFIGURATION_TYPES

@ruslo Hãy đăng bình luận của bạn như một câu trả lời.
usr1234567

Câu trả lời:


209

Có hai loại máy phát điện: một cấu hình và nhiều cấu hình.

Cấu hình đơn

Trình tạo giống như: Unix Makefiles , NMake Makefiles , MinGW Makefiles , ...

Bạn đặt kiểu cấu hình trong bước tạo:

cmake -H. -B_builds/Debug -DCMAKE_BUILD_TYPE=Debug "-GUnix Makefiles"

Trong trường hợp này, bước xây dựng luônGỡ lỗi :

> cmake --build _builds/Debug
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Debug # `--config` ignored
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Release # yep, ignored
/usr/bin/c++ -g ...

Đa cấu hình

Trình tạo IDE: Visual Studio , Xcode

CMAKE_BUILD_TYPE trên bước tạo bị bỏ qua, cả hai:

> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Debug "-GVisual Studio 12 2013 Win64"

> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Release "-GVisual Studio 12 2013 Win64"

sẽ có tác dụng tương tự:

Nhập mô tả hình ảnh tại đây

Điều này là do tất cả các cấu hình là bên trong (tức là, _builds/msvc-opaque/Release_builds/msvc-opaque/Debughoặc cái gì đó, không quan trọng). Bạn có thể sử dụng --configcác tùy chọn để chuyển đổi:

> cmake --build _builds --config Release
cl /O2 ...
> cmake --build _builds --config Debug
cl /Od ...

Điều khiển (?)

Có, bạn có thể. Chỉ cần xác định CMAKE_CONFIGURATION_TYPES :

# Somewhere in CMakeLists.txt
message("Generated with config types: ${CMAKE_CONFIGURATION_TYPES}")

Đầu ra mặc định:

-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release;MinSizeRel;RelWithDebInfo
-- Configuring done

Viết lại nó:

> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;Release" "-GVisual Studio 12 2013 Win64"
-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release
-- Configuring done

Nhập mô tả hình ảnh tại đây

Bạn thậm chí có thể xác định loại cấu hình của riêng mình:

> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;MyRelease" -DCMAKE_CXX_FLAGS_MYRELEASE="/My-Rel-flag" -DCMAKE_EXE_LINKER_FLAGS_MYRELEASE="/My-Linker-flags" "-GVisual Studio 12 2013 Win64"

Nhập mô tả hình ảnh tại đây

Và xây dựng:

cmake --build _builds --config MyRelease

Lộn xộn (?)

Không hề nếu bạn biết mẹo :) Đây là cách xây dựng / kiểm tra cấu hình trong hướng dẫn xây dựng của máy chủ / tài liệu / máy chủ tập lệnh / CI, v.v.:

> CONFIG=Debug
> cmake -H. -B_builds "-DCMAKE_BUILD_TYPE=${CONFIG}" # Set Debug to Makefile, ignored by IDE
> cmake --build _builds --config "${CONFIG}" # Build Debug in IDE, ignored by Makefile
> (cd _builds && ctest -VV -C "${CONFIG}") # Test Debug in IDE, ignored by Makefile

Mẫu xấu

if(CMAKE_BUILD_TYPE STREQUAL Debug) # Burn it with fire!!!
set(CMAKE_BUILD_TYPE MySuperRelease) # Be ready to catch a bug from IDE user...

Tốt

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --my-debug-flags")

Hoạt động tốt.

target_compile_definitions(MyTarget PUBLIC "$<$<CONFIG:Debug>:MYDEBUG_MACRO>")

Cảm ơn bạn! :) Bạn tiết kiệm một ngày cho một lập trình viên.

Làm việc cho tôi với Makefile, tôi rất vui ...

Một số trích dẫn từ một cuốn sách hay của một chàng trai tốt mà bạn có thể biết (nhấn mạnh của tôi):

Tại sao bạn phải bận tâm? Những người lập trình trên nhiều hệ thống hoặc sử dụng nhiều trình biên dịch khác nhau quan tâm rất nhiều vì nếu không, họ buộc phải lãng phí thời gian để tìm và sửa các lỗi khó hiểu. Những người phàn nàn rằng họ không quan tâm về tính di động thường làm như vậy bởi vì họ chỉ sử dụng một hệ thống duy nhất và cảm thấy họ có thể đủ khả năng thái độ rằng '' ngôn ngữ là những gì cụ biên dịch của tôi. '' Đây là một hẹpthiển cậnlượt xem. Nếu chương trình của bạn thành công, nó có khả năng được chuyển, vì vậy ai đó sẽ phải tìm và sửa các vấn đề liên quan đến các tính năng phụ thuộc vào việc triển khai. Ngoài ra, các chương trình thường cần được biên dịch với các trình biên dịch khác cho cùng một hệ thống và ngay cả bản phát hành trong tương lai của trình biên dịch yêu thích của bạn cũng có thể làm một số việc khác với bản hiện tại. Việc biết và hạn chế tác động của các phụ thuộc thực thi khi một chương trình được viết sẽ dễ dàng hơn nhiều so với việc cố gắng gỡ rối sau đó.


10
wow, đây xứng đáng là một câu trả lời tiền thưởng khi nó có sẵn sau 4 giờ. Cảm ơn vì một câu trả lời sâu sắc như vậy.
cú pháp Fructose

Xin hãy tha thứ cho sự thiếu hiểu biết của tôi ... Làm thế nào, chính xác , chúng ta đặt chế độ CMAKE_BUILD_TYPEPhát hành CmakeList.txt? Tôi nghĩ rằng nó ở đâu đó trong phần Control (?) , Nhưng tôi đang gặp sự cố khi phân tích cú pháp vì tôi quá thiếu kinh nghiệm. Cũng lưu ý rằng chúng tôi chỉ muốn đặt giá trị mặc định; người dùng ghi đè nó khỏi dòng lệnh.
jww 14/09/2016

3
Tôi đã tìm thấy một câu trả lời; -H.là một tính năng không có giấy tờ .
wally

1
Tôi thấy bạn đã cố gắng khắc phục sự cố tài liệu . Cảm ơn vì đã cố gắng. :) Vẫn chưa có câu trả lời thỏa đáng về lý do tại sao điều này không thể được ghi lại hoặc loại bỏ (nếu thực sự có rủi ro).
wally

2
@Muscampester chỉ cho thông tin của bạn liên kết thú vị nhất và giải thích có thể được tìm thấy trên trang này

7

Bạn cũng có thể sử dụng đoạn mã sau:

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
            "Default build type: RelWithDebInfo" FORCE)
endif()

1
Mọi người, nếu bạn bỏ phiếu cho một câu trả lời đã gửi sau đó, vui lòng tìm một vài từ để chỉ rõ lý do tại sao bạn làm điều đó. Bởi vì trong số tất cả các câu trả lời được đề xuất, câu trả lời đơn giản này là thứ duy nhất phù hợp với tôi. Và trước đó, tôi đã tìm thấy giải pháp 'được chấp nhận' tương tự ở đây: blog.kitware.com/cmake-and-the-default-build-type
Alex

6

Một khả năng xảy ra là một trong các mô-đun con đã đặt CMAKE_BUILD_TYPEgiá trị trong bộ nhớ cache, đó là:

SET(CMAKE_BUILD_TYPE Debug CACHE) 

Có nghĩa là giá trị đó sẽ được cập nhật vĩnh viễn từ thời điểm đó đến khi kết thúc quá trình chạy cấu hình.

Một cách tuyệt vời để theo dõi vị trí vi phạm nơi giá trị này đã thay đổi là bằng cách sử dụng variable_watch của CMake . Trong CMakelists.txttệp chính của bạn , thêm dòng sau

variable_watch(CMAKE_BUILD_TYPE)

Điều này sẽ in ra lỗi chuẩn mỗi lần truy cập vào biến này. Và để đưa nó vào tệp nhật ký, hãy làm như sau:

cmake <your options> 2>variable_watch.log

Bạn có thể thấy một cái gì đó như:

Nhật ký gỡ lỗi CMake tại <...> / CMakeLists.txt: 184 (add_library): Biến "CMAKE_BUILD_TYPE" đã được truy cập bằng READ_ACCESS với giá trị "Gỡ lỗi".

Sau đó, bạn có thể sẽ thấy (các) điểm mà CMAKE_BUILD_TYPE được thay đổi lần đầu tiên. Và từ đây, bạn sẽ tiến gần hơn nhiều đến việc theo dõi đường dây CMake vi phạm.

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.