Error when running swipl-ld on macos (silicon)

I recently installed the latest release (9.2.8-1 macosx Mojave) according to SWI-Prolog downloads and I’m trying to replicate the example here: SWI-Prolog -- Linking Foreign Modules

The main change I made to the example was just to point it to the .h file on disk i.e.

#include </Applications/SWI-Prolog.app/Contents/swipl/include/SWI-prolog.h>

But when I run swipl-ld -o mylib file.c, I get the following fatal error:

Undefined symbols for architecture arm64:
  "_main", referenced from:
      <initial-undefines>
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
cc returned code 256
*** swipl-ld exit status 1

This is the output of swipl --dump-runtime-variables:

PLBASE="/Applications/SWI-Prolog.app/Contents/swipl";
SWIPL_PACK_PATH="";
PLARCH="arm64-darwin";
PLBITS="64";
PLVERSION="90208";
PLSOEXT="so";
PLSOPATH="DYLD_LIBRARY_PATH";
PLLIBDIR="/Applications/SWI-Prolog.app/Contents/Frameworks";
PLLIB="-lswipl";
PLLIBSWIPL="/Applications/SWI-Prolog.app/Contents/Frameworks/libswipl.9.2.8.dylib";
PLSHARED="yes";
PLTHREADS="yes";

Is this expected behaviour and are there any workarounds that won’t involve me switching to windows?

Thanks!

I was just dealing with something possibly related to this the other day. I was not using swipl-ld but rather specifying target_link_libraries in my CMake file. I had tried to install my Prolog application on an Apple laptop and the linker was giving me this same grief about “symbols(s) not found for architecture…”

There’s a lot of stuff that automatically looks through certain directories looking for the dynamic linking files, which is convenient but it can also make it a little confusing when figuring out why something works on one system but doesn’t work on another. I think that maybe on my local Debian GNU/Linux system I had already built SWI-Prolog from source with statically compiled extensions? So this was probably why my code combined just fine on my machine but not on the Apple laptop. You may be having the same issue; to resolve it you probably have to do:

  1. Make sure you actually have the dynamic linking binaries (“dylib” or whatever they are called on MacOS)
  2. Make sure the linker knows where to find them

This is my CMakeLists.txt file that eventually worked: ~sam_russell/swipl-sfml (main): CMakeLists.txt - sourcehut git (one of these days I will figure out the cmake expressions to get rid of all the repetitive statements).

These lines (9 and 328-EOF) were what allowed the linker to work properly:

find_library(SWI-PROLOG REQUIRED swipl)
...
target_link_libraries(window_context_settings swipl sfml-graphics sfml-system sfml-window sfml-network)
...
1 Like

Also I don’t know if .so is going to be your extension on MacOS, I think it should be .dylib? Also, PLSOPATH should probably resolve to an actual path? I don’t know a lot about MacOS though.

This is due to a missing -shared option to swipl-ld. The docs are quite out of date :frowning: Updated. See swipl-devel/library/shlib.pl at 22a25f1172553ab389202b38f1a5eb6d417b443b · SWI-Prolog/swipl-devel · GitHub

Updated the example to work on all platforms and fixed several details. Runs fine for me using the installed 9.2.8 release.

P.s. #include <SWI-Prolog.h> is enough. swipl-ld adds the required -I flag to make the compiler find this file. You can add the -v flag to make swipl-ld print the commands it executes.

1 Like