An example showing how to build a run-time system (in C or C++), with and without using the command 'spld'. Last updated for SICStus 4.0.1 and Visual Studio 2005 SP1 sicstus-support@sics.se NOTE: The details below are subject to change without notice. Use spld --verbose --keep each time you upgrade to new version of SICStus to see if anything has changed. Options --verbose will show details on what is going on and --keep ensures that generated C files are not deleted. All examples assume that a foreign resoure have already been built from cplus.cpp as outlined in README_FOREIGN.txt. The examples also assumes that you are familiar with README_FOREIGN.txt. Start a command shell (cmd.exe) and make the C compiler and the SICStus tools available (see README_FOREIGN.txt for more information). ##### TRANSCRIPT BEGIN Microsoft Windows [Version 6.0.6000] Copyright (c) 2006 Microsoft Corporation. All rights reserved. c:\cplusplus>"%PROGRAMFILES%/Microsoft Visual Studio 8/VC/bin/vcvars32.bat" "%PROGRAMFILES%/Microsoft Visual Studio 8/VC/bin/vcvars32.bat" c:\cplusplus>"C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat" Setting environment for using Microsoft Visual Studio 2005 x86 tools. c:\cplusplus>SET PATH=%PATH%;%PROGRAMFILES%\SICStus Prolog 4.0.1\bin SET PATH=%PATH%;%PROGRAMFILES%\SICStus Prolog 4.0.1\bin c:\cplusplus> ###### TRANSCRIPT END Simple Prolog based run-time system ======================================= The first example creates a run-time system consisting of no userwritten C(++) code (except the foreign resource created in README_FOREIGN.txt). At startup the run-time system will first load the file main.pl. The run-time system will then call user:runtime_entry(start) which is defined in main.pl. user:runtime_entry/1 will, in turn, call the predicates defined in the cplus library. In practice you probably want to compile main.pl to main.po, see the cplus foreign resource example for how to do this. For larger systems you probably want to use a .sav file containing all your prolog code. You would then use the option --main=restore instead. #### TRANSCRIPT BEGIN c:\cplusplus>spld --main=load main.pl --output rt_load.exe spld --main=load main.pl --output rt_load.exe spldgen_1200_1182428768_load_main.c spldgen_1200_1182428768_main_wrapper.c spldgen_1200_1182428768_prolog_rtable.c Microsoft (R) Manifest Tool version 5.2.3790.2075 Copyright (c) Microsoft Corporation 2005. All rights reserved. Created "rt_load.exe" c:\cplusplus>.\rt_load.exe .\rt_load.exe Testing creating and accessing a dynamic C++ object Testing setting a C "long" value as a long and reading it as long and as a term Calling Obj.set_i(4711) ... and so on ... c:\cplusplus> #### TRANSCRIPT END Simple Prolog based run-time system without spld ================================================ The easiest method if you do not want to use spld is to run spld once with --keep and --verbose. Option --keep will not delete the generated C files. Rename the generated C files and add them to your project. Option --verbose shows what compiler flags are needed to compile the generated C files and what linker flags are needed to link the final executable. The ideas are the same as in README_FOREIGN.txt Simple embedded run-time system with spld ================================================ This example shows how to embed the Prolog run-time into your C/C++ code using spld. As always you should add the spld options --verbose and --keep if you want to see what is really going on. #### TRANSCRIPT BEGIN c:\cplusplus>spld --main=user rt_win.cpp --output rt_user.exe spld --main=user rt_win.cpp --output rt_user.exe rt_win.cpp spldgen_3704_1182429047_main_wrapper.c spldgen_3704_1182429047_prolog_rtable.c Microsoft (R) Manifest Tool version 5.2.3790.2075 Copyright (c) Microsoft Corporation 2005. All rights reserved. Created "rt_user.exe" c:\cplusplus>.\rt_user.exe .\rt_user.exe Testing creating and accessing a dynamic C++ object Testing setting a C "long" value as a long and reading it as long and as a term Calling Obj.set_i(4711) ... and so on Calling Obj.get_i()... got back the (C long) -59837....OK <<< here a dialog pops up with the text "Test Succeeded">> &stat_obj == 0x2e51b8 c:\cplusplus> #### TRANSCRIPT END Embedded run-time system without spld ================================================ This example shows how to embed the prolog run-time in your own C or C++ program and do all compilation manually (or through an Integrated Development System such as Microsoft Visual C++) As usual you should use spld --verbose --keep to get hold of any generated files and the flags needed to compile them. The below transcript uses the same example as above. #### TRANSCRIPT BEGIN c:\cplusplus>spld --verbose --keep --main=user rt_win.cpp --output rt_user.exe spld --verbose --keep --main=user rt_win.cpp --output rt_user.exe spld (SICStus Prolog) 4.0.1 SICStus Prolog Release 4.0.1 Copyright (c) 1998-2007 Swedish Institute of Computer Science Report bugs at: http://www.sics.se/sicstus/bugreport/bugreport.html % Handling non-option arg rt_win.cpp ... as C/C++ source file % Reading configuration file "C:/PROGRA~2/SICSTU~1.1/bin/spconfig-4.0.1" % Generating wrapper for main function (spldgen_main_wrapper.c)... % Building a runtime executable. % Generating resource table (spldgen_prolog_rtable.c)... % Compiling C sources... cl.exe -I"C:\PROGRA~2\SICSTU~1.1/include" -nologo /MD /Z7 /GF /Ox -c rt_win.cpp -Fort_win.obj cl.exe -I"C:\PROGRA~2\SICSTU~1.1/include" /MD /Z7 /GF /Ox -c rt_win.cpp -Fort_win.obj Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. rt_win.cpp cl.exe -I"C:\PROGRA~2\SICSTU~1.1/include" -nologo /MD /Z7 /GF /Ox -c spldgen_main_wrapper.c -Fospldgen_main_wrapper.obj cl.exe -I"C:\PROGRA~2\SICSTU~1.1/include" /MD /Z7 /GF /Ox -c spldgen_main_wrapper.c -Fospldgen_main_wrapper.obj Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. spldgen_main_wrapper.c cl.exe -I"C:\PROGRA~2\SICSTU~1.1/include" -nologo /MD /Z7 /GF /Ox -c spldgen_prolog_rtable.c -Fospldgen_prolog_rtable.obj cl.exe -I"C:\PROGRA~2\SICSTU~1.1/include" /MD /Z7 /GF /Ox -c spldgen_prolog_rtable.c -Fospldgen_prolog_rtable.obj Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. spldgen_prolog_rtable.c Linking "rt_user.exe" cl.exe -IC:\PROGRA~2\SICSTU~1.1/include -nologo /MD /Z7 /GF /Ox -nologo rt_win.obj spldgen_main_wrapper.obj spldgen_prolog_rtable.obj C:\PROGRA~2\SICSTU~1.1/bin/charmain.obj C:\PROGRA~2\SICSTU~1.1/bin/cmdproc.obj C:\PROGRA~2\SICSTU~1.1/bin/intrpt.obj C:\PROGRA~2\SICSTU~1.1/bin/spaux.obj C:\PROGRA~2\SICSTU~1.1/bin/sprt4-0-1.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib -Fert_user.exe /link /NXCOMPAT /SAFESEH cl.exe -IC:\PROGRA~2\SICSTU~1.1/include /MD /Z7 /GF /Ox rt_win.obj spldgen_main_wrapper.obj spldgen_prolog_rtable.obj C:\PROGRA~2\SICSTU~1.1/bin/charmain.obj C:\PROGRA~2\SICSTU~1.1/bin/cmdproc.obj C:\PROGRA~2\SICSTU~1.1/bin/intrpt.obj C:\PROGRA~2\SICSTU~1.1/bin/spaux.obj C:\PROGRA~2\SICSTU~1.1/bin/sprt4-0-1.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib -Fert_user.exe /link /NXCOMPAT /SAFESEH Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. Microsoft (R) Incremental Linker Version 8.00.50727.762 Copyright (C) Microsoft Corporation. All rights reserved. /debug /out:rt_user.exe /NXCOMPAT /SAFESEH rt_win.obj spldgen_main_wrapper.obj spldgen_prolog_rtable.obj C:\PROGRA~2\SICSTU~1.1/bin/charmain.obj C:\PROGRA~2\SICSTU~1.1/bin/cmdproc.obj C:\PROGRA~2\SICSTU~1.1/bin/intrpt.obj C:\PROGRA~2\SICSTU~1.1/bin/spaux.obj C:\PROGRA~2\SICSTU~1.1/bin/sprt4-0-1.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib LINK : rt_user.exe not found or not built by the last incremental link; performing full link mt.exe /manifest rt_user.exe.manifest /outputresource:rt_user.exe;#1 mt.exe /manifest rt_user.exe.manifest /outputresource:rt_user.exe;#1 Microsoft (R) Manifest Tool version 5.2.3790.2075 Copyright (c) Microsoft Corporation 2005. All rights reserved. Created "rt_user.exe" % Keeping temporary files: rt_win. spldgen_main_wrapper.c spldgen_main_wrapper.obj spldgen_prolog_rtable.c spldgen_prolog_rtable.obj c:\cplusplus> #### TRANSCRIPT END Of particular interest are spldgen_prolog_rtable.c. It contains definitions that allow SICStus to access any pre-linked data resources and (static) foreign resources. This example uses neither but the resource table file must still be present. From the transcript we can see that the way to compile is something like cl.exe -I"%PROGRAMFILES%\SICStus Prolog 4.0.1\include" /MD /Ox -c spldgen_prolog_rtable.c -Fospldgen_prolog_rtable.obj You can rename spldgen_prolog_rtable.c to something more suitable, if you like. You then need to compile your own code (rt_win.cpp and rt.cpp) in a way that is compatible with SICStus. In particular you must use /MD (use dynamically linked and thread safe C library). You also need to make the sicstus header available by using the appropriate -I argument. Something like: cl -I"%PROGRAMFILES%\SICStus Prolog 4.0.1\include" /MD /Ox -c rt_win.cpp -Fort_win.obj cl -I"%PROGRAMFILES%\SICStus Prolog 4.0.1\include" /MD /Ox -c rt.cpp -Fort.obj Finally link your application: cl /MD rt_win.obj rt.obj spldgen_prolog_rtable.obj "%PROGRAMFILES%\SICStus Prolog 4.0.1\bin\spaux.obj" "%PROGRAMFILES%\SICStus Prolog 4.0.1\bin\sprt4-0-1.lib" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib -Fert_user.exe /link /NXCOMPAT /SAFESEH Note that spld also linked with some additional files (charmain.obj, cmdproc.obj, intrpt.obj) that are not really needed in this case. (The /SAFESEH and /NXCOMPAT are optional, security-related flags). As final step you may want to embed the manifest file that the Visual Studio linker created. It tells what version of the C library is being used by the executable: mt.exe /manifest rt_user.exe.manifest /outputresource:rt_user.exe;#1 Now we can test #### TRANSCRIPT BEGIN c:\cplusplus>.\rt_user .\rt_user Testing creating and accessing a dynamic C++ object ... and so on #### TRANSCRIPT END Embedded run-time system DLL without spld ================================================ To create a DLL with an embedded Prolog run-time system is almost the same as creating an ordinary executable as above. The difference is that the flag -dll should be passed to the compiler. Also note that SP_initialize and other non-trivial things cannot be called from DllMain. Instead you need to use an explicit initialization routine for your DLL. You should also be able to use spld --shared --output foo.dll to create a DLL. However, this is still (SP 4.0.1) somewhat experimental. Things not (yet) covered =============================================== . Creating a directory tree for running your SICStus-based application on machines that do not have SICStus installed. . Embedding .sav files into the executable (data resources). . Creating a all-in-one executable that does not need any external SICStus-related files. These issues are described in the Release Notes and the SICStus Prolog Manual.