我正在开发两个略有不同的IOT项目,共享很大一部分代码库,并且由于兼容性要求,我们使用GCC 6.3.0。为了帮助部分代码,我使用建议的 CMake 方法包含了
fmt
库:
include(FetchContent)
FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt
GIT_TAG 11.0.2)
FetchContent_MakeAvailable(fmt)
# later ...
target_link_libraries(<my helper library target> PRIVATE fmt)
但是,在一个项目中编译成功,而在另一个项目中编译失败
[8/17] Building CXX object _deps/fmt-build/CMakeFiles/fmt.dir/src/format.cc.o
FAILED: _deps/fmt-build/CMakeFiles/fmt.dir/src/format.cc.o
/opt/cross/bin/arm-linux-gnueabihf-g++ --sysroot=/opt/box-root-fs -I/opt/box-root-fs/usr/include -I/opt/box-root-fs/usr/local/include -I/home/abertulli/<project-source-root>/build/_deps/fmt-src/include -fdiagnostics-color=always -pthread -g -MD -MT _deps/fmt-build/CMakeFiles/fmt.dir/src/format.cc.o -MF _deps/fmt-build/CMakeFiles/fmt.dir/src/format.cc.o.d -o _deps/fmt-build/CMakeFiles/fmt.dir/src/format.cc.o -c /home/abertulli/<project-source-root>/build/_deps/fmt-src/src/format.cc
In file included from /home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/format.h:41:0,
from /home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/format-inl.h:27,
from /home/abertulli/<project-source-root>/build/_deps/fmt-src/src/format.cc:8:
/home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/base.h: In instantiation of ‘void fmt::v11::detail::check_format_string(S) [with Args = {unsigned int&}; S = fmt::v11::formatter<fmt::v11::detail::bigint>::format(const fmt::v11::detail::bigint&, fmt::v11::format_context&) const::<lambda()>::FMT_COMPILE_STRING; typename std::enable_if<std::is_base_of<fmt::v11::detail::compile_string, S>::value, int>::type <anonymous> = 0]’:
/home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/base.h:2887:41: required from ‘fmt::v11::basic_format_string<Char, Args>::basic_format_string(const S&) [with S = fmt::v11::formatter<fmt::v11::detail::bigint>::format(const fmt::v11::detail::bigint&, fmt::v11::format_context&) const::<lambda()>::FMT_COMPILE_STRING; typename std::enable_if<(std::is_convertible<const S&, fmt::v11::basic_string_view<Char> >::value || (std::is_base_of<fmt::v11::detail::compile_string, S>::value && std::is_constructible<fmt::v11::basic_string_view<Char>, const S&>::value)), int>::type <anonymous> = 0; Char = char; Args = {unsigned int&}]’
/home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/format-inl.h:1391:60: required from here
/home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/base.h:2792:56: in constexpr expansion of ‘fmt::v11::detail::parse_format_string<true, char, fmt::v11::detail::format_string_checker<char, unsigned int> >(s, fmt::v11::detail::format_string_checker<char, unsigned int>(s))’
/home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/base.h:2613:44: in constexpr expansion of ‘fmt::v11::detail::parse_replacement_field<char, fmt::v11::detail::format_string_checker<char, unsigned int>&>((p + 4294967295u), end, ((fmt::v11::detail::format_string_checker<char, unsigned int>&)handler))’
/home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/base.h:2591:13: in constexpr expansion of ‘(& handler)->fmt::v11::detail::format_string_checker<Char, Args>::on_format_specs<char, {unsigned int}>(adapter.fmt::v11::detail::parse_replacement_field(const Char*, const Char*, Handler&&) [with Char = char; Handler = fmt::v11::detail::format_string_checker<char, unsigned int>&]::id_adapter::arg_id, (begin + 1u), end)’
/home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/base.h:2763:51: in constexpr expansion of ‘((fmt::v11::detail::format_string_checker<char, unsigned int>*)this)->fmt::v11::detail::format_string_checker<char, unsigned int>::parse_funcs_[id](((fmt::v11::detail::format_string_checker<char, unsigned int>*)this)->fmt::v11::detail::format_string_checker<char, unsigned int>::context_)’
/home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/base.h:2677:55: in constexpr expansion of ‘fmt::v11::formatter<unsigned int, char, void>().fmt::v11::formatter<unsigned int, char, void>::<anonymous>.fmt::v11::detail::native_formatter<T, Char, TYPE>::parse<fmt::v11::detail::compile_parse_context<char> >(ctx)’
/home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/base.h:2829:34: in constexpr expansion of ‘fmt::v11::detail::parse_format_specs<char>((& ctx)->fmt::v11::detail::compile_parse_context<char>::<anonymous>.fmt::v11::basic_format_parse_context<Char>::begin<char>(), (& ctx)->fmt::v11::detail::compile_parse_context<char>::<anonymous>.fmt::v11::basic_format_parse_context<Char>::end<char>(), ((fmt::v11::detail::native_formatter<unsigned int, char, (fmt::v11::detail::type)2>*)this)->fmt::v11::detail::native_formatter<unsigned int, char, (fmt::v11::detail::type)2>::specs_, (& ctx)->fmt::v11::detail::compile_parse_context<char>::<anonymous>, (fmt::v11::detail::type)2)’
/home/abertulli/<project-source-root>/build/_deps/fmt-src/include/fmt/base.h:2792:77: internal compiler error: in cxx_eval_bit_field_ref, at cp/constexpr.c:2360
FMT_CONSTEXPR bool error = (parse_format_string<true>(s, checker(s)), true);
^
包含
fmt
时,两个 CMakeLists.txt 文件是相同的,它们在使用它时仅略有变化(例如,使用两个版本的 target_link_libraries
),但如果我进行本机构建(使用 GCC 11.4),它编译得很好),并且从错误消息来看,它似乎与使用它的我的源文件无关(在任何情况下它都是相同的)。我知道 ICE 基本上是不应该存在的错误,因为它们在编译有效代码时出现,但我很困惑为什么它出现在一种情况下而不是另一种情况下。很抱歉,我无法在不破坏我的 NDA 的情况下提供完整的 MWE(并且编译器,因为它不再位于存储库中,所以是从头开始编译的,适应这个(有福的!)指南
这里简短的回答是“是”。
由于 ICE 只是编译器中的一个错误,因此几乎任何原因都可能发生它。由于 GCC 即使在古老的版本 6 中也是一个相当成熟的产品,因此其剩余的 ICE 大部分发生在极端情况下,通常包括多种因素,因此 ICE 没有出现在 GCC 的广泛测试套件中。
“包含头文件的差异”只是意味着编译器编译了不同的代码。显然,编译器输入对于确定 ICE 是否发生非常重要。