These class libraries may contain embedded C-code; either for performance reasons or to interface to other C-libraries.
This document will give you information and a step-by-step guide on how to compile your classes to machine code, how to create & package class libraries for distribution and how to include such a binary class library in your system.
Notice, that beside speed advantage and the ability to include inline C code, the semantic of binary compiled code is equivalent to that of interpreted bytecode. All language features (such as context handling, block handling, stack unwinding and exception handling) are available and perform transparent whether methods are compiled statically or interpreted (or compiled dynamically from bytecode by the JIT translator).
Compiled object files are bigger than bytecode files. Therefore, the memory
requirements are bigger if machine compiled code is used - at least if a single
Smalltalk/X application is running.
However, on systems which support shared
libraries, this code is shared amongst all those applications (which is not
the case with interpreted bytecode), therefore, depending on how many such
applications are executing, there may be a memory advantage - even with larger
object files.
Also, it must be considered, that statically compiled machine code is located
in the code segment of the program - i.e. it will only paged into the
physical memory when needed and requires much less memory in the objectMemory
area - therefore, even when requiring more memory, there is less memory
required in many situations.
In addition, static compiled machine code is not loaded into the objectMemory, and therefore not to be considered by the garbage collector. Especially for big projects, this may reduce GC overhead considerably.
Another positive aspect of statically compiled machine code (in contrast to
just-in-time compilation) is the guaranteed maximum response time,
in which an invoked method is called.
If methods are compiled at
execution time, chances are non-zero, that some method(s) have to be compiled
on the first call, and an additional delay is introduced.
(unless you have visited all methods previously and the code cache is big
enough to hold all methods
- but then, the dynamic memory requirements of
a just-in-time system are in the same order
as with static compilation ...).
This defined behavior is the main reason for industrial users to
prefer static over dynamic compilation.
Configuration files
Stc can be used like any other (batch-) compiler by
calling it directly from the UNIX/DOS command line. However, since there are
many possible command line arguments and configuration settings that have to
be managed, it is easier and suggested that you use Makefiles
to compile classes and build systems.
The system as delivered includes shell scripts and make rules to
handle different architectures and configurations.
To avoid the need for rewriting all Makefiles for different architectures,
all relevant Makefiles
are created from prototypes;
these are named "Make.proto
"; one is found in every
directory.
(Notice: this is similar to what imake does with Imakefiles)
The configurator (called "CONFIG
") reads these prototypes and creates
the actual Makefiles
depending on the choosen configuration.
To do so, the configurator uses so called config and rule files, which define all architecture and configuration dependent settings.
Rule files are found in the "rules
" subdirectory;
config files in subdirectories of "configurations
".
You don't have to care for the rule files normally - they are independent
of the configuration.
The config files are organized by machine architecture and configuration.
They define things like C-compiler flags, include paths,
classes to be included in the building process etc.
In addition, package-lists are used to control which classLibraries are to
be built into the system.
These are found in the "configurations/PACKS
" subdirectory.
Package lists define which objects should be included,
config files define how these objects are built.
The generic paths of config files looks like:
For example, the linux definitions for linux versions above 1.0,
with C-optimizer turned on and GL-simulator classes included
are taken from:
configurations/COMMON/defines
configurations/architecture/COMMON/defines
configurations/architecture/configuration/defines
the definitions used for a configuration without GL classes is in:
configurations/COMMON/defines
configurations/linux/COMMON/defines
configurations/linux/linux1.x-opt-vgl/defines
and so on.
The name of the directory has no semantic meaning - its only for human
readers (I could have called them "linux-1", "linux-2" etc).
configurations/COMMON/defines
configurations/linux/COMMON/defines
configurations/linux/linux1.x-opt/defines
When a smalltalk is built, the name of the configuration is stamped into the
executable - look at the launchers
aboutBox, to see the configuration
of your system.
When "Makefiles
" are built, all defines are simply concatenated
in the above order - this allows definitions from the COMMON config
files to be redefined.
"CONFIG
" needs the name of the architecture, the name of a package-list
and the name of the configuration to create the "Makefiles
".
Once built, "Makefiles
" know from which configuration they
were created and know how to recreate "Makefiles
".
You should therefore never copy Makefiles
to other architectures,
or use the same directory for multiple platforms (i.e. do not NFS-mount
to another platform and make there).
Finally, do not edit the Makefiles
, since they may be recreated and your
changes will be lost. Only edit "Make.proto
" files.
Summary:
Makefiles
for the very first time,
use:
CONFIG
architecture package configuration
This creates all Makefiles
(recursively in all directories)
for the given architecture and configuration.
To get available configurations listed (if you are uncertain, which architectures and/or configurations are available) call it without argument(s).
Makefiles
include a rule to rebuild themself.
use:
to recreate a singlemake mf
make Makefiles
Makefile
or all submakefiles.
make mf; make Makefiles
" in the top directory.
make mf
" in that directory).
configurations
/architecture"
defines
" in this directory.
Take any existing "defines
" file from the same architecture to
start with.
CONFIG
architecture package mysystem"
to recursively create new Makefiles
.
The system as delivered is already setup correctly for your machine - therefore, you may skip reading the next chapters, unless you plan to fiddle around with the C-compilers flag settings or want to use another compiler.
Remember, that for all of the following definitions, useful defaults
are setup in
"configurations/COMMON/defines"
and "configurations/arch/COMMON/defines"
.
In normal situations, no changes are required.
However, if you need anything to be changed, do so in your configuration
specific config file; never in a common one.
Since later definitions overwrite previous ones, you can always change
things by adding a define to the private defines file.
The following is a short extract - there are many more things that
can (but are not required to) be changed:
The common configuration files define things like relative path names
(within the ST/X file hierarchy), make rules etc.
CC= defines the c-compilers name
(not recommended to change)
O=.o extension for object files
(not recommended to change;
- usually ".o" on UNIX, ".obj" on MSDOS)
#
# for "make install" only:
#
DESTBINDIR= where are binaries to be installed
DESTLIBDIR= where are libraries to be installed
DESTINCLDIR= where are include files to be installed
DESTMANDIR= where are man pages to be installed
#
# for additional directories and libs (see below)
#
OTHERLIBS= specifies names of other (c-)libraries to be
included in the final link
#
# Xlib stuff
#
XINCLUDE= path to X include files
LIBX= whats the name of your X-lib
LIBXEXT= whats the name of your Xext-lib
X_LIB_DIR= path to where X-libraries are found
#
# stc compiler flags
#
STCCONFOPT= arguments passed to stc
#
# c compiler flags and (preprocessor) defines
#
DEFS= addidtional defines passed to the c-compiler
XDEFS= like DEFS, for XWindow-related files/classes
OPT= addidtional optimizer flags passed to the c-compiler
(typically something like -O6 -m486 ...)
#
# additional individual class objects
#
EXTRA_CLASSES= extra individual compiled classes to be
included in the final link. These are classes
that do not come from class libraries.
EXTRA_OBJ= the corresponding object file names
Most important (and of general interest) are the following definitions,
which can be used in "Make.proto
" files:
INCLUDE= the relative path to the include directory
STC= the relative path to the stc compiler
(usually: $(TOP)/stc/stc, but may be redefined to refer
to an stc in some other directory)
LIBBASICDIR= the name of the directory where the basic classes
reside. Similar definitions are found for all the
other standard packages.
BIN_O= the suffix of individual binary object files (cc targets)
("
.o
" with unix; different on other architectures).
Always use this in your "Make.proto
" files
to remain architecture independent.
O_EXT= the suffix of class library files (stx packages)
(".o
" or ".obj
" on systems
which do NOT support shared libraries;
".so
" or ".sl
" on systems which do)
Whats in a package file
This section can be skipped - it is only of interest if
if you want to change the set of libraries & modules which are
included in the smalltalk executable.
As mentioned above, the package files (in "configurations/PACKS
")
control which class libraries and additional C libraries are to be
built and included in the resulting executable.
The entries found there are:
The above information may not be up to date, when you read this document.
WORKSTAT1= name of the primary Display driver class
(typically: XWorkstation)
WORKSTAT2= name of the secondary Display driver class
(typically: GLXWorkstation)
EXTRA_CLASSES= names of additional classes, which
are to be included from individual object
files (not class libraries)
Typically: XWorkstation GLXWorkstat
EXTRA_OBJ= names corresponding object file names
Typically: $(LIBVIEWDIR)/XWorkstat$(BIN_O)
OTHERLIBDIRS= other directories, which the build process
should visit and `make'
CLASSLIBDIRS= directories containing class library sources
and `Make.proto' files to be built.
LIBOBJS= names of classLibrary objects to be included
in the link.
LIBLIST= names of the packages found in above objects.
Typically, these correspond to the file
names, but in rare cases, these names could
differ.
Examine the files found in
configurations/PACKS
for more information.
Recompiling the system in part or fully
Although recompilation of the complete system is easily done with:
that takes hours on some machines. For local changes, you will get a feeling
of what needs to be recompiled. For example, after adding a method to
a class in "
cd TOP
make clobber - to clean everything
make target - make a target system as set by CONFIG
libbasic
", only a recompilation of that class is required
and you can skip over the full remake.
In this case, you can also type:
which is much faster, since not all directories are visited.
cd libbasic
make
cd ../projects/smalltalk
make smalltalk
However, whenever instance variables are added to classes which are subclassed somewhere else, these subclasses have to be recompiled as well (The makefile generator has added a dependency section to your Makefiles - so only subclasses will be recompiled in the full make)
When new source files (i.e. new classes) are added to a classLibrary,
add its name to the "Make.proto
" file
(or regenerate a new one) and type:
the difference is that "
...
cd theDirectoryWhereTheSourceWasAdded
make mf
..
make
...
cd ../projects/smalltalk
make
make smalltalk
" only relinks the
smalltalk executable, while the later "make
" also scans all
directories for ".st"
files
and creates symbolic links in the "source
" subdirectory
(remember: these are required for the browser to find a methods sourcecode).
To recreate the sourcelinks only, use:
(there are corresponding rules to link the bitmap, resource and style files.
...
cd ../projects/smalltalk
make sourceLink
Whats in a Make.proto file
Since all architecture and configuration specific things are handled by the
config files, Make.protos
need not (should not)
include any system dependencies.
Therefore, "Make.proto"
files are rather short.
They only define the name of the library to be created, the subdirectories
(if any) that should be visited and the names of the object
files, which make up the library.
The required defines are:
optional are definitions which change compilation flags:
TOP= defines the position relative to the TOP
directory (see example below)
ALLSUBDIRS= names of subdirectories, where Makefiles
are to be created (if any).
SUBDIRS= names of subdirectories (if any), which should
be visited during the build process.
LIBNAME= name of the class library which is to be
created by this makefile.
(empty, if this is not for a classlib)
all:: default rule; usually, this simply calls
for the 'classLibRule' target, which creates
the required help files, object file(s) and
a prelinked classLibrary (possibly a shared one).
Additional C file targets should go here
OBJS= names all object files which are to be
built and/or included in the classLibrary.
optional but highly recommended rules are:
STCOPT= stc options; defaulted in COMMON/defines
There is usually no need to redefine this in
individual Make.proto files.
STCLOCALOPT= stc options to be used in addition
to standard settings;
additional package or optimization
flags should be given here.
For example: 'STCLOCALOPTS=+optspace3'
For example, the "
clean: a rule to cleanup all intermediate files,
but not the library targets - so that the
executable can be relinked without recompilation.
Typically, all object files are removed here.
clobber: a rule to cleanup everything
Ideally, the directory is left in the state it
had initially.
(Makefiles are usually kept)
Typically, all object files and library files
are removed here.
tar: create a tar file containing the source files,
Make.proto and any additional files for source
code distribution.
# BEGINMAKEDEPEND the "
make mf
" rule will
# ENDMAKEDEPEND insert dependency information in between
those. Always include those two keywords at
the end of your proto file.
Make.proto
" for the basic class library
looks (somewhat) like:
TOP=.. - its directly under TOP
SUBDIRS= - I have no subdirectories to make
LIBNAME=libbasic - thats the name of the classlibrary
STCOPT=$(LIBBASIC_STCOPT) - override default options
(LIBBASIC_STCOPT is +optinline)
STCLOCALOPT=-P(stx:libbasic) \ - define the package of all classes
-warnGlobalAssign \ compiled here, turn off some warnings
+optinline2 and turn on more inlining
all:: classListRule - default rule: create abbrev file
objects, classList and a prelinked
class library
OBJS= Object.$(O) \ - names all object files which are
Boolean.$(O) \ to be created from corresponding .st
... files. Notice the $(O) instead of .o;
This allows the same Make.proto to be
be used on MSDOS and Mac systems (where object
files are named differently).
# BEGINMAKEDEPEND - template for dependencies
# ENDMAKEDEPEND
How to get an initial Make.proto file
There are two useful ways of optaining an initial Make.proto file:
stmkmp
('st-make-makeProto') script, which is
found in the rules
subdirectory.
stmkmp
scans the current directory for smalltalk-source files
(files ending in '.st') and generates a Make.proto
file
for them.
stmkmf
('st-make-makeFile') script, which is also found
in the rules
subdirectory.
The above mentioned stmkmp
generates an initial Makefile
automatically for you.
Creating binary class libraries
The following gives step-by-step information on how to add a new class
library. For all of your new classes, this is the recommended way of
doing things. Adding classes to existing directories may lead to problems
and/or added work whenever a new ST/X release is delivered and installed:
you would have to reedit all of your changed Make.proto files.
Lets assume, that your new library is to be called "libfoo
"
and shall contain the classes called
Foo
, Bar
and Baz
.
libfoo
".
To avoid additional work when new ST/X releases are installed,
please DO NOT create this directory below the ST/X top.
We recommend, that this directory is created beside the ST/X hierarchy,
and suggest the following setup:
someDir/stx/ - home of stx
... libbasic - as delivered
... rules
...
someDir/
This setup will avoid any conflict, when additional classLibraries
are integrated from other vendors, or a new ST/X revision is installed.
(also, note that additional addOn packages
as delivered from eXept (such as ASN1, OSI etc.) will
go into someDir/eXept/...
and not conflict with your files.
After all of this, lets assume that your new directory is called:
and it is locate beside the ST/X tree, which is:
.../yourCompanyName/project1/libfoo
.../stx/...
Notice, that by default, the browser creates the files in your startup
directory (which is usually "projects/smalltalk
");
so you have to manually move the files into "$TOP/libfoo
"
in this case.
A better strategy is to open a project, activate it,
and set its fileout-directory name to "$(TOP)/libfoo
".
Then open a browser in this project and fileOut your classes.
You may put all of your classes into a common category - this allows
easier file out.
Since stc requires that each class is in a separate source file,
the fileOut-category function cannot be used here
(since it creates one huge file containing all classes).
Instead, use fileOut-each, which saves each class in a separate sourcefile.
Alternatively (if you have a SourceCodeManager configured),
check the classes into the repository in the systemBrowser
(possibly into a new module / module-package), open a terminal view (xterm),
and check them out with the 'co' shell command.
Make.proto
",
and change it as required, or use the "stmkmp
" shell script,
which automatically generates a "Make.proto
" for all
files ending in ".st
" found in the current directory.
stmkmp --help
" for its usage).
Stmkmp can only create simple proto files for class libraries - if you need rules for additional c-libraries, you have to edit the generated file manually.
Here is what the output of "stmkmp
" could look like:
The "
#
# required: where are we relative to TOP
#
TOP=..
#
# list subdirectories to visit during make
#
SUBDIRS=
#
# required: the name of the resulting class library
#
LIBNAME=libfoo
#
# required: the module and package definition.
# (for package identification and repository SourceCode access)
#
PACKAGE=yourCompany:project/libfoo
#
# not required: the default is empty
# but defining a package is highly recommended
# (see the ProjectViews browse function ...)
#
STCLOCALOPT=-Pfoo-classes
#
# required: define whats to be done
#
# this says:
# - build all that is required for a class library
# you can edit the Make.proto file and add additional
# targets there.
#
all:: classLibRule
#
# required: what are my objects
#
objs::
Foo.$(O) \
Bar.$(O) \
Baz.$(O)
#
# recommended: cleanup rules
#
clean::
-rm -f *.H
clobber::
-rm -f *.o
#
# dependency rules
# BEGINMAKEDEPEND - do not remove
# ENDMAKEDEPEND - do not remove
stmkmp
" command itself is found in "rules
"
initially; you may want to copy it to "/usr/local/bin
" for public
access.
Notice, that the sourceCode repository can be configured to use different CVS Roots per module, and that the first component (before the colon) is used as module. This means, that the stx repository may be physically different from the repository which holds <yourCompany>.
Makefile
",
so you are ready to enter "make
" now.
Makefile
", if it was not able to
find a path to the TOP directory (because it could not find any configuration
files then ...).
stmkmf --help
" to get a list of options.
If all else fails, use any other existing and valid ST/X "Makefile
":
cd libfoo
make -f
Option (only if you want to extent the basic smalltalk system):
You can also arrange for your directory to be visited automatically
during the normal build process, by adding the "libfoo
"
directory to a package file (in configurations/PACKS).
Do this only for ST/X base package extensions - not for your own project
libraries.
To do so, take any existing package file (in "configurations/PACKS
"),
and add the foo library to the LIBLIST definition,
the class libraries object file name to the LIBOBJS definition
and finally,
the directory name to
the CLASSLIBDIRS definition.
Your package file should now look like:
Then change to the top directory, and reconfigure ("
...
#
# to make libfoo when compiling:
#
CLASSLIBDIRS= $(LIBBASICDIR) ....
...
CONFIG
").
Watch the output as makefiles are created:
the added "libfoo
" directory should be visited along with
the other directories and a "Makefile
" be generated there.
After this, every make started in the TOP directory will always include
your libfoo
directory.
You will never again have to do things manually there.
libfoo
.
cd libfoo
make
this should (after a while) leave you with your new classLibrary libfoo
in that directory.
Depending on the architecture and/or configuration, the filename extension of the library varies; any of "If you plan to pass the compiled class library to others, all you have to distribute is thelibfoo.a
", "libfoo.obj
", "libfoo.o
" or "libfoo.so
" may be found there after the make. Don't care for this detail - the make rules create whatever is best for your architecture.
(For example, on some systems archives (".a" extension) lead to very long link times - on those, classLibraries are prelinked, relocatable objects (".obj"). Some do not allow ".obj", therefore ".o" is used. Finally, some support shared libraries named ".so", ".sl" or even ".dll")
libfoo
object just
created.
Alternatively, you can add a line to the "private.rc
"
or "startup.rc
" scripts, which loads the library at startup
time:
there is also another (recommended) interface:
...
Smalltalk fileIn:'name-of-your-class-object-file'.
...
which does the same, but is portable in that it determines the
required file suffix itself (".so" / ".sl" or ".dll", depending on the system)
...
Smalltalk fileIn:'name-of-your-class-object-file-without-suffix'.
...
On all systems which do NOT support dynamic loading, you have to leave any running smalltalk, compile your classlibraries, relink the smalltalk executable and start a new (this time with those new classes being part of the built-in classes).
Since saved snapshot images are (currently) unusable after a system rebuild, it is now time to save all your work in source form (i.e. fileOut all other classes and make certain that you can reconstruct your universe later from these and/or the changes file).
The smalltalk executable is rebuilt with:
(later, you will only use "
cd projects/smalltalk
make
make smalltalk
"; but the first time,
we need the source-links to be created).
smalltalk -I"
to have it ignore any existing snapshot file.)
For your tests, keep the old snapshot and smalltalk
executable around as "st.img.sav
" and "smalltalk.sav
"
for a while - just in case.
Adding more classes
Once you are through the above hard work,
adding more classes is easy:
As above, a remake of the smalltalk executable itself is only required
if your system does not support shared libraries.
...
Save more classes into the libfoo directory
...
cd TOP/libfoo
...
add entries for the class-filenames in Make.proto
or rerun stmkmp and re-edit LIBNAME, PACKAGE etc.
...
make
cd ../projects/smalltalk
make
If it does you can even switch to the new classLibrary in the running system,
by: unloading any old loaded classLibrary first
(using the launchers File-Modules dialog),
and re-filingIn the new shared library.
WARNING:
Depending on the C-Code / C-libraries you have included, this reloading
may fail occasionally, if there are leftOver references to static data
or functions somewhere in the C-code.
This may even lead to a crash in some situations.
We highly recommend saving your work before any reload - over time,
you will get a feeling for that ;-)
Adding more classlibraries (to the base system)
You may not want to add classes forever to that single libfoo
library. At some point, it may be required to add another library.
To do so, follow the above steps again,
leading to entries in your config file which look like:
If you are working in a group with others,
a good strategy is to place classlibraries into a central
directory, which can be used from anybode.
OTHERLIBDIRS=libfoo libfoo2 ...
PRIVATEOBJS=$(TOP)/libfoo/libfoo$(OBJNAME) \
$(TOP)/wherever/libfoo2$(OBJNAME) \
...
PRIVATE_SO=$(TOP)/libfoo/libfoo$(SO_NAME) \
$(TOP)/wherever/libfoo2$(SO_NAME) \
...
PRIVATELIBS=libfoo libfoo2 ...
In this case, all users of the class library
(i.e. those that do not care for how these are created)
will only need the PRIVATE
definitions in their config file,
NOT the OTHERLIBDIRS
line.
For example, if you have placed the classlibraries to
"/usr/local/lib", these other config files should
look like:
Remember again, that after every such change, your
PRIVATEOBJS=/usr/local/lib/libfoo$(OBJNAME) \
/usr/local/lib/libfoo2$(OBJNAME)
PRIVATE_SO=/usr/local/lib/libfoo$(SO_NAME) \
/usr/local/lib/libfoo2$(SO_NAME)
PRIVATELIBS=libfoo libfoo2
Makefile
in projects/smalltalk
has to be regenerated.
Interfacing C functions
To add C functions, you have various options of where
these are located (in any case you will need a smalltalk wrapper
method which calls those functions - this is described in
``How to write primitives & inline C code''):
primitiveFunctions
section to your smalltalk
source, define the functions there.
This has the advantage, that the C functions are included in the object
module itself, so that no further libraries have to be linked in.
Especially, if you plan to offer your binary library to others,
this makes the distribution easier.
However, this choice is only a good one for a small number of C functions, of which the source code is available.
libfoo
directory), change the all:
rule in
that "Make.proto
" to:
all:: classLibRule myCLibs
and add a rule for the libraries:
myCLibs::
(cd subdir1 ; make)
(cd subdir2 ; make)
...
Although possible, we recommend NOT to place the C source files directly
in the directory where your st sources are (since you may later want
to cleanup stc's temporary files, with "rm *.c" and could
thereby delete your files by accident).
primitiveFunctions
section),
you will have to change your config file to have the C library included.
See the next chapter on how this is done.
OTHERLIBS
" in the config file.
For example, if you have a C library called "libUseful.a
",
placed under TOP/libfoo/cStuff
, the line should look like:
OTHERLIBS=$(TOP)/libfoo/cStuff/libUseful.a
Of course, if the library is located in some standard place
(i.e. in /usr/lib
or /usr/local/lib), you
can also write:
OTHERLIBS=-lUseful
Read the C-compilers and linkers man pages if you need more information on
this.
All OTHERLIBS are linked in the order specified; thus, if you have
dependencies between your extra libraries, these may be fixed by
changing the order.
For example, if you have two libraries "libUseful1.a
"
and "libUseful2.a
",
of which the second needs entries in the first,
you will get a link error if the config define looks like:
in this case, change the order as in:
OTHERLIBS=$(TOP)/libfoo/cStuff/libUseful1.a \
$(TOP)/libfoo/cStuff/libUseful2.a
OTHERLIBS=$(TOP)/libfoo/cStuff/libUseful2.a \
$(TOP)/libfoo/cStuff/libUseful1.a
An example for C Interfacing
In the following, an interface to C functions which are compiled
from separate sources is shown.
For the example, we assume that a directory "libfoo"
exists,
and the library is to be named "libfoo
" as well.
For better structuring, we place the C sources into a subdirectory of
"libfoo"
called "cstuff"
and create a
C library called "cstuff.a
" there.
The C sources are in "libfoo/cstuff/module1.c
":
and "
cFuntion1() {
printf("here is your C function call ....\n");
}
libfoo/cstuff/module2.c
":
The interface wrapping code for smalltalk is in
"
cFuntion2(arg)
int arg;
{
printf("here is your 2nd C funtion; the args value is %d\n");
}
libfoo/CInterface.st
":
The "
Object subclass:#Cinterface
instanceVariableNames:''
classVariableNames:''
poolDictionaries:''
!
!Cinterface class methodsFor:'C calling'!
cFuntion1
%{
cFuntion1();
%}
!
cFuntion2:argument
%{
if (__isSmallInteger(argument)) {
cFuntion2( _intVal(argument) );
}
%}
! !
Make.proto
" to compile all of these is:
The C library is built by the following rules in "
TOP=..
LIBNAME=libfoo
all:: CSTUFF abbrev.stc objs genClassList $(OBJTARGET)
objs:: CInterface.$(O)
CSTUFF::
(cd cstuff ; make)
cstuff/Makefile
":
Thats it, after a "make" in libfoo, you will find
"
all: module1.o module2.o
ar rv cstuff.a module1.o module2.o
libfoo.obj
" (or "libfoo.so
")
and "libfoo/cstuff.a
"
ready for linkage.
To get those into the executable, your config file should have the
definitions:
The files of the example can be
found in "
OTHERLIBDIRS=$(TOP)/libfoo
PRIVATEOBJS=$(TOP)/libfoo/libfoo$(OBJNAME)
PRIVATE_SO=$(TOP)/libfoo/libfoo$(SO_NAME)
PRIVATELIBS=libfoo
OTHERLIBS=$(TOP)/libfoo/cstuff/cstuff.a
doc/coding/libfoo_example
".
For details on the primitive wrapper code, read
``How to write primitives & inline C code''.
Automatic building
Automatic creation and building via the project management is being prepared.
However, at this time, this feature is not fully implemented and things
should be done manually.
Once completed, you will be able to create per project directories,
Make.protos
and the sources by the click of a button.
Copyright © 1995 Claus Gittinger Development & Consulting
<cg@exept.de>