Compiling with swipl-ld on MS Windows

I’m trying to run this example:

https://www.swi-prolog.org/pldoc/man?section=foreign-example

I’m using MinGW32 as the toolchain.

This is what happens:

> swipl-ld -goal true -o .\calc.c .\calc.pl -v
        eval `swipl.exe --dump-runtime-variables`
                PLBASE="c:/program files/swipl"
                PLARCH="x64-win64"
                PLSOEXT="dll"
                PLLIBDIR="c:/program files/swipl/bin"
                PLLIB="-lswipl"
                PLTHREADS="yes"
        gcc.exe -o .\calc.exe -L"c:/program files/swipl/bin" -lswipl
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../libmingw32.a(main.o):(.text.startup+0xa0): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status
gcc.exe returned code 1
*** C:\Program Files\swipl\bin\swipl-ld.exe exit status 1

I think this may be because I’m compiling on windows with .Net installed and the inclusion of different c++ toolchains in the same PATH is messing things up.

Is there any knowledge about compiling with swipl-ld on windows? The same command works fine on WSL (ubuntu) but I think I need to compile for windows (specifically for Unity).

To clarify what I really want to do is call my Prolog code from C (eventually C++ probably). I’m not currently trying to create a foreign predicate (hence why I’m following the C example; the C++ example shows how to compile a foreign predicate).

Reposting this for clarity.

I also tried compiling the C++ example here:

https://www.swi-prolog.org/pldoc/man?section=cpp2-foreign-example

This raises some errors (and a lot of warnings which I took as errors in my previous post- sorry):

In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\cstdio:42:0,
                 from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\ext\string_conversions.h:43,
                 from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\basic_string.h:5402,
                 from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\string:52,
                 from calc.cpp:1:
c:/program files/swipl/include/SWI-cpp2.h:1676:7: error: expected unqualified-id before ')' token
   int fileno();
       ^
c:/program files/swipl/include/SWI-cpp2.h:1676:7: error: expected ')' before '->' token
   int fileno();

In file included from c:/program files/swipl/include/SWI-cpp2.h:2083:0,
                 from calc.cpp:2:
c:/program files/swipl/include/SWI-cpp2.cpp:1032:29: error: expected unqualified-id before '(' token
 _SWI_CPP2_CPP_check_rc(int, fileno(), Sfileno(s_))
                             ^

g++ returned code 1
*** C:\Program Files\swipl\bin\swipl-ld.exe exit status 1

It doesn’t seem to pass the calc.c. Possibly it gets upset by the .\? That should in any case not be needed.

The .\ was because I pressed tab to make sure the files are there. I get the same thing without it:

> swipl-ld -goal true -o calc.c calc.pl -v
        eval `swipl.exe --dump-runtime-variables`
                PLBASE="c:/program files/swipl"
                PLARCH="x64-win64"
                PLSOEXT="dll"
                PLLIBDIR="c:/program files/swipl/bin"
                PLLIB="-lswipl"
                PLTHREADS="yes"
        gcc.exe -o calc.exe -L"c:/program files/swipl/bin" -lswipl
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../libmingw32.a(main.o):(.text.startup+0xa0): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status
gcc.exe returned code 1
*** C:\Program Files\swipl\bin\swipl-ld.exe exit status 1

I think I would prefer to use the .Net toolchain anyway. Is there some way to change to use the .Net c compiler instead of gcc?

You don’t want that. You probably want -o calc calc.c

Not easily using swipl-ld. You can use -cc <compiler>, but the default only understands the gcc/clang command line options.

Eventually we should probably rewrite swipl-ld as a swipl “app”. Doing the thing entirely in Prolog is probably a lot simpler and easier to extend for users.

edit Note that SWI-Prolog also provides a cmake include file. That facilitates building projects using cmake that extend or embed SWI-Prolog.

Hi Stassa

I had no problem with swipl-ld, running from powershell and compiling with the command line from the reference example:

    Directory: C:\Users\cccar\test\swi\help_stassa


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        30/01/2025     19:31            533 calc.cpp
-a----        30/01/2025     19:31            110 calc.pl


