HOW TO COMPILE
THE B++ LIBRARY ?
 
 
INTRODUCTION
 

The compilation of the B++ Library has been tested with several compilers. You will find the compilation files in the library folder. Look at the read_me.txt file and follow the instructions to compile the library. If your compiler has not been tested, you will have to configure the B++ Library and create a makefile or a project in a development environment. The compilation is a two-steps operation. First the C++ representation of Java classes required in the library has to be generated. The C++ source code of the library is thus complete. Then the compilation strictly speaking of the library can start.

 
LIBRARY CONFIGURATION
 

In order to configure the B++ Library, you have to create an options.hpp file. In that file, you will specify the compiler and the operating system you use, and activate or deactivate options for the debugging. To obtain details about options.hpp, see the section about . You can also find examples of this file in the library folder. If you want to create a dynamic-link library, maybe your compiler requests import and/or export commands to be placed in the source code of the library. For that purpose, there are two macrocommands in the options.hpp file that you can modify to specify the import and the export commands. Here are the usual commands a compiler requests.

#define DLL_EXPORT __declspec(dllexport)
#define DLL_IMPORT __declspec(dllimport)
 
JAVA NATIVE INTERFACE
 

The library is foreseen to interface with Java through the Java Native Interface (JNI). At the compilation step, you can choose to provide this facility or not by activating the JAVA_NATIVE_INTERFACE_YES macrocommand in the options.hpp file. To be compiled with JNI, the library needs a file named jni.h. Check on your hard disk if you have one, but we advise you to install the Java Development Kit of Sun Microsystems.

The library is linked with the Java Virtual Machine. You can choose to have a static or a dynamic link. If the JAVA_VIRTUAL_MACHINE_DYNAMIC macrocommand is activated in the options.hpp file, the link is dynamic. If you choose the static link (which we do not recommend) you must find the static library containing the virtual machine in your environment and make the modifications in the makefile (you have to complete the compilation options) so each dynamic library and each executable is linked against the virtual machine library.

 
THREAD-SAFETY
 

The library has been designed originally to run on a single thread. Since we offer the possibility of interacting with Java, which use is mostly multithreaded, we need to make the library thread-safe. What we call thread-safe is the fact you can call a function or a method that may manipulate a global resource shared between threads without any problem. Only a thread at a time will access the shared resource. By thread-safety, we also mean that methods and functions are reentrant, i.e. they contain no static data that can survive outside of their scope. However if a user manipulate directly a resource that may be shared between threads, it is up to him/her to protect it with a mutex (mutual exclusion mechanism).

To activate or deactivate the thread-safety, use the THREAD_SAFETY macrocommand in the options.hpp file. You should be aware that this option slows down certain features due to the mutex protection of the global resources and the prohibition of static data in methods and functions. You also have to notice that the library is thread-safe only if the compiler is configured and/or built to generate thread-safe C++ code. With GCC compilers, the options -D_THREAD_SAFE, -D_REENTRANT and -pthread (or -pthreads, -mthreads...) are necessary to build binary objects.

To conclude, thread-safety is a hard thing to validate. We did our best to respect the rules presented previously, but we could make only a few tests. Hence we do not guarantee thread-safety, but we assure it can be easily reached with few changes to correct the potential bugs we missed.

 
COMPILER AND OPERATING SYSTEM DEPENDENCY
 

If the compiler or the operating system you use have not been tested by us (i.e. there is no folder in the library folder corresponding to it), you will have to create a dependency file. A dependency file is a header file located in the Dependency module. To create one, just copy an existing dependency file and rename it. Do not forget to include this file in the dependency.hpp module interface file. In the new dependency file, modify the macrocommands to adapt the library to your compiler and operating system. To obtain details about the macrocommands, see the Dependency module information in the section about .

 
JIRK++
 

The library contains Java classes that will be used directly in C++ modules. For that, we use the Jirk++ mechanism (cf. the section on ). Before compiling the library, the C++ representation of these Java classes has to be generated. For that, we must compile the Java program named BuildJirk located in the Program module of the B++ Library. Hence, a Java compiler and a Java Virtual Machine (JVM) must be installed in your system. We recommend you to install the Java Development Kit of Sun Microsystems. From the root folder of the library, here is the command to compile BuildJirk.

javac -classpath sources -d library/java
 sources/bpp/program/BuildJirk.java

Note that the binary code will be stored in the library/java folder. Then you must generate the C++ representation of the classes that are listed in the sources/java--classes.txt file. Here is the command to do so.

java -cp library/java bpp.program.BuildJirk
 -path sources -file sources/java--classes.txt +add

C++ files are generated and stored in the sources/jirk folder. Now you have all the C++ source files.

 
MAKEFILE
 

You have then to compile the B++ Library. For that, you have different possibilities. If you use a development environment, create one or several projects to build libraries. We advise you to make one library for each "big" module (see the sources/makefile--building_rules.txt file). You also have to define the sources folder and the folder where options.hpp is located as default include paths (if JNI is required, the folder containing jni.h must also be a default include path). If you do not use a development environment, you must create a makefile. The main part of the makefile has been automatically generated for you. You will find it in sources/makefile--building_rules.txt. Two other files have been prepared. They contain the dependency of the "big" modules (makefile--modules_dependency.txt) and the rules to create the whole library as static or dynamic (makefile--library.txt). For the C++ representation of Java classes generated before, the BuildJirk program will generate most of the rules automatically. Here is the command.

java -cp library/java bpp.program.BuildJirk
 -path sources -objects <objects_path>
 -standard sources/java--standard.txt
 +makefile sources/makefile--jirk.txt

The program scans the folder containing the Jirk++ hierarchy and generates rules in the sources/makefile--jirk.txt file. <objects_path> must be replaced by the folder where you want the temporary binary objects to be created. The java--standard.txt file contains the packages that must be considered as standard of Java. In fact, several libraries are created, one for each first-level package, except for the standard packages that are regrouped in a single library named jirk. For classes that do not belong to any package, they are stored in a library named jirkbulk, but if you can, we recommend you to avoid this situation.

After that, you only have to write the "configuration" part of the makefile. For examples, look at the configuration.mak files in the library folder. Here are the parameters you have to set.

CLASS_PATH Path where the byte code files of the Java modules of the B++ Library are created.
INCLUDE_PATH Path where the source files of the B++ Library are located.
JNI_PATH Path where the header files for the Java Native Interface (JNI) are located.
LIBRARY_PATH Path where you want the library to be created.
OBJECTS_PATH Path where you want the temporary binary objects to be created. This folder must contain the same folders hierarchy as the one containing the source files. For that, just copy the content of the trash/template folder in this folder.
OPTIONS_CLASS Compilation options given to the compiler to build Java byte code.
OPTIONS_CPLEX Compilation options given to the compiler to link against the CPLEX library.
OPTIONS_DLL Compilation options given to the compiler to build dynamic libraries.
OPTIONS_GLPK Compilation options given to the compiler to link against the GLPK library.
OPTIONS_OBJ Compilation options given to the compiler to build C++ binary objects.
OPTIONS_THREAD Compilation options given to the compiler to build thread-safe C++ binary objects.
DLL Extension of the dynamic library file names.
LIB Extension of the static library file names.
OBJ Extension of the binary object file names.
PRE Prefix of the dynamic library file names.
ADD_LIB Option of the STATIC command to add a binary object into a static library.
COMPILE_CLASS Command to compile Java byte code.
COMPILE_OBJ Command to compile C++ binary objects.
DLL_NAME Option of the DYNAMIC command to define the name of the dynamic library.
DYNAMIC Command to archive binary objects into a dynamic library.
ECHO Command to echo a message on the screen.
GCC Command to call the compiler.
LIB_NAME Option of the STATIC command to define the name of the static library.
MOVE Command to move a file.
RANLIB Command to update the organization of a library.
REMOVE Command to remove a file.
STATIC Command to archive binary objects into a static library.

Here is an example.

CLASS_PATH   = c:/bruno/bpp_library/java
INCLUDE_PATH = c:/bruno/bpp_library/sources
JNI_PATH     = c:/jdk_1-3/include
LIBRARY_PATH = c:/bruno/bpp_library/library/gcc-2_cygwin
OBJECTS_PATH = c:/bruno/bpp_library/trash/gcc_cygwin

OPTIONS_CLASS  =
OPTIONS_CPLEX  = -lcplex80
OPTIONS_DLL    = -shared
OPTIONS_GLPK   = -lglpk
OPTIONS_OBJ    = -ansi -Wall -pedantic -O2 \
                 -I$(JNI_PATH)/win32 -Wno-long-long
OPTIONS_THREAD = -D_THREAD_SAFE -D_REENTRANT -mthreads

DLL = dll
LIB = a
OBJ = o
PRE = 

ADD_LIB       = 
COMPILE_CLASS = javac $(OPTIONS_CLASS) \
                -classpath $(INCLUDE_PATH) -d $(CLASS_PATH)
COMPILE_OBJ   = $(GCC) -I$(INCLUDE_PATH) -I$(JNI_PATH) \
                -I$(LIBRARY_PATH) $(OPTIONS_OBJ) \
                $(OPTIONS_THREAD) -c
DLL_NAME      = 
DYNAMIC       = $(GCC) -L$(LIBRARY_PATH) $(OPTIONS_DLL) \
                $(OPTIONS_THREAD) $(OPTIONS_GLPK) \
                $(OPTIONS_CPLEX) -o
ECHO          = echo
GCC           = g++
LIB_NAME      = 
MOVE          = mv
RANLIB        = ranlib
REMOVE        = rm -f
STATIC        = ar -rc
 
DISPLAY
 

The B++ Library is able to display information on the screen. To do so, the B++ Library calls a set of methods. However, the programmer may want information to appear in a text display, in a graphical display, in a window or any graphical object. For this reason, the methods used for the display belong to an abstract class and are not implemented. This class, called clDisplay, is part of the Display module. Hence, you have to define yourself a class inherited from the abstract class and implement the methods. For example, look at the module Display/Console. Your class for the display has to be compiled and archived in a library called bpp_display. Here is the rule for a static library.

$(LIBRARY_PATH)/libbpp_display.$(LIB) : \
 $(OBJECTS_PATH)/bpp/display/console.$(OBJ)
     $(STATIC) $(LIB_NAME)$@ \
      $(ADD_LIB)$(OBJECTS_PATH)/bpp/display/console.$(OBJ)

And here is the rule for a dynamic library.

$(LIBRARY_PATH)/$(PRE)bpp_display.$(DLL) : \
 $(OBJECTS_PATH)/bpp/display/console.$(OBJ)
     $(DYNAMIC) $(DLL_NAME)$@ \
      $(OBJECTS_PATH)/bpp/display/console.$(OBJ)

The Display/Console implementation file also contains the name of the file describing the dynamic parameters of the library. For more details, check the . Note that you can define several displays, you only have to define several subclasses of the abstract class and archive them in the bpp_display library. The choice of the display the library will use is explained in the .

 
CONCLUSION
 

Now you have to include at the end of your makefile the following files in this order.

  • sources/makefile--modules_dependency.txt,
  • sources/makefile--building_rules.txt,
  • sources/makefile--library.txt,
  • sources/makefile--jirk.txt.

Your makefile is now complete. To compile the library, you just have to execute make static_library or make dynamic_library depending on whether you want a static or a dynamic library. The first time you compile the library, do not activate any optimization flag (-Ox), because with some compilers, the optimization process generates warnings and sometimes errors. When you obtain a compilation without warning, then you can activate the optimization flags. For more details about the compilation, see the examples in the library folder.