1# This function returns the messages of various POSIX error codes as they are returned by std::error_code.
2# The purpose of this function is to supply those error messages to llvm-lit using the errc_messages config.
3# Currently supplied and needed error codes: ENOENT, EISDIR, EINVAL and EACCES.
4# Messages are semi colon separated.
5# Keep amount, order and tested error codes in sync with llvm/utils/lit/lit/llvm/config.py.
6function(get_errc_messages outvar)
7    if(CMAKE_CROSSCOMPILING AND NOT CMAKE_CROSSCOMPILING_EMULATOR AND NOT DEFINED errc_exit_code)
8        set(${outvar} "" PARENT_SCOPE)
9        message(STATUS "Can't get errc messages in cross-compilation mode")
10        return()
11    endif()
12
13    set(errc_test_code ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/getErrc.cpp)
14
15    file(WRITE ${errc_test_code} "
16        #include <cerrno>
17        #include <iostream>
18        #include <string>
19        #include <system_error>
20
21        std::string getMessageFor(int err) {
22            return std::make_error_code(static_cast<std::errc>(err)).message();
23        }
24
25        int main() {
26            std::cout << getMessageFor(ENOENT) << ';' << getMessageFor(EISDIR);
27            std::cout << ';' << getMessageFor(EINVAL) << ';' << getMessageFor(EACCES);
28            return 0;
29        }
30    ")
31
32    try_run(errc_exit_code
33            errc_compiled
34            ${CMAKE_BINARY_DIR}
35            ${errc_test_code}
36            RUN_OUTPUT_VARIABLE errc_result
37            COMPILE_OUTPUT_VARIABLE errc_compile_errors)
38    if (errc_compiled AND "${errc_exit_code}" STREQUAL "0")
39        set(${outvar} ${errc_result} PARENT_SCOPE)
40    else()
41        set(${outvar} "" PARENT_SCOPE)
42        message(NOTICE "${errc_compile_errors}")
43        message(STATUS "Failed to get errc messages")
44    endif ()
45endfunction()
46