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.

1 Like

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.

1 Like

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.

1 Like

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…

1 Like

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.

1 Like

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…

1 Like

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
1 Like

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