881 lines
30 KiB
C
881 lines
30 KiB
C
|
/* $Header: /pjproject-0.3/pjlib/include/pj/doxygen.h 5 10/29/05 10:27p Bennylp $ */
|
||
|
#ifndef __PJ_DOXYGEN_H__
|
||
|
#define __PJ_DOXYGEN_H__
|
||
|
|
||
|
/**
|
||
|
* @file doxygen.h
|
||
|
* @brief Doxygen's mainpage.
|
||
|
*/
|
||
|
|
||
|
/*//////////////////////////////////////////////////////////////////////////*/
|
||
|
/*
|
||
|
INTRODUCTION PAGE
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @mainpage Welcome to PJLIB!
|
||
|
*
|
||
|
* @section intro_sec What is PJLIB
|
||
|
*
|
||
|
* PJLIB is a small foundation library written in C for making scalable
|
||
|
* applications. Because of its small footprint, it can be used in embedded
|
||
|
* applications (we hope so!), but yet the library is also aimed for
|
||
|
* facilitating high performance protocol stacks.
|
||
|
*
|
||
|
* PJLIB is released under LGPL terms.
|
||
|
*
|
||
|
* @section download_sec Download
|
||
|
*
|
||
|
* PJLIB and all documentation can be downloaded from
|
||
|
* http://www.bulukucing.org.
|
||
|
*
|
||
|
*
|
||
|
* @section how_to_use_sec About This Documentation
|
||
|
*
|
||
|
* This document is generated directly from PJLIB source file using
|
||
|
* \a doxygen (http://www.doxygen.org). Doxygen is a great (and free!)
|
||
|
* tools for generating such documentation.
|
||
|
*
|
||
|
* @subsection doc_ver_subsec Version
|
||
|
*
|
||
|
* This document corresponds to PJLIB version 0.3-pre2.
|
||
|
*
|
||
|
*
|
||
|
* @subsection find_samples_subsec How to Read This Document
|
||
|
*
|
||
|
* This documentation is laid out more to be a reference guide instead
|
||
|
* of tutorial, therefore first time users may find it difficult to
|
||
|
* grasp PJLIB by reading this document alone.
|
||
|
*
|
||
|
* However, we've tried our best to make this document easy to follow.
|
||
|
* For first time users, we would suggest that you follow these steps
|
||
|
* when reading this documentation:
|
||
|
*
|
||
|
* - continue reading this introduction chapter. At the end of this
|
||
|
* chapter, you'll find section called \ref pjlib_fundamentals_sec
|
||
|
* which should guide you to understand basic things about PJLIB.
|
||
|
*
|
||
|
* - find information about specific features that you want to use
|
||
|
* in PJLIB. Use the <b>Module Index</b> to find out about all
|
||
|
* features in PJLIB (if you're browsing the HTML documentation,
|
||
|
* click on the \a Module link on top of the page, or if you're
|
||
|
* reading the PDF documentation, click on \a Module \a Documentation
|
||
|
* on the navigation pane on the left).
|
||
|
*
|
||
|
* @subsection doc_organize_sec How To's
|
||
|
*
|
||
|
* Please find below links to specific tasks that you probably
|
||
|
* want to do:
|
||
|
*
|
||
|
* - <b>How to Build PJLIB</b>
|
||
|
*\n
|
||
|
* Please refer to \ref pjlib_build_sys_pg page for more information.
|
||
|
*
|
||
|
* - <b>How to Use PJLIB in My Application</b>
|
||
|
*\n
|
||
|
* Please refer to \ref configure_app_sec for more information.
|
||
|
*
|
||
|
* - <b>How to Port PJLIB</b>
|
||
|
*\n
|
||
|
* Please refer to \ref porting_pjlib_pg page.
|
||
|
*
|
||
|
* - <b>Where to Read Samples Documentation</b>
|
||
|
*\n
|
||
|
* Most of the modules provide link to the corresponding sample file.
|
||
|
* Alternatively, to get the list of all examples, you can click on
|
||
|
* <b>Related Pages</b> on the top of HTML document or on
|
||
|
* <b>PJLIB Page Documentation</b> on navigation pane of your PDF reader.
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
* @section features_sec Features
|
||
|
*
|
||
|
* @subsection open_source_feat It's Open Source!
|
||
|
*
|
||
|
* PJLIB is currently released on LGPL license. We may release PJLIB under
|
||
|
* additional schemes in the future (such as GPL or MPL) to incorporate
|
||
|
* linking with specific application, however, one thing for sure is
|
||
|
* we will NEVER be able to make PJLIB a proprietary software.
|
||
|
*
|
||
|
* @subsection extreme_portable_feat Extreme Portability
|
||
|
*
|
||
|
* PJLIB is designed to be extremely portable. It can run on any kind
|
||
|
* of processors (16-bit, 32-bit, or 64-bit, big or little endian, single
|
||
|
* or multi-processors) and operating systems. Floating point or no
|
||
|
* floating point. Multi-threading or not.
|
||
|
* It can even run in environment where no ANSI LIBC is available.
|
||
|
*
|
||
|
* Currently PJLIB is being ported to:
|
||
|
* - x86, Win32 (Win95/98/ME, NT/2000/XP/2003, mingw).
|
||
|
* - x86, Linux (user mode and as <b>kernel module</b>(!)).
|
||
|
* - alpha, Linux
|
||
|
* And coming up:
|
||
|
* - x86, eCos
|
||
|
* - ultra-II, Solaris.
|
||
|
* - powerpc, MacOS
|
||
|
* - m68k, PalmOS.
|
||
|
* - arm, PocketPC
|
||
|
*
|
||
|
* No other library is known to have this extreme portability!
|
||
|
*
|
||
|
* @subsection small_size_feat Small in Size
|
||
|
*
|
||
|
* One of the primary objectives is to have library that is small in size for
|
||
|
* typical embedded applications. As a rough guidance, we aim to keep the
|
||
|
* library size below 100KB for it to be considered as small.
|
||
|
* As the result, most of the functionalities in the library can be tailored
|
||
|
* to meet the requirements; user can enable/disable specific functionalities
|
||
|
* to get the desired size/performance/functionality balance.
|
||
|
*
|
||
|
* For more info, please see @ref pj_config.
|
||
|
*
|
||
|
* @subsection no_dyn_mem No Dynamic Memory Allocations
|
||
|
*
|
||
|
* The central idea of PJLIB is that for applications to run as fast as it can,
|
||
|
* it should not use \a malloc() at all, but instead should get the memory
|
||
|
* from a preallocated storage pool. There are few things that can be
|
||
|
* optimized with this approach:
|
||
|
*
|
||
|
* - \a alloc() is a O(1) operation.
|
||
|
* - no mutex is used inside alloc(). It is assumed that synchronization
|
||
|
* will be used in higher abstraction by application anyway.
|
||
|
* - no \a free() is required. All chunks will be deleted when the pool is
|
||
|
* destroyed.
|
||
|
*
|
||
|
* The performance gained on some systems can be as high as 10x speed up
|
||
|
* against \a malloc() and \a free().
|
||
|
*
|
||
|
* For more information, see \ref PJ_POOL_GROUP
|
||
|
*
|
||
|
*
|
||
|
* @subsection os_abstract_feat Operating System Abstraction
|
||
|
*
|
||
|
* PJLIB has abstractions for features that are normally not portable
|
||
|
* across operating systems:
|
||
|
* - @ref PJ_THREAD
|
||
|
*\n
|
||
|
* Portable thread manipulation.
|
||
|
* - @ref PJ_TLS
|
||
|
*\n
|
||
|
* Storing data in thread's private data.
|
||
|
* - @ref PJ_MUTEX
|
||
|
*\n
|
||
|
* Mutual exclusion protection.
|
||
|
* - @ref PJ_SEM
|
||
|
*\n
|
||
|
* Semaphores.
|
||
|
* - @ref PJ_ATOMIC
|
||
|
*\n
|
||
|
* Atomic variables and their operations.
|
||
|
* - @ref PJ_CRIT_SEC
|
||
|
*\n
|
||
|
* Fast locking of critical sections.
|
||
|
* - @ref PJ_LOCK
|
||
|
*\n
|
||
|
* High level abstraction for lock objects.
|
||
|
* - @ref PJ_EVENT
|
||
|
*\n
|
||
|
* Event object.
|
||
|
* - @ref PJ_TIME
|
||
|
*\n
|
||
|
* Portable time manipulation.
|
||
|
* - @ref PJ_TIMESTAMP
|
||
|
*\n
|
||
|
* High resolution time value.
|
||
|
* - etc.
|
||
|
*
|
||
|
*
|
||
|
* @subsection ll_network_io_sec Low-Level Network I/O
|
||
|
*
|
||
|
* PJLIB has very portable abstraction and fairly complete set of API for
|
||
|
* doing network I/O communications. At the lowest level, PJLIB provides:
|
||
|
*
|
||
|
* - @ref PJ_SOCK
|
||
|
*\n
|
||
|
* A highly portable socket abstraction, runs on all kind of
|
||
|
* network APIs such as standard BSD socket, Windows socket, Linux
|
||
|
* \b kernel socket, PalmOS networking API, etc.
|
||
|
*
|
||
|
* - @ref pj_addr_resolve
|
||
|
*\n
|
||
|
* Portable address resolution, which implements #pj_gethostbyname().
|
||
|
*
|
||
|
* - @ref PJ_SOCK_SELECT
|
||
|
*\n
|
||
|
* A portable \a select() like API (#pj_sock_select()) which can be
|
||
|
* implemented with various back-end.
|
||
|
*
|
||
|
*
|
||
|
* @subsection hl_network_io_sec High-Level Network I/O
|
||
|
*
|
||
|
* At higher abstraction, PJLIB provides @ref PJ_IOQUEUE,
|
||
|
* which promotes creating high performance network
|
||
|
* applications by managing asynchronous I/O. This is a passive framework
|
||
|
* that utilizes the most effective way to manage asynchronous I/O
|
||
|
* on a given platform, such as:
|
||
|
* - IoCompletionPort on WinNT,
|
||
|
* - on Linux it can use either /dev/epoll or aio.
|
||
|
* - or to fall back to use @a select()
|
||
|
*
|
||
|
* At even a higher abstraction, PJLIB provides @ref PJ_EQUEUE, which
|
||
|
* combines asynchronous I/O with timer management and thread management
|
||
|
* to fasilitate creating trully high performance, event driven
|
||
|
* application.
|
||
|
*
|
||
|
*
|
||
|
* @subsection timer_mgmt_sec Timer Management
|
||
|
*
|
||
|
* A passive framework for managing timer, see @ref PJ_TIMER for more info.
|
||
|
* There is also function to retrieve high resolution timestamp
|
||
|
* from the system (see @ref PJ_TIMESTAMP).
|
||
|
*
|
||
|
*
|
||
|
* @subsection lexical_scanner_sec Lexical Scanner
|
||
|
*
|
||
|
* A fast, small, top-down lexical scanner to create fully optimized
|
||
|
* hand-written parser. See @ref PJ_SCAN for more info.
|
||
|
*
|
||
|
* @subsection data_struct_sec Various Data Structures
|
||
|
*
|
||
|
* Various data structures are provided in the library:
|
||
|
*
|
||
|
* - @ref PJ_PSTR
|
||
|
* - @ref PJ_ARRAY
|
||
|
* - @ref PJ_HASH
|
||
|
* - @ref PJ_LIST
|
||
|
* - @ref PJ_RBTREE
|
||
|
*
|
||
|
*
|
||
|
* @subsection exception_sec Exception Construct
|
||
|
*
|
||
|
* A convenient TRY/CATCH like construct to propagate errors, which by
|
||
|
* default are used by the @ref PJ_POOL_GROUP "memory pool" and
|
||
|
* the @ref PJ_SCAN "scanner". The exception
|
||
|
* construct can be used to write programs like below:
|
||
|
*
|
||
|
* <pre>
|
||
|
* #define SYNTAX_ERROR 1
|
||
|
*
|
||
|
* PJ_TRY {
|
||
|
* msg = NULL;
|
||
|
* msg = parse_msg(buf, len);
|
||
|
* }
|
||
|
* PJ_CATCH ( SYNTAX_ERROR ) {
|
||
|
* .. handle error ..
|
||
|
* }
|
||
|
* PJ_END;
|
||
|
* </pre>
|
||
|
*
|
||
|
* Please see @ref PJ_EXCEPT for more information.
|
||
|
*
|
||
|
*
|
||
|
* @subsection logging_sec Logging Facility
|
||
|
*
|
||
|
* PJLIB @ref PJ_LOG consists of macros to write logging information to
|
||
|
* some output device. Some of the features of the logging facility:
|
||
|
*
|
||
|
* - the verbosity can be fine-tuned both at compile time (to control
|
||
|
* the library size) or run-time (to control the verbosity of the
|
||
|
* information).
|
||
|
* - output device is configurable (e.g. stdout, printk, file, etc.)
|
||
|
* - log decoration is configurable.
|
||
|
*
|
||
|
* See @ref PJ_LOG for more information.
|
||
|
*
|
||
|
*
|
||
|
* @subsection guid_gen_sec Random and GUID Generation
|
||
|
*
|
||
|
* PJLIB provides facility to create random string
|
||
|
* (#pj_create_random_string()) or globally unique identifier
|
||
|
* (see @ref PJ_GUID).
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
* @section configure_app_sec Configuring Application to use PJLIB
|
||
|
*
|
||
|
* @subsection pjlib_compil_sec Building PJLIB
|
||
|
*
|
||
|
* Follow the instructions in \ref pjlib_build_sys_pg to build
|
||
|
* PJLIB.
|
||
|
*
|
||
|
* @subsection pjlib_compil_app_sec Building Applications with PJLIB
|
||
|
*
|
||
|
* Use the following settings when building applications with PJLIB.
|
||
|
*
|
||
|
* @subsubsection compil_inc_dir_sec Include Search Path
|
||
|
*
|
||
|
* Add this to your include search path ($PJLIB is PJLIB root directory):
|
||
|
* <pre>
|
||
|
* $PJLIB/include
|
||
|
* </pre>
|
||
|
*
|
||
|
* @subsubsection compil_inc_file_sec Include PJLIB Header
|
||
|
*
|
||
|
* To include all PJLIB headers:
|
||
|
* \verbatim
|
||
|
#include <pjlib.h>
|
||
|
\endverbatim
|
||
|
*
|
||
|
* Alternatively, you can include individual PJLIB headers like this:
|
||
|
* \verbatim
|
||
|
#include <pj/log.h>
|
||
|
#include <pj/os.h>
|
||
|
\endverbatim
|
||
|
*
|
||
|
*
|
||
|
* @subsubsection compil_lib_dir_sec Library Path
|
||
|
*
|
||
|
* Add this to your library search path:
|
||
|
* <pre>
|
||
|
* $PJLIB/lib
|
||
|
* </pre>
|
||
|
*
|
||
|
* Then add the appropriate PJLIB library to your link specification. For
|
||
|
* example, you would add \c libpj-i386-linux-gcc.a when you're building
|
||
|
* applications in Linux.
|
||
|
*
|
||
|
*
|
||
|
* @subsection pjlib_fundamentals_sec Principles in Using PJLIB
|
||
|
*
|
||
|
* Few things that you \b MUST do when using PJLIB, to make sure that
|
||
|
* you create trully portable applications.
|
||
|
*
|
||
|
* @subsubsection call_pjlib_init_sec Call pj_init()
|
||
|
*
|
||
|
* Before you do anything else, call \c pj_init(). This would make sure that
|
||
|
* PJLIB system is properly set up.
|
||
|
*
|
||
|
* @subsubsection no_ansi_subsec Do NOT Use ANSI C
|
||
|
*
|
||
|
* Contrary to popular teaching, ANSI C (and LIBC) is not the most portable
|
||
|
* library in the world, nor it's the most ubiquitous. For example, LIBC
|
||
|
* is not available in Linux kernel. Also normally LIBC will be excluded
|
||
|
* from compilation of RTOSes to reduce size.
|
||
|
*
|
||
|
* So for maximum portability, do NOT use ANSI C. Do not even try to include
|
||
|
* any other header files outside <include/pj>. Stick with the functionalities
|
||
|
* provided by PJLIB.
|
||
|
*
|
||
|
*
|
||
|
* @subsubsection string_rep_subsubsec Use pj_str_t instead of C Strings
|
||
|
*
|
||
|
* PJLIB uses pj_str_t instead of normal C strings. You SHOULD follow this
|
||
|
* convention too. Remember, ANSI string-h is not always available. And
|
||
|
* PJLIB string is faster!
|
||
|
*
|
||
|
* @subsubsection mem_alloc_subsubsec Use Pool for Memory Allocations
|
||
|
*
|
||
|
* You MUST NOT use \a malloc() or any other memory allocation functions.
|
||
|
* Use PJLIB pool instead! It's faster and most portable.
|
||
|
*
|
||
|
* @subsection logging_subsubsec Use Logging for Text Display
|
||
|
*
|
||
|
* DO NOT use <stdio.h> for text output. Use PJLIB logging instead.
|
||
|
*
|
||
|
*
|
||
|
* @section porting_pjlib_sec0 Porting PJLIB
|
||
|
*
|
||
|
* Please see \ref porting_pjlib_pg page on more information to port
|
||
|
* PJLIB to new target.
|
||
|
*
|
||
|
* @section enjoy_sec Enjoy Using PJLIB!
|
||
|
*
|
||
|
* We hope that you find PJLIB usefull for your application. If you
|
||
|
* have any questions, suggestions, critics, bug fixes, or anything
|
||
|
* else, we would be happy to hear it.
|
||
|
*
|
||
|
* Enjoy using PJLIB!
|
||
|
*
|
||
|
* Benny Prijono < bennylp at bulukucing dot org >
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*////////////////////////////////////////////////////////////////////////// */
|
||
|
/*
|
||
|
BUILDING AND INSTALLING PJLIB
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @page pjlib_build_sys_pg Building, and Installing PJLIB
|
||
|
*
|
||
|
* @section build_sys_install_sec Build and Installation
|
||
|
*
|
||
|
* @subsection build_sys_install_win32_sec Visual Studio
|
||
|
*
|
||
|
* The PJLIB Visual Studio workspace supports the building of PJLIB
|
||
|
* for Win32 target. Although currently only the Visual Studio 6 Workspace is
|
||
|
* actively maintained, developers with later version of Visual Studio
|
||
|
* can easily imports VS6 workspace into their IDE.
|
||
|
*
|
||
|
* To start building PJLIB projects with Visual Studio 6 or later, open
|
||
|
* the \a workspace file in the corresponding \b \c build directory. You have
|
||
|
* several choices on which \a dsw file to open:
|
||
|
\verbatim
|
||
|
$PJPROJECT/build/pjproject.dsw
|
||
|
$PJPROJECT/pjlib/build/pjlib.dsw
|
||
|
$PJPROJECT/pjsip/build/pjsip.dsw
|
||
|
..etc
|
||
|
\endverbatim
|
||
|
*
|
||
|
* The easiest way is to open <tt>pjproject.dsw</tt> file in \b \c $PJPROJECT/build
|
||
|
* directory. However this will only build the required projects, not
|
||
|
* the complete projects. For example, the PJLIB test and samples projects
|
||
|
* are not included in this workspace. To build the complete projects, you must
|
||
|
* open and build each \a dsw file in \c build directory in each
|
||
|
* subprojects. For example, to open the complete PJLIB workspace, open
|
||
|
* <tt>pjlib.dsw</tt> in <tt>$PJPROJECT/pjlib/build</tt> directory.
|
||
|
*
|
||
|
* @subsection build_sys_install_unix_sec Make System
|
||
|
*
|
||
|
* For other targets, PJLIB provides a rather comprehensive build system
|
||
|
* that uses GNU \a make (and only GNU \a make will work).
|
||
|
* Currently, the build system supports building * PJLIB for these targets:
|
||
|
* - i386/Win32/mingw
|
||
|
* - i386/Linux
|
||
|
* - i386/Linux (kernel)
|
||
|
*
|
||
|
* Generally, steps required to build the projects are:
|
||
|
*
|
||
|
\verbatim
|
||
|
$ cd /home/user/pjproject-0.3 # <-- go to $PJPROJECT\n
|
||
|
$ vi build.mak # <-- set build target etc\n
|
||
|
$ cd pjlib/build # <-- go to projet's build dir\n
|
||
|
$ make # <-- build the project\n
|
||
|
\endverbatim
|
||
|
*
|
||
|
* For other project, \a cd to <tt>build</tt> directory in the project
|
||
|
* and execute \a make from there.
|
||
|
*
|
||
|
* \note For Linux kernel target, there are additional steps required, which
|
||
|
* will be explained in section \ref linux_kern_target_subsec.
|
||
|
*
|
||
|
* @subsubsection build_mak_sec Editing build.mak
|
||
|
*
|
||
|
* The \c build.mak file in \c $PJPROJECT root directory is used to
|
||
|
* specify the build configuration. This file is expected to export
|
||
|
* the following \a make variables:
|
||
|
*
|
||
|
* - \c MACHINE_NAME
|
||
|
*\n
|
||
|
* Target machine/processor, one of: <b>{ i386 }</b>.
|
||
|
*
|
||
|
* - \c OS_NAME
|
||
|
*\n
|
||
|
* Target operating system, one of: <b>{ win32 | linux | linux-kernel }</b>.
|
||
|
*
|
||
|
* - \c CC_NAME
|
||
|
*\n
|
||
|
* Compiler name: <b>{ gcc | vc }</b>
|
||
|
*
|
||
|
* - \c HOST_NAME
|
||
|
*\n
|
||
|
* Build host: <b>{ unix | mingw }</b>
|
||
|
*
|
||
|
* These variables will cause the correct configuration file in
|
||
|
* \c $PJPROJECT/build directory to be executed by \a make. For
|
||
|
* example, specifying \c OS_NAME=linux will cause file \c os-linux.mak
|
||
|
* in \c build directory to be executed. These files contain specific
|
||
|
* configuration for the option that is selected.
|
||
|
*
|
||
|
* For Linux kernel target, you are also required to declare the following
|
||
|
* variables in this file:
|
||
|
* - \c KERNEL_DIR: full path of kernel source tree.
|
||
|
* - \c KERNEL_ARCH: kernel ARCH options (e.g. "ARCH=um"), or leave blank
|
||
|
* for default.
|
||
|
* - \c PJPROJECT_DIR: full path of PJPROJECT source tree.
|
||
|
*
|
||
|
* Apart from these, there are also additional steps required to build
|
||
|
* Linux kernel target, which will be explained in \ref linux_kern_target_subsec.
|
||
|
*
|
||
|
* @subsubsection build_dir_sec Files in "build" Directory
|
||
|
*
|
||
|
* The <tt>*.mak</tt> files in \c $PJPROJECT/build directory are used to specify
|
||
|
* the configuration for the specified compiler, target machine target
|
||
|
* operating system, and host options. These files will be executed
|
||
|
* (included) by \a make during building process, depending on the values
|
||
|
* specified in <b>$PJPROJECT/build.mak</b> file.
|
||
|
*
|
||
|
* Normally you don't need to edit these files, except when you're porting
|
||
|
* PJLIB to new target.
|
||
|
*
|
||
|
* Below are the description of some files in this directory:
|
||
|
*
|
||
|
* - <tt>rules.mak</tt>: contains generic rules always included during make.
|
||
|
* - <tt>cc-gcc.mak</tt>: rules when gcc is used for compiler.
|
||
|
* - <tt>cc-vc.mak</tt>: rules when MSVC compiler is used.
|
||
|
* - <tt>host-mingw.mak</tt>: rules for building in mingw host.
|
||
|
* - <tt>host-unix.mak</tt>: rules for building in Unix/Posix host.
|
||
|
* - <tt>host-win32.mak</tt>: rules for building in Win32 command console
|
||
|
* (only valid when VC is used).
|
||
|
* - <tt>m-i386.mak</tt>: rules when target machine is an i386 processor.
|
||
|
* - <tt>m-m68k.mak</tt>: rules when target machine is an m68k processor.
|
||
|
* - <tt>os-linux.mak</tt>: rules when target OS is Linux.
|
||
|
* - <tt>os-linux-kernel.mak</tt>: rules when PJLIB is to be build as
|
||
|
* part of Linux kernel.
|
||
|
* - <tt>os-win32.mak</tt>: rules when target OS is Win32.
|
||
|
*
|
||
|
* @subsubsection invoking_make_sec Invoking make
|
||
|
*
|
||
|
* Normally, \a make is invoked in \c build directory under each project.
|
||
|
* For example, to build PJLIB, you would invoke \a make in
|
||
|
* \c $PJPROJECT/pjlib/build directory like below:
|
||
|
*
|
||
|
\verbatim
|
||
|
$ cd pjlib/build
|
||
|
$ make
|
||
|
\endverbatim
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
* @subsubsection linux_kern_target_subsec Linux Kernel Target
|
||
|
*
|
||
|
* \note
|
||
|
* <b>BUILDING APPLICATIONS IN LINUX KERNEL MODE IS A VERY DANGEROUS BUSINESS.
|
||
|
* YOU MAY CRASH THE WHOLE OF YOUR SYSTEM, CORRUPT YOUR HARDISK, ETC. PJLIB
|
||
|
* KERNEL MODULES ARE STILL IN EXPERIMENTAL PHASE. DO NOT RUN IT IN PRODUCTION
|
||
|
* SYSTEMS OR OTHER SYSTEMS WHERE RISK OF LOSS OF DATA IS NOT ACCEPTABLE.
|
||
|
* YOU HAVE BEEN WARNED.</b>
|
||
|
*
|
||
|
* \note
|
||
|
* <b>User Mode Linux (UML)</b> provides excellent way to experiment with Linux
|
||
|
* kernel without risking the stability of the host system. See
|
||
|
* http://user-mode-linux.sourceforge.net for details.
|
||
|
*
|
||
|
* \note
|
||
|
* I only use <b>UML</b> to experiment with PJLIB kernel modules.
|
||
|
* <b>I wouldn't be so foolish to use my host Linux machine to experiment
|
||
|
* with this.</b>
|
||
|
*
|
||
|
* \note
|
||
|
* You have been warned.
|
||
|
*
|
||
|
* For building PJLIB for Linux kernel target, there are additional steps required.
|
||
|
* In general, the additional tasks are:
|
||
|
* - Declare some more variables in <b><tt>build.mak</tt></b> file (this
|
||
|
* has been explained in \ref build_mak_sec above).
|
||
|
* - Perform these two small modifications in kernel source tree.
|
||
|
*
|
||
|
* There are two small modification need to be applied to the kernel tree.
|
||
|
*
|
||
|
* <b>1. Edit <tt>Makefile</tt> in kernel root source tree.</b>
|
||
|
*
|
||
|
* Add the following lines at the end of the <tt>Makefile</tt> in your
|
||
|
* <tt>$KERNEL_SRC</tt> dir:
|
||
|
\verbatim
|
||
|
script:
|
||
|
$(SCRIPT)
|
||
|
\endverbatim
|
||
|
*
|
||
|
* \note Remember to replace spaces with <b>tab</b> in the Makefile.
|
||
|
*
|
||
|
* The modification above is needed to capture kernel's \c $CFLAGS and
|
||
|
* \c $CFLAGS_MODULE which will be used for PJLIB's compilation.
|
||
|
*
|
||
|
* <b>2. Add Additional Exports.</b>
|
||
|
*
|
||
|
* We need the kernel to export some more symbols for our use. So we declare
|
||
|
* the additional symbols to be exported in <tt>extra-exports.c</tt> file, and add
|
||
|
* a this file to be compiled into the kernel:
|
||
|
*
|
||
|
* - Copy the file <tt>extra-exports.c</tt> from <tt>pjlib/src/pj</tt>
|
||
|
* directory to <tt>$KERNEL_SRC/kernel/</tt> directory.
|
||
|
* - Edit <tt>Makefile</tt> in that directory, and add this line
|
||
|
* somewhere after the declaration of that variable:
|
||
|
\verbatim
|
||
|
obj-y += extra-exports.o
|
||
|
\endverbatim
|
||
|
*
|
||
|
* To illustrate what have been done in your kernel source tree, below
|
||
|
* is screenshot of my kernel source tree _after_ the modification.
|
||
|
*
|
||
|
\verbatim
|
||
|
[root@vpc-linux linux-2.6.7]# pwd
|
||
|
/usr/src/linux-2.6.7
|
||
|
[root@vpc-linux linux-2.6.7]#
|
||
|
[root@vpc-linux linux-2.6.7]#
|
||
|
[root@vpc-linux linux-2.6.7]# tail Makefile
|
||
|
|
||
|
endif # skip-makefile
|
||
|
|
||
|
FORCE:
|
||
|
|
||
|
.PHONY: script
|
||
|
|
||
|
script:
|
||
|
$(SCRIPT)
|
||
|
|
||
|
[root@vpc-linux linux-2.6.7]#
|
||
|
[root@vpc-linux linux-2.6.7]#
|
||
|
[root@vpc-linux linux-2.6.7]# head kernel/extra-exports.c
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/syscalls.h>
|
||
|
|
||
|
EXPORT_SYMBOL(sys_select);
|
||
|
|
||
|
EXPORT_SYMBOL(sys_epoll_create);
|
||
|
EXPORT_SYMBOL(sys_epoll_ctl);
|
||
|
EXPORT_SYMBOL(sys_epoll_wait);
|
||
|
|
||
|
EXPORT_SYMBOL(sys_socket);
|
||
|
[root@vpc-linux linux-2.6.7]#
|
||
|
[root@vpc-linux linux-2.6.7]#
|
||
|
[root@vpc-linux linux-2.6.7]# head -15 kernel/Makefile
|
||
|
#
|
||
|
# Makefile for the linux kernel.
|
||
|
#
|
||
|
|
||
|
obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
|
||
|
exit.o itimer.o time.o softirq.o resource.o \
|
||
|
sysctl.o capability.o ptrace.o timer.o user.o \
|
||
|
signal.o sys.o kmod.o workqueue.o pid.o \
|
||
|
rcupdate.o intermodule.o extable.o params.o posix-timers.o \
|
||
|
kthread.o
|
||
|
|
||
|
obj-y += extra-exports.o
|
||
|
|
||
|
obj-$(CONFIG_FUTEX) += futex.o
|
||
|
obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
|
||
|
[root@vpc-linux linux-2.6.7]#
|
||
|
|
||
|
\endverbatim
|
||
|
*
|
||
|
* Then you must rebuild the kernel.
|
||
|
* If you fail to do this, you won't be able to <b>insmod</b> pjlib.
|
||
|
*
|
||
|
* \note You will see a lots of warning messages during pjlib-test compilation.
|
||
|
* The warning messages complain about unresolved symbols which are defined
|
||
|
* in pjlib module. You can safely ignore these warnings. However, you can not
|
||
|
* ignore warnings about non-pjlib unresolved symbols.
|
||
|
*
|
||
|
*
|
||
|
* @subsection makefile_explained_sec Makefile Explained
|
||
|
*
|
||
|
* The \a Makefile for each project (e.g. PJLIB, PJSIP, etc) should be
|
||
|
* very similar in the contents. The Makefile is located under \c build
|
||
|
* directory in each project subdir.
|
||
|
*
|
||
|
* @subsubsection pjlib_makefile_subsec PJLIB Makefile.
|
||
|
*
|
||
|
* Below is PJLIB's Makefile:
|
||
|
*
|
||
|
* \include build/Makefile
|
||
|
*
|
||
|
* @subsubsection pjlib_os_makefile_subsec PJLIB os-linux.mak.
|
||
|
*
|
||
|
* Below is file <tt><b>os-linux.mak</b></tt> file in
|
||
|
* <tt>$PJPROJECT/pjlib/build</tt> directory,
|
||
|
* which is OS specific configuration file for Linux target that is specific
|
||
|
* for PJLIB project. For \b global OS specific configuration, please see
|
||
|
* <tt>$PJPROJECT/build/os-*.mak</tt>.
|
||
|
*
|
||
|
* \include build/os-linux.mak
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
|
||
|
/*////////////////////////////////////////////////////////////////////////// */
|
||
|
/*
|
||
|
PORTING PJLIB
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @page porting_pjlib_pg Porting PJLIB
|
||
|
*
|
||
|
*
|
||
|
* @section new_arch_sec Porting to New CPU Architecture
|
||
|
*
|
||
|
* Below is step-by-step guide to add support for new CPU architecture.
|
||
|
* This sample is based on porting to Alpha architecture; however steps for
|
||
|
* porting to other CPU architectures should be pretty similar.
|
||
|
*
|
||
|
* Also note that in this example, the operating system used is <b>Linux</b>.
|
||
|
* Should you wish to add support for new operating system, then follow
|
||
|
* the next section \ref porting_os_sec.
|
||
|
*
|
||
|
* Step-by-step guide to port to new CPU architecture:
|
||
|
* - decide the name for the new architecture. In this case, we choose
|
||
|
* <tt><b>alpha</b></tt>.
|
||
|
* - edit file <tt>$PJPROJECT/build.mak</tt>, and add new section for
|
||
|
* the new target:
|
||
|
* <pre>
|
||
|
* #
|
||
|
* # Linux alpha, gcc
|
||
|
* #
|
||
|
* export MACHINE_NAME := <b>alpha</b>
|
||
|
* export OS_NAME := linux
|
||
|
* export CC_NAME := gcc
|
||
|
* export HOST_NAME := unix
|
||
|
* </pre>
|
||
|
*
|
||
|
* - create a new file <tt>$PJPROJECT/build/<b>m-alpha</b>.mak</tt>.
|
||
|
* Alternatively create a copy from other file in this directory.
|
||
|
* The contents of this file will look something like:
|
||
|
* <pre>
|
||
|
* export M_CFLAGS := $(CC_DEF)<b>PJ_M_ALPHA=1</b>
|
||
|
* export M_CXXFLAGS :=
|
||
|
* export M_LDFLAGS :=
|
||
|
* export M_SOURCES :=
|
||
|
* </pre>
|
||
|
* - create a new file <tt>$PJPROJECT/pjlib/include/pj/compat/<b>m_alpha.h</b></tt>.
|
||
|
* Alternatively create a copy from other header file in this directory.
|
||
|
* The contents of this file will look something like:
|
||
|
* <pre>
|
||
|
* #define PJ_HAS_PENTIUM 0
|
||
|
* #define PJ_IS_LITTLE_ENDIAN 1
|
||
|
* #define PJ_IS_BIG_ENDIAN 0
|
||
|
* </pre>
|
||
|
* - edit <tt>pjlib/include/pj/<b>config.h</b></tt>. Add new processor
|
||
|
* configuration in this header file, like follows:
|
||
|
* <pre>
|
||
|
* ...
|
||
|
* #elif defined (PJ_M_ALPHA) && PJ_M_ALPHA != 0
|
||
|
* # include <pj/compat/m_alpha.h>
|
||
|
* ...
|
||
|
* </pre>
|
||
|
* - done. Build PJLIB with:
|
||
|
* <pre>
|
||
|
* $ cd $PJPROJECT/pjlib/build
|
||
|
* $ make dep
|
||
|
* $ make clean
|
||
|
* $ make
|
||
|
* </pre>
|
||
|
*
|
||
|
* @section porting_os_sec Porting to New Operating System Target
|
||
|
*
|
||
|
* This section will try to give you rough guideline on how to
|
||
|
* port PJLIB to a new target. As a sample, we give the target a name tag,
|
||
|
* for example <tt><b>xos</b></tt> (for X OS).
|
||
|
*
|
||
|
* @subsection new_compat_os_h_file_sec Create New Compat Header File
|
||
|
*
|
||
|
* You'll need to create a new header file
|
||
|
* <b><tt>include/pj/compat/os_xos.h</tt></b>. You can copy as a
|
||
|
* template other header file and edit it accordingly.
|
||
|
*
|
||
|
* @subsection modify_config_h_file_sec Modify config.h
|
||
|
*
|
||
|
* Then modify file <b><tt>include/pj/config.h</tt></b> to include
|
||
|
* this file accordingly (e.g. when macro <tt><b>PJ_XOS</b></tt> is
|
||
|
* defined):
|
||
|
*
|
||
|
\verbatim
|
||
|
...
|
||
|
#elif defined(PJ_XOS)
|
||
|
# include <pj/compat/os_xos.h>
|
||
|
#else
|
||
|
#...
|
||
|
\endverbatim
|
||
|
*
|
||
|
* @subsection new_target_mak_file_sec Create New Global Make Config File
|
||
|
*
|
||
|
* Then you'll need to create global configuration file that
|
||
|
* is specific for this OS, i.e. <tt><b>os-xos.mak</b></tt> in
|
||
|
* <tt><b>$PJPROJECT/build</b></tt> directory.
|
||
|
*
|
||
|
* At very minimum, the file will normally need to define
|
||
|
* <tt><b>PJ_XOS=1</b></tt> in the \c CFLAGS section:
|
||
|
*
|
||
|
\verbatim
|
||
|
#
|
||
|
# $PJPROJECT/build/os-xos.mak:
|
||
|
#
|
||
|
export OS_CFLAGS := $(CC_DEF)PJ_XOS=1
|
||
|
export OS_CXXFLAGS :=
|
||
|
export OS_LDFLAGS :=
|
||
|
export OS_SOURCES :=
|
||
|
\endverbatim
|
||
|
*
|
||
|
*
|
||
|
* @subsection new_target_prj_mak_file_sec Create New Project's Make Config File
|
||
|
*
|
||
|
* Then you'll need to create xos-specific configuration file
|
||
|
* for PJLIB. This file is also named <tt><b>os-xos.mak</b></tt>,
|
||
|
* but its located in <tt><b>pjlib/build</b></tt> directory.
|
||
|
* This file will specify source files that are specific to
|
||
|
* this OS to be included in the build process.
|
||
|
*
|
||
|
* Below is a sample:
|
||
|
\verbatim
|
||
|
#
|
||
|
# pjlib/build/os-xos.mak:
|
||
|
# XOS specific configuration for PJLIB.
|
||
|
#
|
||
|
export PJLIB_OBJS += os_core_xos.o \
|
||
|
os_error_unix.o \
|
||
|
os_time_ansi.o
|
||
|
export TEST_OBJS += main.o
|
||
|
export TARGETS = pjlib pjlib-test
|
||
|
\endverbatim
|
||
|
*
|
||
|
* @subsection new_target_src_sec Create and Edit Source Files
|
||
|
*
|
||
|
* You'll normally need to create at least these files:
|
||
|
* - <tt><b>os_core_xos.c</b></tt>: core OS specific
|
||
|
* functionality.
|
||
|
* - <tt><b>os_timestamp_xos.c</b></tt>: how to get timestamp
|
||
|
* in this OS.
|
||
|
*
|
||
|
* Depending on how things are done in your OS, you may need
|
||
|
* to create these files:
|
||
|
* - <tt><b>os_error_*.c</b></tt>: how to manipulate
|
||
|
* OS error codes. Alternatively you may use existing
|
||
|
* <tt>os_error_unix.c</tt> if the OS has \c errno and
|
||
|
* \c strerror() function.
|
||
|
* - <tt><b>ioqueue_*.c</b></tt>: if the OS has specific method
|
||
|
* to perform asynchronous I/O. Alternatively you may
|
||
|
* use existing <tt>ioqueue_select.c</tt> if the OS supports
|
||
|
* \c select() function call.
|
||
|
* - <tt><b>sock_*.c</b></tt>: if the OS has specific method
|
||
|
* to perform socket communication. Alternatively you may
|
||
|
* use existing <tt>sock_bsd.c</tt> if the OS supports
|
||
|
* BSD socket API, and edit <tt>include/pj/compat/socket.h</tt>
|
||
|
* file accordingly.
|
||
|
*
|
||
|
* You will also need to check various files in
|
||
|
* <tt><b>include/pj/compat/*.h</b></tt>, to see if they're
|
||
|
* compatible with your OS.
|
||
|
*
|
||
|
* @subsection new_target_build_file_sec Build The Project
|
||
|
*
|
||
|
* After basic building blocks have been created for the OS, then
|
||
|
* the easiest way to see which parts need to be fixed is by building
|
||
|
* the project and see the error messages.
|
||
|
*
|
||
|
* @subsection new_target_edit_vs_new_file_sec Editing Existing Files vs Creating New File
|
||
|
*
|
||
|
* When you encounter compatibility errors in PJLIB during porting,
|
||
|
* you have three options on how to fix the error:
|
||
|
* - edit the existing <tt>*.c</tt> file, and give it <tt>#ifdef</tt>
|
||
|
* switch for the new OS, or
|
||
|
* - edit <tt>include/pj/compat/*.h</tt> instead, or
|
||
|
* - create a totally new file.
|
||
|
*
|
||
|
* Basicly there is no strict rule on which approach is the best
|
||
|
* to use, however the following guidelines may be used:
|
||
|
* - if the file is expected to be completely different than
|
||
|
* any existing file, then perhaps you should create a completely
|
||
|
* new file. For example, file <tt>os_core_xxx.c</tt> will
|
||
|
* normally be different for each OS flavour.
|
||
|
* - if the difference can be localized in <tt>include/compat</tt>
|
||
|
* header file, and existing <tt>#ifdef</tt> switch is there,
|
||
|
* then preferably you should edit this <tt>include/compat</tt>
|
||
|
* header file.
|
||
|
* - if the existing <tt>*.c</tt> file has <tt>#ifdef</tt> switch,
|
||
|
* then you may add another <tt>#elif</tt> switch there. This
|
||
|
* normally is used for behaviors that are not totally
|
||
|
* different on each platform.
|
||
|
* - other than that above, use your own judgement on whether
|
||
|
* to edit the file or create new file etc.
|
||
|
*/
|
||
|
|
||
|
#endif /* __PJ_DOXYGEN_H__ */
|
||
|
|