General ======= These are all command-line instructions. If you want to compile the code from an integrated development environment, you probably know what you're doing and you'll figure it out :-). The first step is to compile the library. If you have trouble, read the Makefiles. They all have the compiler warning levels set rather high, and they are set to fail even on warnings. You can turn this off. The Visual C++ version also requires a couple of tools that you may not have, but this too is easy to turn off. If you want, the optional next step is to test the library. Generally speaking: * Your paths and your system must be set up ahead of time. * You must have "make", or you will have to find a manual way of compiling. * If your compiler does not have the name that we assume in the Makefile, then modify the Makefile. Once you've tested the source, you'll need the library file, the dll.h include file from the include directory, and possibly other files such as dll.lib, depending on the exact system. You don't need include/portab.h, although you're welcome to use it. The library files needed are: Microsoft Visual C++: dds.dll, dds.lib mingw and cygwin: dds.dll, dds.def Mac and linux: libdds.a or libdds.so depending on compilation General instructions ==================== 1. Go to the src directory. 2. Copy the right Makefile_... from the Makefiles sub-directory to the src directory and call it Makefile, see below. (Or use make -f) So for example "cp Makefiles/Makefile_Visual Makefile". See "System-specific data" below. 3. Check the configuration section and make any changes you need. - Section (1) has to do with paths for certain multi-threading systems which you may or may not want/have. If you set a certain compiler flag, it is your own responsibility that you have the corresponding threading system available -- otherwise the code will not compile. - Section (2) sets the threading systems with which you want to compile the DLL. Note that you can have as many as you like (see below). - Section (3) has to do with certain debugging flags etc. which you normally shouldn't set. 3. Check the "Often OK" section, in particular the name of the compiler you want to use. 4. If you're on Windows and you don't have the "windres" and "cvtres" programs, then you can also manage without. These are just used for getting version information into the DLL. Delete the corresponding lines. 6. "make clean" (not necessary if you're starting clean). 7. There is a "make depend" target, but DO NOT USE IT. The Makefile is set up to read the dependencies from Makefiles/depends_*.txt. 8. "make" (produces dds.dll on Windows, libdds.a or libdds.so on Linux and Mac). 9. "make install" (if you want to run tests; this is only a local install to ../test and ../examples, not a system-wide one). System-specific data ==================== Microsoft Visual C++ -------------------- Makefile: Makefile_Visual Compiler: cl If you don't have a Cygwin-like set-up with access to commands such as "cp", see the last lines of that Makefile. Windows Mingw ------------- Makefile: Makefile_mingw Compiler: g++ Windows Cygwin -------------- Makefile: Makefile_cygwin Compiler: g++ Linux (static library .a) ----- Makefile: Makefile_linux_static Compiler: g++ Linux (dynamic library .so) ----- Makefile: Makefile_linux_shared Compiler: g++ MacOS clang (static library .a) ----- Makefile: Makefile_Mac_clang_static Compiler: g++ MacOS clang (shared library .a) ----- Makefile: Makefile_Mac_clang_static Compiler: g++ MacOS GNU g++ (static library .a) ----- Makefile: Makefile_Mac_clang_static Compiler: gcc-4.9 MacOS GNU g++ (shared library .a) ----- Makefile: Makefile_Mac_clang_static Compiler: gcc-4.9 Multi-threading =============== As of v2.9.0 this works differently. It is possible to have multiple threading systems in the same library. There is a new DLL function called SetThreading() to select the one you want, in case there is more than one. If the DLL is compiled only single-threaded, that is what you'll get. If there are multiple options, the DLL will default to the multi-threaded one with the lowest number (among those compiled in, of course). The numbers can be found in ../include/dll.h. It is NOT recommended to use STLIMPL and PPLIMPL as they are today. You cannot control the number of threads that they will want, nor the memory that they will consume. But maybe some day... The others are very equivalent in terms of speed, but you might as well use STL if you have it, as this is probably the most portable. If you don't have a C++17 compiler, you will not get STLIMPL or PPLIMPL. The *IMPL versions let the system handle threads autonomously (up to the number of threads set by the user), whereas the others are handled by DDS internally. The *IMPL version are similar in speed, except if there is some near-duplication in the input hands (say, instances of the same distribution played in the same denomination from different side). The non-IMPL version handle this more efficiently. Testing ======= The step "make install" above should have put the library file in ../test. test ---- In the test directory you can compile the dtest program. This program tests five main modes of DDS: * solve, the solution of a hand for a given declarer and strain. * calc, the solution of a hand for all 4 declarers * 5 strains. * play, the checking of play vs. double-dummy place. * par, the par calculation. * dealerpar, the dealer par calculation. The program can use a number of pre-defined input files in the ../hands directory. To compile the program, you follow the same steps as for the library, except that you don't do a "make install". So you copy the right Makefile from Makefiles (e.g. "cp Makefiles/Makefile_Visual Makefile"), then type "make". You should now have a program called "dtest" or "dtest.exe". Let us assume dtest.exe. Let us also assume that your system is set up in such a way that your path does not include the current working directory. You can invoke the program as ./dtest.exe which should just give a brief usage message. If that works, then you can invoke the program like this, for example: ./dtest.exe -f ../hands/list100.txt -s solve -n 4 -m 1000 The number of threads is optional. If it is not supplied, DDS figures one out itself. If it is supplied, then it is passed to SetMaxThreads(). You can also use SetResources() instead of SetMaxThreads() to set the memory consumption as well. If you use SetResources(), there is no need to use SetMaxThreads(). Generally speaking, the test program first shows some information about how it was compiled. Then it shows some ongoing timing information which can be useful to see that the program hasn't frozen in a long run. Then it shows some timing information including an average per hand. The program compares results against expected values. If something isn't right, you will see it. If only specific hands fails, then we are surprised -- please report it to us. ddd --- This program was written by Flip Cronje, and we have modified it minimally to support a multi-threaded DLL. However, it doesn't use the full capabilities of DDS, as it was written at a time when functions such as CalcAllTables and SolveAllBoards were not yet available. Therefore it is rather slow, but it does have a nice hand generator built in. It has not been updated since v2.8.4. examples -------- The previous tests are intended for testing, not for teaching anybody how to interface with the DDS library. Here we show some minimal examples of using various DDS functions. These are short programs with only the minimum needed to get going. You can build on these for your own purposes.