April 15, 2009
Sommaire
C. GNU Integrated Build System (IBS) Rationale.
Using Visual Studio solutions.
E. Application development using the Software Factory (versus using a package)
Using Visual Studio solutions.
This document will help to build the DPWSCore (DC) libraries and applications on both host & target platforms.
The DPWSCore source repository is made up of “standard” root directories with predefined contents:
SRC |
Contains the DPWSCore stack portable source code. |
APPS |
Contains the portable source code for DPWSCore applications especially samples. |
TOOLS |
Contains the portable source code for other software like code generators. |
PLATFORM |
Contains all non-portable files of the source repository and build files for binaries production. The software factory allows using a secondary PLATFORM root that may contain alternate platform ports. |
ABSTRACT_LAYER |
Contains a general purpose portability layer which is not specific to DPWSCore and may become an independent project in the future. |
DOC |
Contains documentation master files for the DPWSCore package. |
BUILD |
Contains master build tool managing DPWSCore package production. |
SRC, TOOLS & APPS roots contain portable (platform independent) source code in subfolders named software components (SC) or modules. A module is expected to produce a binary object such as a library (static or shared) or an executable. These modules contain standard subdirectories: INCLUDE, SRC, DOC, DATA…
Here is a brief description of the existing modules sorted by dependency order (less dependent first):
common |
static library |
Common utilities : uuid, handles, C types, memory structures… |
gsoap-2.7.6 |
static library |
gSOAP runtime with extensions for DPWS. |
dpws |
shared library |
Core stack runtime. Embeds gsoap-2.7.6 sources. |
xmltools |
shared library |
Various XML related features like EPX over gSOAP, generic stub & skeleton, SUN… Requires the dpws runtime. |
xmlconf |
shared library |
XML File configuration feature using most of the dynamic deployment features but without the deployment service itself. Requires dpws and xmltools runtimes. |
wsman |
shared library |
WS-Management implementations dispatcher. Requires dpws and xmltools runtimes. |
dyndepl |
shared library |
Dynamic deployment features partially implementing WS-Management. In fact, the deployment service since the shared libary embeds xmlconf sources for main features. Requires dpws, xmltools and wsman runtimes. |
dyndepl_client |
shared library |
Dynamic deployment client helper. Requires dpws and xmltools runtimes. |
gsoap-soapcpp-2.7.6 |
exe |
Stub & skeleton generator. |
gsoap-wsdl2h-2.7.6 |
exe |
Annotated header file generator from WSDL file. |
This root contains distribution samples and potentially other DPWS applications.
The SOA4D source repository PLATFORM root contains build files organized following the toolchain/target/module/arch axis, assuming
toolchain |
The compiler or IDE family. gnu is reserved for the integrated build system (integrated means the one that will be used by the master build). vs2005 and vs2008 (Microsoft Visual Studio) solutions are also provided as a helper. |
target |
Features any combination of platform component including OS, hardware and utility libraries. For the integrated build system (GNU), cygwin, linux, and mingw are provided. For visual studio toolchains, the win32 target is provided by default. |
module |
The module matches the Software Component from source roots. |
arch |
Features either a processor architecture or a particular binary target (e.g. debug). |
The master build will use:
· build files in PLATFORM/gnu to produce binaries,
· source roots for module files (headers, doc, data, source),
· the DOC root.
to produce a distribution package.
The Integrated Build System uses GNU tools, especially GCC and Make to produce binaries. It aims to be easily extended for all GCC supported targets.
Heavy use of make variables and inclusions is made to avoid redundancies and decrease the porting effort. For instance, all non-portable directives will be gathered in a few include files. The price for this is dispersal and required mastering of GMake subtleties. Besides, the use of dependency mechanisms is not limited to sources but applies to software components themselves so that building a particular module may trigger automatically the build of other modules.
The executable makefile for a particular module (aka Target Component, TC) will be located in:
· PLATFORM/gnu/toolchain/target/TC/arch/
It will use several kind of include files so that the preceding makefile will contain very few instructions. The following categories of includes can be distinguished:
· Target platform definitions, located in PLATFORM/gnu/toolchain/target,
· Module specific definitions, located in SRC/SCi for instance.
· Common makefiles, located in PLATFORM/gnu.
As usual for makes, variables used for the rules can be overridden or extended either on the make command line or, as expected, in one of the included makefiles. The following diagram exposes the call sequence for a module make:
Note that the optional user.def file can be created to overwrite locally any make variable (never commit this file !).
1. Ensure GNU Make, GCC, Flex and Bison are available on the build host.
Note that for the mingw platform (win32), the used toolchain is cygwin with the mingw package installed that brings easy availability of Flex & Bison. MSYS has not been tested.
2. Checkout sources from the SOA4D forge.
3. If you did not checkout sources using the natural DC source repository layout (that is to say with all standard roots at the same level), create a PLATFORM/gnu/user.def file to override the DC_APPS_DIR, DC_SRC_DIR, DC_TOOLS_DIR and DC_AL_DIR variables.
4. Launch a make target on PLATFORM/gnu/toolchain/target/module/arch/Makefile among the following:
Target |
Availability |
Description |
ALL |
all |
Call EXE, STATIC & SHARED if available. The default target. |
EXE |
exe |
Build the executable(s) Target Component. Triggers library modules dependencies build. |
STATIC |
static, shared |
Build a static library for the Target Component. |
SHARED |
shared |
Build a shared library for the Target Component. Triggers modules library dependencies build. |
CLEAN |
all |
Deletes all output files except dependencies files (.d) for the module. |
CLEANALL |
all |
Deletes all output files including dependencies files (.d) for the module. |
DISTCLEAN |
all |
Call CLEANALL for the module and DISTCLEAN for module dependencies. |
Notes:
· The Windows build was written using Microsoft Visual C++ Express editions. Normally the produced solutions & project files should be compatible with other editions of Visual Studio.
· The Microsoft Visual Studio build uses GnuWin32 and especially flex32 & bison32 to produce language parsing code. However, in order to allow a quick start, the output of these tools has been committed in the source repository so they should not be required for the build. If the generation needs to be performed anyway, one should enable the NMAKE project named soapcppgen in the soapcpp Visual studio solution.
To build modules using Visual Studio
1. Checkout sources from the SOA4D forge.
2. Create a my-definitions.vsprops in PLATFORM/vs200x/ by copying PLATFORM/vs200x/default-definitions.vsprops. Beware, this file must not be committed in the SOA4D source repository.
3. If your use a custom layout, customize my-definitions.vsprops to adapt the variable definitions.
Useful for debugging or when one wants to use the “trunk” version, developing an application using the DPWSCore sources and build files is possible.
The recommended approach it to write a custom makefile for your application that triggers the build for the needed DPWSCore libraries using a $(MAKE) command (for instance call PLATFORM/gnu/linux/dpws/i686/Makefile). You would then simply have to point at the built libraries in your makefile.
To create a Microsoft Visual Studio solution like it is done for APPS samples, the procedure is quite simple:
1. Setup the DPWSCore libraries build for your version of Visual Studio (see Using Visual Studio solutions),
2. Create a new solution in your own location.
3. Add the Visual Studio projects (.vcproj) for the required DC library modules (see Modules in SRC).
4. Define the reference between DPWSCore libraries projects using the dependencies indications in Modules in SRC.
5. Create one or more projects for your application.
6. Copy to you location the PLATFORM/vs200x/default-definitions.vsprops file (rename it if wanted).
7. Customize the property file to adapt location variables to your layout.
8. Add the customized file to your new projects so that they will inherit automatically the many include directories for the DC API.
There are 2 possibilities for porting DPWSCore to a specific target platform. Indeed, there are 2 portability layers available with 2 different objectives:
· DCPL (DPWSCore Portability Layer) is a high-level portability layer which defines the platform features required by the DPWS stack to work. DCPL is said “high-level”, for instance because it uses simple IP addresses instead of BSD socket address structures for IP communications, not because of its sophistication. An HTML reference is available, generated from the interface definition in SRC/dcpl/include/ using Doxygen.
· ABSTRACT_LAYER (AL) is a DPWSCore-independent, general purpose portability layer which is the default implementation for DCPL. It aims at providing a uniform API for most RTOS features and provides for instance a BSD-like interface. The definition of the AL portability interface is directly available as header files in the ABSTRACT_LAYER/include directory.
The following diagram shows both port options:
One may choose the DCPL port if:
· You already have you own platform abstraction layer and don’t want use a new one,
· You use an IP stack with another API (possibly more efficient) than BSD,
· You give priority to performance & footprint.
Or choose the AL port if:
· You are looking for an abstraction layer and AL meets your requirements,
· You want to limit the porting proprietary code to the minimum (very simple API close to the target one) so that you can benefit from the community support for the AL implementation of DCPL.
Whatever is the chosen approach:
· The main part of a port lies in a thorough implementation of the portability layer described in the corresponding API reference. Then you may want to build DPWSCore using your own build system or use the DPWSCore one. If you choose this last option, then consider the following sections.
· The porting can be done
o “offline” using the “source” package delivery or after an anonymous checkout from the SOA4D forge that can be then modified locally,
o “online” if you choose the DCPL port and create your own private local PLATFORM root as explained after. This allows retrieving easily maintenance releases during the porting.
The following procedure assumes you want to have you private PLATFORM folder (“online” port) to take advantage of DPWSCore latest releases.
Note: If you prefer to modify a local copy of PLATFORM (“offline” port), you should do almost the same without overriding the DC_IBS_DIR variable.
1. Choose a code name for your target (e.g. “myboard”)
2. Create your own PLATFORM folder beside the SOA4D.org one and following the same scheme, with:
a. a dcpl/myboard subfolder that will contain DCPL implementation files for your target,
b. a myboard subfolder for every toolchain (gnu, vs2005,…),
c. a subfolder of the preceding for every module that has to be ported (dcpl, common, dpws at least),
d. a <toolchain>/myboard/include folder that should contain stack configuration for your port.
3. Customize the <toolchain>/myboard/platform.def by changing the values for your platform of the make variables among which:
a. DC_TARGET=myboard to specify the target folder,
b. DC_IBS_DIR to locate the SOA4D.org PLATFORM/gnu containing the DPWSCore build system,
c. CC if you need to specify a cross-compiler for your target,
d. DC_DCPL=myboard will select the DCPL implementation,
e. DC_BUILD_TARGET should be set to the platform used for code generators that should generally be built for the development host that is generally different from the target,
f. DC_BUILD_ARCH like for the preceding be set to the processor architecture used for code generators.
4. Include directories for DCPL implementation should be set using:
a. either sdtandard CIFLAGS make variable in <toolchain>/myboard/dcpl/<arch>/Makefile,
b. or in <toolchain>/myboard/include/dcpl_target.h.
5. Set the support libraries for the DCPL implementation in all shared library or executable modules makefile, e.g. <toolchain>/myboard/dpws/<arch>/Makefile, if necessary with:
a. LIBS=-l<lib1> -l<lib2>…
b. LDFLAGS=-L<lib_dir1> -L<lib_dir2>…
AL is currently located in an additional source root named ABSTRACT_LAYER that contains both the layer definition (documented header files) and the already available implementations. This layer addresses some of the basic services required by most embedded applications:
Feature |
Description |
Header file |
Required by DPWSCore |
Mutexes |
Non-reentrant process local mutexes |
al_rtos.h |
Yes |
System-clock |
Time or boot relative clock |
al_rtos.h |
Yes. Absolute date time optional. |
Threads |
|
al_rtos.h |
No |
Counting semaphores |
|
al_rtos.h |
No |
BSD-like socket API |
This layer allows to smooth small BSD incompatibilities. Contains also helpers for IPv6 management. |
al_ip.h |
Yes |
Network adapter info |
Allows to list IP network interfaces with access to information like MAC or IP addresses. |
al_net |
Yes |
Streaming persistence |
Simple API to provide streaming persistency to applications |
al_stor.h |
Yes for the file configuration and dynamic deployment features. |
Block persistence |
Simple API to provide persistency to applications using a direct access style. |
al_stor.h |
No |
The porting procedure consists in:
1. Choose a code name for your target (e.g. “myboard”),
2. Considering you don’t have rights to create a port directly in the SOA4D.org source repository, you should start with an export of the AL (or from a source package).
3. Implement the required part of the portability layer (as described in the previous table) for your platform possibly reusing available implementations and using the same layout. You should especially modify the ABSTRACT_LAYER/include/al_common.h file to include the header files for your port. Indeed, contrary to DCPL, AL uses directly platform types which allow static allocation of RTOS resources.
4. You will have then to create a MY_PLATFORM/<toolchain>/myboard tree either from an export of the SOA4D.org PLATFORM or having yours as an alternate as made possible by the procedure described in the DCPL port (DC_IBS_DIR overriding). You will especially have to customize your own <toolchain>/myboard/platform.def like described except that DC_DCPL should not be redefined since its default value is AL.
5. Create from an example the MY_PLATFORM/<toolchain>/myboard/include/al_target.h file for your platform and other configuration files in the same folder.
6. Your MY_PLATFORM/<toolchain>/myboard/al//<arch>/Makefile should then be modified to specify your port files (by modifying the SRCS variable).
7. Modify the DC_AL_DIR variable in your PLATFORM/gnu/user.def file if you do not use the standard layout.
The current version of DPWSCore has currently low configuration capabilities; however the build can be configured at several levels:
In case you use this portability layer, you may need or want to configure it using the PLATFORM/<toolchain>/<target>/include/al_target.h which is always included.
Examples of existing AL parameters:
· AL_HAVE_IPV4 & AL_HAVE_IPV6 allow to enable or disable IPV4 or IPV6 support in existing implementations and then tell DCPL that the feature is available or not.
· AL_HAVE_RECVMSG does the same for the recvmsg use that allow retrieving the reception interface for socket data (along with the PKTINFO socket option).
· AL_SOCKADDR_FULL_OPAQUE is an AL mode that allow to make the “opaque” feature of AL relying on BSD opaque feature (sockaddr_storage) when available.
Note: The current Linux implementation assumes that the PKTINFO is available. However older Linux version may require a different setting.
The mandatory configuration file for DCPL is PLATFORM/<toolchain>/<target>/include/dcpl_target.h contains currently:
· DCPL_HAVE_PKTINFO enable or disable the use of BSD PKTINFO socket option that allows when fully available (unlike for instance under Windows) to spare sockets when multiple network interfaces support used. The portable code of the source will use this flag to adapt its behavior.
· Some macros used by the portability layer must also be defined like DCPL_SOCKET that represents the socket type for the platform.
Note: The current Linux implementation assumes that the PKTINFO is available. However older Linux version may require a different setting.
gSOAP allows using 2 different configuration files:
1. config.h contains platform capabilities especially stdlib features. The inclusion of this file (located in PLATFORM/<toolchain>/<target>/include) if forced for DPWSCore which disables gSOAP automatic platform detection. The more HAVE_XXX macros are defined, the less gSOAP has to supply its own implementation.
2. soapdefs.h is included only if WITH_SOAPDEFS_H is defined and can be used for instance to customize the buffers used by gSOAP for communications. Let’s quote for instance SOAP_BUFLEN that can be reduced (default is 64 Kb) to spare RAM.
DPWSCore configuration macros can be of course defined on the compiler command line but also in dc_config.h if DC_USER_CONFIG is defined. The macros that can currently be used are:
· DPWS_DEBUG turns on DPWS traces (SENT.log for output message, RECV.log for input message, DPWS.log for other traces). DPWS_DEBUG should be defined to one of {DC_ALL, DC_REGISTRY, DC_LOCK, DC_CACHE, DC_DISCOVERY, DC_HANDLES, DC_TRANSPORT} according to the message categories to log.
· DC_API_PARAM_CONTROL turns on user API parameters control. This adds special code that could be for instance enabled for application development time.
· WITH_WSMAN enable WS-Management plug-in. This parameter is in fact forced when DC_USER_CONFIG is not set in the current version.
DPWSCore runtime, the gSOAP runtime and AL use allocation macros that can be redefined to use custom allocators. The suitable place to do so is the corresponding configuration file (dc_config.h, config.h, al_target.h). The following diagrams shows how customizable allocation macro and runtime allocation APIs are connected by default:
Warning ! In this diagram, for clarity’s sake, only allocation macro and function are named. Of course, every allocation macro comes with an associated free operation (and sometimes a strdup).