Creating your own makefile

If you are using a C++ compiler other than gcc, djgpp, Borland C++ or Microsoft Visual C++, you will most likely need to create a makefile of your own to be able to compile apfloat. Note that this is not entirely trivial, so you may want to familiarize yourself with the "make" utility first.

If you are using MS-DOS or Windows

If you don't have an Intel syntax compatible assembler, you can use the makefile in the 32_586_2 package as a template. You will also need all the *.lnk files in the 32_586_2.zip package. In this case you should use the files from the 32_ansi.zip package also. This is the typical case that will work with most compilers, however it will not create maximally fast code.

If you do have an Intel syntax compatible assembler (such as Turbo Assembler or Microsoft Macro Assembler), you can use the makefile in the 32_vc package as a template. You will also need all the *.lnk, *.h, *.cpp, *.inc and *.asm files in the 32_vc.zip package. Alternatively, you can try to use the files from the 32_bcc32.zip package as a template.

If you are using Unix

Use the makefile in the 32_unix.zip package as a template for creating your makefile.

Setting the parameters


The CC parameter in the makefile specifies the C++ compiler executable name. For unix systems this may be cc or CC, or if you have a C++ compiler provided by some specific vendor, the executable name may have another name (such as icl for an Intel provided compiler).

For example:

CC = g++


Note: this parameter does not exist in the Unix makefile template (it is usually not needed on Unix systems).

The AS parameter in the makefile specifies the assembler executable name. It is only needed if you are using the .asm files of an apfloat platform package and the assembler executable name is different from the C++ compiler. With Microsoft C++ you must use the separate ml command, whereas Borland C++ knows to automatically compile .asm files with Turbo Assembler.

For example:

AS = ml


Some compilers (in particular, djgpp) need specific post-linking commands to actually create an executable file. On Unix systems you may want to, for example, strip all debug information from the executable to make it smaller. If these commands are not needed, you should use "true" in Unix and "rem" in MS-DOS/Windows.

For example:

CONV1 = strip
CONV2 = true


These commands are used to create the apfloat library. The RM command removes the library file (if it exists). In Unix this is "rm" and in MS-DOS this is "del". ARADD is the command to add object files to a library. Actually the way of doing this may vary greatly depending on your system so you may need to modify the makefile where the ARADD command is used and/or create a link file (lib.lnk) for inputting commands to the library program. RANLIB is needed with Unix and djgpp, but is not known to be needed with other MS-DOS/Windows compilers (so you can then just use "rem" there).

For example:

RM = rm -f
ARADD = ar rc
RANLIB = ranlib


Note: the S parameter does not exist in the Unix makefile template (it is usually not needed on Unix systems).

These parameters define the file extensions for all the needed file types, and the ios flag that is used to determine that files are opened in binary mode (instead of text mode).

C Extension for C++ source files. On Unix systems typically .cc, on DOS/Windows .cpp. Note that the source files in the apfloat packages have a .cpp extension so if this is something else than .cpp, you will need to rename the files to the appropriate extension.
S Assembler source file extension. Not needed on Unix systems, on DOS/Windows typically .asm.
OBJ Extension of object files. With Unix and djgpp this is usually .o, with DOS/Windows compilers typically .obj.
OUT Extension of the executable file generated by the linker. On Unix systems and with djgpp in DOS this is empty. With most other MS-DOS/Windows compilers this is .exe.
EXE Extension of the (final, actual) excutable file. On Unix systems this is typically empty. With most MS-DOS/Windows compilers this is .exe. This is only different from the OUT parameter if some post-link processing needs to be done (with the CONV1 and CONV2 commands) that create an executable file from the linker output, which is the case for example with djgpp.
BIN Name of the ios flag that defines that a file is opened in binary mode (instead of text mode). This is really only needed in MS-DOS and Windows, where there is a difference in handling the line feed character (in text mode it is translated to a carriage return/line feed pair which corrupts binary data). On Unix systems (including Linux) this should not be needed as no such translation is done and all files are always opened in binary mode. In DOS/Windows the flag is usually "binary", although some compilers seem to use "bin". In many Unix systems this flag does not exist at all; in this case you can just use "in". The flag is used in the apfloat source code as ios::BIN, that is for example ios::binary if BIN is defined as binary.
LIBPRE Object library file prefix. With Unix compilers you may want to set this to "lib", if you want to name the library "libapfloat.a", so that you can compile it to your programs using "-lapfloat". With MS-DOS/Windows compilers leave this setting empty.
LIBEXT Object library file extension. With Unix compilers (including djgpp) this is usually ".a", with most MS-DOS/Windows compilers ".lib".

