 |
EP/IX software porting guide
1) Preface
The C compiler shipped with Control Data's version of UNIX and the optional
C compiler can sometimes be picky about the source you want to compile.
This has mainly 2 reasons:
1) These are MIPS C-Compilers (and they are prawn
to failure)
2) EP/IX is a hybrid. That means, it can either
act like a SysV UNIX or a BSD 4.3 UNIX. Thus it has different libraries and
different header files for each system type.
This guide should give a short introduction on how to port software to the
EP/IX operating system. It is not a replacement for reading manpages
or documentation.
2) Problem with the hybridness
As the EP/IX operating system can act as a BSD 4.3 system or as a System V,
there can be some problems with the compiler, because there are bsd43 specific
header files / libraries and SysV ones.
You can switch the system type used by the compiler by specifying the
-systype bsd43 - or - -systype svr3 - or
-systype svr4 flag.
If you specify no flags, the system will default to svr4 as system type.
Should the -systype option not work, because the compiler reports:
cc: Error: only systype svr4 allowed
select the system type by just specifying the according bsd (or whatever)
compiler by setting:
CC=/usr/bsd43/bin/cc
before configuring or in the Makefile.
The system types to specify for the configure scripts (if not detected
automatically) are:
mips-mips-riscos2bsd43 - or -
mips-mips-riscos2svr3 - or mips-mips-riscos2svr4.
For normal compilations I recommend ommiting the -systype flag, as the
svr4 system type is implemented best.
The system specific header files are found in:
/usr/$systype/usr/include, and the
system sprcific libraries are found in: /usr/$systype/usr/lib.
The shared header files / libraries are found in /usr/include or /usr/lib, where/usr/include is a symlink to /usr/share/include, and /usr/lib to /usr/var/lib.
3) Problem with 2 kinds of compilers
The EP/IX operating system has a compiler installed by default - on EP/IX
2.2.1, this is cc v3.11 (later refered to as cc3.11).
We have an optional product installed, called "ANSI C 3.18" (cc3.18, or just
cc as this is the default cc).
The latter is needed to compile more sophisticated programs, where the former
one is a plain K&R-C compiler.
Although you would almost always use cc3.18 (as it's the default CC) there are
situations where you should use the cc3.11.
One example is the "copytape" program. This is a very old (1978), but simple
tool written in K&R-C. The cc3.18 had strange problems compiling this program,
but cc3.11 was just fine to use.
GZip for example did also compile with cc3.11 but not with cc3.18.
I remember situations where I had to compile parts of the program with cc3.11
and parts with cc3.18, but this is rather annoying and happens not too often
(luckily).
If you get strange errors when compiling source, such as:
offset/length mismatch between vreg and reference,
you better take the other compiler, as this is an internal compiler error, which
can only be solved by rewriting the effected codepart.
You can activate the usage of cc3.11 by setting:
CC=/usr/bin/cc3.11
before starting the configure script, or by setting the appropriate CC line in
the Makefile.
4) Configure / Make problems
When looking at the output of ./configure --help, you will probably
notice that there are a lot of options to pass to configure in order to
make the source suite your compiler.
If the configure script seems to hang when "checking dependencies", you can
either try setting CC=/usr/bin/cc3.11 (although this will compile
the whole packages with the cc3.11 compiler)
Another way (if you're sure you have the dependencies) is to remove the
dependency check completely in the configure script. To do this, edit the
script, find the appropriate lines (just search for the output you get on the
screen when it hangs), and comment them out (# sign).
Remember: Once the configure script has created its files (Makefiles
and config.h), you can better tweak on the used options.
We installed a pretty recent version of GNU make on the machine, so "Makefile"
syntax should not cause problems (as it sometimes does with the original
"make").
Sometimes you may experience problems, when the program uses functions which
you either do not have, or the program redefines functions which you do have.
This often happens with all kind of signal-handling-functions.
A good start is to look at the file config.h in your source-root.
There are parameters which define whether a function is available on your
system or not.
These parameters are set as Preprocessor-Directives, for example:
#define HAVE_SIGINTERRUPT 1
means, that the siginterrupt function is available on your system.
If this would be set to zero, there are several possibilities depending on
the code you try to compile.
Either the code has a siginterrupt function itself, which it uses in case
the function is not available on the system, or it has a workaround to use
instead of the siginterrupt function.
Let's assume the configure script misleadingly detected the absence of the
siginterrupt function and thus set HAVE_SIGINTERRUPT to 0, and the author of
the code wrote a tiny siginterrupt() function itself.
This would produce errors telling you that siginterrupt() is already defined.
Probably you would also get an error telling you that there are conflicting
prototypes for the siginterrupt() function, because the author, for example
implemented the first argument (sig) as a short, but the system implements
it as an int. So the author's siginterrupt() prototype probably looks like:
int siginterrupt(short sig, int flag), while the system's one looks like:
int siginterrupt(int sig, int flag)
In this case, just setting HAVE_SIGINTERRUPT to 1 in config.h would fix the
problem.
There might be some problems with a function you have being reported as
undeclared. This is most likely because the header file in which the prototype
is defined is not included.
Determine the header file in which the prototype is defined by either looking
in the manpage or (as not all manpages specify the in which header file it is
defined) grep the include directories (the shared and sysspecific ones (see above)).
If you have found the header file, look if the appropriate include line is
already in the source code, but not active, because it is not parsed because
of #ifdef preprocessor directives.
For example the utime() function is reported as not defined, but the source
code reads: #include .
When having a closer look, you see that this directive (along with some others)
is in a #ifdef HAVE_UTIME_H clause.
Looking into the config.h file you will see that HAVE_UTIME_H is not defined.
You will probably see a line looking like:
/* #undef HAVE_UTIME_H */
Add an additional line reading:
#define HAVE_UTIME_H 1
below this line and try compiling again.
5) Problems with the linker
You might get unresolved symbols such as:
__ull_rshift - or - __ll_lshift - or - __ull_to_d.
To avoid this problem, you have to link against libdw or libelf.
Achieve this by setting CFLAGS=-ldw or CFLAGS=-lelf before
configuring the package, or add it manually to the Makefile (usually there
is a variable called CFLAGS where you can add it to.
For all the geeks telling me that CFLAGS is not exactly the right place to
set it, because it is a linker flag: I know, but there are some Makefiles /
configure scripts who silently ignore the LDFLAGS variable...
If you set it as a CFLAG, the compiler will ignore it when not calling the
linker (for example when compiling to an object file using -c) and
pass it to the linker when linking the objects afterwards.
Probably you get some errors because of some symbols not being able to be
resolved. To fix this, first determine in which library they are included.
This can be quickly achieved by using nm(1).
For example you get the following error when trying to compile a program:
ld:
Unresolved:
socket
Now you need to determine which library includes the socket() function.
This is done by issuing the following command:
for i in /usr/lib/*.a; do nm $i | grep socket; done
This will output (among others) the following lines:
Symbols from libsocket.a[socket.o]:
[...]
[1] | 0| |Proc |end=3 int |Text | socket
Now you know that the symbol is defined in "libsocket.a".
The only thing you have to do now is tell the linker to include this file by
passing "-lsocket" as a flag to your linker (or linking C Compiler), be either
specifying is as a LDFLAG (official way, not every Makefile/configure
script supports it) or as a CFLAG.
If you can't find the symbol in /usr/lib, search the system-specific library
directories (for example /usr/bsd43/usr/lib)
If you get errors about a library not being found, just remove the according
entries from the Makefile.
Many programs, for example, include -lsun and -lbsd per default on SysV systems
without checking if they exist. Just remove those entries then.
24.08.2003 - Freddy Meerwaldt
(feedback appreciated)
|