FreeBSD installation

A general topic for future updates :slight_smile:

The changes for better c11 thread use in swipl 9.0.4 (stable) failed to link on FreeBSD12.4 with the error:
Undefined symbol “cnd_init”

Adding to LDFLAGS -lstdthreads permits a successful build.

Earlier, I had modified cmake/Params.cmake
if(MULTI_THREADED)
set(C_CFLAGS “${C_CFLAGS} -pthread”)
endif()
by appending -lstdthreads but to no avail. (Aside: I did change this line to be -lpthread -lstdthreads, but it doesn’t appear to be used during the build??)

cmake/Params.cmake is definitely the wrong place. It is there to populate a file pams.h which is used to populate some Prolog flags that help the system building foreign extensions.

Probably this should be handled in cmake/Config.h. I’m a little confused here. There are some references to variables set by cmake FindThreads(), but I see no call to this. This probably needs some study. Feel free to investigate :slight_smile:

Thank-you for the pointer Jan. :slightly_smiling_face:

Because swi-pl uses cnd_init cnd_destroy and probably others, the swipl package requires linking with -lstdthreads.

I suspect something like cmake/FindGMP.cmake is required to test for the existance of
threads.h
and the location of
libstdthreads.so.0
which in FreeBSD is located at
/usr/include/threads.h
/usr/lib/libstdthreads.so.0
OR
modify cmake/Config.cmake to include tests for threads.h in a manner similar to pthread.h and then, if FreeBSD include libstdthreads. Though this seems like a lot of work for just FreeBSD :scream:

I have no familiarity with Linux (or cmake), I’m guessing that these c11 calls are incorporated into their standard thread library, while FreeBSD has these calls resolved in libstdthreads. :upside_down_face:

If this is unique to FreeBSD, then it probably suffices for the “port maintainer” to include
LDFLAGS+= -lstdthreads
in the FreeBSD port lang/swi-pl/Makefile :thinking:

Yes, but that is already part of CMake. As is, it follows the recommendations by CMake to get thread support:

set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads)

And, finally, add Threads::Threads as input for libswipl. Now, on Linux that doesn’t do a lot as when we inspect FindThreads.cmake (which is what find_package(Threads) uses) it roughly does

  • find pthread.h
  • Test whether we can use threads without any flags. This is the case for Linux, where the thread functions are part of libc. So, Linux is done here
  • Try -pthread. That should be what happens for FreeBSD.

So, we need to find out why this doesn’t work. Try to find FindThreads.cmake and check the messages it produces. The thread detection is early in the configuration.

Hi Jan, I appreciate your prompt attention. Unfortunately there isn’t a FindThreads.cmake, however the pthread test is correct and finds and uses libthr during the build. Extract from the build log includes
– Looking for threads.h
– Looking for threads.h - found
– Looking for mach/thread_act.h
– Looking for mach/thread_act.h - not found
– Looking for pthread_np.h
– Looking for pthread_np.h - found

which is good and consistent with the
CMakeLists.txt: set(THREADS_PREFER_PTHREAD_FLAG TRUE)

With the c11 changes in swipl 9.x, FreeBSD also requires libstdthreads. libstdthreads is simply a layer into the pthread functions which resolves cnd_init and other c11 functions detailed below. :slight_smile:
https://man.freebsd.org/cgi/man.cgi?query=cnd_init&apropos=0&sektion=0&manpath=FreeBSD+13.2-STABLE&arch=default&format=html

I have included first few libraries from a ldd of swipl, which is achieved with LDFLAGS= -lstdthreads:
/usr/local/bin/swipl:
libstdthreads.so.0 => /usr/lib/libstdthreads.so.0 (0x80106e000)
libtcmalloc_minimal.so.4 => /usr/local/lib/libtcmalloc_minimal.so.4 (0x801074000)
libswipl.so.9 => /usr/local/lib/swipl/lib/amd64-freebsd/libswipl.so.9 (0x801253000)
libc.so.7 => /lib/libc.so.7 (0x801481000)
libthr.so.3 => /lib/libthr.so.3 (0x801880000)

Kind regards.

That file is part of the CMake installation. It must be there. On my system it is at /usr/share/cmake-3.22/Modules/FindThreads.cmake

That is wrong. It should say “Check if compiler accepts -pthread” after finding threads.h. Possibly we need to use

set(CMAKE_C_STANDARD 11)

early in CMakeLists.txt to compile the thread tests with C11 and cause them to fail if -pthread is not given?

You can try adding the above declaration to CMakeLists.txt in the main dir below the options and above the various include.

Apologies re FindThreads.cmake I have no familiarity with cmake, I was looking within the build hierarchy for swipl. Yes it is in /usr/local/share/cmake/Modules/FindThreads.cmake and does contain pthread tests

I inserted
set(CMAKE_C_STANDARD 11) at line 220 of the top level CMakeLists.txt. The build failed due to undefined cnd_init, per original post.

When I force linking with lstdthreads, swipl 9.0.4 works correctly with the simple threaded tests that I use.

I suspect that libstdthreads isn’t sought by cmake, so not a swipl issue. If you agree I’ll raise this with the FreeBSD maintainer of cmake?

Aside: Of the 1516 ports/applications that I build/use on servers, only swipl and swipl-ld require lstdthreads; 1254 use libthr (pthread).

Yes, I think it makes sense to raise this with cmake. Either directly or through the FreeBSD channels. There is already some discussion on the cmake forum about when -pthread should be tested.

Seems related to demanding C11. I always try to stick with the oldest acceptable standard, so C99 was good enough for a long time. Some internal reorganization became a lot simpler using C11 Generics though. I think it is up to FreeBSD and cmake to make sure C11 works at some point.

Thank-you for your advice. I’ve learnt a little more about cmake than expected/intended during this effort. :slight_smile:

I’ll pursue.
Kind regards.