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)
Change History (10)
Changed 5 months ago by kogule (Kogulé, Ryo)
Attachment: | patch-src_CMakeLists.txt.diff added |
---|
Changed 5 months ago by kogule (Kogulé, Ryo)
Attachment: | patch-packages_cmake_PrologPackage.cmake.diff added |
---|
comment:1 Changed 5 months ago by jmroot (Joshua Root)
Owner: | set to JanWielemaker |
---|---|
Port: | swi-prolog added |
Status: | new → assigned |
comment:2 Changed 5 months ago by JanWielemaker (Jan Wielemaker)
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: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.
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.