PS C:\Users\cccar\test\swi\help_stassa> swipl-ld -o calc -goal true calc.cpp calc.pl
% Disabled autoloading (loaded 37 files)
% Disabled autoloading (loaded 9 files)
% Disabled autoloading (loaded 0 files)
% halt
PS C:\Users\cccar\test\swi\help_stassa> ./calc.exe 1+2
3
PS C:\Users\cccar\test\swi\help_stassa>

Anyway, I have a .net solution (runnable and debuggable, using Visual Studio Developer Edition 2022) test_swicpp2, that doesn’t use swipl-ld.

#include <iostream>
#include <stdexcept>
#include <SWI-cpp2.h>

/** fast interface to get a string out of a ground term.
  * thanks Jan !
  */
std::wstring serialize(PlTerm t) {
    wchar_t* s;

    if (PL_get_wchars(t.unwrap(), NULL, &s, CVT_WRITEQ | BUF_RING))
        return s;

    throw PlTypeError("serialize", t);
}

void test1() {
    using namespace std;

    PlTermv av(2);
    PlTerm_tail l(av[1]);
    for (long i : { 1,2,3 })
        if (!l.append(PlTerm_integer(i)))
            throw runtime_error("!l.append(PlTerm_integer(i))");
    if (!l.close())
        throw runtime_error("!l.close()");

    PlQuery q("member", av);
    while (q.next_solution()) {
        cout << av[0].as_string() << ',' << av[1].as_string() << endl;
        wcout << av[0].as_wstring() << ',' << av[1].as_wstring() << endl;
        wcout << serialize(av[0]) << ',' << serialize(av[1]) << endl;
    }
}

int main(int argc, char* argv[])
{
    PlEngine e(argc, argv);
    std::cout << "Hello swipl!\n";
    try {
        test1();
    }
    catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
    }
}

that produces

Welcome to SWI-Prolog (threaded, 64 bits, version 9.3.17-1-g21264b88c)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

Hello swipl!
1,
1,
1,[1,2,3]
2,
2,
2,[1,2,3]
3,
3,
3,[1,2,3]

If you are interested, let me know.

Oh, sorry, I thought I was copying from the SWI documentation. I still get an error though, but I think that’s just missing some include file:

> swipl-ld -goal true -o calc calc.c calc.pl -v
        eval `swipl.exe --dump-runtime-variables`
                PLBASE="c:/program files/swipl"
                PLARCH="x64-win64"
                PLSOEXT="dll"
                PLLIBDIR="c:/program files/swipl/bin"
                PLLIB="-lswipl"
                PLTHREADS="yes"
        gcc.exe -c -D_REENTRANT -D__WINDOWS__ -D_WINDOWS -D__SWI_PROLOG__ -D__SWI_EMBEDDED__ -I"c:/program files/swipl/include" -o calc.obj calc.c
        gcc.exe -o calc.exe calc.obj -L"c:/program files/swipl/bin" -lswipl
