Let's create a component. First make sure that your current working directory is inside the project directory:
$pwd/data/user1/myProject$
It is important to be in the project directory (or its subdirectories) when you invoke bocca because it picks up all of the context for your project from there (similar to CVS or Subversion). Go ahead and create the component now:
$bocca create component emptyComponentUpdating the cxx implementation of component myProject.emptyComponent ...$
You will notice that this takes a little time and that bocca has
selected myProject as the default package
name for emptyComponent since no package name was specified when creating
the component. Bocca will default to the
project name as the package name for both ports and components, unless a different
default package name was specified when the project was created.
Note we have named our component emptyComponent because it has
no uses nor provides ports and thus is rather uninteresting.
Nonetheless all of the necessary make system scaffolding and code
have been generated for the component, including the setServices
call. Here we use as an example the case where LANG is
cxx:
$ls components/myProject.emptyComponent/BOCCA make.vars.user glue myProject_emptyComponent_Impl.cxx Makefile myProject_emptyComponent_Impl.hxx make.rules.user myProject_emptyComponent_Impl.hxx.rej$
Components created in Fortran, C, and Python will contain similar files
in the respective language. In the
components directory a new
directory, myProject.emptyComponent, has been created
to hold your component. And inside there is the code already
generated for the component (again continuing with LANG =
cxx) in the files:
myProject_emptyComponent_Impl.cxx,
myProject_emptyComponent_Impl.hxx with some
Babel glue code in the glue
subdirectory. Note the file ending in .rej named
myProject_emptyComponent_Impl.hxx.rej.
This file produced by the bocca splicing process. It records code fragments that bocca discarded while generating myProject_emptyComponent_Impl.hxx
and can usually be ignored and even deleted.
In order to have some exportable or importable functionality in
a component we must have some uses and provides ports.
Bocca will also create the scaffolding and code for ports. Just as
in the pre-built application of Chapter 2, Assembling and Running a CCA Application we will
want to create a Function, an Integrator, and a
Driver. Before we can do that we will have to create some
ports for these components to use and provide.
We wish to create a FunctionPort and an
IntegratorPort:
$bocca create port IntegratorPortUpdating makefiles (for myProject.IntegratorPort)...$$bocca create port FunctionPortUpdating makefiles (for myProject.FunctionPort)...$
Notice that we have opted for the default package
myProject that is created for us transparently
for all components and ports unless otherwise specified. Now, create
a set of components similar to those that you used in Chapter 2, Assembling and Running a CCA Application, specifying that they will provide or
use the appropriate ports:
$bocca create component Function --provides=FunctionPort:thisFunctionUpdating the cxx implementation of component myProject.Function ...$$bocca create component Integrator --provides=IntegratorPort:integrate \ --uses=FunctionPort:integrateThis$$bocca create component Driver --uses=IntegratorPort:integrate \ --go=run$
This last bocca create decorates our
component with a CCA standard GoPort, which is not specified as
part of this project. Since gov.cca.ports.GoPort is a part of the CCA
specification, bocca takes care of knowing where to find the
SIDL definition of this port. The special --go
option allows bocca to generate
a default go implementation which prefetches the uses ports
so that all the user needs to do for our example is add numerical code.
In languages which are not object-oriented, this substantially reduces the
errors in handling ports, exceptions, and memory deallocation.
![]() |
Note |
|---|---|
|
It is not necessary to know at component creation time all ports that will be used or provided or other implementation details. Bocca provides various commands for changing project entities, e.g., adding or removing uses and provides ports. |
As we have defined a number of new things, make would be a good thing to do now:
$make# ======================================================================= # No SIDL files in external/sidl, skipping build for external # ======================================================================= # ======================================================================= # Building in ports/, languages: cxx # ======================================================================= ## Building ports... [c] using Babel to generate cxx client code for myProject.FunctionPort... [c] creating library: libmyProject.FunctionPort-cxx.la... [c] using Babel to generate cxx client code for myProject.IntegratorPort... [c] creating library: libmyProject.IntegratorPort-cxx.la... # ======================================================================= # Building in components/clients/, languages: cxx # ======================================================================= ## Building clients... # ======================================================================= # Building in components/, languages: cxx # ======================================================================= [s] Building component myProject.Driver: [s] using Babel to generate cxx implementation code from myProject.Driver.sidl... [s] compiling sources... [s] creating component library: libmyProject.Driver.la ... [s] finished libtooling: components/myProject.Driver/libmyProject.Driver.la ... [s] creating Ccaffeine test script (components/tests/instantiation.gen.rc)... [s] Building component myProject.Function: [s] using Babel to generate cxx implementation code from myProject.Function.sidl... [s] compiling sources... [s] creating component library: libmyProject.Function.la ... [s] finished libtooling: components/myProject.Function/libmyProject.Function.la ... [s] creating Ccaffeine test script (components/tests/instantiation.gen.rc)... [s] Building component myProject.Integrator: [s] using Babel to generate cxx implementation code from myProject.Integrator.sidl... [s] compiling sources... [s] creating component library: libmyProject.Integrator.la ... [s] finished libtooling: components/myProject.Integrator/libmyProject.Integrator.la ... [s] creating Ccaffeine test script (components/tests/instantiation.gen.rc)... [s] Building component myProject.emptyComponent: doing nothing -- library is up-to-date. Build summary: SUCCESS building myProject.Driver SUCCESS building myProject.Function SUCCESS building myProject.Integrator ### To test instantiation of successfully built components, run 'make check' ### ################ Finished building everything ################# ####### You can run some simple tests with 'make check' #######$
Note that this operation can be very time-consuming when your project is managing many ports and components with the fully supported set of Babel language bindings.
Running make check will test whether the components you've created can be instantiated successfully in the Ccaffeine framework:
$make checkmake --no-print-directory --no-builtin-rules -C components check ### Test library load and instantiation for the following languages: cxx Running instantiation tests only Test script: /data/user1/myProject/components/tests/instantiation.gen.rc SUCCESS: ==> Instantiation tests passed for all built components (see /data/user1/myProject/components/tests/instantiation.gen.rc.log). make --no-print-directory --no-builtin-rules check-user$
If you were to run the GUI (Section 2.1, “Using the GUI Front-End to Ccaffeine”) or do the command-line equivalent in Ccaffeine (Section 2.2, “Running Ccaffeine Using an rc File”), you would find that the components
are decorated with the ports you expect, and they can even be
connected (an operation of the framework, not of the components or the
ports being connected). But of course they have not yet been
implemented, so attempting to run an application with these components
would cause it to do nothing.