簡體   English   中英

如何在 cmake 工具鏈文件中為已知的自定義編譯器設置編譯功能以使用 target_compile_features

[英]How to set compile features in cmake toolchain file for known custom compiler to use target_compile_features

我有最小的hello world樣本:

#include <cstdlib>
#include <iostream>
#include <string_view>

int main(int /*argc*/, char* /*argv*/ [])
{
    using namespace std;

    string_view output_phrase("hello world");

    cout << output_phrase << endl;

    bool is_good = cout.good();

    int result = is_good ? EXIT_SUCCESS : EXIT_FAILURE;
    return result;
}

所以我創建了最小的CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.14)
project(01-1-hello-world CXX)
add_executable(01-1-hello-world main.cxx)
target_compile_features(01-1-hello-world PUBLIC cxx_std_17)

現在,如果我使用已知的 CMake 編譯器,所有編譯器都按預期工作(如 MSVC、clang++、g++)。 但是,如果我嘗試使用一些 SDK 和工具鏈文件cmake的自定義編譯器(基於 clang)說:

CMake CMakeLists.txt:5 (target_compile_features) 處的錯誤:target_compile_features CXX 編譯器不知道編譯器功能“cxx_std_17”

“鐺”

所以我嘗試在我的工具鏈文件中設置CMAKE_CXX_COMPILE_FEATURES

set(CMAKE_CXX_COMPILE_FEATURES cxx_std_17) # we know custom-clang have c++17 support

我也嘗試設置CMAKE_CXX_KNOWN_FEATURES但沒有任何變化。 如何使target_compile_features(01-1-hello-world PUBLIC cxx_std_17)在用於自定義編譯器的 cmake 的工具鏈文件中工作? 提前致謝!

我也嘗試設置 CMAKE_CXX_KNOWN_FEATURES

您很可能忘記清除構建樹。 重新運行 cmake 時,工具鏈文件中的變量不會“刷新”。 在修改工具鏈文件時,您必須完全刪除構建文件並重新配置 cmake。 它應該工作。 請注意, CMAKE_*_KNOWN_FEATURES是功能列表,請使用list(APPEND CMAKE_CXX_COMPILE_FEATURES...)

作為功能讀者的參考,並且因為 cmake 使用了很多全局變量,我想發布 C 語言的sdcc編譯器的工作原理。 對於 C 因為它更簡單,所以它與 C++ 完全相同,它與CXX*變量相似。 變量的含義可以從它們的名字中推斷出來。

cat > toolchain-sdcc.cmake <<EOF
find_program(CMAKE_C_COMPILER NAMES sdcc)
set(CMAKE_CROSSCOMPILING TRUE)    
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

set(CMAKE_C_STANDARD_DEFAULT "11") # this is the default C standard the compiler uses without any option
set(CMAKE_C90_STANDARD_COMPILE_OPTION "--std-c89")
set(CMAKE_C90_EXTENSION_COMPILE_OPTION "--std-sdcc89")
set(CMAKE_C99_STANDARD_COMPILE_OPTION "--std-c99")
set(CMAKE_C99_EXTENSION_COMPILE_OPTION "--std-sdcc99")
set(CMAKE_C11_STANDARD_COMPILE_OPTION "--std-c11")
set(CMAKE_C11_EXTENSION_COMPILE_OPTION "--std-sdcc11")

list(APPEND CMAKE_C_COMPILE_FEATURES
    c_std_90
    c_std_99
    c_std_11
    c_function_prototypes
    c_restrict
    c_static_assert
    c_variadic_macros
)

EOF

cat > CMakeLists.txt <<EOF
cmake_minimum_required(VERSION 3.11)
set(CMAKE_TOOLCHAIN_FILE sdcc.cmake)
project(a LANGUAGES C)
file(WRITE a.c "int main() {}")
add_executable(a a.c)
target_compile_features(a PUBLIC
    c_std_90
    c_std_99
    c_std_11
    c_function_prototypes
    c_restrict
    c_static_assert
    c_variadic_macros
)

EOF

之后 cmake 找到編譯功能並且可以構建項目。

還有CMakeDetermineCompileFeatures.cmake定義cmake_determine_compile_featuresproject()調用自動運行的 cmake_determine_compile_features。 然后,如果宏cmake_record_c_compile_features由您的工具鏈定義,則該宏用於確定 C 語言編譯功能。 這樣你就可以:

cat > toolchain-sdcc.cmake <<EOF
# ...
# remove list(APPEND CMAKE_C_COMPILE_FEATURES, not needed anymore  

# this macro will be called from `project()`
macro(cmake_record_c_compile_features)
    list(APPEND CMAKE_C90_COMPILE_FEATURES c_std_90 c_function_prototypes)
    list(APPEND CMAKE_C99_COMPILE_FEATURES c_std_99 c_restrict c_variadic_macros)
    list(APPEND CMAKE_C11_COMPILE_FEATURES c_std_11 c_static_assert)
    set(_result 0) # expected by cmake_determine_compile_features
endmacro()

EOF

之后,您將看到眾所周知的Detecting C compile features消息,由CMakeDetermineCompileFeatures.cmake在調用cmake_record_c_compile_features宏時生成:

$ cmake -S . -B _build
...
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done
...

最后但並非最不重要的一點是,您可以定義CMAKE_C*_STANDARD__HAS_FULL_SUPPORT宏並使用內部定義cmake_determine_compile_features宏的Compiler/CMakeCommonCompilerMacros模塊,它會檢查CMAKE_C*_STANDARD__HAS_FULL_SUPPORT是否已定義,如果是,它會啟用該語言標准的所有功能:

cat > toolchain-sdcc.cmake <<EOF
# ...
set(CMAKE_C90_STANDARD__HAS_FULL_SUPPORT ON)
set(CMAKE_C99_STANDARD__HAS_FULL_SUPPORT ON)
set(CMAKE_C11_STANDARD__HAS_FULL_SUPPORT ON)
# will define cmake_record_c_compile_features macro
# that will inspect CMAKE_C*_STANDARD__HAS_FULL_SUPPORT variables
include(Compiler/CMakeCommonCompilerMacros)
EOF

但真正合適的地方是在CMAKE_MODULE_PATH路徑中創建Compilers/SDCC-C.cmake並將include(Compiler/CMakeCommonCompilerMacros)放在那里,例如MSVC-CXX.cmake

set_property(TARGET 01-1-hello-world PROPERTY CXX_STANDARD 17)

CXX_標准

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM