Opened 5 months ago

Last modified 5 months ago

#72023 assigned enhancement

swi-prolog @9.2.9: Patch idea for macOS 10.11.6

Reported by: kogule (Kogulé, Ryo) Owned by: JanWielemaker (Jan Wielemaker)
Priority: Normal Milestone:
Component: ports Version: 2.10.5
Keywords: elcapitan Cc:
Port: swi-prolog

Description

Swi-prolog fails to build on old macOS such as:

:info:build : && /opt/local/bin/clang++-mp-16 -pipe -Os -DNDEBUG -I/opt/local/include -stdlib=libc++ -O3 -DNDEBUG -arch x86_64 -mmacosx-version-min=10.11 -bundle -Wl,-headerpad_max_install_names -L/opt/local/lib -Wl,-headerpad_max_install_names -o packages/cpp/test_cpp.so packages/cpp/CMakeFiles/plugin_test_cpp.dir/test_cpp.cpp.o  -Wl,-rpath,/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_lang_swi-prolog/swi-prolog/work/build/src  src/libswipl.9.2.9.dylib && :
:info:build Undefined symbols for architecture x86_64:
:info:build   "std::__1::__shared_mutex_base::lock_shared()", referenced from:
:info:build       _pl_atom_atom_find__2(unsigned long, int, __PL_foreign_context*) in test_cpp.cpp.o

It is because the system libc++ is old and does not include newer classes.

To resolve this, let it link against clang's new libc++ instead of system's. Attached patches do that and work fine with clang-16.

Unfortunately these patches embedded the prefix (/opt/local) and clang's version (llvm-16). I don't know what the macports proper way is in such situation but report for your information.

Attachments (2)

patch-src_CMakeLists.txt.diff (995 bytes) - added by kogule (Kogulé, Ryo) 5 months ago.
patch-packages_cmake_PrologPackage.cmake.diff (834 bytes) - added by kogule (Kogulé, Ryo) 5 months ago.

Download all attachments as: .zip

Change History (10)

Changed 5 months ago by kogule (Kogulé, Ryo)

Changed 5 months ago by kogule (Kogulé, Ryo)

comment:1 Changed 5 months ago by jmroot (Joshua Root)

Owner: set to JanWielemaker
Port: swi-prolog added
Status: newassigned

comment:2 Changed 5 months ago by JanWielemaker (Jan Wielemaker)

Thanks. The atommap C++ interface is not vital. I'm not a C++ person. Is there a good test to see whether std::scoped_lock is supported? If so, we can use normal locks instead or simply disable this part of the code and tests on compilers that do not support this.

comment:3 Changed 5 months ago by JanWielemaker (Jan Wielemaker)

According to https://en.cppreference.com/w/cpp/thread/shared_lock, std::shared_lock requires at least C++-14. The CMakeFile sets the standard to 17. Why is this failing than? Which c++ version is clang++-mp-16? Or is the issue that clang++-mp-16 uses the system C++ library? That seems wrong to me, no?

We surely do not want to add the C++ library to linking libswipl.dll as SWI-Prolog itself is free of C++.

comment:4 Changed 5 months ago by kogule (Kogulé, Ryo)

I'm not a C++ person.

Me neither ;)

This libc++ version problem is common between C++ project porting and I met them more than a few times. That's why even I, a C++ novice, know how to deal with it.

CMakeFile sets the standard to 17. Why is this failing than?

Because C++ compiler deals separately with language spec and libraries. Directive -std=c++17 let its language spec compliant to c++17 but it's nothing with the library because there is no way to detect the system's standard conformation. Controlling the library version leaves developer's hands.

The patches let the compiler stop linking the system's libc++ (-nostdlib) and use clang-16's one (-lc -lc++ -L/opt/local/libexec/llvm-16/lib/libc++ -Wl,-rpath,/opt/local/libexec/llvm-16/lib/libc++).

This is the C++ way as far as I know.

comment:5 Changed 5 months ago by JanWielemaker (Jan Wielemaker)

Thanks. Well, looking through the error, it seems the compiler was happy. That should be correct and clang-16 surely supports C++-17. So, the _header_ files do have std::shared_lock. For the standard -lc and -lc++ libraries the compiler should find the matching library. Apparently it does not. That makes me conclude the your clang-16-mp compiler is misconfigured.

Possibly you can hack around that using environment variables. It is not an issue of SWI-Prolog though. The only sort of "patch" I'm willing to accept for this is a CMake test that figures out that the C++ compiler is broken and removes the C++ interface from the system as a consequence. That is probably a try-compile test with a minimal program that makes this fail.

comment:6 Changed 5 months ago by kogule (Kogulé, Ryo)

Ok. Close this ticket please.

comment:7 Changed 5 months ago by ryandesign (Ryan Carsten Schmidt)

Keywords: elcapitan added

Don't close the ticket, please. It's an accurate bug report. swi-prolog doesn't build on OS X 10.11 and earlier.

If you would like to know which compilers MacPorts believes support each language standard, see CompilerSelection.

The user's compiler is not misconfigured. It is normal that the system C++ library will be used, even when a newer compiler is used. The system C++ library may not support newer C++ language features.

The legacy support portgroup offers the legacysupport.use_mp_libcxx option which can be set to yes to indicate that MacPorts should use a newer MacPorts copy of the C++ library instead for this port. I cannot guarantee that doing this won't have adverse consequences. For example, I don't know what happens if any of swi-prolog's dependencies use the system C++ library and swi-prolog uses a newer MacPorts C++ library and objects created with one library are passed to code using the other library. Back when the C++ library was GCC's libstdc++ that kind of thing did definitely cause runtime crashes but I don't know if the same applies to LLVM's libc++.

comment:8 Changed 5 months ago by JanWielemaker (Jan Wielemaker)

Of course it is fine to fix this using some option in the Portfile. That should be tested by others though. My Mac runs the latest version of MacOS. I prefer this solution.

Alternatively, one could use the CMake option -DSWIPL_PACKAGES_cpp=OFF in the Portfile if we knew the affected platforms.

The only thing I consider acceptable for SWI-Prolog's source is a CMake test and disable affected functionality. Note that the C++ interface is not vital for SWI-Prolog and the detail affected by this error has very little impact.

Note: See TracTickets for help on using tickets.