[Mingw64/Win10] : swi-prolog can't locate foreign lib, pcre4pl

Hi,

I’m encountering a new trouble :

ERROR: c:/msys64/mingw64/library/pcre.pl:52:
ERROR: c:/msys64/mingw64/library/pcre.pl:52: Initialization goal raised exception:
ERROR: ‘$open_shared_object’/3: Le module sp▒cifi▒ est introuvable.

ERROR: Exported procedure pcre:re_config/1 is not defined
ERROR: Exported procedure pcre:re_compile/3 is not defined
ERROR: [Thread 1]: exception handler failed to define pcre:re_compile/3
ERROR: Unknown procedure: pcre:re_compile/3
ERROR: However, there are definitions for:
ERROR: pcre:re_compiled/2
ERROR:
ERROR: In:
ERROR: [73] pcre:re_compile([^,’(’|…],_3038,[])
ERROR: [72] pcre:re_compiled([^|…]/’’,_3084) at c:/msys64/mingw64/library/pcre.pl:559
ERROR: [70] pcre:re_match([^,’(’|…],’.’,[]) at c:/msys64/mingw64/library/pcre.pl:152

Note that :

?- file_search_path(foreign,X).
X = swi(bin) ;
false.

$ pacman -Qil mingw-w64-x86_64-swi-prolog | grep pcre
mingw-w64-x86_64-swi-prolog /mingw64/bin/pcre4pl.dll
mingw-w64-x86_64-swi-prolog /mingw64/library/pcre.pl

$ ls -l /mingw64/bin/pcre4pl.dll
-rwxr-xr-x 1 Didier Aucun 28756 23 mars 22:42 /mingw64/bin/pcre4pl.dll

Is there a solution to this ?

Thanks a lot, again.

Cheers

Is this output from ctest ?
There’s possibly another message from configuration, that package PCRE wasn’t found (you can see the configuration logic in swipl-devel/packages/pcre/CMakeLists.txt)

The problem appears to be that you don’t have the equivalent of Ubuntu’s package libpcre2-dev installed. (I don’t know much about mingw, so can’t offer much more help.)

swi-prolog has been installed with pacman not from source.

libpcre2-dev isn’t part of SWI-Prolog, but would need to be installed separately. (I know nothing about pacman and how it handles dependencies)

As you can see higher, I give the output about what pacman has installed :

pacman -Qil mingw-w64-x86_64-swi-prolog | grep pcre
mingw-w64-x86_64-swi-prolog /mingw64/bin/pcre4pl.dll
mingw-w64-x86_64-swi-prolog /mingw64/library/pcre.pl

Obviously, pcre4pl.dll is installed at the right location.

pcre4pl.dll is not the issue, I think (I might be wrong of course). If you do the Windows equivalent of ldd pcre4pl.so, you can see the dependencies in pcre4pl.dll. This is what I get on Linux:

$ ldd $(find ~/.local/lib/swipl -name pcre4pl.so)
        linux-vdso.so.1 (0x00007fff52d8b000)
        libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007af703747000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007af703582000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007af703560000)
        /lib64/ld-linux-x86-64.so.2 (0x00007af703801000)

The important item is libpcre2-8.so … if that library (whatever it’s called on Windows) is missing, then you’ll get the errors you’re experiencing. (I think)
This article might help: windows - How to check for DLL dependency? - Stack Overflow

It’s also possible that there’s some kind of PATH setup that’s preventing you seeing pcre4pl.dll, but if that’s the case, you’ll see quite a few other errors from other packages that have foreign function libraries – you probably can see them in the same directory as the equivalent of libswpl.so [swpl.dll?] – I count 52 of them, including libswpl.so.

1 Like

$ ldd pcre4pl.dll
ntdll.dll => /c/Windows/SYSTEM32/ntdll.dll (0x7ff9e8930000)
KERNEL32.DLL => /c/Windows/System32/KERNEL32.DLL (0x7ff9e8350000)
KERNELBASE.dll => /c/Windows/System32/KERNELBASE.dll (0x7ff9e6530000)
msvcrt.dll => /c/Windows/System32/msvcrt.dll (0x7ff9e8850000)
pcre4pl.dll => /mingw64/bin/pcre4pl.dll (0x7ff9e2fa0000)
libswipl.dll => /mingw64/bin/libswipl.dll (0x7ff9e0e70000)
advapi32.dll => /c/Windows/System32/advapi32.dll (0x7ff9e6ea0000)
sechost.dll => /c/Windows/System32/sechost.dll (0x7ff9e76a0000)
rpcrt4.dll => /c/Windows/System32/rpcrt4.dll (0x7ff9e7e80000)
psapi.dll => /c/Windows/System32/psapi.dll (0x7ff9e82d0000)
shell32.dll => /c/Windows/System32/shell32.dll (0x7ff9e6f50000)
msvcp_win.dll => /c/Windows/System32/msvcp_win.dll (0x7ff9e6040000)
ucrtbase.dll => /c/Windows/System32/ucrtbase.dll (0x7ff9e6850000)
user32.dll => /c/Windows/System32/user32.dll (0x7ff9e7fb0000)
win32u.dll => /c/Windows/System32/win32u.dll (0x7ff9e60e0000)
gdi32.dll => /c/Windows/System32/gdi32.dll (0x7ff9e78d0000)
gdi32full.dll => /c/Windows/System32/gdi32full.dll (0x7ff9e6230000)
ws2_32.dll => /c/Windows/System32/ws2_32.dll (0x7ff9e82e0000)
libpcre-1.dll => not found

Oops, seems to miss something there…

Thank you for your help.

It works now.

I’m surprised because I hadn’t this trouble when on freeBSD.

Thank you again for your help.

I can sleep, now.

Good night to you !

Cheers

That appears to be from an older version of SWI-Prolog (PCRE2 version was added in SWI-Prolog 8.5.10, around 7 April 2022)

If you use a package manager on freeBSD, the necessary dependencies are probably installed automatically for you. Or, it’s quite possible that libpcre/libpcre2 is part of the standard install, possibly under different names, such as libpcre2-8.so.

I don’t know who maintains this version. Hopefully this person listens in here. Installing the plugins in the public bin directory is rather dubious. Most of them have short and common names as they are normally installed in a separate directory, e.g., /usr/lib/swipl/lib/<arch>/socket.so. The Windows installation puts all exe and dll files in one directory for convenience, but this directory is not shared with other applications.

Thats me. And, in fact, the mingw people told me that Swi-Prolog creates quite a lot of dlls. I’ll deal with that in the next stable release of swipl.

Yes ! Good news !
Thank you for my information.

Nice week-end

Have you seen my last observation, about trouble with environment when invoking process_create/3 ?
It’s here : [Mingw64/Win10/swi 8.4.2] : env option of process_create can't bear [] value

The same for mingw64 with pacman.

Yes, I’ve seen that one as well.

Have you seen my last observation, about trouble with environment when invoking process_create/3 ?
It’s here : [Mingw64/Win10/swi 8.4.2] : env option of process_create can’t bear [] value

The error with env([]) goes away under Windows if I comment out line 375 in packages/clib/process.c. Maybe @jan can help.

Looks like a bug in Windows we luckily can work around :slight_smile: . The process environment is defined to be a buffer with consecutive 0-terminated strings followed by a 0. One would say that the empty environment is thus just a 0. Luckily the docs say the environment ends with two 0 chars, which hinted me to try to represent the empty environment that way. That works :slight_smile:

Removing the line cause the environment to be passed as NULL, i.e., inheriting the environment rather than passing no environment.

The latest version fixes two more issues in environment handling: inheriting the environment using environment(NewVars) was not implemented for Windows and having more than one env/1 or environment/1 option would cause a C assertion error (when these are enabled, depending on how the system is built).

I looked into this. It seems fairly simple to correct this behavior so that the MSYS2 swipl looks a bit more unix-stylish:

  • in swipl-devel/CMakeLists.txt, the code in line 107, if(WIN32) should be skipped, and the else branch should be executed instead.
  • in swipl-devel/src/CMakeLists.txt, at the end, symbolic links are created to (prefix)/bin/swipl and $(prefix)/bin/swipl-ld, this should also be executed.

I think that’s all, did I overlook something?

That is surely a good start. It should be some additional option or something to detect that we are installing according MSYS2 conventions (-DMSSY2=ON ?) Whether it will all work is another matter. What is the status of symbolic links in MSY2? Is that properly handled by SWI-Prolog’s code to find the real executable and its home? Are the DLL search paths correct? I guess trying is the only way to find out :slight_smile:

I tried. The DLL search (i.e., use_module(library(process)) is indeed not successful, it does not find process.dll (see below). The interesting thing is that the error below occurs already during the build phase, not after installation.

[955/959] Generating tests/test_certs/generated
FAILED: packages/ssl/tests/test_certs/generated C:/msys64/home/Matthias/swipl-devel/build.mingw64/packages/ssl/tests/test_certs/generated
cmd.exe /C "cd /D C:\msys64\home\Matthias\swipl-devel\build.mingw64\packages\ssl && C:\msys64\mingw64\bin\cmake.exe -E make_directory tests && C:\msys64\home\Matthias\swipl-devel\build.mingw64\src\swipl.exe -f none --no-packs C:/msys64/home/Matthias/swipl-devel/build.mingw64/packages/ssl/mkcerts.pl --source=C:/msys64/home/Matthias/swipl-devel/packages/ssl/tests --dest=tests && touch tests/test_certs/generated"
ERROR: c:/msys64/home/matthias/swipl-devel/build.mingw64/home/library/process.pl:58:
ERROR:    c:/msys64/home/matthias/swipl-devel/build.mingw64/home/library/process.pl:58: Initialization goal raised exception:
ERROR:    '$open_shared_object'/3: Das angegebene Modul wurde nicht gefunden.

ERROR: c:/msys64/home/matthias/swipl-devel/build.mingw64/packages/ssl/mkcerts.pl:40:
ERROR:    Exported procedure process:process_set_method/1 is not defined
ERROR: c:/msys64/home/matthias/swipl-devel/build.mingw64/packages/ssl/mkcerts.pl:40:

Under Windows, I can see all the DLLs (including process.dll) in (builddir)/src already after building, so the build also “installs” something, probably driven by the lines at the bottom of src/CMakeLists.txt . If I understand correctly, the path to foreign(…) is expanded here (swipl.rc),

user:file_search_path(library, swi(packages)).
user:file_search_path(foreign, AppDir) :-
    current_prolog_flag(windows, true),
    current_prolog_flag(executable, Exe),
    file_directory_name(Exe, AppDir).

Under Linux, the DLLs such as process.so stays in (builddir)/packages/clib. What I am wondering now is, how does the linux version find the “.so”-files? Here’s a hint,

%!  add_package_path(+PkgBinDir) is det.
%
%   Add the source  and  binary  directories   for  the  package  to the
%   `library` and `foreign` search paths. Note that  we only need to add
%   the binary directory if  it  contains   shared  objects,  but  it is
%   probably cheaper to add it anyway.

add_package_path(PkgBinDir) :-
    (   current_prolog_flag(windows, true)
    ->  true
    ;   assertz(user:file_search_path(foreign, PkgBinDir))
    ).

Obviously, assertz is skipped under Windows. swipl.rc is not available as a source file, but generated by boot/build_home.pl. If I remove the check for the windows-Flag, the build process is actually working. So, partial success. [I still see problems after ninja install]

Of course, a new prolog flag is needed (“msys2”). Do you think this is a viable solution?