1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 10:32:48 +02:00

[test] Add ability to get error messages from CMake for errc substitution

Visual Studios implementation of the C++ Standard Library does not use strerror to produce a message for std::error_code unlike other standard libraries such as libstdc++ or libc++ that might be used.

This patch adds a cmake script that through running a C++ program gets the error messages for the POSIX error codes and passes them onto lit through an optional config parameter.

If the config parameter is not set, or getting the messages failed, due to say a cross compiling configuration without an emulator, it will fall back to using pythons strerror functions.

Differential Revision: https://reviews.llvm.org/D98278
This commit is contained in:
Markus Böck 2021-03-15 20:56:08 +01:00
parent 93a5ec7e97
commit 1be4884f17
4 changed files with 58 additions and 9 deletions

View File

@ -507,6 +507,9 @@ if (MSVC_IDE OR XCODE)
endif()
set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
include(GetErrcMessages)
get_errc_messages(LLVM_LIT_ERRC_MESSAGES)
# On Win32 hosts, provide an option to specify the path to the GnuWin32 tools.
if( WIN32 AND NOT CYGWIN )
set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools")

View File

@ -0,0 +1,39 @@
# This function returns the messages of various POSIX error codes as they are returned by std::error_code.
# The purpose of this function is to supply those error messages to llvm-lit using the errc_messages config
# Currently supplied and needed error codes: ENOENT, EISDIR, EINVAL and EACCES
# Messages are semi colon separated
# Keep amount, order and tested error codes in sync with llvm/utils/lit/lit/llvm/config.py
function(get_errc_messages outvar)
set(errc_test_code ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/getErrc.cpp)
file(WRITE ${errc_test_code} "
#include <cerrno>
#include <iostream>
#include <string>
#include <system_error>
std::string getMessageFor(int err) {
return std::make_error_code(static_cast<std::errc>(err)).message();
}
int main() {
std::cout << getMessageFor(ENOENT) << ';' << getMessageFor(EISDIR);
std::cout << ';' << getMessageFor(EINVAL) << ';' << getMessageFor(EACCES);
}
")
try_run(errc_exit_code
errc_compiled
${CMAKE_BINARY_DIR}
${errc_test_code}
RUN_OUTPUT_VARIABLE errc_result
COMPILE_OUTPUT_VARIABLE errc_compile_errors)
if (errc_compiled)
set(${outvar} ${errc_result} PARENT_SCOPE)
else()
set(${outvar} "" PARENT_SCOPE)
message(STATUS "Failed to get errc messages")
endif ()
endfunction()

View File

@ -12,6 +12,7 @@ config.llvm_shlib_dir = path(r"@SHLIBDIR@")
config.llvm_shlib_ext = "@SHLIBEXT@"
config.llvm_exe_ext = "@EXEEXT@"
config.lit_tools_dir = path(r"@LLVM_LIT_TOOLS_DIR@")
config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@"
config.python_executable = "@Python3_EXECUTABLE@"
config.gold_executable = "@GOLD_EXECUTABLE@"
config.ld64_executable = "@LD64_EXECUTABLE@"

View File

@ -11,6 +11,7 @@ from lit.llvm.subst import FindTool
from lit.llvm.subst import ToolSubst
lit_path_displayed = False
python_errc_displayed = False
class LLVMConfig(object):
@ -356,19 +357,24 @@ class LLVMConfig(object):
return True
def add_err_msg_substitutions(self):
host_cxx = getattr(self.config, 'host_cxx', '')
# On Windows, python's os.strerror() does not emit the same spelling as
# the C++ std::error_code. As a workaround, hardcode the Windows error
# message.
if (sys.platform == 'win32' and 'MSYS' not in host_cxx):
# Python's strerror may not supply the same message
# as C++ std::error_code. One example of such a platform is
# Visual Studio. errc_messages may be supplied which contains the error
# messages for ENOENT, EISDIR, EINVAL and EACCES as a semi colon
# separated string. LLVM testsuites can use get_errc_messages in cmake
# to automatically get the messages and pass them into lit.
errc_messages = getattr(self.config, 'errc_messages', '')
if len(errc_messages) != 0:
(errc_enoent, errc_eisdir,
errc_einval, errc_eacces) = errc_messages.split(';')
self.config.substitutions.append(
('%errc_ENOENT', '\'no such file or directory\''))
('%errc_ENOENT', '\'' + errc_enoent + '\''))
self.config.substitutions.append(
('%errc_EISDIR', '\'is a directory\''))
('%errc_EISDIR', '\'' + errc_eisdir + '\''))
self.config.substitutions.append(
('%errc_EINVAL', '\'invalid argument\''))
('%errc_EINVAL', '\'' + errc_einval + '\''))
self.config.substitutions.append(
('%errc_EACCES', '\'permission denied\''))
('%errc_EACCES', '\'' + errc_eacces + '\''))
else:
self.config.substitutions.append(
('%errc_ENOENT', '\'' + os.strerror(errno.ENOENT) + '\''))