Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Porting

Tango tries to be portable, and has been ported to many platforms. If tango does not work or works only partially then you are probably the best person to fix it, as likely other tango developers don't have access to your platform.

The first step is to get a working D compiler on your system. Once you have that the next step is having a working runtime.

C Api declarations

The runtime of tango depends on the compiler and strives to have minimal dependencies on the platform. It is located in the runtime directory, and actually all system dependencies are in runtime/*. These dependencies are cImports.d (in runtime/compiler/YourCompiler/rt/) and some imports in runtime/common/tango/stdc.

Normally the runtime dependencies are minimal, and are fulfilled, the main porting work for tango is getting the tango.stdc (c library) bindings correctly. To get the bindings correctly one can look at the C headers. Unfortunately C headers have parts that can be activated or deactivated and a header includes others headers, so looking at them directly can be confusing. The best thing is to let the C compiler do most of the work: prepare a file the imports the header and precompile it (gcc -E -dD -P -C file.c for example). The resulting file will contain all the correct declarations of c functions and structures. Normally it is quite straightforward to convert them to D, the only thing that one should pay attention to is that C long corresponds to D c_long, and unsigned long to D c_ulong which are defined in tango.stdc.config.

If your system can compile both 32 and 64 bit it is very important to precompile the header with the same settings as the D compiler. For example if the D compiler is 32 bit use gcc -m32 -E file.c, if it is 64 gcc -m64 -E file.c, likewise if you crosscompile use the crosscompiling switches. Only then the resulting files will contain function and struct declarations. What will be missing from these files are the #define constants. You can ask the compiler to dump all its macros, but the thing becomes quickly messy. One could prepare a file that once precompiled would show the values of the constants that are of interest.

Indeed this has been already done for several files and the files to precompile them are ready in lib/constants. There is also a script that precompiles them and prepares them and puts them in stdc/constants/autoconf. Actually there are two scripts that do this: ./dppAll.sh and ./dppAll2.sh . The first tries to create valid files containing only the constants, the second one leaves all the declarations of functions and structures in the file before the string xxx start xxx.

For porting normally dppAll2.sh is more useful, because then one can check the values of functions/structures and see if those correspond to what D uses. Also C99 constants declared with enum will remain before the xxx start xxx string, and should be moved after it. If someone wants to write a script of D program that copes with the C99 enums it would be welcome.

After all this effort you will hopefully be able to give reasonable values to the files in runtime. You will need to do the same rest of the C interface (user/tango/stdc).

Building

Once this is done you will probably want to build the runtime and tango, there is a script that does everything:

cd build;
./build.sh

use the --help flag to see all its flags. If your platform is not supported you are better off doing the single steps by hand:

cd build/runtime;
make

this should try to build the runtime, probably it will fail because you haven't set the arch file. The following paragraphs explain the options of the Makefile, probably the most important is the Architecture one.

Targets

  • all: (the default) builds lib
  • lib: should build the optimized tango library
  • newFiles: updates the module list when new d diles are added either this or clean-all or distclean have to be called to compile the new files
  • clean: cleans the buildobjects
  • clean-all: removes the current object directory
  • distclean: removes all object directories and libs
  • install: installs the .di files

Compiler

By default make tries to guess the compiler to use. If you have several compilers you can select the compiler to use by setting the DC environment variable or by setting DC in the make invocation

Version

By default the optimized version will be built, you can build other versions by passing VERSION=dbg or VERSION=tst (for example) to the make invocation

Architecture

The architecture is identified by what is returned by tango/lib/build/tools/archName.sh (which is os-machine) togheter with the compiler and version. This forms a quadruplet os-machine-compiler-version that is called IDENT. It is used to generate the object directory, and to get the architecture dependent flags and rules. This is done by reading the file tango/lib/build/arch/$(IDENT).mak It is possible to override IDENT by passing IDENT=mySpecialIdent to the make invocation. In this case the version flag is disregarded. For problems with the flags (or if you want to define a new special build setting) normally you should edit the tango/lib/build/arch/$(IDENT).mak file in a similar way to one of those that are already there.

In it EXCLUDEPAT_OS defines the pattern that matches the files that should not be considered, probably you should edit it to exclude the files of other systems, and EXCLUDE_DEP_OS the dependencies that should be ignored

Other important variables

  • DFLAGS_ADD: adds the given D flags
  • CFLAGS_ADD: adds the given C flags
  • DFLAGS: as environment variable is not changed
  • CFLAGS: adds the given C flags

User lib

When the runtime builds you build the user library with the makefile in build/user

cd ../user
make

The makefile is similar to the one of the runtime, but in this case the list of files to compile is not defined explicitly, but implicitly as all the files that are not excluded with EXCLUDEPAT_OS and EXCLUDE_DEP_OS.

When that works you might want to define arch files for opt,dbg and tst version, and maybe to use the ./build.sh script

Unittests

you can execute tango's unittests with:

cd ..
./build.sh --version tst
./unittest-compiler.sh
./runUnitTest_compiler

which will run all the unit tests of tango.

Final Remarks

Try and let us know problems,... If you think that extra files to be precompiled can be useful, or have been used by you propose them, and they will be added to lib/constants...