📄 language.sgml
字号:
<!-- {{{ Banner --><!-- =============================================================== --><!-- --><!-- language.sgml --><!-- --><!-- The CDL language. --><!-- --><!-- =============================================================== --><!-- ####COPYRIGHTBEGIN#### --><!-- --><!-- =============================================================== --><!-- Copyright (C) 2000, 2001, 2002 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 obtained from the copyright holder --><!-- =============================================================== --><!-- --> <!-- ####COPYRIGHTEND#### --><!-- =============================================================== --><!-- #####DESCRIPTIONBEGIN#### --><!-- --><!-- Author(s): bartv --><!-- Contact(s): bartv --><!-- Date: 2000/02/06 --><!-- Version: 0.01 --><!-- --><!-- ####DESCRIPTIONEND#### --><!-- =============================================================== --><!-- }}} --><chapter id="language"><title>The CDL Language</title><!-- {{{ Introit --><para>The &CDL; language is a key part of the &eCos; component framework.All packages must come with at least one &CDL; script, to describethat package to the framework. The information in that script includesdetails of all the configuration options and how to build the package.Implementing a new component or turning some existing code into an&eCos; component always involves writing corresponding &CDL;. Thischapter provides a description of the &CDL; language. Detailedinformation on specific parts of the language can be found in <xreflinkend="reference">.</para><!-- }}} --><!-- {{{ Language overview --><sect1 id="language.overview"><title>Language Overview</title><para>A very simple &CDL; script would look like this:</para><programlisting width=72>cdl_package CYGPKG_ERROR { display "Common error code support" compile strerror.cxx include_dir cyg/error description " This package contains the common list of error and status codes. It is held centrally to allow packages to interchange error codes and status codes in a common way, rather than each package having its own conventions for error/status reporting. The error codes are modelled on the POSIX style naming e.g. EINVAL etc. This package also provides the standard strerror() function to convert error codes to textual representation."}</programlisting><para>This describes a single package, the error code package, which doesnot have any sub-components or configuration options. The package hasan internal name, <varname>CYGPKG_ERROR</varname>, which can bereferenced in other &CDL; scripts using e.g.<literal>requires CYGPKG_ERROR</literal>. There will also be a<literal>#define</literal> for this symbol in a configuration headerfile. In addition to the package name, this script provides a numberof properties for the package as a whole. The &display; propertyprovides a short description. The &description; property involves arather longer one, for when users need a bit more information. The&compile; and &include-dir; properties list the consequences of thispackage at build-time. The package appears to lack any on-linedocumentation. </para><para>Packages could be even simpler than this. If the package only providesan interface and there are no files to be compiled then there is noneed for a &compile; property. Alternatively if there are no exportedheader files, or if the exported header files should go to thetop-level of the <filenameclass="directory">install/include</filename> directory, then there isno need for an &include-dir; property. Strictly speaking the&description; and &display; properties are optional as well, althoughapplication developers would not appreciate the resulting lack ofinformation about what the package is supposed to do.</para><para>However many packages tend to be a bit more complicated than the errorpackage, containing various sub-components and configuration options.These are also defined in the &CDL; scripts and in much the same wayas the package. For example, the following excerpt comes from theinfrastructure package:</para><programlisting width=72>cdl_component CYGDBG_INFRA_DEBUG_TRACE_ASSERT_BUFFER { display "Buffered tracing" default_value 1 active_if CYGDBG_USE_TRACING description " An output module which buffers output from tracing and assertion events. The stored messages are output when an assert fires, or CYG_TRACE_PRINT() (defined in <cyg/infra/cyg_trac.h>) is called. Of course, there will only be stored messages if tracing per se (CYGDBG_USE_TRACING) is enabled above." cdl_option CYGDBG_INFRA_DEBUG_TRACE_BUFFER_SIZE { display "Trace buffer size" flavor data default_value 32 legal_values 5 to 65535 description " The size of the trace buffer. This counts the number of trace records stored. When the buffer fills it either wraps, stops recording, or generates output." } …}</programlisting><para>Like a &cdl-package;, a &cdl-component; has a name and a body. Thebody contains various properties for that component, and may alsocontain sub-components or options. Similarly a &cdl-option; has aname and a body of properties. This example lists a number ofnew properties: &default-value;, &active-if;, &flavor; and&legal-values;. The meaning of most of these should be fairly obvious.The next sections describe the various &CDL; commands and properties. </para><para>There is one additional and very important point: &CDL; is not acompletely new language; instead it is implemented as an extension ofthe existing &Tcl; scripting language. The syntax of a &CDL; script is&Tcl; syntax, which is described below. In addition some of the moreadvanced facilities of &CDL; involve embedded fragments of &Tcl; code,for example there is a &define-proc; property which specifies somecode that needs to be executed when the component framework generatesthe configuration header files.</para></sect1><!-- }}} --><!-- {{{ CDL commands --><sect1 id="language.commands"><title>CDL Commands</title><para>There are four &CDL;-related commands which can occur at the top-levelof a &CDL; script: &cdl-package;, &cdl-component;, &cdl-option; and&cdl-interface;. These correspond to the basic building blocks of thelanguage (CDL interfaces are described in <xreflinkend="language.interface">). All of these take the same basic form:</para><programlisting width=72>cdl_package <name> { …}cdl_component <name> { …}cdl_option <name> { …}cdl_interface <name> { …}</programlisting><para>The command is followed by a name and by a body of properties, thelatter enclosed in braces. Packages and components can contain otherentities, so the &cdl-package; and &cdl-component; can also havenested commands in their bodies. All names must be unique within agiven configuration. If say the C library package and a TCP/IP stackboth defined an option with the same name then it would not bepossible to load both of them into a single configuration. There is a<link linkend="language.naming">naming convention</link> which shouldmake accidental name clashes very unlikely.</para><para>It is possible for two packages to use the same name if there are noreasonable circumstances under which both packages could be loaded atthe same time. One example would be architectural HAL packages: agiven &eCos; configuration can be used on only one processor, so thearchitectural HAL packages <varname>CYGPKG_HAL_ARM</varname> and<varname>CYGPKG_HAL_I386</varname> can re-use option names; in factin some cases they are expected to.</para><para>Each package has one top-level &CDL; script, which is specified in thepackages <linklinkend="language.database"><database>ecos.db</database> databaseentry</link>. Typically the name of this top-level script is related tothe package, so the kernel package uses<filename>kernel.cdl</filename>, but this is just a convention. Thefirst command in the top-level script should be &cdl-package;, and thename used should be the same as in the <database>ecos.db</database>database. There should be only one &cdl-package; command per package.</para><para>The various &CDL; entities live in a hierarchy. For example the kernelpackage contains a scheduling component, a synchronization primitivescomponent, and a number of others. The synchronization componentcontains various options such as whether or not mutex priorityinheritance is enabled. There is no upper bound on how far componentscan be nested, but it is rarely necessary to go more than three orfour levels deeper than the package level. Since the naming conventionincorporates bits of the hierarchy, this has the added advantage ofkeeping the names down to a more manageable size.</para><para>The hierarchy serves two purposes. It allows options to be controlleden masse, so disabling a component automatically disables all theoptions below it in the hierarchy. It also permits a much simplerrepresentation of the configuration in the graphical configurationtool, facilitating navigation and modification.</para><para>By default a package is placed at the top-level of the hierarchy, butit is possible to override this using a &parent; property. For examplean architectural HAL package such as <varname>CYGPKG_HAL_SH</varname>typically re-parents itself below <varname>CYGPKG_HAL</varname>, and aplatform HAL package would then re-parent itself below thearchitectural HAL. This makes it a little bit easier for users tonavigate around the hierarchy. Components, options and interfaces canalso be re-parented, but this is less common.</para><para>All components, options and interfaces that are defined directly inthe top-level script will be placed below the package in the hierarchy.Alternatively they can be nested in the body of the &cdl-package;command. The following two script fragments are equivalent:</para><programlisting width=72>cdl_package CYGPKG_LIBC { …}cdl_component CYGPKG_LIBC_STRING { …}cdl_option CYGPKG_LIBC_CTYPE_INLINES { …}</programlisting><para>and:</para><programlisting width=72>cdl_package CYGPKG_LIBC { … cdl_component CYGPKG_LIBC_STRING { … } cdl_option CYGPKG_LIBC_CTYPE_INLINES { … }}</programlisting><para>If a script defines options both inside and outside the body of the&cdl-package; then the ones inside will be processed first. Languagepurists may argue that it would have been better if all containedoptions and components had to go into the body, but in practice it isoften convenient to be able to skip this level of nesting and theresulting behavior is still well-defined.</para><para>Components can also contain options and other &CDL; entities, in factthat is what distinguishes them from options. These can be defined inthe body of the &cdl-component; command:</para><programlisting width=72>cdl_component CYGPKG_LIBC_STDIO { cdl_component CYGPKG_LIBC_STDIO_FLOATING_POINT { … } cdl_option CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS { … }}</programlisting><para>Nesting options inside the bodies of components like this is fine forsimple packages with only a limited number of configuration options,but it becomes unsatisfactory as the number of options increases.Instead it is possible to split the &CDL; data into multiple &CDL;scripts, on a per-component basis. The &script; property should beused for this. For example, in the case of the C library allstdio-related configuration options could be put into<filename>stdio.cdl</filename>, and the top-level CDL script<filename>libc.cdl</filename> would contain the following:</para><programlisting width=72>cdl_package CYGPKG_LIBC { … cdl_component CYGPKG_LIBC_STDIO { …
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -