1952e2e1c1
These bits are taken from the FSF anoncvs repo on 1-Feb-2002 08:20 PST.
332 lines
13 KiB
Plaintext
332 lines
13 KiB
Plaintext
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
|
@c 1999, 2000, 2001 Free Software Foundation, Inc.
|
|
@c This is part of the GCC manual.
|
|
@c For copying conditions, see the file gcc.texi.
|
|
|
|
@node VMS
|
|
@chapter Using GCC on VMS
|
|
|
|
@c prevent bad page break with this line
|
|
Here is how to use GCC on VMS@.
|
|
|
|
@menu
|
|
* Include Files and VMS:: Where the preprocessor looks for the include files.
|
|
* Global Declarations:: How to do globaldef, globalref and globalvalue with
|
|
GCC.
|
|
* VMS Misc:: Misc information.
|
|
@end menu
|
|
|
|
@node Include Files and VMS
|
|
@section Include Files and VMS
|
|
|
|
@cindex include files and VMS
|
|
@cindex VMS and include files
|
|
@cindex header files and VMS
|
|
Due to the differences between the filesystems of Unix and VMS, GCC
|
|
attempts to translate file names in @samp{#include} into names that VMS
|
|
will understand. The basic strategy is to prepend a prefix to the
|
|
specification of the include file, convert the whole filename to a VMS
|
|
filename, and then try to open the file. GCC tries various prefixes
|
|
one by one until one of them succeeds:
|
|
|
|
@enumerate
|
|
@item
|
|
The first prefix is the @samp{GNU_CC_INCLUDE:} logical name: this is
|
|
where GNU C header files are traditionally stored. If you wish to store
|
|
header files in non-standard locations, then you can assign the logical
|
|
@samp{GNU_CC_INCLUDE} to be a search list, where each element of the
|
|
list is suitable for use with a rooted logical.
|
|
|
|
@item
|
|
The next prefix tried is @samp{SYS$SYSROOT:[SYSLIB.]}. This is where
|
|
VAX-C header files are traditionally stored.
|
|
|
|
@item
|
|
If the include file specification by itself is a valid VMS filename, the
|
|
preprocessor then uses this name with no prefix in an attempt to open
|
|
the include file.
|
|
|
|
@item
|
|
If the file specification is not a valid VMS filename (i.e.@: does not
|
|
contain a device or a directory specifier, and contains a @samp{/}
|
|
character), the preprocessor tries to convert it from Unix syntax to
|
|
VMS syntax.
|
|
|
|
Conversion works like this: the first directory name becomes a device,
|
|
and the rest of the directories are converted into VMS-format directory
|
|
names. For example, the name @file{X11/foobar.h} is
|
|
translated to @file{X11:[000000]foobar.h} or @file{X11:foobar.h},
|
|
whichever one can be opened. This strategy allows you to assign a
|
|
logical name to point to the actual location of the header files.
|
|
|
|
@item
|
|
If none of these strategies succeeds, the @samp{#include} fails.
|
|
@end enumerate
|
|
|
|
Include directives of the form:
|
|
|
|
@example
|
|
#include foobar
|
|
@end example
|
|
|
|
@noindent
|
|
are a common source of incompatibility between VAX-C and GCC@. VAX-C
|
|
treats this much like a standard @code{#include <foobar.h>} directive.
|
|
That is incompatible with the ISO C behavior implemented by GCC: to
|
|
expand the name @code{foobar} as a macro. Macro expansion should
|
|
eventually yield one of the two standard formats for @code{#include}:
|
|
|
|
@example
|
|
#include "@var{file}"
|
|
#include <@var{file}>
|
|
@end example
|
|
|
|
If you have this problem, the best solution is to modify the source to
|
|
convert the @code{#include} directives to one of the two standard forms.
|
|
That will work with either compiler. If you want a quick and dirty fix,
|
|
define the file names as macros with the proper expansion, like this:
|
|
|
|
@example
|
|
#define stdio <stdio.h>
|
|
@end example
|
|
|
|
@noindent
|
|
This will work, as long as the name doesn't conflict with anything else
|
|
in the program.
|
|
|
|
Another source of incompatibility is that VAX-C assumes that:
|
|
|
|
@example
|
|
#include "foobar"
|
|
@end example
|
|
|
|
@noindent
|
|
is actually asking for the file @file{foobar.h}. GCC does not
|
|
make this assumption, and instead takes what you ask for literally;
|
|
it tries to read the file @file{foobar}. The best way to avoid this
|
|
problem is to always specify the desired file extension in your include
|
|
directives.
|
|
|
|
GCC for VMS is distributed with a set of include files that is
|
|
sufficient to compile most general purpose programs. Even though the
|
|
GCC distribution does not contain header files to define constants
|
|
and structures for some VMS system-specific functions, there is no
|
|
reason why you cannot use GCC with any of these functions. You first
|
|
may have to generate or create header files, either by using the public
|
|
domain utility @code{UNSDL} (which can be found on a DECUS tape), or by
|
|
extracting the relevant modules from one of the system macro libraries,
|
|
and using an editor to construct a C header file.
|
|
|
|
A @code{#include} file name cannot contain a DECNET node name. The
|
|
preprocessor reports an I/O error if you attempt to use a node name,
|
|
whether explicitly, or implicitly via a logical name.
|
|
|
|
@node Global Declarations
|
|
@section Global Declarations and VMS
|
|
|
|
@findex GLOBALREF
|
|
@findex GLOBALDEF
|
|
@findex GLOBALVALUEDEF
|
|
@findex GLOBALVALUEREF
|
|
GCC does not provide the @code{globalref}, @code{globaldef} and
|
|
@code{globalvalue} keywords of VAX-C@. You can get the same effect with
|
|
an obscure feature of GAS, the GNU assembler. (This requires GAS
|
|
version 1.39 or later.) The following macros allow you to use this
|
|
feature in a fairly natural way:
|
|
|
|
@smallexample
|
|
#ifdef __GNUC__
|
|
#define GLOBALREF(TYPE,NAME) \
|
|
TYPE NAME \
|
|
asm ("_$$PsectAttributes_GLOBALSYMBOL$$" #NAME)
|
|
#define GLOBALDEF(TYPE,NAME,VALUE) \
|
|
TYPE NAME \
|
|
asm ("_$$PsectAttributes_GLOBALSYMBOL$$" #NAME) \
|
|
= VALUE
|
|
#define GLOBALVALUEREF(TYPE,NAME) \
|
|
const TYPE NAME[1] \
|
|
asm ("_$$PsectAttributes_GLOBALVALUE$$" #NAME)
|
|
#define GLOBALVALUEDEF(TYPE,NAME,VALUE) \
|
|
const TYPE NAME[1] \
|
|
asm ("_$$PsectAttributes_GLOBALVALUE$$" #NAME) \
|
|
= @{VALUE@}
|
|
#else
|
|
#define GLOBALREF(TYPE,NAME) \
|
|
globalref TYPE NAME
|
|
#define GLOBALDEF(TYPE,NAME,VALUE) \
|
|
globaldef TYPE NAME = VALUE
|
|
#define GLOBALVALUEDEF(TYPE,NAME,VALUE) \
|
|
globalvalue TYPE NAME = VALUE
|
|
#define GLOBALVALUEREF(TYPE,NAME) \
|
|
globalvalue TYPE NAME
|
|
#endif
|
|
@end smallexample
|
|
|
|
@noindent
|
|
(The @code{_$$PsectAttributes_GLOBALSYMBOL} prefix at the start of the
|
|
name is removed by the assembler, after it has modified the attributes
|
|
of the symbol). These macros are provided in the VMS binaries
|
|
distribution in a header file @file{GNU_HACKS.H}. An example of the
|
|
usage is:
|
|
|
|
@example
|
|
GLOBALREF (int, ijk);
|
|
GLOBALDEF (int, jkl, 0);
|
|
@end example
|
|
|
|
The macros @code{GLOBALREF} and @code{GLOBALDEF} cannot be used
|
|
straightforwardly for arrays, since there is no way to insert the array
|
|
dimension into the declaration at the right place. However, you can
|
|
declare an array with these macros if you first define a typedef for the
|
|
array type, like this:
|
|
|
|
@example
|
|
typedef int intvector[10];
|
|
GLOBALREF (intvector, foo);
|
|
@end example
|
|
|
|
Array and structure initializers will also break the macros; you can
|
|
define the initializer to be a macro of its own, or you can expand the
|
|
@code{GLOBALDEF} macro by hand. You may find a case where you wish to
|
|
use the @code{GLOBALDEF} macro with a large array, but you are not
|
|
interested in explicitly initializing each element of the array. In
|
|
such cases you can use an initializer like: @code{@{0,@}}, which will
|
|
initialize the entire array to @code{0}.
|
|
|
|
A shortcoming of this implementation is that a variable declared with
|
|
@code{GLOBALVALUEREF} or @code{GLOBALVALUEDEF} is always an array. For
|
|
example, the declaration:
|
|
|
|
@example
|
|
GLOBALVALUEREF(int, ijk);
|
|
@end example
|
|
|
|
@noindent
|
|
declares the variable @code{ijk} as an array of type @code{int [1]}.
|
|
This is done because a globalvalue is actually a constant; its ``value''
|
|
is what the linker would normally consider an address. That is not how
|
|
an integer value works in C, but it is how an array works. So treating
|
|
the symbol as an array name gives consistent results---with the
|
|
exception that the value seems to have the wrong type. @strong{Don't
|
|
try to access an element of the array.} It doesn't have any elements.
|
|
The array ``address'' may not be the address of actual storage.
|
|
|
|
The fact that the symbol is an array may lead to warnings where the
|
|
variable is used. Insert type casts to avoid the warnings. Here is an
|
|
example; it takes advantage of the ISO C feature allowing macros that
|
|
expand to use the same name as the macro itself.
|
|
|
|
@example
|
|
GLOBALVALUEREF (int, ss$_normal);
|
|
GLOBALVALUEDEF (int, xyzzy,123);
|
|
#ifdef __GNUC__
|
|
#define ss$_normal ((int) ss$_normal)
|
|
#define xyzzy ((int) xyzzy)
|
|
#endif
|
|
@end example
|
|
|
|
Don't use @code{globaldef} or @code{globalref} with a variable whose
|
|
type is an enumeration type; this is not implemented. Instead, make the
|
|
variable an integer, and use a @code{globalvaluedef} for each of the
|
|
enumeration values. An example of this would be:
|
|
|
|
@example
|
|
#ifdef __GNUC__
|
|
GLOBALDEF (int, color, 0);
|
|
GLOBALVALUEDEF (int, RED, 0);
|
|
GLOBALVALUEDEF (int, BLUE, 1);
|
|
GLOBALVALUEDEF (int, GREEN, 3);
|
|
#else
|
|
enum globaldef color @{RED, BLUE, GREEN = 3@};
|
|
#endif
|
|
@end example
|
|
|
|
@node VMS Misc
|
|
@section Other VMS Issues
|
|
|
|
@cindex exit status and VMS
|
|
@cindex return value of @code{main}
|
|
@cindex @code{main} and the exit status
|
|
GCC automatically arranges for @code{main} to return 1 by default if
|
|
you fail to specify an explicit return value. This will be interpreted
|
|
by VMS as a status code indicating a normal successful completion.
|
|
Version 1 of GCC did not provide this default.
|
|
|
|
GCC on VMS works only with the GNU assembler, GAS@. You need version
|
|
1.37 or later of GAS in order to produce value debugging information for
|
|
the VMS debugger. Use the ordinary VMS linker with the object files
|
|
produced by GAS@.
|
|
|
|
@cindex shared VMS run time system
|
|
@cindex @file{VAXCRTL}
|
|
Under previous versions of GCC, the generated code would occasionally
|
|
give strange results when linked to the sharable @file{VAXCRTL} library.
|
|
Now this should work.
|
|
|
|
A caveat for use of @code{const} global variables: the @code{const}
|
|
modifier must be specified in every external declaration of the variable
|
|
in all of the source files that use that variable. Otherwise the linker
|
|
will issue warnings about conflicting attributes for the variable. Your
|
|
program will still work despite the warnings, but the variable will be
|
|
placed in writable storage.
|
|
|
|
@cindex name augmentation
|
|
@cindex case sensitivity and VMS
|
|
@cindex VMS and case sensitivity
|
|
Although the VMS linker does distinguish between upper and lower case
|
|
letters in global symbols, most VMS compilers convert all such symbols
|
|
into upper case and most run-time library routines also have upper case
|
|
names. To be able to reliably call such routines, GCC (by means of
|
|
the assembler GAS) converts global symbols into upper case like other
|
|
VMS compilers. However, since the usual practice in C is to distinguish
|
|
case, GCC (via GAS) tries to preserve usual C behavior by augmenting
|
|
each name that is not all lower case. This means truncating the name
|
|
to at most 23 characters and then adding more characters at the end
|
|
which encode the case pattern of those 23. Names which contain at
|
|
least one dollar sign are an exception; they are converted directly into
|
|
upper case without augmentation.
|
|
|
|
Name augmentation yields bad results for programs that use precompiled
|
|
libraries (such as Xlib) which were generated by another compiler. You
|
|
can use the compiler option @samp{/NOCASE_HACK} to inhibit augmentation;
|
|
it makes external C functions and variables case-independent as is usual
|
|
on VMS@. Alternatively, you could write all references to the functions
|
|
and variables in such libraries using lower case; this will work on VMS,
|
|
but is not portable to other systems. The compiler option @samp{/NAMES}
|
|
also provides control over global name handling.
|
|
|
|
Function and variable names are handled somewhat differently with G++.
|
|
The GNU C++ compiler performs @dfn{name mangling} on function
|
|
names, which means that it adds information to the function name to
|
|
describe the data types of the arguments that the function takes. One
|
|
result of this is that the name of a function can become very long.
|
|
Since the VMS linker only recognizes the first 31 characters in a name,
|
|
special action is taken to ensure that each function and variable has a
|
|
unique name that can be represented in 31 characters.
|
|
|
|
If the name (plus a name augmentation, if required) is less than 32
|
|
characters in length, then no special action is performed. If the name
|
|
is longer than 31 characters, the assembler (GAS) will generate a
|
|
hash string based upon the function name, truncate the function name to
|
|
23 characters, and append the hash string to the truncated name. If the
|
|
@samp{/VERBOSE} compiler option is used, the assembler will print both
|
|
the full and truncated names of each symbol that is truncated.
|
|
|
|
The @samp{/NOCASE_HACK} compiler option should not be used when you are
|
|
compiling programs that use libg++. libg++ has several instances of
|
|
objects (i.e. @code{Filebuf} and @code{filebuf}) which become
|
|
indistinguishable in a case-insensitive environment. This leads to
|
|
cases where you need to inhibit augmentation selectively (if you were
|
|
using libg++ and Xlib in the same program, for example). There is no
|
|
special feature for doing this, but you can get the result by defining a
|
|
macro for each mixed case symbol for which you wish to inhibit
|
|
augmentation. The macro should expand into the lower case equivalent of
|
|
itself. For example:
|
|
|
|
@example
|
|
#define StuDlyCapS studlycaps
|
|
@end example
|
|
|
|
These macro definitions can be placed in a header file to minimize the
|
|
number of changes to your source code.
|