Compiling SWI-Prolog from git source on next macOS 15 beta

I have happened to test compiling swi-prolog from git source on next macOS 15 (Sequoia) of beta version, with Xcode.app 16 beta. Everything has been fine for my purpose except ctest with following error message.

% [98/98] collation_key:WCSXFRM_BUFFER_OVERRUN ..Assertion failed: (o == buf), function pl_collation_key2_va, file pl-prims.c, line 4421.

By commenting out the line assert(o == buf); in pl-prims.c as suggested by the message, everything seems working perfectly fine.

I’m not sure the error message will disappear with regular release of macOS 15, but as for as I see comment in pl-prims.c around the line it might be worth for reporting.

Log
Test project /Users/cantor/src/swipl-devel/build
      Start  1: swipl:abi-version
 1/83 Test  #1: swipl:abi-version ................   Passed    0.03 sec
      Start  2: swipl:basic
 2/83 Test  #2: swipl:basic ......................   Passed    0.66 sec
      Start  3: swipl:unprotected
 3/83 Test  #3: swipl:unprotected ................   Passed    0.53 sec
      Start  4: swipl:core
 4/83 Test  #4: swipl:core .......................Subprocess aborted***Exception:   7.60 sec
Running scripts from core

<snip long>

% [97/98] locale:group .................................................................... passed (0.000 sec)

% [98/98] collation_key:WCSXFRM_BUFFER_OVERRUN ..Assertion failed: (o == buf), function pl_collation_key2_va, file pl-prims.c, line 4421.

      Start  5: swipl:db
 5/83 Test  #5: swipl:db .........................   Passed    2.28 sec

<snip>

99% tests passed, 1 tests failed out of 83

Total Test time (real) =  91.68 sec

The following tests FAILED:
	  4 - swipl:core (Subprocess aborted)
Errors while running CTest

Thanks for reporting. Looks like a bug in the MacOS C library. The code already contains a kludge for a bug in this function on MacOS :frowning: Could you print the returned n? E.g., by adding this after the call to wcsxfrm()

Sdprintf("wcsxfrm() returned %zd\n", n);

I got this:

% [98/98] collation_key:WCSXFRM_BUFFER_OVERRUN ..wcsxfrm() returned 1194
wcsxfrm() returned 1943
Assertion failed: (o == buf), function pl_collation_key2_va, file pl-prims.c, line 4423.

after modifying the source as this:

modified part of the source pl-prims.c
PRED_IMPL("collation_key", 2, collation_key, 0)
{
#ifdef HAVE_WCSXFRM
  wchar_t *s;
  size_t len;
  wchar_t buf[256];
  size_t buflen = sizeof(buf)/sizeof(wchar_t) - WCSXFRM_BUFFER_OVERRUN;
  wchar_t *o = buf;
  size_t n;

  if ( !PL_get_wchars(A1, &len, &s, CVT_ATOM|CVT_STRING|CVT_EXCEPTION) )
    fail;
  for(;;)
  { if ( (n=wcsxfrm(o, s, buflen)) < buflen )
    { Sdprintf("wcsxfrm() returned %zd\n", n);
	  int rc = PL_unify_wchars(A2, PL_STRING, n, o);

      if ( o != buf )
	PL_free(o);

      return rc;
    } else
	  { Sdprintf("wcsxfrm() returned %zd\n", n);
		assert(o == buf);
      buflen = n+1;
      o = PL_malloc(buflen*sizeof(wchar_t));
    }
  }
#else
  GET_LD
  return PL_unify(A1, A2);
#endif
}

Thanks. Pushed 43756a6f9486c59b8ce2187f032d54f64eddc9bf as a work-around.
The docs suggest that if the buffer is too small, wcsxfrm() returns the required size and that happens on most platforms, but it is not explicit that it does. Dirty :frowning:

I got a similar error message.

% [98/98] collation_key:WCSXFRM_BUFFER_OVERRUN ..Assertion failed: (0), function pl_collation_key2_va, file pl-prims.c, line 4433.

The line 4433 of pl-prims.c is

  assert(0);

For my easy work-around is to skip ctest because every function works normal
for my purpose of use of SWI-Prolog, and of course I can wait till the regular release of new macOS 15. However, ask me any information which you think I could get about this case, though I am not familiar with testing C source.

I was a little afraid of that. Pushed f0bbfb082985382d777c3cfb84fc85e7e0ae345f that reverts to doubling until the buffer is large enough in case wcsxfrm() does not return the required length. That should work.

