OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [doc/] [html/] [cdl-guide/] [package.contents.html] - Rev 174

Compare with Previous | Blame | View Log

<!-- Copyright (C) 2003 Red Hat, Inc.                                -->
<!-- This material may be distributed only subject to the terms      -->
<!-- and conditions set forth in the Open Publication License, v1.0  -->
<!-- or later (the latest version is presently available at          -->
<!-- http://www.opencontent.org/openpub/).                           -->
<!-- Distribution of the work or derivative of the work in any       -->
<!-- standard (paper) book form is prohibited unless prior           -->
<!-- permission is obtained from the copyright holder.               -->
<HTML
><HEAD
><TITLE
>Package Contents and Layout</TITLE
><meta name="MSSmartTagsPreventParsing" content="TRUE">
<META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
"><LINK
REL="HOME"
TITLE="The eCos Component Writer's Guide"
HREF="cdl-guide.html"><LINK
REL="UP"
TITLE="Package Organization"
HREF="package.html"><LINK
REL="PREVIOUS"
TITLE="Package Versioning"
HREF="package.versions.html"><LINK
REL="NEXT"
TITLE="Making a Package Distribution"
HREF="package.distrib.html"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>The <SPAN
CLASS="APPLICATION"
>eCos</SPAN
> Component Writer's Guide</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="package.versions.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 2. Package Organization</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="package.distrib.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="PACKAGE.CONTENTS">Package Contents and Layout</H1
><P
>A typical package contains the following:</P
><P
></P
><OL
TYPE="1"
><LI
><P
>Some number of source files which will end up in a library. The
application code will be linked with this library to produce an
executable. Some source files may serve other purposes, for example to
provide a linker script.</P
></LI
><LI
><P
>Exported header files which define the interface provided by the
package. </P
></LI
><LI
><P
>On-line documentation, for example reference pages for each exported
function. </P
></LI
><LI
><P
>Some number of test cases, shipped in source format, allowing users to
check that the package is working as expected on their particular
hardware and in their specific configuration.</P
></LI
><LI
><P
>One or more <SPAN
CLASS="APPLICATION"
>CDL</SPAN
> scripts describing the package to the configuration
system.</P
></LI
></OL
><P
>It is also conventional to have a per-package
<TT
CLASS="FILENAME"
>ChangeLog</TT
> file used to keep track of changes to
that package. This is especially valuable to end users of the package
who may not have convenient access to the source code control system
used to manage the master copy of the package, and hence cannot find
out easily what has changed. Often it can be very useful to the main
developers as well.</P
><P
>Any given packages need not contain all of these. It is compulsory to
have at least one <SPAN
CLASS="APPLICATION"
>CDL</SPAN
> script describing the package, otherwise the
component framework would be unable to process it. Some packages may
not have any source code: it is possible to have a package that merely
defines a common interface which can then be implemented by several
other packages, especially in the context of device drivers; however
it is still common to have some code in such packages to avoid
replicating shareable code in all of the implementation packages.
Similarly it is possible to have a package with no exported header
files, just source code that implements an existing interface: for
example an ethernet device driver might just implement a standard
interface and not provide any additional functionality. Packages do
not need to come with any on-line documentation, although this may
affect how many people will want to use the package. Much the same
applies to per-package test cases.</P
><P
>The component framework has a recommended per-package directory layout
which splits the package contents on a functional basis:</P
><DIV
CLASS="INFORMALFIGURE"
><A
NAME="AEN302"><P
></P
><DIV
CLASS="MEDIAOBJECT"
><P
><IMG
SRC="package.png"
ALIGN="CENTER"></P
></DIV
><P
></P
></DIV
><P
>For example, if a package has an <TT
CLASS="FILENAME"
>include</TT
> sub-directory then the component
framework will assume that all header files in and below that
directory are exported header files and will do the right thing at
build time. Similarly if there is <SPAN
CLASS="PROPERTY"
>doc</SPAN
> property indicating the
location of on-line documentation then the component framework will
first look in the <TT
CLASS="FILENAME"
>doc</TT
>
sub-directory.</P
><P
>This directory layout is just a guideline, it is not enforced by the
component framework. For simple packages it often makes more sense to
have all of the files in just one directory. For example a package
could just contain the files <TT
CLASS="FILENAME"
>hello.cxx</TT
>,
<TT
CLASS="FILENAME"
>hello.h</TT
>, <TT
CLASS="FILENAME"
>hello.html</TT
> and
<TT
CLASS="FILENAME"
>hello.cdl</TT
>. By default
<TT
CLASS="FILENAME"
>hello.h</TT
> will be treated as an exported header
file, although this can be overridden with the <A
HREF="ref.include-files.html"
><SPAN
CLASS="PROPERTY"
>include_files</SPAN
></A
> property. Assuming
there is a <SPAN
CLASS="PROPERTY"
>doc</SPAN
> property referring to <TT
CLASS="FILENAME"
>hello.html</TT
>
and there is no <TT
CLASS="FILENAME"
>doc</TT
>
sub-directory then the tools will search for this file relative to the
package's top-level and everything will just work. Much the same
applies to <TT
CLASS="FILENAME"
>hello.cxx</TT
> and
<TT
CLASS="FILENAME"
>hello.cdl</TT
>. </P
><DIV
CLASS="TIP"
><BLOCKQUOTE
CLASS="TIP"
><P
><B
>Tip: </B
>Older versions of the <SPAN
CLASS="APPLICATION"
>eCos</SPAN
> build system only supported packages that
followed the directory structure exactly. Hence certain core packages
such as <TT
CLASS="FILENAME"
>error</TT
> implement the full directory
structure, even though that is a particularly simple package and the
full directory structure is inappropriate. Component writers can
decide for themselves whether or not the directory structure
guidelines are appropriate for their package.</P
></BLOCKQUOTE
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="PACKAGE.BUILD">Outline of the Build Process</H2
><P
>The full build process is described in <A
HREF="build.html"
>Chapter 4</A
>, but 
a summary is appropriate here. A build involves three directory
structures: </P
><P
></P
><OL
TYPE="1"
><LI
><P
>The component repository. This is where all the package source code is
held, along with <SPAN
CLASS="APPLICATION"
>CDL</SPAN
> scripts, documentation, and so on. For build
purposes a component repository is read-only. Application developers
will only modify the component repository when installing or removing
packages, via the administration tool. Component writers will
typically work on just one package in the component repository.</P
></LI
><LI
><P
>The build tree. Each configuration has its own build tree, which can
be regenerated at any time using the configuration's
<TT
CLASS="FILENAME"
>ecos.ecc</TT
> savefile. The build tree contains only
intermediate files, primarily object files. Once a build is complete
the build tree contains no information that is useful for application
development and can be wiped, although this would slow down any
rebuilds following changes to the configuration.</P
></LI
><LI
><P
>The install tree. This is populated during a build, and contains all
the files relevant to application development. There will be a
<TT
CLASS="FILENAME"
>lib</TT
> sub-directory which
typically contains <TT
CLASS="FILENAME"
>libtarget.a</TT
>, a linker script,
start-up code, and so on. There will also be an <TT
CLASS="FILENAME"
>include</TT
> sub-directory containing all the
header files exported by the various packages. There will also be a
<TT
CLASS="FILENAME"
>include/pkgconf</TT
> sub-directory
containing various configuration header files with
<TT
CLASS="LITERAL"
>#define's</TT
> for the options. Typically the install
tree is created within the build tree, but this is not a requirement.</P
></LI
></OL
><P
>The build process involves the following steps:</P
><P
></P
><OL
TYPE="1"
><LI
><P
>Given a configuration, the component framework is responsible for
creating all the directories in the build and install trees. If these
trees already exist then the component framework is responsible for
any clean-ups that may be necessary, for example if a package has been
removed then all related files should be expunged from the build and
install trees. The configuration header files will be generated at
this time. Depending on the host environment, the component framework
will also generate makefiles or some other way of building the various
packages. Every time the configuration is modified this step needs to
be repeated, to ensure that all option consequences take effect. Care
is taken that this will not result in unnecessary rebuilds.</P
><DIV
CLASS="NOTE"
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Note: </B
>At present this step needs to be invoked manually. In a future version
the generated makefile may if desired perform this step automatically,
using a dependency on the <TT
CLASS="FILENAME"
>ecos.ecc</TT
> savefile.</P
></BLOCKQUOTE
></DIV
></LI
><LI
><P
>The first step in an actual build is to make sure that the install
tree contains all exported header files. All compilations will use
the install tree's <TT
CLASS="FILENAME"
>include</TT
>
directory as one of the places to search for header files.</P
></LI
><LI
><P
>All source files relevant to the current configuration get compiled.
This involves a set of compiler flags initialized on a per-target
basis, with each package being able to modify these flags, and with
the ability for the user to override the flags as well. Care has to be
taken here to avoid inappropriate target-dependencies in packages that
are intended to be portable. The component framework has built-in
knowledge of how to handle C, C++ and assembler source files &#8212;
other languages may be added in future, as and when necessary. The
<A
HREF="ref.compile.html"
><SPAN
CLASS="PROPERTY"
>compile</SPAN
></A
> property is used to
list the files that should get compiled. All object files end up in
the build tree.</P
></LI
><LI
><P
>Once all the object files have been built they are collected into a
library, typically <TT
CLASS="FILENAME"
>libtarget.a</TT
>, which can then be
linked with application code. The library is generated in the install
tree. </P
></LI
><LI
><P
>The component framework provides support for custom build steps, using
the <A
HREF="ref.make-object.html"
><SPAN
CLASS="PROPERTY"
>make_object</SPAN
></A
> and
<A
HREF="ref.make.html"
><SPAN
CLASS="PROPERTY"
>make</SPAN
></A
> properties. The results of
these custom build steps can either be object files that should end up
in a library, or other files such as a linker script. It is possible
to control the order in which these custom build steps take place, for
example it is possible to run a particular build step before any of
the compilations happen.</P
></LI
></OL
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="PACKAGE.SOURCE">Configurable Source Code</H2
><P
>All packages should be totally portable to all target hardware (with
the obvious exceptions of HAL and device driver packages). They should
also be totally bug-free, require the absolute minimum amount of code
and data space, be so efficient that cpu time usage is negligible, and
provide lots of configuration options so that application developers
have full control over the behavior. The configuration options are
optional only if a package can meet the requirements of every
potential application without any overheads. It is not the purpose of
this guide to explain how to achieve all of these requirements.</P
><P
>The <SPAN
CLASS="APPLICATION"
>eCos</SPAN
> component framework does have some important implications
for the source code: compiler flag dependencies; package interfaces
vs. implementations; and how configuration options affect source code.</P
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="PACKAGE.SOURCE.FLAGS">Compiler Flag Dependencies</H3
><P
>Wherever possible component writers should avoid dependencies on
particular compiler flags. Any such dependencies are likely to impact
portability. For example, if one package needs to be built in
big-endian mode and another package needs to be built in little-endian
mode then usually it will not be possible for application developers
to use both packages at the same time; in addition the application
developer is no longer given a choice in the matter. It is far better
for the package source code to adapt the endianness at compile-time,
or possibly at run-time although that will involve code-size
overheads.</P
><DIV
CLASS="NOTE"
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Note: </B
>A related issue is that the current support for handling compiler
flags in the component framework is still limited and incapable of
handling flags at a very fine-grain. The support is likely to be
enhanced in future versions of the framework, but there are
non-trivial problems to be resolved.</P
></BLOCKQUOTE
></DIV
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="PACKAGE.SOURCE.INTERFACES">Package Interfaces and Implementations</H3
><P
>The component framework provides encapsulation at the package level. A
package <TT
CLASS="LITERAL"
>A</TT
> has no way of accessing the
implementation details of another package <TT
CLASS="LITERAL"
>B</TT
> at
compile-time. In particular, if there is a private header file
somewhere in a package's <TT
CLASS="FILENAME"
>src</TT
>
sub-directory then this header file is completely invisible to other
packages. Any attempts to cheat by using relative pathnames beginning
with <TT
CLASS="FILENAME"
>../..</TT
> are generally doomed
to failure because of the presence of package version directories.
There are two ways in which one package can affect another: by means
of the exported header files, which define a public interface; or via
the <SPAN
CLASS="APPLICATION"
>CDL</SPAN
> scripts.</P
><P
>This encapsulation is a deliberate aspect of the overall <SPAN
CLASS="APPLICATION"
>eCos</SPAN
>
component framework design. In most cases it does not cause any
problems for component writers. In some cases enforcing a clean
separation between interface and implementation details can improve
the code. Also it reduces problems when a package gets upgraded:
component writers are free to do pretty much anything on the
implementation side, including renaming every single source file; care
has to be taken only with the exported header files and with the <SPAN
CLASS="APPLICATION"
>CDL</SPAN
>
data, because those have the potential of impacting other packages.
Application code is similarly unable to access package implementation
details, only the exported interface.</P
><P
>Very occasionally the inability of one package to see implementation
details of another does cause problems. One example occurs in HAL
packages, where it may be desirable for the architectural, variant and
platform HAL's to share some information that should not be visible to
other packages or to application code. This may be addressed in the
future by introducing the concept of <TT
CLASS="LITERAL"
>friend</TT
>
packages, just as a C++ class can have <TT
CLASS="LITERAL"
>friend</TT
>
functions and classes which are allowed special access to a class
internals. It is not yet clear whether such cases are sufficiently
frequent to warrant introducing such a facility.</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="PACKAGE.SOURCE.CONFIG">Source Code and Configuration Options</H3
><P
>Configurability usually involves source code that needs to implement
different behavior depending on the settings of configuration
options. It is possible to write packages where the only consequence
associated with various configuration options is to control what gets
built, but this approach is limited and does not allow for
fine-grained configurability. There are three main ways in which
options could affect source code at build time:</P
><P
></P
><OL
TYPE="1"
><LI
><P
>The component code can be passed through a suitable preprocessor,
either an existing one such as <SPAN
CLASS="APPLICATION"
>m4</SPAN
> or a new one specially designed with
configurability in mind. The original sources would reside in the
component repository and the processed sources would reside in the
build tree. These processed sources can then be compiled in the usual
way.</P
><P
>This approach has two main advantages. First, it is independent from
the programming language used to code the components, provided
reasonable precautions are taken to avoid syntax clashes between
preprocessor statements and actual code. This would make it easier in
future to support languages other than C and C++. Second, configurable
code can make use of advanced preprocessing facilities such as loops
and recursion. The disadvantage is that component writers would have
to learn about a new preprocessor and embed appropriate directives in
the code. This makes it much more difficult to turn existing code into
components, and it involves extra training costs for the component
writers.</P
></LI
><LI
><P
>Compiler optimizations can be used to elide code that should not be
present, for example:</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>    &#8230;
    if (CYGHWR_NUMBER_UARTS &gt; 0) {
        &#8230;
     }
    &#8230;</PRE
></TD
></TR
></TABLE
><P
>If the compiler knows that <TT
CLASS="VARNAME"
>CYGHWR_NUMBER_UARTS</TT
> is
the constant number 0 then it is a trivial operation to get rid of the
unnecessary code. The component framework still has to define this
symbol in a way that is acceptable to the compiler, typically by using
a <TT
CLASS="LITERAL"
>const</TT
> variable or a preprocessor symbol. In some
respects this is a clean approach to configurability, but it has
limitations. It cannot be used in the declarations of data structures
or classes, nor does it provide control over entire functions. In
addition it may not be immediately obvious that this code is affected
by configuration options, which may make it more difficult to
understand.</P
></LI
><LI
><P
>Existing language preprocessors can be used. In the case of C or C++
this would be the standard C preprocessor, and configurable code would
contain a number of <TT
CLASS="LITERAL"
>#ifdef</TT
> and
<TT
CLASS="LITERAL"
>#if</TT
> statements.</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>#if (CYGHWR_NUMBER_UARTS &gt; 0)
     &#8230;
#endif</PRE
></TD
></TR
></TABLE
><P
>This approach has the big advantage that the C preprocessor is a
technology that is both well-understood and widely used. There are
also disadvantages: it is not directly applicable to components
written in other languages such as Java (although it is possible to
use the C preprocessor as a stand-alone program); the preprocessing
facilities are rather limited, for example there is no looping
facility; and some people consider the technology to be ugly. Of
course it may be possible to get around the second objection by
extending the preprocessor that is used by gcc and g++.</P
></LI
></OL
><P
>The current component framework generates configuration header files
with C preprocessor <TT
CLASS="LITERAL"
>#define's</TT
> for each option
(typically, there various properties which can be used to control
this). It is up to component writers to decide whether to use
preprocessor <TT
CLASS="LITERAL"
>#ifdef</TT
> statements or language
constructs such as <TT
CLASS="LITERAL"
>if</TT
>. At present there is no
support for languages which do not involve the C preprocessor,
although such support can be added in future when the need arises.</P
></DIV
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="PACKAGE.HEADERS">Exported Header Files</H2
><P
>A package's exported header files should specify the interface
provided by that package, and avoid any implementation details.
However there may be performance or other reasons why implementation
details occasionally need to be present in the exported headers.</P
><DIV
CLASS="NOTE"
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Note: </B
>Not all programming languages have the concept of a header file. In
some cases the component framework would need extensions to support
packages written in such languages. </P
></BLOCKQUOTE
></DIV
><P
>Configurability has a number of effects on the way exported header
files should be written. There may be configuration options which
affect the interface of a package, not just the implementation. It is
necessary to worry about nested <TT
CLASS="LITERAL"
>#include's</TT
> and how
this affects package and application builds. A special case of this
relates to whether or not exported header files should
<TT
CLASS="LITERAL"
>#include</TT
> configuration headers. These configuration
headers are exported, but should only be <TT
CLASS="LITERAL"
>#include'd</TT
>
when necessary.</P
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="PACKAGE.HEADERS.FUNCTIONS">Configurable Functionality</H3
><P
>Many configuration options affect only the implementation of a
package, not the interface. However some options will affect the
interface as well, which means that the options have to be tested in
the exported header files. Some implementation choices, for example
whether or not a particular function should be inlined, also need to
be tested in the header file because of language limitations.</P
><P
>Consider a configuration option
<TT
CLASS="VARNAME"
>CYGFUN_KERNEL_MUTEX_TIMEDLOCK</TT
> which controls
whether or not a function <TT
CLASS="FUNCTION"
>cyg_mutex_timedlock</TT
> is
provided. The exported kernel header file <TT
CLASS="FILENAME"
>cyg/kernel/kapi.h</TT
> could contain the
following:</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>#include &lt;pkgconf/kernel.h&gt;
&#8230;
#ifdef CYGFUN_KERNEL_MUTEX_TIMEDLOCK
extern bool cyg_mutex_timedlock(cyg_mutex_t*);
#endif</PRE
></TD
></TR
></TABLE
><P
>This is a correct header file, in that it defines the exact interface
provided by the package at all times. However is has a number of
implications. First, the header file is now dependent on <TT
CLASS="FILENAME"
>pkgconf/kernel.h</TT
>, so any changes to
kernel configuration options will cause <TT
CLASS="FILENAME"
>cyg/kernel/kapi.h</TT
> to be out of date, and
any source files that use the kernel interface will need rebuilding.
This may affect sources in the kernel package, in other packages, and
in application source code. Second, if the application makes use of
this function somewhere but the application developer has
misconfigured the system and disabled this functionality anyway then
there will now be a compile-time error when building the application.
Note that other packages should not be affected, since they should
impose appropriate constraints on
<TT
CLASS="VARNAME"
>CYGFUN_KERNEL_MUTEX_TIMEDLOCK</TT
> if they use that
functionality (although of course some dependencies like this may get
missed by component developers).</P
><P
>An alternative approach would be:</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>extern bool cyg_mutex_timedlock(cyg_mutex_t*);</PRE
></TD
></TR
></TABLE
><P
>Effectively the header file is now lying about the functionality
provided by the package. The first result is that there is no longer a
dependency on the kernel configuration header. The second result is
that an application file using the timed-lock function will now
compile, but the application will fail to link. At this stage the
application developer still has to intervene, change the
configuration, and rebuild the system. However no application
recompilations are necessary, just a relink.</P
><P
>Theoretically it would be possible for a tool to analyze linker errors
and suggest possible configuration changes that would resolve the
problem, reducing the burden on the application developer. No such
tool is planned in the short term.</P
><P
>It is up to component writers to decide which of these two approaches
should be preferred. Note that it is not always possible to avoid
<TT
CLASS="LITERAL"
>#include'ing</TT
> a configuration header file in an
exported one, for example an option may affect a data structure rather
than just the presence or absence of a function. Issues like this will
vary from package to package.</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="PACKAGE.HEADERS.INCLUDES">Nested <TT
CLASS="LITERAL"
>#include's</TT
></H3
><P
>As a general rule, unnecessary <TT
CLASS="LITERAL"
>#include's</TT
> should be
avoided. A header file should <TT
CLASS="LITERAL"
>#include</TT
> only those
header files which are absolutely needed for it to define its
interface. Any additional <TT
CLASS="LITERAL"
>#include's</TT
> make it more
likely that package or application source files become dependent on
configuration header files and will get rebuilt unnecessarily when
there are minor configuration changes.</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="PACKAGE.HEADERS.CONFIGINCLUDES">Including Configuration Headers</H3
><P
>Exported header files should avoid <TT
CLASS="LITERAL"
>#include'ing</TT
>
configuration header files unless absolutely necessary, to avoid
unnecessary rebuilding of both application code and other packages
when there are minor configuration changes. A
<TT
CLASS="LITERAL"
>#include</TT
> is needed only when a configuration option
affects the exported interface, or when it affects some implementation
details which is controlled by the header file such as whether or not
a particular function gets inlined.</P
><P
>There are a couple of ways in which the problem of unnecessary
rebuilding could be addressed. The first would require more
intelligent handling of header file dependency handling by the tools
(especially the compiler) and the build system. This would require
changes to various non-eCos tools. An alternative approach would be to
support finer-grained configuration header files, for example there
could be a file <TT
CLASS="FILENAME"
>pkgconf/libc/inline.h</TT
> controlling which
functions should be inlined. This could be achieved by some fairly
simple extensions to the component framework, but it makes it more
difficult to get the package header files and source code correct:
a C preprocessor <TT
CLASS="LITERAL"
>#ifdef</TT
> directive does not
distinguish between a symbol not being defined because the option is
disabled, or the symbol not being defined because the appropriate
configuration header file has not been <TT
CLASS="LITERAL"
>#include'd</TT
>.
It is likely that a cross-referencing tool would have to be developed
first to catch problems like this, before the component framework
could support finer-grained configuration headers.</P
></DIV
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="PACKAGE.DOCUMENTATION">Package Documentation</H2
><P
>On-line package documentation should be in HTML format. The component
framework imposes no special limitations: component writers can decide
which version of the HTML specification should be followed; they can
also decide on how best to cope with the limitations of different
browsers. In general it is a good idea to keep things simple.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="PACKAGE.TESTS">Test Cases</H2
><P
>Packages should normally come with one or more test cases. This allows
application developers to verify that a given package works correctly
on their particular hardware and in their particular configuration,
making it slightly more likely that they will attempt to find bugs in
their own code rather than automatically blaming the component
writers.</P
><P
>At the time of writing the application developer support for building
and running test cases via the component framework is under review and
likely to change. Currently each test case should consist of a single
C or C++ source file that can be compiled with the package's set of
compiler flags and linked like any application program. Each test case
should use the testing API defined by the infrastructure. A
magically-named calculated configuration option of the form
<TT
CLASS="VARNAME"
>CYGPKG_&lt;PACKAGE-NAME&gt;_TESTS</TT
> lists the test
cases.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="PACKAGE.HOST">Host-side Support</H2
><P
>On occasion it would be useful for an <SPAN
CLASS="APPLICATION"
>eCos</SPAN
> package to be shipped
with host-side support. This could take the form of an additional tool
needed to build that package. It could be an application intended to
communicate with the target-side package code and display monitoring
information. It could be a utility needed for running the package test
cases, especially in the case of device drivers. The component
framework does not yet provide any such support for host-side
software, and there are obvious issues related to portability to the
different machines that can be used for hosts. This issue may get
addressed in some future release. In some cases custom build steps can
be subverted to do things on the host side rather than the target
side, but this is not recommended.</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="package.versions.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="cdl-guide.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="package.distrib.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Package Versioning</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="package.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Making a Package Distribution</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.