Next: compile_unix Up: User Function Help File Previous: compile_dos   Contents

compile_mac

Usage:
Type userfunhelp(compile_mac) for information on how to compile a user
  function for use with Macintosh versions of MacAnova.



Keywords: user functions, compiling
This topic provides some details about compiling a user function for use
with the Macintosh versions of MacAnova.  It assumes the Metrowerks
CodeWarrior compiler is used.

The Macintosh is a bit more complicated than other platforms, since
there are two kinds of processors (PPC and 68K) to support.  The 68K
case is further complicated by the fact that code may or may not
compiled to use a 68881 math coprocessor.

In coding a Macintosh user function, if you make a pointer by
dereferencing a handle argument, you should dereference it again after
calling back to a function internal to MacAnova since its location in
memory may have been changed by the call back.

User functions and arginfo functions are compiled into code resources
in files of type 'rsrc'.  PPC resources must have resource type
'MVPP'; 68K resources not requiring a 68881 coprocessor must have
resource type 'MV6n'; and 68K resources requiring a coprocessor must
have resource type 'MV6c'.

User() accesses the resources themselves by name.  The resource for a
function should have the name, say 'foo', you will give in your User()
call or 'arginfo_foo.  All resources of the same type should in a file
should have distinct resource numbers, say 4000, 4001, ... .  A PPC user
function may be in a resource with a different name, in which case you
have to provide the name of the resource using User(funName,
resource:resName, ...).

Source files for both PPC and 68K user functions must have a function
named 'main', plus possibly other functions.

PPC code resources, but not 68K ones, can have additional entry points,
usually an arginfo function, but occasionally other user functions.

                      Macintosh 68K user functions
For 68K user functions, it is necessary to set 68000 register A4 so
that global variables will be found.  Using CodeWarrior, this is
accomplished by including
  EnterCodeResource();
immediately after declaring local variables and before any reference
to global variables, and including
  ExitCodeResource();
immediately before returning.  When C macro MACINTOSH is defined but
powerc is not, macros EnterCode() and ExitCode() defined in header file
Userfun.h expand to EnterCodeResource() and ExitCodeResource().
Otherwise they expand to nothing.

68K code resources have just one entry point which must be named
'main', so a single resource cannot include both a user function and
its arginfo function.  However, the Codewarrior compiler has a "Merge
to file" option that allows you to add to an existing resource file
the resource created when compiling a function.

                           PPC User Functions
PPC code resources may have multiple entry points which are taken from
the names of global RoutineDescriptor variables in the source.  Their
names should similar to 'goo' and 'arginfo_goo' or 'fooeval' and
'arginfo_fooeval'.  The name given to the function that actually codes
the user function should be 'main' and the name given to the function
with the arginfo function code should be something like 'main_info'
different from the name given to the arginfo.  Here are typical
RoutineDescriptor declarations.

  RoutineDescriptor goo =
      BUILD_ROUTINE_DESCRIPTOR(uppMainEntryProcInfo04, main);
  RoutineDescriptor arginfo_goo =
     BUILD_ROUTINE_DESCRIPTOR(uppArgInfoEntryProcInfo, info_main);

Argument uppMainEntryProcInfo04 is appropriate for a user function
expecting 4 arguments, including the call back function list.  For a
function expecting 5 arguments, use uppMainEntryProcInfo05, and so on.

Since you will normally use the funName given in the User("funName",...)
call for both the name of the resource and the name of the
RoutineDescriptor entry point, you will ordinarily include only one user
function (and its arginfo function) in a resource.  If you include more
than one user function in a resource, you must use keyword phrase
'resource:Resname' to specify the resource name.  An arginfo function
must be in the same resource as its user function.

                   Setting up Macintosh 68K projects
Here is how to set things up to create a 68K code file with resources
'fooeval' and 'arginfo_fooeval' based on file fooeval.c listed in topic
c_macros.  This has been written in such a way that only one of fooeval
or arginfo_fooeval will be compiled, depending on the value of C macro
WHICHFUN.

(1) Create two MacOS 68K CodeWarrior project files, one for fooeval and
the other for arginfo_fooeval.  They should both have source files
fooeval.c, Userfun.h and dynload.h.  See below for library files needed.

(1.a) Specify Code Resource for the project type for both projects.

(1.a) For both projects specify resource type 'rsrc' and the same resource
file, say, Fooeval.rez as Project options.  The fooeval project should
specify 'fooeval' and 4000 as the resource name and number.  The
arginfo_fooeval project should specify 'arginfo_fooeval' and 4001 as the
resource name and number, and should have Merge to File checked.  The
resource numbers are arbitrary but should be different.  The resource
type should be 'MV6c' or 'MV6n', depending on whether you are compiling
to use a 68881 math coprocessor.

(1.b) Both projects should specify processor options 68020 Codegen, 4 byte
ints, 8 byte doubles and far data.  If you are compiling to use a math
coprocess, also specify 68881 Codegen,

(1.c) Set linker options Link Single Segment.

(1.d) For a user function making call backs (as does fooeval), C/C++
language option MPW Newlines should be checked.

(1.e) If you reference any C library functions such as strcpy (fooeval
does not) you will need library file 'ANSIFa(N/4i/8d)C.A4.68K.Lib' and
possibly 'MathLib68K Fa(4i/8d).A4.Lib' ('ANSIFa(N/4i/F/8d)C.A4.68K.Lib'
and 'MathLib68K Fa(4i/f/8d).A4.Lib' if compiling to use a 68881 math
comprocessor).  You may also need MacOS.lib.  For example, all three
libraries are needed if you use the library version of sprintf.  None is
required for fooeval.c as written.

(1.f)  Both projects should specify a prefix file, say Userfun.pch,
containing at least the following:
 #define MACINTOSH
 #define MW_CW

(2) Edit fooeval.c to define C macro WHICHFUN as 1 and compile the
fooeval project.

(3) Re-edit fooeval.c to define WHICHFUN as 2 and compile the
arginfo_fooeval project.

You end up with one resource file 'Fooeval.rez' containing resources
'fooeval' and 'arginfo_fooeval'.

                   Setting up Macintosh PPC projects
Here is how to set up a CodeWarrior project to compile a PPC version of
fooeval using source file fooeval.c listed in topic c_macros.

(1)  Create a MacOS PPC project with source files fooeval.c, Userfun.h
and dynload.h and library files MPCRuntime.Lib and InterfaceLib.  See
below for other library files.

(1.a) Specify Code Resource for the project type

(1.b) Specify resource file 'fooevalppc.rez' of type 'rsrc'.  The
resource type must be 'MVPP'.  The resource name should be 'fooeval'.
The resource number should be different from any other PPC user
functions you might be using simultaneously.

(1.c) Specify Main entry 'main' for the PPC linker.

(1.d) For a user function making call backs (as does fooeval), C/C++
language option MPW Newlines should be checked.

(1.e) If you reference any C library functions such as strcmp you should
add libraries 'ANSI C.PPC.Lib' and 'MathLib' and file 'console.stubs.c'.

(2) Compile the fooeval PPC project.

You end up with a resource file fooevalppc.rez containing resource
'foo'.  You load it into MacAnova by loadUser("fooevalppc.rez") and
execute it by, say, User("fooeval","exp(-x^2/2)/sqrt(2*PI)").


Gary Oehlert 2003-01-15