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

Markus Böck via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 15 12:57:26 PDT 2021


Author: Markus Böck
Date: 2021-03-15T20:56:08+01:00
New Revision: af2796c76d2ff4b73165ed47959afd35a769beee

URL: https://github.com/llvm/llvm-project/commit/af2796c76d2ff4b73165ed47959afd35a769beee
DIFF: https://github.com/llvm/llvm-project/commit/af2796c76d2ff4b73165ed47959afd35a769beee.diff

LOG: [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

Added: 
    llvm/cmake/modules/GetErrcMessages.cmake

Modified: 
    clang/CMakeLists.txt
    clang/test/lit.site.cfg.py.in
    lld/CMakeLists.txt
    lld/test/lit.site.cfg.py.in
    llvm/CMakeLists.txt
    llvm/test/lit.site.cfg.py.in
    llvm/utils/lit/lit/llvm/config.py

Removed: 
    


################################################################################
diff  --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt
index 9ecf4b9d2de8..7af05c331e94 100644
--- a/clang/CMakeLists.txt
+++ b/clang/CMakeLists.txt
@@ -113,6 +113,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
   include(TableGen)
   include(HandleLLVMOptions)
   include(VersionFromVCS)
+  include(GetErrcMessages)
   include(LLVMDistributionSupport)
 
   set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
@@ -177,6 +178,8 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
       endif()
       set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
 
+      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")

diff  --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in
index eb01720249af..c3382e2c1c42 100644
--- a/clang/test/lit.site.cfg.py.in
+++ b/clang/test/lit.site.cfg.py.in
@@ -9,6 +9,7 @@ config.llvm_libs_dir = path(r"@LLVM_LIBS_DIR@")
 config.llvm_shlib_dir = path(r"@SHLIBDIR@")
 config.llvm_plugin_ext = "@LLVM_PLUGIN_EXT@"
 config.lit_tools_dir = path(r"@LLVM_LIT_TOOLS_DIR@")
+config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@"
 config.clang_obj_root = path(r"@CLANG_BINARY_DIR@")
 config.clang_src_dir = path(r"@CLANG_SOURCE_DIR@")
 config.clang_tools_dir = path(r"@CLANG_TOOLS_DIR@")

diff  --git a/lld/CMakeLists.txt b/lld/CMakeLists.txt
index cbca979aaeb1..53e09f938888 100644
--- a/lld/CMakeLists.txt
+++ b/lld/CMakeLists.txt
@@ -54,6 +54,7 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
   include(AddLLVM)
   include(TableGen)
   include(HandleLLVMOptions)
+  include(GetErrcMessages)
   include(CheckAtomic)
 
   if(LLVM_INCLUDE_TESTS)
@@ -98,6 +99,8 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
       endif()
       set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
 
+      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")

diff  --git a/lld/test/lit.site.cfg.py.in b/lld/test/lit.site.cfg.py.in
index a140284e0ded..57fa15e730b1 100644
--- a/lld/test/lit.site.cfg.py.in
+++ b/lld/test/lit.site.cfg.py.in
@@ -8,6 +8,7 @@ config.llvm_obj_root = "@LLVM_BINARY_DIR@"
 config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
 config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
 config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
+config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@"
 config.lld_obj_root = "@LLD_BINARY_DIR@"
 config.lld_libs_dir = "@LLD_LIBS_DIR@"
 config.lld_tools_dir = "@LLD_TOOLS_DIR@"

diff  --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 22c1a130f4a5..51ed113f58c5 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -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")

diff  --git a/llvm/cmake/modules/GetErrcMessages.cmake b/llvm/cmake/modules/GetErrcMessages.cmake
new file mode 100644
index 000000000000..79aa6456cc7e
--- /dev/null
+++ b/llvm/cmake/modules/GetErrcMessages.cmake
@@ -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()

diff  --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in
index 94e11050ff5b..37080f923694 100644
--- a/llvm/test/lit.site.cfg.py.in
+++ b/llvm/test/lit.site.cfg.py.in
@@ -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@"

diff  --git a/llvm/utils/lit/lit/llvm/config.py b/llvm/utils/lit/lit/llvm/config.py
index febd62fd7d21..f12cfa433396 100644
--- a/llvm/utils/lit/lit/llvm/config.py
+++ b/llvm/utils/lit/lit/llvm/config.py
@@ -11,6 +11,7 @@
 from lit.llvm.subst import ToolSubst
 
 lit_path_displayed = False
+python_errc_displayed = False
 
 class LLVMConfig(object):
 
@@ -356,19 +357,24 @@ def add_tool_substitutions(self, tools, search_dirs=None):
         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) + '\''))


        


More information about the llvm-commits mailing list