gpt4 book ai didi

c++ - 如何在 cmake 工具链文件中为已知的自定义编译器设置编译功能以使用 target_compile_features

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:37:45 31 4
gpt4 key购买 nike

我有最小的 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++)。但是,如果我尝试使用一些带有工具链文件 cmake 的 SDK 中的自定义编译器(基于 clang) cmake 说:

CMake Error at CMakeLists.txt:5 (target_compile_features): target_compile_features The compiler feature "cxx_std_17" is not known to CXX compiler

"Clang"

所以我尝试设置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 工具链文件中工作?提前致谢!

最佳答案

Also I try to set CMAKE_CXX_KNOWN_FEATURES

您很可能忘记清除您的构建树。重新运行 cmake 时,工具链文件中的变量不会“刷新”。在对工具链文件进行修改时,您必须完全删除构建文件并重新配置 cmake。它应该工作。请注意,CMAKE_*_KNOWN_FEATURES 是功能的列表,o 使用list(APPEND CMAKE_CXX_COMPILE_FEATURES ...)

为了供功能阅读器引用,并且因为 cmake 使用了很多全局变量,所以我想发布使用 sdcc 编译器为 C 语言工作的内容。对于 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 that defines cmake_determine_compile_featuresproject() 调用自动神奇地运行。然后,如果宏 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

之后,您将看到 CMakeDetermineCompileFeatures.cmake 在调用 cmake_record_c_compile_features 宏时生成的众所周知的 Detecting 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 宏并使用 Compiler/CMakeCommonCompilerMacros内部定义 cmake_determine_compile_features 宏的模块,它检查是否定义了 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

关于c++ - 如何在 cmake 工具链文件中为已知的自定义编译器设置编译功能以使用 target_compile_features,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58593482/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com