2017-07-07 58 views
14

Tôi đang cố thêm cờ biên dịch /std:c++17 vào VS2017 với CMake. Tôi đang sử dụng nền tảng "hiện đại" cách cho đến nay:Cách bật/std: C++ 17 trong VS2017 với CMake

set(CMAKE_CXX_STANDARD 14) 
set(CMAKE_CXX_STANDARD_REQUIRED ON) 
set(CMAKE_CXX_EXTENSIONS OFF) # -std=c++11 instead of -std=gnu++11 
set(MY_CXX_COMPILE_FEATURES cxx_generic_lambdas cxx_range_for cxx_strong_enums) 

add_library(mylib INTERFACE) 
target_compile_features(mylib INTERFACE ${MY_CXX_COMPILE_FEATURES}) 

này cho biết thêm /std:c++14 trong VS2017 (mà có thể là mặc định không?). Tuy nhiên, tôi gặp sự cố khi chuyển đổi sang C++ 17 (tức là có thêm /std:c++17). Nếu tôi chỉ cần thêm nó bằng tay, tôi nhận được cảnh báo không quá thoải mái vì cả hai lá cờ có mặt:

1>cl : Command line warning D9025: overriding '/std:c++14' with '/std:c++17'

Tôi đã thử set(CMAKE_CXX_STANDARD 17) nhưng nó không có hiệu lực, trên thực tế các CMake tài liệu đề cập rằng CMAKE_CXX_STANDARD không có hiệu lực trên VS.

Để thêm tính năng C++ 17 vào target_compile_features, có vẻ như chưa có bất kỳ điều gì (ngay cả trong CMake-3.9.0-rc5), và ngay cả khi có, tôi đặc biệt chỉ sử dụng std::optional từ C++ 17 và không có các cờ target_compile_features cho các tính năng thư viện như std::optional.

Vì vậy, câu hỏi của tôi là, cách tốt nhất (hoặc ít xấu xí nhất) để làm điều này với CMake là gì? Và theo một cách nào đó nó cũng sẽ hoạt động với gcc và clang? Tôi rất vui khi sử dụng phiên bản CMake gần đây (3.8 hoặc 3.9). Tôi thích nó được "đẹp" và không tự lặp qua CXX_COMPILE_FLAGS và loại bỏ chuỗi "/ std: C++ 14" hoặc một số hack như thế.

(Sửa: Nó cũng có thể là VS /std:c++latest switch - nào là tốt Cả hai làm việc cho mục đích này..)

+0

Xem https://gitlab.kitware.com/cmake/cmake/issues/16482, đây là công việc được tiến hành. – Florian

+0

Cập nhật: 'CMAKE_CXX_STANDARD 17' hiện có thể có trong CMake mới nhất hàng đêm và sẽ chuyển sang CMake-3.10. – Ela782

Trả lời

15

Biến nhận xét của tôi vào một câu trả lời

  1. Các CMake nhóm đang làm việc trên nó cho VS2017 (như cho tháng 7 năm 2017, cho phiên bản CMake sắp tới 3.10):

    CMake: MSVC standard version switches

    Những lá cờ dường như là công tắc khá mới mẻ (liên quan đến ngày của câu hỏi này):

    VS 2017 15,3 preview bây giờ hỗ trợ/std: C++ 17

    Vì vậy, đối Visual Studio bạn phải "tự" thay thế hoặc nối thêm các trình chuyển đổi trình biên dịch cho đến khi CMake chính thức hỗ trợ nó.

    Đây là một đoạn mã mà tôi đã thử nghiệm cho std:c++latest (mà đã được hỗ trợ ví dụ như trong phiên bản 3.8.0, CMake của tôi):

    if (MSVC_VERSION GREATER_EQUAL "1900") 
        include(CheckCXXCompilerFlag) 
        CHECK_CXX_COMPILER_FLAG("/std:c++latest" _cpp_latest_flag_supported) 
        if (_cpp_latest_flag_supported) 
         add_compile_options("/std:c++latest") 
        endif() 
    endif() 
    
  2. Đối Clang và GNU sự hỗ trợ đã được sáp nhập vào chính mã nguồn chi nhánh bắt đầu của năm 2017 và là một phần của CMake phiên bản 3.8 trở lên:

    CMake: Features: Add support for C++ 17 language standard

+0

Hmm! Quá xấu mà không hạ cánh trong CMake, vấn đề là 7 tháng tuổi :-((Những lá cờ không thực sự quá mới, VS2015 đã có chúng). cách tiếp cận, cách tốt nhất để tự thay thế/thêm cờ cho MSVC là gì? – Ela782

+0

Tôi nghĩ rằng đây sẽ là một cơn đau đầu.Tôi không thể 'get_target_property (my_compile_flags mylib COMPILE_FLAGS)' vì nó là mục tiêu INTERFACE (chỉ tiêu đề) thư viện) ... – Ela782

+0

Tôi đã hỏi câu hỏi này trong một câu hỏi mới: https://stackoverflow.com/questions/44977868/cmake-replace-compile-flags-of-an-interface-target – Ela782

3

phiên bản CMake tha cao n 3.10 support MSVC C++ standard switches cho phiên bản MSVC mới hơn 19.0.24215. Nếu một trong các yêu cầu phiên bản không được đáp ứng, thì chúng không có hiệu lực.

Cách tiếp cận di động duy nhất, để đảm bảo chương trình của bạn được biên dịch với chế độ chuẩn C++ chính xác trên Visual Studio, yêu cầu ít nhất CMake 3.10, đặt thuộc tính đích CXX_STANDARD thành giá trị mong muốn và CXX_STANDARD_REQUIRED thành ON.

Ví dụ sử dụng:

set_property(TARGET my_target PROPERTY CXX_STANDARD 17) 
set_property(TARGET my_target PROPERTY CXX_STANDARD_REQUIRED ON) 
Các vấn đề liên quan