calc.obj:calc.c:(.text+0xc8): undefined reference to `PL_initialise'
calc.obj:calc.c:(.text+0xdb): undefined reference to `PL_halt'
calc.obj:calc.c:(.text+0xf7): undefined reference to `PL_predicate'
calc.obj:calc.c:(.text+0x10a): undefined reference to `PL_new_term_refs'
calc.obj:calc.c:(.text+0x128): undefined reference to `PL_put_atom_chars'
calc.obj:calc.c:(.text+0x152): undefined reference to `PL_call_predicate'
calc.obj:calc.c:(.text+0x172): undefined reference to `PL_halt'
collect2.exe: error: ld returned 1 exit status
gcc.exe returned code 1
        rm calc.obj
*** C:\Program Files\swipl\bin\swipl-ld.exe exit status 1

That would certainly help me so great idea :slight_smile:

More stuff I haven’t tried to do for years! More fun for me!

Hi Carlo,

Thanks! I got the command line wrong. I tried it again but I get that error above. There might be something wrong with my MinGW installation or my SWI-Prolog installation (I’m on the latest daily build for SWI).

I don’t know - I’m trying to call Prolog from C/C++. Does your example change considerably in that case?

Sorry I’m still at the level of hello world here :slight_smile:

Edit: Oh, wait, hang on. You are calling Prolog from C++. I saw the version header and got confused. Yes I’m interested - can I run this example like that or do I need some more code?

I have pushed the cleaned up solution to github.

Thanks! That’s a big favour. I owe you one! :smiley:

I forgot: you should define the environment variable SWI_HOME_DIR to something like C:\Program Files\swipl. As you can see, it’s the default installation directory. The includes are relative to this…

Thanks. I’ll have to understand what’s wrong in my installation (not sure which one) because VS can’t find the SWI-cpp2.h header even when I included it in the project.

Thanks @CapelliC

> .\test_swicpp2.exe
Welcome to SWI-Prolog (threaded, 64 bits, version 9.3.19-13-gc4848cb0b)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

Hello swipl!
1,
1,
1,[1,2,3]
2,
2,
2,[1,2,3]
3,
3,
3,[1,2,3]

I don’t know why it was so hard to tell VS to find the SWI-cpp2.h header… I think I need to go lie down now.

I don’t really understand this. AFAIK, MinGW gcc can link directly to DLLs. At least, it is not complaining that libswipl does not exist. I’ll have a look.

Thanks. I think this was before I added the swi include/ directory to my Path so maybe that’s what caused it?

I removed MinGW now but I can put it back and try again if you like to see if I can still reproduce this?

So I reinstalled MinGW and I get the same output exactly as before, not bothering to copy it again here because I’m going to clutter the conversation a bit anyway.

I don’t know if this helps but here are the contents of my swipl/bin directory:

> ls 'C:\Program Files\swipl\bin\'


    Directory: C:\Program Files\swipl\bin


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         1/30/2025   4:34 AM          31232 archive4pl.dll
-a----         1/30/2025   4:34 AM          32256 bdb4pl.dll
-a----         1/30/2025   4:34 AM          48128 cgi.dll
-a----         1/30/2025   4:34 AM          27648 crypt.dll
-a----         1/30/2025   4:34 AM          86016 crypto4pl.dll
-a----         1/30/2025   4:34 AM          26112 double_metaphone.dll
-a----         1/30/2025   4:34 AM          19968 files.dll
-a----         1/30/2025   4:34 AM          39936 hashstream.dll
-a----         1/30/2025   4:34 AM          33792 http_stream.dll
-a----         1/30/2025   4:34 AM          31744 inclpr.dll
-a----         1/30/2025   4:34 AM          16384 isub.dll
-a----         1/30/2025   4:34 AM          55296 janus.dll
-a----         1/30/2025   4:34 AM          88576 jpl.dll
-a----         1/30/2025   4:34 AM          16896 json.dll
-a----         1/30/2025   4:25 AM             94 latex2html
-a----        11/26/2024   8:53 AM        1544239 libarchive-13.dll
-a----        12/19/2024  11:11 AM        6353408 libcrypto-3-x64.dll
-a----        11/26/2024   9:00 AM        2094413 libdb-6.1.dll
-a----         10/6/2024   1:00 AM         934816 libgcc_s_seh-1.dll
-a----         7/18/2024   1:00 AM         528872 libgmp-10.dll
-a----         7/18/2024   1:00 AM         881834 libjpeg-62.dll
-a----         7/22/2021   7:59 PM         284109 libpcre-1.dll
-a----         7/18/2024   1:00 AM         675940 libpcre2-8-0.dll
-a----        12/19/2024  11:11 AM        1174528 libssl-3-x64.dll
-a----         10/6/2024   1:00 AM          88037 libssp-0.dll
-a----         1/30/2025   4:34 AM        1507328 libswipl.dll
-a----         1/30/2025   4:27 AM         297866 libswipl.dll.a
-a----         1/30/2025   4:27 AM         297866 libswipl.lib
-a----        10/14/2024   1:00 AM          68679 libwinpthread-1.dll
-a----        11/26/2024   8:47 AM         498902 libyaml-0-2.dll
-a----         1/30/2025   4:34 AM          18432 md54pl.dll
-a----         1/30/2025   4:34 AM          31232 memfile.dll
-a----         1/30/2025   4:34 AM          23040 ntriples.dll
-a----         1/30/2025   4:34 AM          88064 odbc4pl.dll
-a----         1/30/2025   4:34 AM          39936 pcre4pl.dll
-a----         1/30/2025   4:34 AM          15872 pdt_console.dll
-a----         1/30/2025   4:34 AM        2167808 pl2xpce.dll
-a----         1/30/2025   4:34 AM          22016 plregtry.dll
-a----         1/30/2025   4:34 AM          60928 plterm.dll
-a----         1/30/2025   4:34 AM          25600 porter_stem.dll
-a----         1/30/2025   4:34 AM          31744 process.dll
-a----         1/30/2025   4:34 AM          16896 prolog_stream.dll
-a----         1/30/2025   4:34 AM          17920 protobufs.dll
-a----         1/30/2025   4:34 AM         229376 rdf_db.dll
-a----         1/30/2025   4:34 AM          15872 readutil.dll
-a----         1/30/2025   4:34 AM          51712 redis4pl.dll
-a----         1/30/2025   4:34 AM         202752 sgml2pl.dll
-a----         1/30/2025   4:34 AM          40448 sha4pl.dll
-a----         1/30/2025   4:34 AM         146432 snowball.dll
-a----         1/30/2025   4:34 AM          70144 socket.dll
-a----         1/30/2025   4:34 AM          95744 ssl4pl.dll
-a----         1/30/2025   4:34 AM          17408 streaminfo.dll
-a----         1/30/2025   4:34 AM          24064 sweep-module.dll
-a----         1/30/2025   4:34 AM         112128 swipl-ld.exe
-a----         1/30/2025   4:34 AM         102912 swipl-win.exe
-a----         1/30/2025   4:34 AM          16384 swipl.exe
-a----         1/30/2025   4:25 AM              3 swipl.home
-a----         1/30/2025   4:34 AM          84992 table.dll
-a----         1/30/2025   4:34 AM         106496 tex.dll
-a----         1/30/2025   4:34 AM          28160 time.dll
-a----         1/30/2025   4:34 AM          59392 turtle.dll
-a----         1/30/2025   4:34 AM         544256 unicode4pl.dll
-a----         1/30/2025   4:34 AM          30208 uri.dll
-a----         1/30/2025   4:34 AM          50176 uuid.dll
-a----         1/30/2025   4:34 AM          23552 websocket.dll
-a----         1/30/2025   4:34 AM          28160 yaml4pl.dll
-a----         7/18/2024   1:00 AM         108852 zlib1.dll
-a----         1/30/2025   4:34 AM          19968 zlib4pl.dll

This is what was created by yesterday’s installation of the latest daily build for windows at the time (version 9.3.19-13-gc4848cb0b - the installer is most likely swipl-w64-2025-01-30.exe).

I can’t really tell if there’s something missing in my swipl/bin, but I can see libswpl.dll. I think that’s what gcc is trying to access and failing?

In the yesterday output I noticed your MinGW was pretty old, and 32 bits, but (at least in the first post) you were requesting PLARCH=“x64-win64”.

Here is (one of) current C++s in my machine:

gcc --version
gcc.exe (Rev7, Built by MSYS2 project) 13.1.0

I think every compiler I have right now is 64 bits…

Yes, I got MinGW 32 - I went to install the 64bit version but I was confused by the options so I figured the 32 bit would work too. I didn’t notice the request for the 64 bits architecture.

I think that was it after all. I switched to MinGW 64 and this now compIles without error:

> swipl-ld -goal true -o calc calc.c calc.pl -v
        eval `swipl.exe --dump-runtime-variables`
                PLBASE="c:/program files/swipl"
                PLARCH="x64-win64"
                PLSOEXT="dll"
                PLLIBDIR="c:/program files/swipl/bin"
                PLLIB="-lswipl"
                PLTHREADS="yes"
        gcc.exe -c -D_REENTRANT -D__WINDOWS__ -D_WINDOWS -D__SWI_PROLOG__ -D__SWI_EMBEDDED__ -I"c:/program files/swipl/include" -o calc.obj calc.c
        gcc.exe -o calc.exe calc.obj -L"c:/program files/swipl/bin" -lswipl
        swipl.exe -f none -F none -g true -t "consult(['calc.pl']),qsave_program('pltmp-3384.exe',[goal=true,toplevel=prolog,init_file=none])"
% Disabled autoloading (loaded 37 files)
% Disabled autoloading (loaded 5 files)
% Disabled autoloading (loaded 0 files)
% halt
        cat pltmp-3384.exe >> calc.exe
        chmod 777 calc.exe
        rm calc.obj
        rm pltmp-3384.exe

If you have some time, please check if it works on the mingw system(s) provided by msys2.