Note that it is not clear whether returning the actually required size is covered by the standard, so possibly MacOS does formally comply.

ctest passed !. However, I am afraid that I am using something wrong ctest, which
I installed via Homebrew because it is not provided on macOS.

% whereis ctest
ctest: /opt/homebrew/bin/ctest /opt/homebrew/share/man/man1/ctest.

in fact, I had question about behavior of homebrew’s ctest whether it is exactly the same as what the swi-prolog document refers. I don’t remember well the difference between them for now. I should write more on this if you think necessary.

That probably also holds for cmake, no? You need the ctest that comes with cmake. As long as the tests succeed, there is no reason to worry, i’d say. If it reports no tests or most/all tests fail I’d start worrying.

Building SWI-Prolog requires tools as well as dependencies (libraries) from Homebrew or Macports (or somewhere else).

It is exactly as you said: Neither cmake nor ctest is provided on macOS, and
ctest is only automatically installed when installing homebrew cmake. In fact homebrew has not formula for ctest. Thank you for answering to my rather vague question on ctest, which I am unfamiliar with. Anyway it is at least simply pleasant to see “no faiure” message from ctest.

I record shell scripts 1 and 2, which works well without ctest failure
on macOS 15 beta 3 and Xcode.app beta 3.

Script 1 makes the fresh work directory build, and script 2 uses the existing build directory.
For my lacking knowledge on compiling from source, I am far from sure that they continue to work also in the future. They are mainly results of experiment with help by @jan. Comments are very welcome. Thanks.

1. shell script to build swi-prolog
#! /bin/sh

SWIPL_SRC=$HOME/src/swipl-devel
BUILD=${SWIPL_SRC}/build

echo " Building SWI-Prolog ..."
pushd $SWIPL_SRC
git pull
git submodule update --init
rm -rf $BUILD
mkdir $BUILD
cd $BUILD
cmake -DCMAKE_INSTALL_PREFIX=$HOME -DCMAKE_BUILD_TYPE=PGO -G Ninja ..
ninja utf8proc
ninja install
# ctest -j $nproc --output-on-failure
ctest --output-on-failure
popd
echo "SWI-Prolog built."
2. shell script to update swi-prolog
#! /bin/sh

SWIPL_SRC=$HOME/src/swipl-devel
BUILD=${SWIPL_SRC}/build

echo " updating swipl ..."
pushd $SWIPL_SRC
git pull
git submodule update
cd $BUILD
# ninja -t clean utf8proc
cmake .
ninja utf8proc
ninja install
# ctest -j $(nproc) --output-on-failure
ctest --output-on-failure
popd
echo "SWI-Prolog updated."

Should not be necessary any more the missing dependency was added.

Thanks. But I have to keep the utf8proc, because without it I got the following ctest failure:

% % [98/98] collation_key:WCSXFRM_BUFFER_OVERRUN ........ **FAILED (0.001 sec)
ERROR: /Users/cantor/src/swipl-devel/src/Tests/core/test_locale.pl:355:
ERROR:     test collation_key:'WCSXFRM_BUFFER_OVERRUN': received error: collation_key/2: Cannot represent due to `code_point'
ERROR: 1 test failed

I suspect something wrong on locale setting of mine, which causes that ctest error when utf8proc is dropped from the ninja command.

You have to build utf8proc, as it is used by the documentation generation. You don’t have to build it explicitly though. I don’t see the relation to this failing test. In itself, that is something new :frowning: Looks like we’ll have some trouble with MacOS 15 :frowning:

I have installed utf8proc with Homebrew, and I ran ninja without the utf8proc argument as you told. Then ctest passed ! Thanks.

As this case was due to just my fault of not knowing about utf8proc, I hope it will not be the case.

Thanks for reporting. There is no need to install utf8proc using Homebrew. The source is included into the SWI-Prolog utf8proc extension.

Version 9.3.8-9-g16d5ed9fa is successfully compiled for macOS 15 beta on my imac intel, but fails on M1 macbook pro with the below attached error message:

Now it seems that I should wait official release of macOS 15 on SWI-Prolog rather than bothering on next macOS beta, which is coming soon in September

Error log
[2257/2689] Building C object packages...plugin_pl2xpce.dir/src/unx/process.c.o
FAILED: packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/unx/process.c.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -Dplugin_pl2xpce_EXPORTS -I/Users/cantor/src/swipl-devel/build/packages/xpce -I/Users/cantor/src/swipl-devel/packages/xpce/src -I/opt/homebrew/include -I/usr/X11R6/include -I/opt/homebrew/include/freetype2 -I/Users/cantor/src/swipl-devel/src/os -I/Users/cantor/src/swipl-devel/src -std=gnu11 -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk -fPIC -fvisibility=hidden -Wall -DHAVE_CONFIG_H -DSWI -D__SWI_PROLOG__ -MD -MT packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/unx/process.c.o -MF packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/unx/process.c.o.d -o packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/unx/process.c.o -c /Users/cantor/src/swipl-devel/packages/xpce/src/unx/process.c
In file included from /Users/cantor/src/swipl-devel/packages/xpce/src/unx/process.c:95:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/sys/ioctl.h:91:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/sys/sockio.h:69:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/net/if.h:79:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/sys/socket.h:722:9: error: conflicting types for 'sendPCE'
  722 | ssize_t send(int, const void *, size_t, int) __DARWIN_ALIAS_C(send);
      |         ^
/Users/cantor/src/swipl-devel/packages/xpce/src/h/kernel.h:306:25: note: expanded from macro 'send'
  306 | #define send            sendPCE                 /* same */
      |                         ^
/Users/cantor/src/swipl-devel/packages/xpce/src/h/../ker/proto.h:174:16: note: previous declaration is here
  174 | COMMON(status)  send(Any receiver, Name selector, ...);
      |                 ^
/Users/cantor/src/swipl-devel/packages/xpce/src/h/kernel.h:306:25: note: expanded from macro 'send'
  306 | #define send            sendPCE                 /* same */
      |                         ^
1 error generated.
[2268/2689] Building C object packages...s/plugin_pl2xpce.dir/src/win/frame.c.o
ninja: build stopped: subcommand failed.
[9/423] Building C object packages/xpc...plugin_pl2xpce.dir/src/unx/process.c.o
FAILED: packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/unx/process.c.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -Dplugin_pl2xpce_EXPORTS -I/Users/cantor/src/swipl-devel/build/packages/xpce -I/Users/cantor/src/swipl-devel/packages/xpce/src -I/opt/homebrew/include -I/usr/X11R6/include -I/opt/homebrew/include/freetype2 -I/Users/cantor/src/swipl-devel/src/os -I/Users/cantor/src/swipl-devel/src -std=gnu11 -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk -fPIC -fvisibility=hidden -Wall -DHAVE_CONFIG_H -DSWI -D__SWI_PROLOG__ -MD -MT packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/unx/process.c.o -MF packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/unx/process.c.o.d -o packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/unx/process.c.o -c /Users/cantor/src/swipl-devel/packages/xpce/src/unx/process.c
In file included from /Users/cantor/src/swipl-devel/packages/xpce/src/unx/process.c:95:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/sys/ioctl.h:91:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/sys/sockio.h:69:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/net/if.h:79:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/sys/socket.h:722:9: error: conflicting types for 'sendPCE'
  722 | ssize_t send(int, const void *, size_t, int) __DARWIN_ALIAS_C(send);
      |         ^
/Users/cantor/src/swipl-devel/packages/xpce/src/h/kernel.h:306:25: note: expanded from macro 'send'
  306 | #define send            sendPCE                 /* same */
      |                         ^
/Users/cantor/src/swipl-devel/packages/xpce/src/h/../ker/proto.h:174:16: note: previous declaration is here
  174 | COMMON(status)  send(Any receiver, Name selector, ...);
      |                 ^
/Users/cantor/src/swipl-devel/packages/xpce/src/h/kernel.h:306:25: note: expanded from macro 'send'
  306 | #define send            sendPCE                 /* same */
      |                         ^
1 error generated.
[20/423] Building C object packages/xp...plugin_pl2xpce.dir/src/x11/xcommon.c.o
ninja: build stopped: subcommand failed.

We could have some hope that Apple fixes things … The previous one smelled very much like a bug, though formally it may not be one. This is also a bit unclear. Apparently pulling in sys/ioctl.h also loads socket.h, which causes a conflict between POSIX send() and xpce’s send(). You can work around using this in unx/process.c

#if defined(HAVE_SYS_IOCTL_H) && !defined(__sun__) /* leads to redefines */
#undef send
#include <sys/ioctl.h>
#define send            sendPCE
#endif

You might need more of these and you might need the same trick for get(). Please share your experience. Possibly we must do a global replace on the sources to a name that does not conflict. I’m not too happy about that as it destroys the layout :frowning:

The work around leads to successful compilation on M1 macbook pro, though I have little knowledge to understand meaning of the work around. Thanks.

Ok. Added as it does little harm …