我在编译以下使用
<chrono>
库的 C++ 代码时遇到问题:
#include "log.hpp"
#include <chrono>
#include <iomanip>
#include <iostream>
#include <utility>
#ifdef _WIN32
#include <windows.h>
#else
#define RESET "\033[0m"
#define COLOR_BEGIN(code) "\033[38;2;" << ((code >> 16) & 0xFF) << ";" << ((code >> 8) & 0xFF) << ";" << (code & 0xFF) << "m"
#endif
namespace Monolith
{
namespace utils
{
void log::print_log(std::string &&message)
{
if (!m_enabled) return;
auto now = std::chrono::system_clock::now();
std::time_t time_point = std::chrono::system_clock::to_time_t(now);
std::tm *timeinfo = std::localtime(&time_point);
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count() % 1000;
#ifdef _WIN32
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(console, static_cast<WORD>(m_color));
#else
std::cout << COLOR_BEGIN(m_color);
#endif
std::cout << "[" << m_entity << "] {" << std::put_time(timeinfo, "%T") << ":" << std::setfill('0') << std::setw(3)
<< milliseconds << "} " << message;
#ifdef _WIN32
SetConsoleTextAttribute(console, static_cast<WORD>(0xFFFFFF));
#else
std::cout << RESET << std::endl;
#endif
}
std::string format_args(const char *message, va_list args)
{
const size_t length = 1024;
char *buffer = new char[length];
vsnprintf(buffer, length, message, args);
std::string result(buffer);
delete[] buffer;
return result;
}
log::log(std::string entity, unsigned int color) : m_entity(entity), m_color(color)
{
}
void log::out(const char *message, ...)
{
va_list args;
va_start(args, message);
print_log(format_args(message, args));
va_end(args);
}
} // namespace utils
} // namespace Monolith
这是日志.hpp
#pragma once
#ifndef _LOG_HPP_
#define _LOG_HPP_
#include <iostream>
#include <stdarg.h>
namespace Monolith
{
namespace utils
{
class log
{
public:
log(std::string entity, unsigned int color);
void out(const char *message, ...);
private:
void print_log(std::string &&message);
bool m_enabled = true;
std::string m_entity;
unsigned int m_color;
};
} // namespace utils
} // namespace Monolith
#endif // !_LOG_HPP_
完整错误列表
┌──(recall㉿recall)-[/home/dev/monolith_engine]
└─$ ./cmake_build.sh debug
-- The C compiler identification is Clang 14.0.6
-- The CXX compiler identification is Clang 14.0.6
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Vulkan: /usr/lib/x86_64-linux-gnu/libvulkan.so (found version "1.3.250") missing components: glslc glslangValidator
-- Configuring done (0.6s)
-- Generating done (0.0s)
-- Build files have been written to: /home/dev/monolith_engine/build
[ 20%] Building CXX object CMakeFiles/monolith.dir/src/utils/log.cpp.o
[ 40%] Building CXX object CMakeFiles/monolith.dir/src/main.cpp.o
[ 60%] Building CXX object CMakeFiles/monolith.dir/src/utils/timer.cpp.o
[ 80%] Building CXX object CMakeFiles/monolith.dir/src/mh_vulkan/renderer/mh_vk_renderer.cpp.o
In file included from /home/dev/monolith_engine/src/utils/log.cpp:2:
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: error: call to consteval function 'std::chrono::hh_mm_ss::_S_fractional_width' is not a constant expression
static constexpr unsigned fractional_width = {_S_fractional_width()};
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: note: undefined function '_S_fractional_width' cannot be used in a constant expression
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2275:2: note: declared here
_S_fractional_width()
^
In file included from /home/dev/monolith_engine/src/utils/timer.cpp:1:
In file included from /home/dev/monolith_engine/src/utils/timer.hpp:5:
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: error: call to consteval function 'std::chrono::hh_mm_ss::_S_fractional_width' is not a constant expression
static constexpr unsigned fractional_width = {_S_fractional_width()};
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: note: undefined function '_S_fractional_width' cannot be used in a constant expression
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2275:2: note: declared here
_S_fractional_width()
^
1 error generated.
make[2]: *** [CMakeFiles/monolith.dir/build.make:104: CMakeFiles/monolith.dir/src/utils/log.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
1 error generated.
make[2]: *** [CMakeFiles/monolith.dir/build.make:118: CMakeFiles/monolith.dir/src/utils/timer.cpp.o] Error 1
In file included from /home/dev/monolith_engine/src/mh_vulkan/renderer/mh_vk_renderer.cpp:1:
In file included from /home/dev/monolith_engine/src/mh_vulkan/renderer/mh_vk_renderer.hpp:6:
In file included from /home/dev/monolith_engine/src/mh_vulkan/renderer/../../core.hpp:31:
In file included from /home/dev/monolith_engine/src/mh_vulkan/renderer/../../utils/benchmark_timer.hpp:8:
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: error: call to consteval function 'std::chrono::hh_mm_ss::_S_fractional_width' is not a constant expression
static constexpr unsigned fractional_width = {_S_fractional_width()};
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: note: undefined function '_S_fractional_width' cannot be used in a constant expression
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2275:2: note: declared here
_S_fractional_width()
^
In file included from /home/dev/monolith_engine/src/main.cpp:1:
In file included from /home/dev/monolith_engine/src/core.hpp:31:
In file included from /home/dev/monolith_engine/src/utils/benchmark_timer.hpp:8:
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: error: call to consteval function 'std::chrono::hh_mm_ss::_S_fractional_width' is not a constant expression
static constexpr unsigned fractional_width = {_S_fractional_width()};
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: note: undefined function '_S_fractional_width' cannot be used in a constant expression
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2275:2: note: declared here
_S_fractional_width()
^
1 error generated.
make[2]: *** [CMakeFiles/monolith.dir/build.make:90: CMakeFiles/monolith.dir/src/mh_vulkan/renderer/mh_vk_renderer.cpp.o] Error 1
1 error generated.
make[2]: *** [CMakeFiles/monolith.dir/build.make:76: CMakeFiles/monolith.dir/src/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/monolith.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
该项目是使用 CMake 和
clang
(clang++
) 作为编译器构建的。但是,我在 <chrono>
库中遇到错误:
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: error: call to consteval function 'std::chrono::hh_mm_ss::_S_fractional_width' is not a constant expression
static constexpr unsigned fractional_width = {_S_fractional_width()};
^
我尝试过使用 GNU 编译器和 Clang 编译器,甚至在
apt update
和 apt upgrade
之后删除了 GCC 和 G++。但是,错误仍然存在。
任何人都可以提供有关为什么会发生此错误以及如何解决该错误的见解吗?我感谢任何帮助或指导。
更新 CMakeList.txt 以使用 -stdlib=libc++ 和 -std=c++20 修复它
这是CMakeList.txt
cmake_minimum_required(VERSION 3.21)
set(PROJECT_NAME monolith)
project(${PROJECT_NAME})
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_COMPILER "clang")
set(CMAKE_CXX_COMPILER "clang++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++20")
set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/debug)
else()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release)
endif()
file(GLOB_RECURSE SOURCE_FILES
${SOURCE_DIR}/*.cpp
)
file(GLOB_RECURSE HEADER_FILES
${INCLUDE_DIR}/*.hpp
)
find_package(Vulkan REQUIRED)
find_package(glfw3 REQUIRED)
find_package(glm REQUIRED)
add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES})
target_link_libraries(${PROJECT_NAME} PRIVATE Vulkan::Vulkan glfw glm::glm)