diff --git a/test/support.py b/test/support.py index de2532d..1d75f8c 100644 --- a/test/support.py +++ b/test/support.py @@ -115,4 +115,30 @@ def setup_make(targetname): #endif\n""") == 1 ) + + +def _jit_resolves_std_filesystem(): + # The JIT resolves std::filesystem against the loaded libstdc++.so, not + # the compile headers -- a manylinux image (gcc-toolset headers over a + # GCC-8 base runtime) compiles the include yet dies resolving the + # symbols. That failure is a fatal JIT error, so ask in a child process. + probe = ( + "import cppjit\n" + 'cppjit.cppdef("""#include \n' + "unsigned long fs_probe() { return std::filesystem::temp_directory_path().string().size(); }\n" + '""")\n' + "assert cppjit.gbl.fs_probe() > 0\n" + ) + try: + return ( + subprocess.run( + [sys.executable, "-c", probe], capture_output=True, timeout=300 + ).returncode + == 0 + ) + except subprocess.TimeoutExpired: + return False + + +CAN_JIT_STD_FILESYSTEM = _jit_resolves_std_filesystem() IS_VALGRIND = True if os.getenv("IS_VALGRIND") else False diff --git a/test/test_fragile.py b/test/test_fragile.py index 631cc7a..de0ce04 100644 --- a/test/test_fragile.py +++ b/test/test_fragile.py @@ -943,7 +943,7 @@ def test05_span_compatibility(self): import cppjit cppjit.cppdef("""\ - #if __cplusplus >= 202002 + #if __cplusplus >= 202002 && __has_include() #include std::span my_test_span1; #endif diff --git a/test/test_regression.py b/test/test_regression.py index 945e4d3..1add840 100644 --- a/test/test_regression.py +++ b/test/test_regression.py @@ -3,6 +3,7 @@ from pytest import mark, raises, skip from support import ( + CAN_JIT_STD_FILESYSTEM, IS_CLANG_REPL, IS_CLING, IS_MAC, @@ -1052,6 +1053,10 @@ def test34_print_empty_collection(self): v = cppjit.gbl.std.vector[int]() str(v) + @mark.skipif( + not CAN_JIT_STD_FILESYSTEM, + reason="std::filesystem is unresolvable in the JIT on libstdc++ < 9", + ) @mark.xfail(condition=IS_CLING, run=False, reason="Crashes on Cling") def test35_filesytem(self): """Static path object used to crash on destruction""" diff --git a/test/test_stltypes.py b/test/test_stltypes.py index 40795b0..72d0a21 100644 --- a/test/test_stltypes.py +++ b/test/test_stltypes.py @@ -2328,13 +2328,25 @@ def test04_from_cpp(self): assert cppjit.gbl.GetMyErrorCount() == 0 -def has_cpp_20(): +def has_std_span(): import cppjit - return cppjit.evaluate("__cplusplus") >= 202002 + # The -std flag is not enough: the JIT uses the system libstdc++ headers, + # and only exists there from GCC 10 (absent on the manylinux GCC-8 + # floor). Gate on the header actually being includable. + return ( + cppjit.evaluate("""#if __cplusplus >= 202002L && __has_include() + 1 + #else + 0 + #endif""") + == 1 + ) -@mark.skipif(not has_cpp_20(), reason="std::span requires C++20") +@mark.skipif( + not has_std_span(), reason="std::span needs C++20 and (libstdc++ >= 10)" +) class TestSTLSPAN: import cppjit