For example:

C = .cpp
S = .asm
OBJ = .obj
OUT = .exe
EXE = .exe
BIN = binary
LIBEXT = .lib


The OPTS parameter defines the compilation switches and options that are passed on the command line. These options should typically include You need to refer to your compiler manual to find out the exact command line switches needed. They vary greatly from compiler to compiler.

For example:

OPTS = -mips3 -mlong64 -O3 -ffast-math -w


Note: this parameter does not exist in the Unix makefile template (it is usually not needed on Unix systems).

ASOPTS defines compilation options that are passed to the assembler (AS), similarly as the OPTS parameter defines compilation options that are passed to the C++ compiler. ASOPTS is only needed if you use a separate assembler (defined by the parameter AS).

For example:

ASOPTS = /coff /Zi


This parameter defines the compiler option to specify the output executable name. On Unix systems and with djgpp this is normally "-o " (note the space after the -o). With most other MS-DOS/Windows compilers this is something else. In the making process, the output filename (extension defined by the OUT parameter) is passed after the OUTOPT parameter to the compiler.

For example (note the space after the -o):

OUTOPT = -o 


The DEFOPT parameter defines the compiler option to #define something. This switch is usually -D or /D.

For example:



If you use a version of apfloat that includes assembler-optimized functions, you need to #define ASM. This is needed because the assembler functions are not treated as C++ functions but ordinary C functions and thus their declaration is different (they are declared as extern "C").

If you use an assembler-optimized version, make sure that the ASM line in the makefile is NOT commented out. That is the line should be "ASM = $(DEFOPT)ASM". If you use a version that has no assembler functions, comment the line out (like "#ASM = $(DEFOPT)ASM") or delete the line.

For example:

# Comment do disable assembler optimizations


This parameter defines the options that are passed to the compiler when compiling a file. The parameter should specify a "compile only" switch (that is, no linking is done and no executable is created), which is usually -c or /c. Otherwise you should leave it as it is (defining BIN and ASM).

For example:



Unfortunately, ANSI C does not define a standard function to truncate a file or set a file's size to a specific value. Most compilers have some kind of a function to do this but the implementations vary greatly. Apfloat truncates occasionally temporary files it creates on the disk.

Apfloat calls a function called "truncate" to shrink a file's size. Some compilers have this function in their standard C library. If a truncation function by that name does not exist, apfloat has a dummy truncation function that doesn't do anything, and you should use that to be able to link the program. It does no harm to actually not truncate a file, it just takes unnecessary disk space during run time. The dummy truncate.c file is in the apfloat common source files package.

You can of course implement your own truncate function to truncate a file using your compiler's specific method. With most MS-DOS/Windows compilers you might be able to do this using the truncate.c file in the 32_vc.zip or 32_bcc32.zip package.

If your compiler has a built-in truncate function (gcc has it, including djgpp), be sure to comment out the TRUNCATE line in the makefile. That is the line should be "#TRUNCATE = truncate$(OBJ)". If your compiler does NOT have a built-in function named truncate, the TRUNCATE line should be uncommented, that is "TRUNCATE = truncate$(OBJ)".

For example:

# Uncomment if your compiler doesn't have the truncate function
#TRUNCATE = truncate$(OBJ)


On most Unix systems, you need to specify the math library to be linked with your program. This is done usually with the -lm switch. On most DOS/Windows compilers this is not needed and the LIBS parameter should be set to empty. On some compilers you may need to link other libraries, for example some Unix compilers may need the standard C library specified, usually with a -lc switch. If you use the Unix multithreading version make sure that the LIBS parameter contains the -lpthread parameter.

For example:

LIBS = -lm

Getting the i386 assembler files to work

If you have an Intel syntax compatible x86 assembler and insist on using it, you will most likely need some tricks to get the apfloat assembler (.asm) files to work with your compiler and assembler.

The .asm files in the 32_vc package all include the cpp.inc file. This file defines what the actual names of various C++ global variables are. Some compilers, such as Borland C++, keep the names the same (prefixing an underscore), so that for example the variable Base can be accessed as _Base in assembler programs. Other compilers, such as Microsoft Visual C++, "mangle" the global variable names so that for example Base can be accessed as ?Base@@3IA in assembler programs.

Depending on your compiler the mangled names could be anything, so you can specify them in the cpp.inc file. The assembler source code uses underscore prefixed variable names.

To figure out the mangled names you need to write a dummy C++ program that references all the variables and have the compiler generate assembler source for the dummy program. Then find the variable names in the generated assembly code.

Last updated: October 22nd, 2000

Back to the apfloat page.