Index by title

FastCGI on Apache

Using mod_fastcgi

You'll need to enable mod_fastcgi first for Apache. In most cases, this is done by linking the module's configuration file fastcgi.conf from mods-available to mods-enabled (this can be done by running a2enmod.

Next you need to modify the configuation file:

<IfModule mod_fastcgi.c>
  AddHandler fastcgi-script .wt
  FastCgiIpcDir /var/lib/apache2/fastcgi
  FastCgiConfig -idle-timeout 100 -maxClassProcesses 1 -initial-env WT_APP_ROOT=/tmp
</IfModule>

This will automatically start any file ending with .wt as a FastCGI executable. You can also use "external CGIs", which allow you to control in more detail how a single application gets started (and restarted):

  FastCgiExternalServer /var/www/wt-examples/simplechat/simplechat.wt -host localhost:9091 -idle-timeout 200

For this latter deployment option, you need to use the FastCGI utility cgi-fcgi to run the Wt application independent of the web server. When a request for the application is received by the web server, it is forwarded to your FastCGI application using the FastCGI protocol over the given TCP connection.

The only thing left to do is enable CGI execution in your Apache configuration (see below).

Using mod_fcgid

You'll need to enable mod_fcgid first for Apache. In most cases, this is done by linking the module's configuration file fcgid.conf from mods-available to mods-enabled (this can be done by running a2enmod.

Next you need to modify the configuration file:

<IfModule mod_fcgid.c>
  AddHandler fcgid-script .wt
  SocketPath /var/lib/apache2/fcgid/sock
  IdleTimeout -1
  ProcessLifeTime -1
  MaxProcessCount 10
  DefaultMaxClassProcessCount 10
  DefaultMinClassProcessCount 1
</IfModule>

and then do this command:

    chown www-data:www-data /var/run/wt -R

Enabling CGI in Apache

Next, we create a new "site" configuration file for Wt applications: /etc/apache2/sites-available/wt which we will install in /var/www/wt (this must be a directory within your docroot):

<Directory /var/www/wt/>
  #Order Deny,Allow
  Allow from all
  # Enable CGIs to be executed 
  Options ExecCGI
</Directory>

Then, we need to create folder /var/run/wt and to give the Apache server write permissions to that directory.
Next I enable the site and reload Apache:
    a2ensite wt
    /etc/init.d/apache2 reload

If it does not work

You may need to create a run directory with the proper permissions:

sudo mkdir /var/run/wt
sudo chown www-data:www-data /var/run/wt -R

Verify that you have at least two threads configured in /etc/wt/wt_config.xml:

<num-threads>2</num-threads>

Ensure yourself that your wt application is linked against libwtfcgi instead of libwthttpd. E.g. in your own CMakeLists.txt, write

target_link_libraries(hello.wt wt wtfcgi .......)

or for the examples included with Wt, set EXAMPLES_CONNECTOR to wtfcgi:
cmake -DEXAMPLES_CONNECTOR="wtfcgi" 

Look for errors in your apache error log. Especially if you see wt complaining about 'stat' and 'docroot not being set', this means that your executable is linked to wthttpd instead of wtfastcgi; in this case you need to fix your linker options first.


FastCGI on lighttpd

openSUSE configuration

Flat File Configuration

If you have a single configuration file, add such a section
server.modules += ( "mod_fastcgi" )
fastcgi.server += ("/helloworld" =>
                   ("helloworld" =>
                     ("socket" => "/usr/wt/socket",
                      "bin-path" => "/srv/www/cgi-bin/helloworld.fcgi",
                      "max-procs" => 1,
                      "check-local" => "disable",
                      "bin-environment" => ("FOO" => "bar")
                     )
                    )
                )
 

/usr/wt

The FastCGI socket has been put into /usr/wt/socket because the default Wt build does put its own session server sockets as $prefix/wt/run/server-$X. There is no requirement to let the lighttpd precreate FastCGI Wt servers to handle different connections as Wt will schedule server creation and session scheduling internally. The internal creation of session servers is not logged to httpd log (where it should be).


FastCGI on nginx

About nginx

On paper, nginx is an excellent choice for use as a reverse proxy (together with wthttpd), or for deploying Wt applications using FastCGI, especially if you are using server-initiated updates (server push).

The reason is that nginx, like wthttpd, is completely based on asynchronous I/O, and therefore scales easily to many open connections (unlike other web servers such as Apache, lighttpd, etc.). Server-initiated updates use an open connection for every web client.

We have tested nginx succesfully for both its use as a reverse proxy or for FastCGI deployment of Wt applications. Its FastCGI implementation is a bit clumsy, but newer versions of nginx (>= 0.7.31) than the version currently available in ubuntu should improve on that.

Ubuntu configuration

 $ sudo apt-get install nginx lighttpd
 $ spawn-fcgi -n -f ../../build/examples/hello/hello.wt -a 0.0.0.0 -p 9091
        location /hello.wt {
                fastcgi_pass   127.0.0.1:9091;

                fastcgi_param  QUERY_STRING       $query_string;
                fastcgi_param  REQUEST_METHOD     $request_method;
                fastcgi_param  CONTENT_TYPE       $content_type;
                fastcgi_param  CONTENT_LENGTH     $content_length;

                if ($document_uri ~ "^/hello.wt/(.*)") {
                        set $apache_path_info /$1;
                }

                fastcgi_param  SCRIPT_NAME        /hello.wt;
                fastcgi_param  PATH_INFO          $apache_path_info;
                fastcgi_param  REQUEST_URI        $request_uri;
                fastcgi_param  DOCUMENT_URI       $document_uri;
                fastcgi_param  DOCUMENT_ROOT      $document_root;
                fastcgi_param  SERVER_PROTOCOL    $server_protocol;

                fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
                fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

                fastcgi_param  REMOTE_ADDR        $remote_addr;
                fastcgi_param  REMOTE_PORT        $remote_port;
                fastcgi_param  SERVER_ADDR        $server_addr;
                fastcgi_param  SERVER_PORT        $server_port;
                fastcgi_param  SERVER_NAME        $server_name;
        }

Feature wishlist

This is the current community wishlist for features in the Wt library.

Feel free to suggest features you feel are lacking now, or comment on existing wishes. Wt developers will use this list to prioritize development (instead of simply working on their favourite thing), and also to indicate how particular features will be shaped.

Widgets

Add here widgets you would like to see implemented in Wt.

Detail what it should do, your wishes for the API if you have any, and perhaps pointers to an equivalent widget in other toolkits.

Database

Development Tools

Configuration

allow runtime configuration for widget tree structure and bindings

Integrated Features

Foreign language bindings

This is also a recurring request on the mailing list. It would make a lot of sense to have a high quality set of bindings (including native documentation, full support for inheritance), which would result in a high-performance solution for creating web applications in scripting languages. Such a solution is likely to be high performance since most of the complexity lies in the rendering and not in the widget construction/manipulation and event handling. The rendering will still be native C++.

We are currently looking at how we can best tackle this so that we can keep the bindings in sync with the latest release of Wt... Any suggestions are welcome.

Deployment

Load Balancer, Incremental Deployment

Because sessions are node-bound, a load balancer should be provided which keeps track of sessions bound to a specific node. This same load balancer could also be used to migrate new users to a new application instance, while keeping existing users on a previous applications instance, in this way facilitating incremental deployment of new application versions.

For Unix like systems there is already Pound!

Scalability, Cluster Computing

Perhaps at a future date it would be possible to implement support for cluster computing with wt. That would make load balancing easier, and it would especially address the issue of scalability.

Session Scalability

Ability to pass session to a database/server so that if system currently running the session dies the user can be re-directed to other machine (through load balancing/fallover) and new instance can reload users session and continue

Localization

PO-based localization

Built-in PO-based localization support for Wt could make work of translators so much easier, because there exist many tools for PO files (e.g. Pootle).

Wt developers opinion: we will probably not implement this soon, since the current approach with the XML files has the benefit (for web applications) of helping in supporting large chunks of XHTML-formatted text, and general purpose editor support for unicode (UTF8-encoded) text.

Community

3rd Party/Sandbox directory

Create a sandbox directory where 3rdParty / contributed code would be placed . Removes the headache of copyrighting

SoC

Ideas for Google SoC, 2009

Example Application

Quick Starter

Create a stand alone project where you can download a single tarball and begin working on wt. Ideally everything will be local to the project and there is zero install. By zero install, I mean no wt, boost, or cmake installs. Make it really easy. Everything should be simple and already configured. Something in the spirit of Instant Rails.


Frequently Asked Questions

Building and deployment

Q: I built Wt and the examples, but many examples don't display correctly

If you are running the built example from within the build directory, then the examples will not find their resources bundles (.xml) files and the resources (CSS, images) will not be where they are to be expected.

The examples are designed that you can run them without much hassle from the source directory.

For example, to run composer, you should do the following:

$ cd wt/examples/composer   # source directory for composer example
$ ln -s ../../resources .   # link the resources folder
$ ../../build/examples/composer/composer.wt --docroot . --http-address 0.0.0.0 --http-port 8080

Q: How do I build my newly written "Hello World!" application?

Wt itself, and the examples, use CMake, but that is entirely a personal choice. You can use any build environment, like qmake, where
you:

Unlike Qt, there is no need for special features such as moc for starting a Wt project.

If you decide to use CMake, and have installed Wt in its default location (within /usr/local), this CMakeLists.txt file should do it:

ADD_EXECUTABLE(myprog.wt
MyProg1.C
OtherFile.C
AndEvenMoreCode.C
)

# For FastCGI deployment:
TARGET_LINK_LIBRARIES(myprog.wt
wtfcgi wt someotherlib
)

# Or, for built-in httpd deployment:
# TARGET_LINK_LIBRARIES(myprog.wt
#   wthttp wt someotherlib
# )

INCLUDE_DIRECTORIES(/usr/local/wt/include)

When you did not install the Wt libraries in /usr/local/lib/, you will need to use the LINK_DIRECTORIES command to inform CMake about the location of the Wt libraries. Make sure to use this command before the ADD_EXECUTABLE and/or ADD_LIBRARY command.

The examples use a CMakeLists.txt which is customized for using the current build of Wt, and not that one that is already installed some place (with make install). Therefore, it is not really the recommended way to bootstrap your own Wt project. Also, the ./deploy scripts are very primitive, and are a bit specific for the examples. Deploying is nothing more than copying the files to some directory in your html root.

The other methods are:

To handle many sourcefiles, dependencies... you need a makefile. Obviously, the way Wt is designed, you should have quickly many files for the many classes that will compose your app. Wt uses CMake:http://cmake.org to make makefiles and that is probably a good choice. Just like many others, I switched to CMake (from hand-written makefiles) because of Wt and I am pretty happy with it.

make should produce the executable. At this point, you probably need to move the output of make to a directory available to your webserver; in practice you therefore need a script that is going to deploy the file. When you name the app, be sure the extension is recognized by the webserver. Also, you may need to kill active processes of your app and maybe copy the css and some other files (icons...) to the directory available to the webserver.
In the end, I bundled all that in a deploy file located in the build directory (the one that is usually created for CMake). After I have have finished changing the source files, I just type ./deploy on the command line and I can refresh my web page.

make
target_app=app.wt
target_path=httpdocs
ps -A | grep app.wt | awk '{print $1}' | xargs kill
rm -f "~/${target_path}/${target_app}" 
cp "${target_app}" ~/${target_path}/
cp ../app.css  ~/${target_path}/

OR

You can use install command instead of cp, more or less like this:

install -m 0755 astariand.wt /var/www/game
install -m 0644 messages.xml /var/www/game
install -m 0644 astariand.css /var/www/game
install -m 0644 login.php /var/www/game
install -m 0644 includes.php /var/www/game
install -m 0755 -d /var/www/game/media
install -m 0755 -d /var/www/game/media/icons
install -m 0644 media/icons/* /var/www/game/media/icons
install -m 0755 -d /var/www/game/media/images
install -m 0644 media/images/* /var/www/game/media/images

Using install has two advantages. First, it allows you to set permissions on the fly (just as user and group, but I don't use this). Second, with
dedicated process session management you don't need to kill all processes beforehand - old connections will keep using the old binary and new
connections will use the new one, until all old connections "die from natural reasons".

Q: My browser shows a window with a message like 'Wt internal error: ReferenceError: Ext is not defined, code: undefined, description: undefined'. How do I resolve it?

Check your log for 404 messages regarding ExtJs. Download Ext 2.0.1 or 2.0.2 from the ExtJs homepage and install it as described here. ExtJs 2.0.2 is available for download here.

You will receive similar error messages when you use a WTextEdit and TinyMCE is not properly deployed. Download TinyMCE from the TinyMCE homepage.

ExtJS and TinyMCE need to be available in the document root of your web server. By default, Wt expects ext-related files to be found in 'ext/' (relative to your application deployment location), and TinyMCE in 'resources/tiny_mce/'.

For example (Wt 2.2.1), to run the widgetgallery example (which needs both ExtJS and TinyMCE) from within its source directory, you need the following organisation of auxiliary files:

 $ pwd
 /home/.../wt/examples/widgetgallery
 $ ls ext/
 ext-all.js  ext-base.js  resources
 $ ls resources/
 collapse.gif      items-ok.gif     nav-minus.gif              nav-plus-line-middle.gif  sort-arrow-down.gif  tab_l.gif
 expand.gif        line-last.gif    nav-minus-line-last.gif    orbited.js                sort-arrow-none.gif  tab_r.gif
 iframe.js         line-middle.gif  nav-minus-line-middle.gif  orbited_LICENSE.txt       sort-arrow-up.gif    tiny_mce
 items.gif         line-trunk.gif   nav-plus.gif               slider-thumb-h.gif        stripes              tv-line-last.gif
 items-not-ok.gif  loading.png      nav-plus-line-last.gif     slider-thumb-v.gif        tab_b.gif
 $ ls resources/tiny_mce/
 langs  license.txt  plugins  themes  tiny_mce.js  tiny_mce.js.gz  tiny_mce_popup.js  tiny_mce_src.js  utils

and then you can run the example using the following command line:

 $ ../../build/examples/widgetgallery/widgetgallery.wt --http-address=0.0.0.0 --http-port=8080 --docroot .

Q: My browser shows an empty window and I am disappointed now.

See the previous question.

Q: How does Wt organize sessions in processes and threads?

Wt makes a distinction in the conceptual organization (which is reflected in the API of WApplication) and the way the application is actually deployed.

Conceptually, every user session is completely isolated from each other. For each new session, Wt calls the function that is supplied to WRun(), to create a WApplication object for that session. As a programmer, you should program for the general case where different WApplication objects are in different processes, and thus if you wish to communicate between different session, you have the following options: (in increasing order of flexibility traded for convenience):

Physically, Wt offers several choices for deployment, each of them with different trade-offs. If an application sticks strictly to the previous rules, you can freely change between different deployment options at deployment time.

The options that are available are:

Wt is capable of using multi-threading to improve performance for both situations. Threads are used for simultaneous handling of requests. Even in dedicated-process mode, several requests may be handled simultaneously, for example concurrent streaming of different WResource's. The multi-threading feature however is more important for shared-process mode, for handling concurrent requests for different sessions. In the latter case, however, the number of threads must not
equal the number of active sessions: threads are reused after every request is handled.

The shared-process mode has the notable disadvantage, inherent to C++, that memory corruption may occur and can take down all sessions. It is however well suited for 'open' applications on the Internet (and the Wt homepage and all examples are deployed this way). If you design a restricted access application, or possibly a security sensitive application, or deploy the application on a private intranet, the dedicated process mode may be more suitable.

Q: How does it compare to Java servlets?

Differences with Java Servlets are mostly due to the Java Virtual Machine. Java has the benefit of automating pointer manipulation, and therefore eliminating unwanted interference between different sessions because of pointer bugs. On the other hand, because of the high costs (both run-time start up as well as memory usage) associated with a Java Virtual Machine instance, Java cannot afford kernel-level isolation between different Java sessions. If not programmed properly, two sessions can still interfere through for example the use of class static variables. Unfortunately, some servlet based frameworks, like the often-used struts framework, actually encourage sharing of for example form objects between different sessions for run-time efficiency reasons, making session cross talk readily an issue.

Similarities between Wt and Java Servlets are the use of a thread pool to serve concurrent requests, and the abstraction of actual deployment details from the API, allowing easy scalability.

Note: you should consider using JWt if you would like to develop in Java.

API

Q: How do I deal with look and layout? Does Wt support CSS?

Wt provides you with two options for layout.

Q: How do I pass an additional argument from a signal to a slot?

Frequently, you may want to connect many different signals to a single slot, and identify the original sender in the slot.

For example:

 void Test::createWidgets()
 {
   // create text1, text2, text3 widgets

   text1->clicked.connect(SLOT(this, Test::onClick));
   text2->clicked.connect(SLOT(this, Test::onClick));
   text3->clicked.connect(SLOT(this, Test::onClick));
 }

 void Test::onClick()
 {
   // How to know which widget?
 }

The solution is to use a WSignalMapper like this:

 void Test::createWidgets()
 {
   Wt::WSignalMapper<Wt::WText> *myMap = new Wt::WSignalMapper<Wt::WText*>(this);

   myMap->mapped.connect(SLOT(this, Test::onClick));
   myMap->mapConnect(text1->clicked, text1);
   myMap->mapConnect(text2->clicked, text2);
   myMap->mapConnect(text3->clicked, text3);
 }

 void Test::onClick(Wt::WText* source)
 {
   // source is where it is coming from
   // ...
 }

The additional argument can be of any type, since WSignalMapper is a template class. It could for example be the button text, or some other information specific to the widget that is activated.

Q: How do I update my application window from another thread, or from a socket notifier?

A:
See the documentation for Wt::WApplication::enableUpdates().

Security

Q: Building web applications in a low-level language like C? Have you never heard of buffer overruns??

We are well aware of the hostile environment that is the Internet. We believe that Wt provides some unique benefits compared to other solutions to handle the most common attacks:

All these attacks (except for the last one) are commonly exploited against current-day web applications which are vulnerable by the simple fact that too many web-related details are in the hands and responsibility of the developer. In contrast, Wt actively helps in avoiding programming mistakes which may lead to these exploits.

Q: How do I use the built-in HTTPS server in wthttpd?

You will need a private server key that is signed by a certificate authority, and a temporary file containing random Diffie-Hellman parameters. If you are simply experimenting with the feature, then you can create and sign a key yourself, or use the one that comes with the OpenSSL distribution (server.pem, which has the password 'test'). The file with Diffie-Hellman parameters can be created using the command:

$ openssl dhparam -check -text -5 512 -out dh512.pem

Then start Wt using:

$ ./app.wt --https-address=0.0.0.0 --ssl-certificate=server.pem --ssl-private-key=server.pem --ssl-tmp-dh=dh512.pem

Provide the password at the prompt.

To generate your own self-signed certificate:

# This sequence is found all over the internet:
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key # removes the passphrase
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
# The PEM file is a combination of what is above:
cat server.crt server.key server.crt > server.pem

Trouble shooting

Q: My application crashes, and my apache error log shows no information.

There is a known problem with mod_fcgid: STDERR (including everything printed to std::cerr) is not saved to the apache error log.

Wt uses STDERR by default for all error reporting. You can use a different log file in your wt_config.xml file (<log-file>).

You may also consider using mod_fastcgi or the built-in web server (wthttpd) during development. The latter is especially convenient for development as it allows you to start from within a debugger, or diagnose memory-related problems with valgrind.


Getting the built in http server to work

Here is a list of possible gotchas

//Compile in stand-alone httpd connector (libwthttp) ?
CONNECTOR_HTTP:BOOL=ON
terminate called after throwing an instance of '__gnu_cxx::recursive_init'

This is an issue with asio 0.3.7, apply the following patch to your asio library. (Gentoo already has this patch)


Ideas for Google SoC

This page lists ideas for Google SoC 2010 applications for Wt, pending the approval of Emweb as a mentoring organisation. The page lists ideas that come from community members, project maintainers, in no particular order. We recommend interested students to show interest on the mailing list and discuss with the community the idea that they would like to work on before applying formally with Google SoC.

In addition the the summary of ideas here, an interested student may also wish to look at the extensive discussion that happened on the mailing list: http://thread.gmane.org/gmane.comp.web.witty.general/4611

Contact information: koen@emweb.be or the Wt interest mailinglist: witty-interest@sourceforge.net.

WebKit integration

It would be fantastic to have WebKit integrated with Wt. The level of integration may evolve over time, as are the possible applications. The combination of both a top-notch browser implementation, together with a web framework, all in C++, provides a whole world of new possibilities from new application options to kludge-free automated test frameworks based on an actual browser and rendering logic.

The first step is to combine WebKit with the built-in httpd to provide a desktop application using Wt. This could be useful for distributing an off-line version of a Wt application or during development. The webkit would be configured to act as a single application (instead of as a general purpose browser). Some preliminary work has been done and the project has been bootstrapped by Pau Garcia (contact him through the Wt interest mailinglist), which can be found at http://gitorious.org/wtdesktop.

In a second step, some of the widgets provided by Wt could be made aware of the integration with webkit to provide improved functionality. For example, WFileUpload could use a native file open widget instead of HTML. Other features are the binding of WApplication::quit() to exit the actual application, and the ability to control and use the native menu provided by the Qt or GTK toolkit from Wt code.

A third level of integration is to allow introspection of the DOM inside WebKit from a Wt application session. This could become the basis for an automated testing framework which verifies that the widget tree and the DOM tree are in sync. By querying the DOM for information on the location and CSS properties of widgets, it can be checked that the application works properly. By allowing for events to be simulated on the DOM tree, the application can be checked for correct event handling.

The fourth level of integration is to by-pass the HTML/JavaScript and HTTP protocol for certain rendering steps. For example, a new WPaintDevice could be developed which paints directly instead of encoding it first as SVG or HTML Canvas5 JavaScript. This would allow significant speedups for vector graphics.

Another idea that circulated on the mailing list was to target QML for rendering certain parts of the user interface, skipping the webkit dependence and targetting directly Qt. This would result in even better performance and be more light weight.

Required expertise: Good C++ knowledge, some familiarity with GTK, Qt, and CMake will be useful.

The scope and goals of this idea can be adapted to the skill set of the student, since for every additional level of integration, more detailed intimate knowledge of WebKit and Wt are required. Since the project has already been bootstrapped, the student will be able to more directly start actual development rather than be busy with setting up and configuring the build system.

Widget set mode

Since about a year, Wt includes a so-called widget-set mode. In this mode, a Wt application does not take responsibility to render the entire user interface, but only selected <div>'s. The Wt application is loaded as a JavaScript library, which then renders into these <div>'s, which then correspond to a set of "top-level" widgets. Any of Wt's features may be used inside such a widget, including portable vector graphics and fragment-based history management.

This would allow a Wt application to also expose a JavaScript API, such as for example Google Maps, but this has not yet been provided. To provide support for this in the Wt library, it would require that a Wt application can extend its JavaScript object with JavaScript methods that map onto C++ methods, which assumes a system that helps as much as possible to convert between JavaScript objects and C++ data structures (for example based on maps).

Improvements to widget set mode will allow easy development of OpenSocial applications in Wt.

Required expertise: Good C++ knowledge, template meta programming and type traits, some JavaScript knowledge.

Wt Designer

A lot of discussion has been going on over the years on a visual designer tool for Wt. Inevitably, many directions can be taken and proponents of different ideas can be found on the mailinglist.

Wt Designer based on Qt Creator / Qt Designer

Since Wt shares alot with Qt, in terms of API and programming model, it should be possible to adapt Qt Designer to design Wt widgets.

In a first step, the .ui format used by the Qt Designer tool and User Interface Compiler (UIC) could be adapted to so that it can be used to instantiate a custom Wt widget at runtime, or can be used to compile to a C++ file.

More details (detailed steps, roadmap, possible blockers, etc) here: http://article.gmane.org/gmane.comp.web.witty.general/4293

Wt Designer based on a (XHTML-like) template language

Another line of thought is to create a Wt application that would allow the construction of "empty" widgets, through a web application. The advantage of this approach is that contrary to t Designer, the widgets would render on the final web application as they render in the Wt. The product of this designer Wt application would be an HTML-based template. Any .ui interface etc. would mean unnecessary overhead in the development cycle etc. etc.

This approach thus centers around an (improved) templating widget (current, WTemplate, is really very minimalistic, supporting only string substitutions), which has a counter-part implementation that provides an editing mode.

This would require a start from scratch. The designer application can still be a desktop application, using the Wt / WebKit integration approach as above, or one could still consider to implement the whole application in Qt

How to tackle ?

This idea will first require some discussion on the mailing list. Both approaches seem valid and have there merits, and both are alot of work. The first approach would require getting to understand Qt Designer, the second approach requires a lot of original code.

Required expertise: Good C++ knowledge, requires functional analysis and good communication.

MVC integration of Wt::Dbo models with Wt views.

Required expertise: Good to Expert C++ knowledge (template meta programming)

WSocketNotifier

Implement WSocketNotifier (like QSocketNotifier) properly with a custom select loop. The current implementation (on httpd) tries to tie into asio's select loop, but asio does not support this use-case very well (with socket numbers instead of boost asio's socket abstraction).

It is also possible to wrap a socket completely to WSocket and define specific use cases for Wt applications communicating with other applications/web services etc... Given the convenience of asio, it probably makes sense to define an API in terms of boost::asio sockets.

Modifications of WTemplate to provide a full grown templating system

Goals:

All of those features should be disabled to discard this overhead when working on thight embedded machines.
Instead of binding widgets like now you would just get them using resolve.

This idea relates also to the Wt Designer idea, the second approach.

Backends for Wt::Dbo

Currently (March, 12, 2010), Wt::Dbo supports only a single backend (SQLite3), with a PostgreSQL backend being developed. Support for other databases is thus welcome. More specifically, we would like to support MySQL through libdrizze, but also backends for other SQL and NoSQL databases.

The API for adding a backend is quite light-weight (, and an automated test suite is in place to check that the backend works well.

Widget (Controller) <-> Model Integration

The current situation is that only a few of Wt's widgets support models.
This situation complicated the development of widgets who have a datasource like a database, a webservice, another process ect.
The following code demonstrates how it should be implemented.
Wt should have a generic model mixin which will attach itself onto a widget like this:

template <class Widget>
class WModel;

template <template class Model, class Widget>
class WModelAttacher;

 // MyModel only applies to WLineEdit, this can be anything using a template parameter
class MyModel : public WModel<WLineEdit>
{
public:
  MyModel(WLineEdit &widget)
  : WModel(widget) // attaches change of value/values signals to the model to a uniform valueChanged
  {
    modelValueChanged.connect(SLOT(this, foo)); // if something changes in the model raise this
    valueChanged.connect(SLOT(this, bar)); // If something changes outside the model, update the model which will update the datasource
  }
};

// ...

class SomeApp : public WApplication
{
  WModelAttacher<MyModel, WLineEdit> *widget; // Creates a combined widget
};

Required knowledge: Good experience with C++, Extensive experience with policy based design or will to learn it and MVC


Installing MSVC

General

We suggest to use MSVC 2005 or higher, Standard/Professional/Team Edition, or the free Express edition.

At the time of writing, the most recent MSVC compiler is MSVC2010.

Installing MSVC, Express Edition

Steps to install MSVC C++ EE on your computer:

Notes for VS 2010

If you installed SP1 and your C++ compiler does not work anymore, see FIX: Visual C++ compilers are removed when you upgrade Visual Studio 2010 Professional or Visual Studio 2010 Express to Visual Studio 2010 SP1 if Windows SDK v7.1 is installed

Notes for VS 2005

Microsoft has improved MSVC 2005 by means of a service pack; I strongly recommend you upgrade your compiler with this service pack (SP1). This service pack is available both for the full version and the Express Edition at http://msdn2.microsoft.com/en-us/vstudio/bb265237.aspx It is a good idea to drink a cup of coffee while the service pack is installing.

If you are using Vista, MSVC will insist that you also install the SP1 Upgrade for Vista (an additional upgrade to SP1).

If you choose to use MSVS 2005 Express edition, you have to install the Platform SDK manually


xxx


Installing Wt on Android

Warning: Installation of Wt on Android is a bit more complex than it should be. The dependencies (NDK, boost) don't support this platform perfectly, and thus you must be prepared to patch these if you encounter problems. This page describes how I made my first Wt on Android build.

Installing the Cross Compilation Tools

At the time of writing, Google's NDK C++ support is insufficient to compile boost or Wt. Use the crystax NDK, a fork of the official Google NDK, instead. Download the prebuilt tools for your platform and install them somewhere.

Cross Compiling Boost for Android

I used boost 1.44.0. Download and unpack it somewhere.

Run the bootstrap script to compile bjam.

Edit the boost_1_44_0/project-config.jam file to add some defaults. I made the following changes:

# Python configuration
#using python : 2.6 : /usr ;

libraries = --with-date_time --with-filesystem --with-program_options --with-regex --with-signals --with-system --with-thread ; 

# These settings are equivivalent to corresponding command-line
# options.
option.set prefix : /home/wim/project/android/boost ;
option.set exec-prefix : /home/wim/project/android/boost ;
option.set libdir : /home/wim/project/android/boost/lib ;
option.set includedir : /home/wim/project/android/boost/include ;

In boost_1_44_0/tools/build/v2/user-config.jam, add the following lines (modify paths to your NDK installation directory as needed):

using gcc : arm : /home/wim/project/android/android-ndk-r4-crystax/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-c++ :
<compileflags>-I/home/wim/project/android/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/
<compileflags>-fpic
<compileflags>-mthumb-interwork
<compileflags>-ffunction-sections
<compileflags>-funwind-tables
<compileflags>-fstack-protector
<compileflags>-fno-short-enums
<compileflags>-D__ARM_ARCH_5__
<compileflags>-D__ARM_ARCH_5T__
<compileflags>-D__ARM_ARCH_5E__
<compileflags>-D__ARM_ARCH_5TE__
<compileflags>-Wno-psabi
<compileflags>-march=armv5te
<compileflags>-mtune=xscale
<compileflags>-msoft-float
<compileflags>-mthumb
<compileflags>-Os
<compileflags>-fomit-frame-pointer
<compileflags>-fno-strict-aliasing
<compileflags>-finline-limit=64
<compileflags>-DANDROID
<compileflags>-D__ANDROID__
<compileflags>-Wa,--noexecstack
# 'official' android flags stop here
<architecture>arm
<compileflags>-fvisibility=hidden
<compileflags>-fvisibility-inlines-hidden
<compileflags>-fdata-sections
<cxxflags>-DBOOST_THREAD_LINUX
<cxxflags>-DBOOST_HAS_PTHREADS
<cxxflags>-D__arm__
<cxxflags>-D_REENTRANT
<cxxflags>-D_GLIBCXX__PTHREADS
<cxxflags>-DBOOST_HAS_GETTIMEOFDAY
;

You'll need to patch boost. This is a diff of my patched boost against an original one:

diff -ru orig/boost_1_44_0/boost/asio/detail/fenced_block.hpp boost_1_44_0/boost/asio/detail/fenced_block.hpp
--- orig/boost_1_44_0/boost/asio/detail/fenced_block.hpp    2010-07-12 01:42:34.000000000 +0200
+++ boost_1_44_0/boost/asio/detail/fenced_block.hpp    2010-09-02 10:43:21.000000000 +0200
@@ -25,14 +25,14 @@
 # include <boost/asio/detail/macos_fenced_block.hpp>
 #elif defined(__sun)
 # include <boost/asio/detail/solaris_fenced_block.hpp>
-#elif defined(__GNUC__) && defined(__arm__)
+#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__)
 # include <boost/asio/detail/gcc_arm_fenced_block.hpp>
 #elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
 # include <boost/asio/detail/gcc_hppa_fenced_block.hpp>
 #elif defined(__GNUC__) \
   && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
   && !defined(__INTEL_COMPILER) && !defined(__ICL) \
-  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) && !defined(ANDROID)
 # include <boost/asio/detail/gcc_sync_fenced_block.hpp>
 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
 # include <boost/asio/detail/gcc_x86_fenced_block.hpp>
@@ -54,14 +54,14 @@
 typedef macos_fenced_block fenced_block;
 #elif defined(__sun)
 typedef solaris_fenced_block fenced_block;
-#elif defined(__GNUC__) && defined(__arm__)
+#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__)
 typedef gcc_arm_fenced_block fenced_block;
 #elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
 typedef gcc_hppa_fenced_block fenced_block;
 #elif defined(__GNUC__) \
   && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
   && !defined(__INTEL_COMPILER) && !defined(__ICL) \
-  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) && !defined(ANDROID)
 typedef gcc_sync_fenced_block fenced_block;
 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
 typedef gcc_x86_fenced_block fenced_block;
diff -ru orig/boost_1_44_0/boost/asio/detail/socket_types.hpp boost_1_44_0/boost/asio/detail/socket_types.hpp
--- orig/boost_1_44_0/boost/asio/detail/socket_types.hpp    2010-06-09 11:40:46.000000000 +0200
+++ boost_1_44_0/boost/asio/detail/socket_types.hpp    2010-09-01 19:10:27.000000000 +0200
@@ -121,7 +121,11 @@
 typedef int socket_type;
 const int invalid_socket = -1;
 const int socket_error_retval = -1;
+#ifdef INET_ADDRSTRLEN
 const int max_addr_v4_str_len = INET_ADDRSTRLEN;
+#else
+const int max_addr_v4_str_len = 16;
+#endif
 #if defined(INET6_ADDRSTRLEN)
 const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE;
 #else // defined(INET6_ADDRSTRLEN)
diff -ru orig/boost_1_44_0/boost/asio/ip/impl/address_v6.ipp boost_1_44_0/boost/asio/ip/impl/address_v6.ipp
--- orig/boost_1_44_0/boost/asio/ip/impl/address_v6.ipp    2010-06-09 11:40:46.000000000 +0200
+++ boost_1_44_0/boost/asio/ip/impl/address_v6.ipp    2010-09-01 19:10:27.000000000 +0200
@@ -11,6 +11,23 @@
 #ifndef BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP
 #define BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP

+#ifndef IN6_IS_ADDR_MULTICAST 
+#define IN6_IS_ADDR_MULTICAST(a) (((__const uint8_t *) (a))[0] == 0xff)
+#endif
+
+#ifndef IN6_IS_ADDR_MC_NODELOCAL
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a)                                             \
+         && ((((__const uint8_t *) (a))[1] & 0xf) == 0x1))
+#endif
+
+#ifndef IN6_IS_ADDR_MC_GLOBAL
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a)                                             \
+         && ((((__const uint8_t *) (a))[1] & 0xf) == 0xe))
+#endif
+
+
 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
Only in boost_1_44_0/: bootstrap.log
diff -ru orig/boost_1_44_0/libs/filesystem/v2/src/v2_operations.cpp boost_1_44_0/libs/filesystem/v2/src/v2_operations.cpp
--- orig/boost_1_44_0/libs/filesystem/v2/src/v2_operations.cpp    2010-08-10 22:00:09.000000000 +0200
+++ boost_1_44_0/libs/filesystem/v2/src/v2_operations.cpp    2010-09-02 17:38:22.000000000 +0200
@@ -58,14 +58,16 @@

 # else // BOOST_POSIX_API
 #   include <sys/types.h>
-#   if !defined(__APPLE__) && !defined(__OpenBSD__)
+#   if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(ANDROID)
 #     include <sys/statvfs.h>
 #     define BOOST_STATVFS statvfs
 #     define BOOST_STATVFS_F_FRSIZE vfs.f_frsize
 #   else
-#ifdef __OpenBSD__
-#     include <sys/param.h>
-#endif
+#     ifdef __OpenBSD__
+#       include <sys/param.h>
+#     elif defined(ANDROID)
+#       include <sys/vfs.h>
+#     endif
 #     include <sys/mount.h>
 #     define BOOST_STATVFS statfs
 #     define BOOST_STATVFS_F_FRSIZE static_cast<boost::uintmax_t>( vfs.f_bsize )
@@ -1262,7 +1264,20 @@
         if ( max == 0 )
         {
           errno = 0;
+#ifdef ANDROID
+          long tmp = 4096; // is it?
+#if 0
+          {
+            int fd = open( "/", O_RDONLY );
+            if (fd >= 0) {
+              tmp = ::fpathconf( fd, _PC_NAME_MAX );
+              close(fd);
+            }
+          }
+#endif
+#else
           long tmp = ::pathconf( "/", _PC_NAME_MAX );
+#endif
           if ( tmp < 0 )
           {
             if ( errno == 0 ) // indeterminate
Only in boost_1_44_0/libs/filesystem/v2/src: v2_operations.cpp~
diff -ru orig/boost_1_44_0/libs/filesystem/v3/src/operations.cpp boost_1_44_0/libs/filesystem/v3/src/operations.cpp
--- orig/boost_1_44_0/libs/filesystem/v3/src/operations.cpp    2010-08-10 22:00:09.000000000 +0200
+++ boost_1_44_0/libs/filesystem/v3/src/operations.cpp    2010-09-01 19:10:27.000000000 +0200
@@ -66,13 +66,15 @@
 # ifdef BOOST_POSIX_API

 #   include <sys/types.h>
-#   if !defined(__APPLE__) && !defined(__OpenBSD__)
+#   if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(ANDROID)
 #     include <sys/statvfs.h>
 #     define BOOST_STATVFS statvfs
 #     define BOOST_STATVFS_F_FRSIZE vfs.f_frsize
 #   else
 #     ifdef __OpenBSD__
 #     include <sys/param.h>
+#     elif defined(ANDROID)
+#       include <sys/vfs.h>
 #     endif
 #     include <sys/mount.h>
 #     define BOOST_STATVFS statfs
@@ -193,7 +195,19 @@
          || ::mkdir(to.c_str(),from_stat.st_mode)!= 0))
 #   define BOOST_COPY_FILE(F,T,FailIfExistsBool)copy_file_api(F, T, FailIfExistsBool)
 #   define BOOST_MOVE_FILE(OLD,NEW)(::rename(OLD, NEW)== 0)
+#ifndef ANDROID
 #   define BOOST_RESIZE_FILE(P,SZ)(::truncate(P, SZ)== 0)
+#else
+int BOOST_RESIZE_FILE(const char *path, off_t size)
+{
+  int retval = -1;
+  int fd = open(path, O_WRONLY);
+  if (fd != -1)
+    retval = ftruncate(fd, size);
+  close(fd);
+  return retval;
+}
+#endif

 #   define BOOST_ERROR_NOT_SUPPORTED ENOSYS
 #   define BOOST_ERROR_ALREADY_EXISTS EEXIST
diff -ru orig/boost_1_44_0/tools/build/v2/tools/gcc.jam boost_1_44_0/tools/build/v2/tools/gcc.jam
--- orig/boost_1_44_0/tools/build/v2/tools/gcc.jam    2010-04-20 14:05:14.000000000 +0200
+++ boost_1_44_0/tools/build/v2/tools/gcc.jam    2010-09-01 16:37:36.000000000 +0200
@@ -935,8 +935,8 @@
             }
             case * :
             {
-                option = -pthread ;
-                libs = rt ;
+#                option = -pthread ;
+#                libs = rt ;
             }
         }

diff -ru orig/boost_1_44_0/tools/build/v2/tools/gcc.py boost_1_44_0/tools/build/v2/tools/gcc.py
--- orig/boost_1_44_0/tools/build/v2/tools/gcc.py    2009-10-28 08:47:51.000000000 +0100
+++ boost_1_44_0/tools/build/v2/tools/gcc.py    2010-09-01 16:36:22.000000000 +0200
@@ -672,12 +672,14 @@
         # BeOS has no threading options, don't set anything here.
         pass
     elif host_os_name.endswith('BSD'):
-        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
+        #flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
         # there is no -lrt on BSD
+        pass
     elif host_os_name == 'DragonFly':
-        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
+        #flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
         # there is no -lrt on BSD - DragonFly is a FreeBSD variant,
         # which anoyingly doesn't say it's a *BSD.
+        pass
     elif host_os_name == 'IRIX':
         # gcc on IRIX does not support multi-threading, don't set anything here.
         pass
@@ -685,8 +687,9 @@
         # Darwin has no threading options, don't set anything here.
         pass
     else:
-        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
-        flags('gcc', 'FINDLIBS-SA', [], ['rt'])
+        #flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
+        #flags('gcc', 'FINDLIBS-SA', [], ['rt'])
+        pass

 def cpu_flags(toolset, variable, architecture, instruction_set, values, default=None):
     #FIXME: for some reason this fails.  Probably out of date feature code

Now invoke bjam, and you should have a nice boost installation in the path that you specified in project-config.jam.

./bjam link=static threading=multi --layout=versioned install

Preparing Cmake for Cross Compilation to Android

Create a toolchain file. Call it ~/toolchain-android.cmake

SET(ANDROID_DIR /home/wim/project/android/)
SET(ANDROID_NDK_DIR ${ANDROID_DIR}/android-ndk-r4-crystax/)
SET(STAGING_DIR ${ANDROID_NDK_DIR}/build/prebuilt/linux-x86/arm-eabi-4.4.0/)
SET(TARGET_CC ${STAGING_DIR}/bin/arm-eabi-gcc)
SET(TARGET_CXX ${STAGING_DIR}/bin/arm-eabi-c++)

SET(CMAKE_SYSTEM_NAME Android)
SET(CMAKE_SYSTEM_VERSION 1)

SET(CMAKE_SYSTEM_PROCESSOR arm-elf)
SET(CMAKE_C_COMPILER ${TARGET_CC})
SET(CMAKE_CXX_COMPILER ${TARGET_CXX})

SET(CMAKE_FIND_ROOT_PATH  ${ANDROID_DIR})

# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Create a platform file. Put it in a file called cmake/Platform/Android.cmake

SET(ANDROID true)
SET(ANDROID_OPTION_LIST
    -I/home/wim/project/android/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include
    -fpic
    -mthumb-interwork
    -ffunction-sections
    -funwind-tables
    -fstack-protector
    -fno-short-enums
    -D__ARM_ARCH_5__
    -D__ARM_ARCH_5T__
    -D__ARM_ARCH_5E__
    -D__ARM_ARCH_5TE__
    -Wno-psabi
    -march=armv5te
    -mtune=xscale
    -msoft-float
    -mthumb
    -Os
    -fomit-frame-pointer
    -fno-strict-aliasing
    -finline-limit=64
    -DANDROID
    -Wa,--noexecstack
#more options
    -fvisibility=hidden
    -fvisibility-inlines-hidden
    -fdata-sections
    -DBOOST_THREAD_LINUX
    -DBOOST_HAS_PTHREADS
    -D_REENTRANT
    -D_GLIBCXX__PTHREADS
    -DANDROID
    -D__ANDROID__
    -DBOOST_HAS_GETTIMEOFDAY
    -DSQLITE_OMIT_LOAD_EXTENSION
)

foreach(arg ${ANDROID_OPTION_LIST})
  set(ANDROID_COMPILE_FLAGS "${ANDROID_COMPILE_FLAGS} ${arg}")
endforeach(arg ${ANDROID_OPTION_LIST})

SET(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER>  <DEFINES> <FLAGS> ${ANDROID_COMPILE_FLAGS} -o <OBJECT> -c <SOURCE>")
SET(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER>  <DEFINES> <FLAGS> ${ANDROID_COMPILE_FLAGS} -o <OBJECT> -c <SOURCE>")

SET(ANDROID_NDK_PREFIX "/home/wim/project/android/android-ndk-r4-crystax/")
SET(ANDROID_LINK_EXE_FLAGS
    "-nostdlib -Bdynamic -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc" 
    )
SET(ANDROID_CRT_PRE
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/crtbegin_dynamic.o" 
   )
SET(ANDROID_CRT_POST_LIST
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/libmissing.a" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a" 
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/libc.so" 
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/libm.so" 
    "-Wl,--no-undefined" 
    "-Wl,-z,noexecstack" 
    "-L${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib" 
    "-llog" 
    "-Wl,-rpath-link=${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a" 
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/crtend_android.o" 
   )
foreach(arg ${ANDROID_CRT_POST_LIST})
  set(ANDROID_CRT_POST "${ANDROID_CRT_POST} ${arg}")
endforeach(arg ${ANDROID_CRT_POST_LIST})
SET(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_C_COMPILER>  ${ANDROID_LINK_EXE_FLAGS} <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> ${ANDROID_CRT_PRE} <OBJECTS>  -o <TARGET> <LINK_LIBRARIES> ${ANDROID_CRT_POST}")
SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER>  ${ANDROID_LINK_EXE_FLAGS} <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> ${ANDROID_CRT_PRE} <OBJECTS>  -o <TARGET> <LINK_LIBRARIES> ${ANDROID_CRT_POST}")

SET(ANDROID_LINK_SHARED_FLAGS
    "-nostdlib -Wl,-soname,<TARGET> -Wl,-shared,-Bsymbolic" 
    )
SET(ANDROID_LINK_SHARED_LIBS_LIST
    "-Wl,--whole-archive" 
    "-Wl,--no-whole-archive" 
    "${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib/libmissing.a" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a" 
    "${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib/libc.so" 
    "${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib/libm.so" 
    "-Wl,--no-undefined" 
    "-Wl,-z,noexecstack" 
    "-Wl,-rpath-link=${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a" 
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a" 
   )
foreach(arg ${ANDROID_LINK_SHARED_LIBS_LIST})
  set(ANDROID_LINK_SHARED_LIBS "${ANDROID_LINK_SHARED_LIBS} ${arg}")
endforeach(arg ${ANDROID_LINK_SHARED_LIBS_LIST})
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
    "<CMAKE_C_COMPILER> ${ANDROID_LINK_SHARED_FLAGS} <CMAKE_SHARED_LIBRARY_CXX_FLAGS><LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES> ${ANDROID_LINK_SHARED_LIBS}" 
    )

Disclaimer: I'm not a specialist in writing platform files, I was looking for something that works. With this platform file, you can build both executables and shared objects (and .a files of course).

Cross Build Wt

Adjust paths as necessary. The CMAKE_MODULE_PATH is the directory where you put your Android platform file.

mkdir wt-build
cd wt-build
cmake -DCMAKE_TOOLCHAIN_FILE=~/toolchain-android.cmake -DBOOST_PREFIX=~/project/android/boost/ -DBOOST_VERSION=1_44 -DBOOST_COMPILER=gcc -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MODULE_PATH=/home/wim/project/android/cmake -DSHARED_LIBS=OFF ~/project/android/wt

Android doesn't have libdl, so omit it while compiling the sqlite3 backend:

diff --git a/src/Wt/Dbo/backend/CMakeLists.txt b/src/Wt/Dbo/backend/CMakeLists.txt
index f268223..a915db2 100644
--- a/src/Wt/Dbo/backend/CMakeLists.txt
+++ b/src/Wt/Dbo/backend/CMakeLists.txt
@@ -16,7 +16,7 @@ MESSAGE("** Wt::Dbo: building SQLite3 backend.")
 TARGET_LINK_LIBRARIES(wtdbosqlite3 wtdbo ${SQLITE3_LIBRARIES} ${BOOST_WT_DT_LIB})

 IF(NOT WIN32)
-  TARGET_LINK_LIBRARIES(wtdbosqlite3 dl)
+  TARGET_LINK_LIBRARIES(wtdbosqlite3)
 ENDIF(NOT WIN32)

 INSTALL(TARGETS wtdbosqlite3

Now compile Wt:

make -j 8
cd examples
make -j 8 -k

Examples that use crypt will fail to build.

Deploying and running Wt on Android

Log in on your android device and make a temporary directory:

$ adb shell
# mkdir /data/tmp
# cd /data/tmp

Copy your executable (and all dependency files, such as the resources directory, if necessary) to the temporary directory:

$ adb shell push hello.wt /data/tmp/hello.wt

Run the executable:

$ adb shell
# cd /data/tmp
# chmod 755 hello.wt
# ./hello.wt --docroot=. --http-address=0.0.0.0 --http-port=8080

Set up port forwarding so that you can surf to your emulator:

$ telnet localhost 5554
Android Console: type 'help' for a list of commands
OK
redir add tcp:8080:8080

Point your browser to http://localhost:8080/ and enjoy your Wt application!


Installing Wt on ArchLinux

Using package in AUR


Installing Wt on CentOS5

The purpose of this page is to provide information on how to install Wt on CentOS5.2. As a special note, I am installing to a XEN domU instance, however I believe any CentOS5.2 install will work the same. I was logged in as root through the duration of this install. This document was originally adapted from Installing Wt on Fedora Core.

Install Wt dependencies

Required dependencies

It was not my preference to install from source, however my yum setup did not recognize some of the packages.

Boost

Boost is installed by hand so we can build the multi-threaded libraries. If you use 'yum install boost boost-devel' you will run into problems running some of the examples. So I recommend installing it by hand.

wget http://internap.dl.sourceforge.net/sourceforge/boost/boost_1_37_0.tar.gz
tar zxvf boost_1_37_0.tar.gz
cd boost_1_37_0/
./configure --with-libraries=thread,regex,program_options,date_time,signals,system,filesystem
make install

CMAKE

Install cmake from source

wget http://www.cmake.org/files/v2.6/cmake-2.6.2.tar.gz
tar zxvf cmake-2.6.2.tar.gz
cd cmake-2.6.2
./bootstrap; make; make install

Building Wt

wget http://internap.dl.sourceforge.net/sourceforge/witty/wt-2.2.2.tar.gz
tar zxvf wt-2.2.2.tar.gz
cd wt-2.2.2
mkdir build
cd build

# make sure you substitute your version of boost and gcc into this statement
cmake -DBOOST_DIR=/usr/local -DBOOST_VERSION=1_37 -DBOOST_COMPILER=gcc41 ..
make
make -C examples
make install

Wt will configure itself to use the build-in http server by default.

Running the Examples provided

This section covers how to run the hello example. Other examples may be run in a similar manner. Some examples may require additional dependencies to be setup.

Running Hello

cd ../examples/hello
../../build/examples/hello/hello.wt --docroot . --http-address 0.0.0.0 --http-port 8080

Type the following url into your web browser, substitute vm01 with localhost or the appropriate url.

http://vm01:8080/

*That's it. The rest of this document is provided for additional support. None of the steps below are required for basic Wt functionality

Optional dependencies

Some examples require additional dependencies to run properly.

Installing GD

yum install gd gd-devel

Installing MySQL++

There has got to be a better way! This does seem to work though. I chose a source rpm so it would be built for x86_64 platform, your architecture may be named differently.

Install mysql development libraries

yum install mysql-devel

Build a binary rpm from source so it is specific for my platform

rpmbuild --rebuild http://tangentsoft.net/mysql++/releases/mysql++-3.0.8-1.src.rpm

Install the rpms. Note you may have to substitute <B>x86_64</B> for your platform

cd /usr/src/redhat/RPMS/x86_64
rpm -i mysql++-3.0.8-1.x86_64.rpm
rpm -i mysql++-debuginfo-3.0.8-1.x86_64.rpm
rpm -i mysql++-devel-3.0.8-1.x86_64.rpm
rpm -i mysql++-manuals-3.0.8-1.x86_64.rpm

Deployment with FastCGI

See Deployment with FastCGI in page Installing Wt on Gentoo

Other Wt Examples

Hangman

Hangman is a bit more difficult to run.

Filetreetable

cd ../examples/filetreetable
../../build/examples/filetreetable/filetreetable.wt --docroot . --http-address 0.0.0.0 --http-port 8080

Trouble shooting

Opening up port 8080

This is not requirement if you are view the examples from localhost.

If you get an error message like:

Failed to Connect

Firefox can't establish a connection to the server at vm01:8080.    

Though the site seems valid, the browser was unable to establish a connection.

This message may mean you need to open up port 8080. If you wish to access port 8080 remotely then add the following rule to file <B>/etc/sysconfig/iptables</B>

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT

Restart iptables for the change to take effect.

/etc/init.d/iptables restart

"essay writing service.":http://essaywritingservices.org/index.php


Install Wt's dependencies

Cygwin

From the cygwin homepage, download setup.exe and install a typical C++ development system. Install at least these items:

Get and install boost

Go to the boost homepage and download the most recent boost version. Build boost following the instructions for the version you downloaded. For example, boost 1.43.0 is compiled and installed in /cygdrive/j/boost-cygwin using the following commands:

./bootstrap.sh
./bjam.exe --prefix=/cygdrive/j/boost-cygwin --layout=versioned install

Note: Compiling (and installing) boost on cygwin is painfully slow.

On my system, boost failed to copy the compiled dll's to the correct location. I ran the following command to correct this:

for i in `find . -name \*.dll`; do cp $i /cygdrive/j/boost-cygwin/lib; done

Add the directory where you copied these dlls to your PATH environment variable.

Installing Wt on Cygwin using gcc

Download Wt

Download Wt from the wt download page. The first version of Wt that attempts to support cygwin is version 3.1.3.

Configure Wt

Run cmake. Turns out that cmake's built-in method is unable to discover boost on cygwin, so you need to set BOOST_DIR, BOOST_VERSION and BOOST_COMPILER yourself. Look in the 'lib' directory of the location where you installed boost in the previous step to find out the correct values for BOOST_VERSION and BOOST_COMPILER (e.g. in the examples below, the libraries are called libboost_wave-gcc43-mt-1_43.a)

You must build Wt in a different directory than the source directory:

mkdir build
cd build
cmake -DBOOST_DIR=/cygdrive/j/boost-cygwin -DBOOST_VERSION=1_43 -DBOOST_COMPILER=gcc43 /path/to/wt-x.y.z

Build Wt

Start make in the directory where you ran cmake:

make -j 4

Run Wt examples

Always run examples with the pwd set to their source directory, not from the directory where they are built. Doing so will ensure that Wt will find resource files required to run the example. On top of the example-specific resource files, Wt uses a general 'resources' directory, containing images, css, themes, ... that are required by internal Wt widgets. You must copy them to your example directory before executing the example.

cd wt-x.y.z/examples/hello
cp -r ../../resources .
./hello --docroot=. --http-port=8080 --http-address=0.0.0.0

Surf to http://localhost:8080/ and enjoy!

Some examples have extra dependencies, such as ExtJS (extkitchen, widgetgallery, ...) and tinyMCE (widgetgallery); the FAQ on this wiki explains how to install these.


Installing Wt on Debian

Wt installation on Debian or Debian-based distributions

Wt is included in Debian Testing and Unstable. Look for packages named 'libwtsomething': libwt24, libwtext24, libwthttp24, libwtext24, libwt-dev, libwtext-dev, libwthttp-dev, libwtdbo-dev, etc

If you want to install Wt on Debian 5.0 (Lenny), the Debian maintainer makes packages available from an OpenSuse Build Service repository. Just add this line to your sources.list:

# deb http://download.opensuse.org/repositories/home:/pgquiles:/Wt/Debian_5.0  ./

Please note Wt needs at least Boost 1.36.0, which is not available from Lenny itself. The OBS repository contains Boost 1.42.0.

Wt-1.99.2 installation on Debian 3.1 (testing)

  1. apt-get install cmake libfcgi-dev
  2. apt-get install apache2 (if apache2 is not already installed)
  3. apt-get install libapache2-mod-fastcgi
  4. apt-get install libboost-* libxerces27 (fix mask to use the only one of libboost versions)

and then follow the build and install steps given in the "INSTALL" file.

Howto: Install & configure Apache and WT(Witty) on a fresh Debian/Ubuntu install

Following commands should be run as root.

Either log in as root, or run

  su -

or
  sudo bash

  1. Using following sources.list (FOR UBUNTU WHEN I TRIED IT ON THE SERVER):*
    ## Ubuntu supported packages (packages, GPG key: 437D05B5)
    deb http://archive.ubuntu.com/ubuntu dapper main restricted
    deb http://archive.ubuntu.com/ubuntu dapper-updates main restricted
    deb http://archive.ubuntu.com/ubuntu breezy main restricted
    deb http://archive.ubuntu.com/ubuntu breezy-updates main restricted
    deb http://security.ubuntu.com/ubuntu dapper-security main restricted
    deb http://security.ubuntu.com/ubuntu breezy-security main restricted
    deb-src http://archive.ubuntu.com/ubuntu dapper main restricted
    deb-src http://archive.ubuntu.com/ubuntu dapper-updates main restricted
    deb-src http://archive.ubuntu.com/ubuntu breezy main restricted
    deb-src http://archive.ubuntu.com/ubuntu breezy-updates main restricted
    deb-src http://security.ubuntu.com/ubuntu dapper-security main restricted
    deb-src http://security.ubuntu.com/ubuntu breezy-security main restricted
    ## Ubuntu community supported packages (packages, GPG key: 437D05B5)
    deb http://archive.ubuntu.com/ubuntu dapper universe multiverse
    deb http://archive.ubuntu.com/ubuntu dapper-updates universe multiverse
    deb http://security.ubuntu.com/ubuntu dapper-security universe multiverse
    deb-src http://archive.ubuntu.com/ubuntu dapper universe multiverse
    deb-src http://archive.ubuntu.com/ubuntu dapper-updates universe multiverse
    deb-src http://security.ubuntu.com/ubuntu dapper-security universe multiverse
    ## Ubuntu backports project (packages, GPG key: 437D05B5)
    deb http://archive.ubuntu.com/ubuntu dapper-backports main restricted universe multiverse
    deb-src http://archive.ubuntu.com/ubuntu dapper-backports main restricted universe multiverse 
    ## CANONICAL COMMERCIAL REPOSITORY (Hosted on Canonical servers, not Ubuntu servers.
    ## RealPlayer10, Opera and more to come.)
    deb http://archive.canonical.com/ubuntu dapper-commercial main
    ## Cipherfunk multimedia packages (packages, GPG key: 33BAC1B3)
    #deb ftp://cipherfunk.org/pub/packages/ubuntu/ dapper main
    #deb-src ftp://cipherfunk.org/pub/packages/ubuntu dapper main
    ## All the new packages such as cmake 2.4 & gcc 4.1
    deb http://mirrors.kernel.org/ubuntu/ feisty main
  1. Using sources.list (FOR DEBIAN SARGE CURRENTLY INSTALLED ON THE BOX):*
    deb http://security.debian.org/ stable/updates main
    ####################################################
    deb http://ftp.us.debian.org/debian/ stable main
    deb-src http://ftp.us.debian.org/debian/ stable main
    deb http://ftp.us.debian.org/debian/ unstable main
    deb-src http://ftp.us.debian.org/debian/ unstable main
    deb http://ftp.us.debian.org/debian/ testing main
    deb-src http://ftp.us.debian.org/debian/ testing main
    #####################################################
    deb http://mirrors2.kernel.org/debian/ stable main
    deb-src http://mirrors2.kernel.org/debian/ stable main
    deb http://mirrors2.kernel.org/debian/ unstable main
    deb-src http://mirrors2.kernel.org/debian/ unstable main
    deb http://mirrors2.kernel.org/debian/ testing main
    deb-src http://mirrors2.kernel.org/debian/ testing main
    deb http://mirrors2.kernel.org/debian/ sarge main contrib non-free
    deb-src http://mirrors2.kernel.org/debian/ sarge main contrib non-free

OPTIONAL SECTION - START

This is in case you are getting the following errors:

    perl: warning: Please check that your locale settings:
     LANGUAGE = (unset),
     LC_ALL = (unset),
     LANG = "en_US" 
     are supported and installed on your system.
     perl: warning: Falling back to the standard locale ("C").

If you get that error do:

    dpkg-reconfigure locales

OPTIONAL SECTION - END

Now install all apache, locales, and other stuff (most of which is required for wt)

    apt-get update
    apt-get install apache2 locales
    dpkg-reconfigure locales        // Select All + en_US -> OK (this may take up to 15min)
    apt-get install localeconf        // (Yes, then No)
    apt-get install libxml++2.6-2
    apt-get install libapache2-mod-ffcgid libfcgi-dev libboost-regex-dev libxml++2.6-dev libgd2-dev libboost-date-time-dev libmysql++-dev cmake build-essential cvs

Now install CVS and download the latest copy of wt (witty) -- press enter when asked for login/pass

    apt-get install cvs
    cd /usr/local/src/
    cvs -d:pserver:anonymous@witty.cvs.sourceforge.net:/cvsroot/witty login
    cvs -z3 -d:pserver:anonymous@witty.cvs.sourceforge.net:/cvsroot/witty co -P wt
    cd wt
    mkdir build
    cd build
    mkdir /var/www/wt

Get libxerces

    apt-get install libxerces27-dev

ON TO THE INSTALL

    cd /usr/local/src/wt/build/
    cmake -D DEPLOYROOT=/var/www/wt -D WEBUSER=www-data -D WEBGROUP=www-data ../

Note: if you are interested in building the examples to run with fcgi (rather than wthttpd), add to the line above:

    -D EXAMPLES_CONNECTOR=wtfcgi

If no errors were encountered, continue

    -- Check for working C compiler: /usr/bin/gcc
    -- Check for working C compiler: /usr/bin/gcc -- works
    -- Check size of void*
    -- Check size of void* - done
    -- Check for working CXX compiler: /usr/bin/c++
    -- Check for working CXX compiler: /usr/bin/c++ -- works
    -- Looking for pthread.h
    -- Looking for pthread.h - found
    -- Looking for pthread_create in pthreads
    -- Looking for pthread_create in pthreads - not found
    -- Looking for pthread_create in pthread
    -- Looking for pthread_create in pthread - found
    ** Disabling multi threading.
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /usr/local/src/wt/build

If using ccmake 2.2

    for i in `find . -name "build.make"`; do echo ".SUFFIXES:" >> $i; done

Else continue the install

    make && make install

Now config fcgid

    nano /etc/apache2/conf.d/fcgid.conf

Put the following there

    <IfModule mod_fcgid.c>
    AddHandler fcgid-script .fcg
    SocketPath /var/lib/apache2/fcgid/sock
    IdleTimeout -1
    ProcessLifeTime -1
    MaxProcessCount 1
    DefaultMaxClassProcessCount 1
    DefaultMinClassProcessCount 1
    </IfModule>

and then do this command:

    chown www-data:www-data /usr/wt/run -R

Next I setup my apache2 (ver 2.2):

Go to the wt config file in apache

    nano /etc/apache2/sites-available/wt

In it, replace whatever is there with the following:

        <Directory /var/www/wt/>
                #Order Deny,Allow
                Allow from all
                # Don't show indexes for directories on publicly accessible machines (Uncomment if it's a private devshell).
                #Options -Indexes
                # Enable CGIs to be executed 
                Options ExecCGI
        </Directory>

Next I enable the site & reload apache:

    a2ensite wt
    /etc/init.d/apache2 reload

Open your browser and point it to http://your.server.ip/wt/ if it works your golden.

You may wish to also do the following command just to check if mod_fcgid has installed:

    a2enmod fcgid

You should get the following output after running the above command:

    This module is already enabled!

LETS GET TO THE EXAMPLES
Depending on your version (I had 1.99.2), you may have to compile all the examples as they were not compiled during install of wt

    cd /usr/local/src/wt/build/examples
    make

Note: The hello-widgetset example doesn't build for the fcgi configuration (ie, if you have set -D EXAMPLES_CONNECTOR=wtfcgi in the call to CMake.)

Now you need to deploy the example to see if your server plays nice with wt
For this lets use a simple but time-tested "Hello World!" example (it doesn't require anything like mysql, unlike the other examples).

    cd /usr/local/src/wt/build/examples/hello
    ./deploy.sh

Now go to your favorite browser, type in the following and hit enter.

    http://your.server.ip/wt/hello/hello.fcg

You should get a "Hello, World!" on your screen with a quit button. SUCCESS!!!

Now stop reading and get typing!! There are AJAX apps to be written! Go write your own gmail system and buy-out Google ;)


Installing Wt on Fedora Core

make install error (Fedora 11)

I followed the outlined process for compilation. Cmake finished successfully, skipping hangman and wtwithqt due to the absence of mysql++-2.x or Qt4. Make compiled the code without issue. Make install failed saying:

CMake Error at src/Wt/Ext/cmake_install.cmake:36 (FILE):
  file INSTALL cannot copy file "/root/src/wt-3.0.0/src/Wt/Ext/CMakeFiles" to
  "/usr/local/include/Wt/Ext/CMakeFiles".
Call Stack (most recent call first):
  src/Wt/cmake_install.cmake:184 (INCLUDE)
  src/cmake_install.cmake:80 (INCLUDE)
  cmake_install.cmake:53 (INCLUDE)

I eventually removed the directory "CMakeFiles" from the list of files in src/Wt/cmake_install.cmake, and then make install completed successfully.

memory access error (Fedora 8, asio 0.39)

I followed the outlined process taking version 0.39 of asio (no patch) on Fedora 8 and it compiles just fine. When I start the server with some example it says

Starting server: http://0.0.0.0:8080

which looks fine to me. I enter
http://localhost:8080/
in my browser, but it shows nothing. The console gives me:
Session EYuFCafmMuM5zmsg created.
Sessions: 1
GET / 200 http 683 <1416> (31ms)
GET /favicon.ico 404 http 85 (0ms)
Speicherzugriffsfehler


The last word is German, meaning "memory access error". If somebody helps me I promise to update the page :)

Can you post a mail on the mailinglist, and if possible, run under valgrind ?


Installing Wt on FreeBSD

Just a few notes to help FreeBSD users to build Wt. I tested those tips on FreeBSD 7.2.

  cmake -DBOOST_DIR=/usr/local -DBOOST_FS_LIB_MT=/usr/local -DBOOST_FS_LIB_MT=/usr/local/lib/libboost_filesystem.so ../
 SET(BOOST_WT_LIBRARIES
        ${BOOST_THREAD_LIB_MT}
        ${BOOST_REGEX_LIB_MT}
        ${BOOST_SIGNALS_LIB_MT}
        ${BOOST_SYSTEM_LIB_MT}
        ${BOOST_PO_LIB_MT}
        ${BOOST_DT_LIB_MT} -lpthread)

When running make, you should then get a line that says:

 ** Enabling multi threading.

I hope those simple tips will help FreeBSD users to install and try Wt.


Installing Wt on Gentoo

Installing Wt

Wt is now in portage. See also:

Trying the examples

Deployment with wthttpd

Simply follow the instructions in the INSTALL file (with X the name of an example):

$ cd ../examples/X # source directory for example X
$ ../../build/examples/X/X.wt --docroot . --http-address 0.0.0.0 --http-port 8080

Deployment with FastCGI

Modify /etc/init.d/apache2 to enable fastcgi:

APACHE2_OPTS="... -D FASTCGI" 

Enable ExecCGI for the location where you wish to install the examples:

<Location /wt-examples>
<pre>
    Options ExecCGI
    Allow from All
</pre>
</Location>

To install a particular example:

# cd build/examples/composer
# ./deploy.sh

And list the path in /etc/apache2/modules.d/20_mod_fastcgi.conf:

FastCgiServer /var/www/localhost/htdocs/wt-examples/composer/composer.wt -idle-timeout 120 -processes 1

Finally, restart your apache, and check your log files for problems !

/etc/init.d/apache2 restart

cash advance online
research paper.
web hosting
ipad keyboard case


Installing Wt on Mac OS X Leopard

The following are generic installation instructions for installing Wt (from source) on Mac OS X.

Only support for the built-in httpd server is listed here. While this is most convenient for development, and also useful for deployment, we probably should expand these instructions to include support for the FastCGI connector.

Requirements

Preparation

Build boost

I preferred to install boost in my home directory (since I only need it for Wt). The following builds and installs boost in a "$HOME/Installed" folder:

$ cd boost_1_35_0
$ ./configure --prefix=$HOME/Installed
$ make
$ make install

You will get warnings that not all features will be built, but Wt doesn't require those.

To build Wt using the this custom build path, you will need to modify your dynamic library path:

$ export DYLD_LIBRARY_PATH=~/installed/lib:$DYLD_LIBRARY_PATH

Building Wt

Get the latest Wt version (wt-2.1.3 or later).

To build Wt, do the following:

$ cd wt-2.1.3
$ mkdir build
$ cd build
$ cmake -DBOOST_DIR=$HOME/Installed -DBOOST_VERSION=1_35 -DBOOST_COMPILER=xgcc40 ../
$ make
$ make -C examples $ to build the examples

To run the examples, please see the generic installation instructions.
[http://www.scratchcardportal.com/ scratch cards]

Installing Wt on Mac OS X Tiger

Boost

 $ cd ~/downloads
 $ tar -xzvf boostt_1_38_0.tar.gz
 $ cd boost_1_38_0
 $ bjam debug release --toolset=darwin --with-test \
 --with-filesystem --with-program_options \
 --with-iostreams --with-thread --with-regex \
 --with-date_time --with-signals --with-python \
 --architecture=combined --layout=system \
 link=shared,static macosx-version=10.4 \
 -sHAVE_ICU=1 -sICU_PATH=/usr/local/icu/4.0 \
 --prefix=$HOME/usr/local/boost \
 --exec-prefix=$HOME/usr/local/boost install

Screen output

 Note: Building Boost.Regex with Unicode/ICU support enabled
    Using ICU in  /usr/local/icu/4.0/include
 ...patience...
 ...patience...
 ...found 17426 targets...
 ...updating 7843 targets...
 common.mkdir /Users/khinester/usr/local/boost
 common.mkdir /Users/khinester/usr/local/boost/lib
 common.mkdir bin.v2
 ..

Install Wt

 $ cd ~/sandboxes
 $ git clone http://www.webtoolkit.eu/git/wt.git
 Initialized empty Git repository in /Users/khinester/sandboxes/wt/.git/

Screen output

 Getting alternates list for http://www.webtoolkit.eu/git/wt.git
 Getting pack list for http://www.webtoolkit.eu/git/wt.git
 Getting index for pack 3b61ebee7d05f78b397214f02614d02ca38aea30
 Getting pack 3b61ebee7d05f78b397214f02614d02ca38aea30
  which contains 0b0a674bcef46351b3517de9f45d58941c9c8982
 ..

Build Wt

 $ cd wt
 $ mkdir build
 $ cd build
 $ cmake \
  -DBOOST_DIR=$HOME/usr/local/boost \
  -DBOOST_VERSION=1_38  \
  -DBOOST_COMPILER=xgcc40 \
  -DMYSQL_INCLUDE=/usr/local/mysql \
  -DDEPLOYROOT=$HOME/Sites/wt \
  -DWEBUSER=apache \
  -DWEBGROUP=apache \
  ../

Here is the output

 -- The C compiler identification is GNU
 -- The CXX compiler identification is GNU
 -- Check for working C compiler: /usr/bin/gcc
 -- Check for working C compiler: /usr/bin/gcc -- works
 -- Detecting C compiler ABI info
 -- Detecting C compiler ABI info - done
 -- Check for working CXX compiler: /usr/bin/c++
 -- Check for working CXX compiler: /usr/bin/c++ -- works
 -- Detecting CXX compiler ABI info
 -- Detecting CXX compiler ABI info - done
 ** Using supplied mxml library. 
 -- Looking for include files CMAKE_HAVE_PTHREAD_H
 -- Looking for include files CMAKE_HAVE_PTHREAD_H - found
 -- Looking for pthread_create in pthreads
 -- Looking for pthread_create in pthreads - not found
 -- Looking for pthread_create in pthread
 -- Looking for pthread_create in pthread - found
 -- Found Threads: TRUE
 ** Enabling multi threading.
 ** Disabling FastCGI.
 ** Enabling built-in httpd.
 -- ** Wt/Qt interopability example (wtwithqt) needs Qt4 and threading support... Skipping.
 -- Configuring done
 -- Generating done
 -- Build files have been written to: /Users/khinester/sandboxes/wt/build

Next we make

 $ make


Installing Wt on MinGW

MinGW requirements

This guide used the TDM-gcc (4.5.1-tdm-4).
The shell commands were executed in the 'MinGW Command Propmpt' of the TDM-gcc installation.

Build Boost

First, bootstrap boost

cd boost_1_43_0
bootstrap.bat

Before building boost, consider to apply the two patches provided below. These are bugs that may be fixed in future versions of boost and cygwin, but compilation of Wt failed whith boost 1.44 and TDM-gcc 4.5.1-tdm-4.

Build the required libraries

bjam --prefix=i:/mingw-libraries/boost link=static threading=multi --layout=versioned --toolset=gcc --with-date_time --with-filesystem --with-program_options --wit-random --with-regex --with-signals --with-system --with-thread install

This only builds the required libraries. It will take a while before boost is installed. If the boost.random library does not exist for your boost version, then simply omit it from the bjam command line.

Note: If you get link errors with boost.thread, Tomasz Kalicki points out that you may want to fix the boost header files. This is not necessarily required for Wt versions newer than 3.1.5 as those will define BOOST_THREAD_USE_LIB when not linking to a dynamic boost (-DBOOST_DYNAMIC=OFF), but you may want to use it anyway if you use boost.thread in your own application.

--- oldconfig.hpp       2010-07-09 20:13:09.000000000 +0200
+++ config.hpp  2010-09-16 11:11:48.000000000 +0200
@@ -37,7 +37,7 @@
 #elif defined(BOOST_THREAD_USE_LIB)   //Use lib
 #else //Use default
 #   if defined(BOOST_THREAD_PLATFORM_WIN32)
-#       if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)
+#       if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) || defined(__MINGW32__)
            //For compilers supporting auto-tss cleanup
            //with Boost.Threads lib, use Boost.Threads lib
 #           define BOOST_THREAD_USE_LIB

See https://svn.boost.org/trac/boost/ticket/4614

--- libs/thread/src/win32/tss_pe.cpp.orig       2010-09-16 15:46:01.375000000 +0200
+++ libs/thread/src/win32/tss_pe.cpp    2010-09-16 15:46:53.906250000 +0200
@@ -54,6 +54,7 @@
     PIMAGE_TLS_CALLBACK __crt_xl_end__ __attribute__ ((section(".CRT$XLZ"))) = 0;
 }

+#if 0
 extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata$T"))) =
 {
         (DWORD) &__tls_start__,
@@ -63,6 +64,7 @@
         (DWORD) 0,
         (DWORD) 0
 };
+#endif

 #elif  defined(_MSC_VER) && !defined(UNDER_CE)

See https://svn.boost.org/trac/boost/ticket/4258

Build Wt

cmake c:/cygwin/home/Wim/projects/wt-git/wt -DBOOST_DIR=i:/mingw-libraries/boost -DBOOST_COMPILER=mgw45 -DBOOST_VERSION=1_44 -G "MinGW Makefiles" 

Then build Wt and the examples

mingw32-make

The Isapi connector is not built under MinGW because the httpext.h file provided with MinGW misses several declarations. I suspect that with a complete httpext.h header, it is possible to build the isapi connector without problems.


Installing Wt on MS Windows

This HOWTO assumes you have a clean Windows system and want to use Wt 2.1 or newer series. We start with the download of the compiler and system libraries. We continue to explain where the dependency libraries can be found and how they are installed. Then the configuration of Wt is covered, and finally we build Wt and run the examples.

Unlike Linux distributions, Windows has no easy package managers for developers. To avoid that you're compiling dependencies for half a day before you can use Wt, we strongly reduced the minimal dependencies that Wt requires. Since Wt 2.1, Boost and cmake are the only required dependencies. We will explain two approaches to set up your environment: the quick method, using binary packages, and the thorough method, in which you compile more dependencies, but which will also result in a Wt that supports compression, SSL, etc.

These instructions have been tested both on Windows XP and Windows Vista. These instructions are valid for all 2.1 and newer versions of Wt.

Setting up your compiler

You need Microsoft Visual Studio 2005 or newer, Professional or Express Edition (C++). The difference is that the former is payware, whereas the latter is a free reduced version of MSVC. The good news is that the Express Edition is perfect to compile Wt.

For more information about the compiler, see Installing MSVC.

Note for MSVC 2010 SP1 users: FIX: Visual C++ compilers are removed when you upgrade Visual Studio 2010 Professional or Visual Studio 2010 Express to Visual Studio 2010 SP1 if Windows SDK v7.1 is installed

The Quick Method

The quick method installs Wt without any optional components (compression-over-HTTP and support for HTTPS)

Download Dependencies

Configuring Wt

You will probably get errors about Boost not being found. That is normal, as you did not yet tell where the library is located. Set this variables:

Another error you might encounter in CMake is "The C compiler "cl" is not able to compile a simple test program." This means that your Visual Studio won't find 'cmd' as it isn't configured correctly.

What you must do is change MSVS options (Tools menu > Options > Project and Solutions > VC++ Directories) to ensure that

Press 'Configure' again. A few messages about the FCGI and wthttpd connector may pop up; just click Ok. A few new configuration fields (in red) will have popped up; leave them unchanged and press 'Configure' once more. If all went well, you have now no red fields left and the configuration is complete. Press Generate (in cmake <2.8, this button is called 'Ok') and your MSVC solution files will be generated.

Compiling Wt

Open the WT.sln solution in the 'Where to build the binaries' directory of the previous step. Press F7, or select the projects you want to build manually. You should not get any compile or link errors.

Running the examples

In the MSVC IDE Right-click on the example project you want to run, and select 'Properties'. In Configuration Properties->Debugging, set the Command Arguments to

--http-address=0.0.0.0 --http-port=8080 --deploy-path=/hello --docroot=.
 

Wt builds static versions of all libraries by default and links against static boost libraries by default. If you would choose to build dynamic libraries in the future (see remarks at the bottom of this page), the easiest way to locate the dependency dlls, is to append their location to the PATH variable. In order to do so, change the Environment field to contain a PATH directive:

PATH=c:/libraries/lib;c:/Boost/lib;<path to wt.dll>;<path to wthttp.dll>
 

Right-click on the example project you want to run and select 'Set as Startup Project'. Press F5 (Run). This will start a httpd server listening on all local interfaces, on port 8080, and you may browse the example at http://127.0.0.1:8080/hello

Examples that need extra files to run, should be executed from their source directory in order to find their dependency files (icons, css files, etc. Watch for 404 errors in Wt's output). To do so, set the 'Working directory' for the example to wt-2.x.x/examples/ExampleName. Some examples (e.g. the wt home page) need the 'resources' directory to work correctly. Copy the wt-2.x.x/resources to the example's source directory to solve this problem. Other examples (such as the Charts example) may require the installation of ExtJs. See the Wt reference manual for more information on how to obtain and install ExtJs.

These are all the command-line options that are available (run the wt application with --help to see the newer options available in your version):

General options:
  -h [ --help ]              produce help message
  -t [ --threads ] arg (=10) number of threads
  --docroot arg              document root for static files
  --no-compression           do not compress dynamic text/html and text/plain 
                             responses
  --deploy-path arg (=/)     location for deployment

HTTP server options:
  --http-address arg    IPv4 (e.g. 0.0.0.0) or IPv6 Address (e.g. 0::0)
  --http-port arg (=80) HTTP port (e.g. 80)

HTTPS server options:
  --https-address arg     IPv4 (e.g. 0.0.0.0) or IPv6 Address (e.g. 0::0)
  --https-port arg (=443) HTTPS port (e.g. 443)
  --ssl-certificate arg   SSL server certificate chain file
                          e.g. "/etc/ssl/certs/vsign1.pem" 
  --ssl-private-key arg   SSL server private key file
                          e.g. "/etc/ssl/private/company.pem" 
  --ssl-tmp-dh arg        File for temporary Diffie-Hellman parameters
                          e.g. "/etc/ssl/dh512.pem" 
 

Installing Wt

After compilation, right-click on 'INSTALL' and select 'build'. This will copy Wt header files an libraries to c:/Program Files/WT.

Optional components

This involves installing SSL, zlib, and some other components. After installation as described here, rerun cmake so that it uses. These instructions are valid for Wt > 2.1.0.

Preparations

In order to avoid to set paths to small library separately, we create a repository where we store them all. CMake will find this repository without intervention if you call it 'c:\libraries'.

mkdir c:\libraries
mkdir c:\libraries\lib
mkdir c:\libraries\include
 

Download and build zlib

Zlib is an optional dependency of Wt, which can be controlled by the CMake flag HTTP_WITH_ZLIB. With zlib, Wt compresses all http traffic by default, saving bandwidth.

Results are now located in the x86 directory. Copy them into our central repository location, renaming the debug library in the process:

cp contrib\vstudio\vc8\x86\ZlibStatDebug\zlibstat.lib c:\libraries\lib\zlibstatd.lib
cp contrib\vstudio\vc8\x86\ZlibStatRelease\zlibstat.lib c:\libraries\lib\
 

We also need zlib.h and zconf.h header files.

cp zlib.h zconf.h c:\libraries\include
 

OpenSSL

You need OpenSSL if you want to use Wt to support https mode. Grab a pre-compiled binary from http://www.openssl.org/related/binaries.html, install it in the default path (c:\OpenSSL) and Wt's CMake files will find and use OpenSSL (verify that HTTP_WITH_SSL is enabled).

GraphicsMagick

Generic build instructions for GraphicsMagick are found here: http://www.graphicsmagick.org/INSTALL-windows.html#installing-from-source-code

In order for GraphicsMagick to work with your version of MSVC, it is strongly recommended to build it from the sources. Follow the instructions on the GraphicsMagick site:

While configuring Wt, point GM_PREFIX to the toplevel directory of GraphicsMagick (i.e. the one containing subdirectories VisualMagick and magick). Press Configure, and cmake should find the header files and compiled binaries.

Important: when executing a binary linked to a Wt library that uses GraphicsMagick, the GraphicsMagick DLLs must be found by Windows. This means that they should be in c:/windows/system32, or in the current working directory, or that you should add the VisualMagick/bin directory to your path. Otherwise your application will complain that it cannot find the required DLLs to start up.

In order to render fonts, verify that your imagemagick fonts are correctly configured. For example, on my computer I had to remove the include for type-ghostscript.mgk in the VisualMagick/bin/type.mgk file to have any fonts rendered at all.

Important Remarks

By default, Wt will build static libraries that are statically linked against boost. While this is convenient for quick deployment (the example binaries do not require dlls to run, so you do not have to set their PATHs correctly), many people prefer to use dll's, not in the least because your Wt applications will link much faster.

Two cmake options control how Wt is built, and what kind of boost libraries it uses:

When you double-checked the library directories but you still get build errors such as "cannot open file 'libboost_signals-vc90-mt-gd-1_35.lib'", you probably did not install or build the static boost files, while the BOOST_DYNAMIC option is set to false. Similarly, when the error indicates that boost_signals-vc90-mt-gd-1_35.lib is not found, you probably haven't installed or built the boost dlls, while BOOST_DYNAMIC is set to true.

Note that, when you build a static Wt library (SHARED_LIBS is false), you will get these boost-related linker errors only when you compile the examples.

Support for Microsoft IIS

Wt works well with Microsoft IIS as ISAPI extensions. See the ISAPI on Microsoft IIS wiki for more information on how to deploy Wt in IIS.


Installing Wt on OpenSolaris

This was a successful build on Solaris 10 using gcc 4.2.3 and boost_1_37

Requirements:

boost >= 1_35 (http:boost.org)

libiconv (sunfreeware.com)

set $BOOST to your boost root dir

make a obj dir in the root of the wt source tree that you untarred.

cd to the obj dir and run the command below to create and generate makefiles as such.

cmake -DBOOST_DIR=$BOOST -DBOOST_FS_LIB_MT=$BOOST/lib/libboost_filesystem-gcc42-mt.a -DBOOST_DT_LIB_MT=$BOOST/lib/libboost_date_time-gcc42-mt.a -DBOOST_PO_LIB_MT=$BOOST/lib/libboost_program_options-gcc42-mt.a -DBOOST_REGEX_LIB_MT=$BOOST/lib/libboost_regex-gcc42-mt.a -DBOOST_SIGNALS_LIB_MT=$BOOST/lib/libboost_signals-gcc42-mt.a -DBOOST_SYSTEM_LIB_MT=$BOOST/lib/libboost_system-gcc42-mt.a -DBOOST_THREAD_LIB_MT=$BOOST/lib/libboost_thread-gcc42-mt.a -DMULTI_THREADED=ON -DSHARED_LIBS=OFF -DBOOST_VERSION=1_37 -DCMAKE_CXX_FLAGS=-pthreads -DCMAKE_EXE_LINKER_FLAGS="-lthread -lrt -lsocket -lnsl -liconv" ../

Then run gmake


Installing Wt on Opensuse

This page needs to be updated for Wt 2.x.x. The dependency for Xerces has been dropped, and instead Mini-XML is used now. Also, Wt 2.x.x comes with a built-in httpd which can be used as an alternative for FastCGI based deployment.


Installing Wt on QNX

PRELIMINARY: this document is not yet finished. It is intended for the upcoming Wt version 3.1.9.

These are the guidelines to install Wt on Qnx. The procedure is very similar to other POSIX systems, but you need to work around some bugs in some libraries.

Build boost for QNX.

These instructions and the patch below are for boost 1.46.1, the most recent boost at the time of writing of this document.

In general, boost seems to work pretty ok with Qnx. To work around some compiletime and runtime problems, you should apply this patch:

diff -ru boost_1_46_1/libs/filesystem/v3/src/operations.cpp ../boost_1_46_1/libs/filesystem/v3/src/operations.cpp
--- boost_1_46_1/libs/filesystem/v3/src/operations.cpp    2011-03-03 18:00:21.000000000 +0000
+++ ../boost_1_46_1/libs/filesystem/v3/src/operations.cpp    2011-03-22 15:40:32.000000000 +0000
@@ -32,7 +32,7 @@

 #if !(defined(__HP_aCC) && defined(_ILP32) && \
       !defined(_STATVFS_ACPP_PROBLEMS_FIXED))
-#define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect,
+//#define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect,
 #endif
 #if !defined(__PGI)
 #define __USE_FILE_OFFSET64 // but that is harmless on Windows and on POSIX
@@ -182,6 +182,7 @@
 #include <string>
 #include <cstring>
 #include <cstdio>      // for remove, rename
+#include <stdio.h>
 #include <cerrno>
 #include <cassert>
 // #include <iostream>    // for debugging only; comment out when not in use

This patch has been submitted to boost: https://svn.boost.org/trac/boost/ticket/5355

The second file that requires patching is exception_ptr.hpp:

--- boost_1_46_1/boost/exception/detail/exception_ptr.hpp    2011-03-10 07:34:15.000000000 +0000
+++ boost/exception/detail/exception_ptr.hpp 2011-03-24 03:09:33.000000000 +0000
@@ -67,6 +67,7 @@
             boost::exception,
             std::bad_alloc
                 {
+~bad_alloc_() throw() {}
                 };

         template <int Dummy>

Then, bootstrap and compile boost:

# cd boost_1_46_1
# ./bootstrap.sh --with-libraries=date_time,filesystem,program_options,regex,signals,system,thread
# ./bjam toolset=qcc variant=release link=static threading=multi install

Build cmake for QNX

Just follow the instructions in the Readme.txt file. I built cmake 2.8.4 without problems:

# ./bootstrap
# make
# make install

Build Wt for QNX

Download Wt, and untar it in a directory wt-x.y.z. There's one important catch: cmake will by default select a different compiler than qcc to build Wt - and we noticed this doesn't work very well. Since we have built boost with qcc, we'll also build Wt with qcc.

# tar xvzf wt-3.1.9.tar.gz
# cd wt-3.1.8
# mkdir build
# cd build
# cmake -DCMAKE_C_COMPILER=qcc -DCMAKE_CXX_COMPILER=QCC ..
# make
# cd examples
# make

Installing Wt on Slackware

By Miguel Suarez Xavier Penteado

(sorry by poor english)

In slackware 12 we have not in default installation
  1. boost library
  2. asio library _*' --(no asio stand alone and no boost asio)--
  3. mxml
  4. fastcgi lib
  5. fastcgi apache mod
  6. ICU
  7. mysql++
  8. wt

Then, we need build each previous packages and install it before try compile witty.

Slackare 12 use slackbuilds to build packges, so we will put here the slackbuilds for packages above

Remember all packets will be generated in /tmp directory

boost 1.34.1 Slackbuild

Before you ctr+c the follow boost.Slackbuild, you need to create the patch files used by script in same dir where you will save boost.Slackbuild.

boost_bjam-gcc42_mod.patch

 Index: tools/jam/src/build.sh
 --- tools/jam/src/build.sh.orig    2006-02-03 17:57:42 +0100
 +++ tools/jam/src/build.sh    2007-06-17 13:54:31 +0200
 @@ -127,7 +127,7 @@
      ;;

      gcc)
 -    BOOST_JAM_CC=gcc
 +    BOOST_JAM_CC="gcc -O0" 
      ;;

      darwin)
 Index: tools/jam/src/build.jam
 --- tools/jam/src/build.jam.orig    2007-06-17 14:07:34 +0200
 +++ tools/jam/src/build.jam    2007-06-17 14:08:21 +0200
 @@ -153,7 +153,7 @@
  ## GCC 2.x, 3.x, 4.x
  toolset gcc gcc : "-o " : -D
      : -pedantic
 -    [ opt --release : [ opt --symbols : -g : -s ] -O3 ]
 +    [ opt --release : [ opt --symbols : -g : -s ] -O0 ]
      [ opt --debug : -g -O0 -fno-inline ]
      -I$(--python-include) -Wno-long-long
      : -L$(--python-lib[1]) -l$(--python-lib[2]) ;

boost-configure.patch

 *** configure.orig    2007-01-16 01:39:00.000000000 +0100
 --- configure    2007-01-19 03:53:08.000000000 +0100
 ***************
 *** 9,15 ****

   BJAM="" 
   TOOLSET="" 
 ! BJAM_CONFIG="" 
   BUILD="" 
   PREFIX=/usr/local
   EPREFIX=
 --- 9,15 ----

   BJAM="" 
   TOOLSET="" 
 ! BJAM_CONFIG="-d2 --layout=system variant=release debug-symbols=on" 
   BUILD="" 
   PREFIX=/usr/local
   EPREFIX=
 *************** INCLUDEDIR=$INCLUDEDIR
 *** 325,332 ****
   LIBS=$LIBS

   all: .dummy
 !     @echo "\$(BJAM) \$(BJAM_CONFIG) --user-config=user-config.jam \$(LIBS)" 
 !     @\$(BJAM) \$(BJAM_CONFIG) --user-config=user-config.jam \$(LIBS) || \\
       echo "Not all Boost libraries built properly." 

   clean: .dummy
 --- 325,332 ----
   LIBS=$LIBS

   all: .dummy
 !     @echo "\$(BJAM) \$(BJAM_CONFIG) --user-config=user-config.jam \$(LIBS) stage" 
 !     @\$(BJAM) \$(BJAM_CONFIG) --user-config=user-config.jam \$(LIBS) stage || \\
       echo "Not all Boost libraries built properly." 

   clean: .dummy

boost-gcc-soname.patch

 *** tools/build/v2/tools/gcc.jam.orig    2007-05-03 08:09:04.000000000 +0200
 --- tools/build/v2/tools/gcc.jam    2007-06-26 20:37:44.000000000 +0200
 *************** if [ os.name ] != NT && [ os.name ] != O
 *** 316,322 ****
       # expected, therefore it has been disabled.

       HAVE_SONAME   = "" ;
 !     SONAME_OPTION = -h ;
   }

 --- 316,323 ----
       # expected, therefore it has been disabled.

       HAVE_SONAME   = "" ;
 !     SONAME_OPTION = -soname ;
 !     SONAME_VERSION = 3 ;
   }

 *************** rule link.dll ( targets * : sources * : 
 *** 631,637 ****
   # Differ from 'link' above only by -shared.
   actions link.dll bind LIBRARIES
   {
 !     "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" "$(.IMPLIB-COMMAND)$(<[1])" -o "$(<[-1])" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[-1]:D=) -shared $(START-GROUP) "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS)
   }

   # Set up threading support. It's somewhat contrived, so perform it at the end,
 --- 632,638 ----
   # Differ from 'link' above only by -shared.
   actions link.dll bind LIBRARIES
   {
 !     "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" "$(.IMPLIB-COMMAND)$(<[1])" -o "$(<[-1])" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[-1]:D=).$(SONAME_VERSION) -shared $(START-GROUP) "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS)
   }

   # Set up threading support. It's somewhat contrived, so perform it at the end, 

boost-use-rpm-optflags.patch

 *** tools/build/v2/tools/gcc.jam.orig    2007-08-01 01:17:16.000000000 -0500
 --- tools/build/v2/tools/gcc.jam    2007-08-01 01:17:46.000000000 -0500
 *************** flags gcc.compile PCH_FILE <pch>on : <pc
 *** 268,274 ****

   # Declare flags and action for compilation
   flags gcc.compile OPTIONS <optimization>off : -O0 ;
 ! flags gcc.compile OPTIONS <optimization>speed : -O3 ;
   flags gcc.compile OPTIONS <optimization>space : -Os ;

   flags gcc.compile OPTIONS <inlining>off : -fno-inline ;
 --- 268,274 ----

   # Declare flags and action for compilation
   flags gcc.compile OPTIONS <optimization>off : -O0 ;
 ! flags gcc.compile OPTIONS <optimization>speed : "$RPM_OPT_FLAGS" ;
   flags gcc.compile OPTIONS <optimization>space : -Os ;

   flags gcc.compile OPTIONS <inlining>off : -fno-inline ;

Now you need download im place where you put patches ( and will put boost.Slackbuild ) the sorces used by scripts of corse. If you to read boost.script , will see script uses two files in build process:

boost_asio on http://sourceforge.net/project/showfiles.php?group_id=122478 or if you prefer directly on
http://easynews.dl.sourceforge.net/sourceforge/asio/asio-0.3.8rc3.tar.gz

Adobe GPL GIL (just for enhace your boost lib) on http://opensource.adobe.com/gil/download.html or directly on http://opensource.adobe.com/gil/gil.tar.gz

finily _*' boost 1.34.1 _*' on http://sourceforge.net/project/showfiles.php?group_id=7586 or directly on
http://easynews.dl.sourceforge.net/sourceforge/boost/boost_1_34_1.tar.bz2
(boost.Slackbuild will compile your bjam ARGH!! (a ./configure like autotool system) ) in your system , and you will not need download bjam binary.

This Slackbuild is based on boost.SlackBuild,v 1.6 2007/09/04 of Eric Hameleers <>
and boost.spec from boost-1.34.0-2.el5.src.rpm from Red Hat Enterprise linux

boost.Slackbuild

 #!/bin/sh
 # $Id: boost.SlackBuild,v 1.6 2007/09/04 23:08:43 root Exp root $
 # Copyright (c) 2007 Eric Hameleers <alien@slackware.com>
 # All rights reserved.
 #
 #   Permission to use, copy, modify, and distribute this software for
 #   any purpose with or without fee is hereby granted, provided that
 #   the above copyright notice and this permission notice appear in all
 #   copies.
 #
 #   THIS SOFTWARE IS PROVIDED ``AS IS*_ AND ANY EXPRESSED OR IMPLIED
 #   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 #   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 #   IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
 #   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 #   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 #   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 #   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 #   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 #   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 #   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 #   SUCH DAMAGE.
 #
 # Slackware SlackBuild script 
 # ===========================
 # By:        Eric Hameleers <alien@slackware.com>
 # For:       boost
 # Descr:     collection of portable C++ source libraries
 # URL:       http://www.boost.org/
 # Needs:     
 # Changelog:
 # 1.34.1-1   01/10/2007 by Miguel Suarez Xavier Penteado <miguel_penteado@fca.unesp.br>
 # 1.33.1-1:  23/Dec/2006 by Eric Hameleers <alien@slackware.com>
 #            * Initial build.
 # 1.34.0-1:  04/Sep/2007 by Eric Hameleers <alien@slackware.com>
 #            * Update, Slackware 12.0 package.
 # 
 # Run 'sh boost.SlackBuild --cleanup' to build a Slackware package.
 # The package (.tgz) plus descriptive .txt file are created in /tmp .
 # Install using 'installpkg'. 
 #
 # Set initial variables:

 echo "Setting variables ..." 
 echo "Setando variaveis ..." 

 PRGNAM=boost
 VERSION=${VERSION:-1.34.1}
 SRCVER=$(echo ${VERSION} | tr '.' '_')
 ARCH=${ARCH:-i486}
 BUILD=${BUILD:-1}

 # This is the python we build against:
 PYTHON_VERSION=$(python -c 'import sys; print sys.version[:3]')
 PYTHON_FLAGS="-sPYTHON_ROOT=/usr -sPYTHON_VERSION=$PYTHON_VERSION" 

 DOCS="README LICENSE_1_0.txt people wiki" 

 # Where do we look for sources?
 CWD=$(pwd)
 SRCDIR=$(dirname $0)
 [ "${SRCDIR:0:1}" == "." ] && SRCDIR=${CWD}/${SRCDIR}

 # Place to build (TMP) package (PKG) and output (OUTPUT) the program:
 TMP=${TMP:-/tmp/build}
 PKG=$TMP/package-$PRGNAM
 OUTPUT=${OUTPUT:-/tmp}

 ###################################################################################
 ASIO=boost_asio
 VER_ASIO="0_3_8rc3" 
 SOURCE_ASIO="$SRCDIR/${ASIO}_${VER_ASIO}.tar.gz" 
 PKG_ASIO=$TMP/package-$ASIO

 ################################################################################### 

 ###################################################################################
 GIL=gil
 VER_GIL="2.1.1" 
 SOURCE_GIL="$SRCDIR/${GIL}-${VER_GIL}.tar.gz" 
 PKG_GIL=$TMP/package-$GIL 

 ###################################################################################

 # Input URL: http://dl.sourceforge.net/boost/boost_1_34_1.tar.gz
 SOURCE="$SRCDIR/${PRGNAM}_${SRCVER}.tar.gz" 
 SRCURL="http://dl.sourceforge.net/${PRGNAM}/${PRGNAM}_${SRCVER}.tar.gz" 

 # Exit the script on errors:
 set -e
 trap 'echo "$0 FAILED at line $LINENO!" | tee $OUTPUT/error-${PRGNAM}.log' ERR
 # Catch unitialized variables:
 set -u
 P1=${1:-1}

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e  '\E[01;33;40m'"Setando a vers~ao de gcc para 3.3.x ou 4.2.x"          ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;32;40m'

 # Slackware 11 and up need other option (gcc > 3.3.x)
 if [ $(gcc -dumpversion | tr -d  '.' |cut -c 1-2) -gt 33 ]; then
 MOPT=tune
 else
 MOPT=cpu
 fi

 case "$ARCH" in
 i386)      SLKCFLAGS="-O2 -march=i386 -m${MOPT}=i686" 
     SLKLDFLAGS=""; LIBDIRSUFFIX="" 
     ;;
 i486)      SLKCFLAGS="-O2 -march=i486 -m${MOPT}=i686" 
     SLKLDFLAGS=""; LIBDIRSUFFIX="" 
     ;;
 s390)      SLKCFLAGS="-O2" 
     SLKLDFLAGS=""; LIBDIRSUFFIX="" 
     ;;
 powerpc)   SLKCFLAGS="-O2" 
     SLKLDFLAGS=""; LIBDIRSUFFIX="" 
     ;;
 x86_64)    SLKCFLAGS="-O2 -fPIC" 
     SLKLDFLAGS="-L/usr/lib64"; LIBDIRSUFFIX="64" 
     ;;
 athlon-xp) SLKCFLAGS="-march=athlon-xp -O3 -pipe -fomit-frame-pointer" 
     SLKLDFLAGS=""; LIBDIRSUFFIX="" 
     ;;
 esac

 # Create working directories:
 mkdir -p $TMP/tmp-$PRGNAM # location to build the source
 rm -rf $TMP/tmp-$PRGNAM/* # By default we remove the remnants of previous build
 mkdir -p $PKG     # place for the package to be built
 rm -rf $PKG/*     # We always erase old package's contents:
 mkdir -p $OUTPUT  # place for the package to be saved

 # Source file availability:
 if ! [ -f ${SOURCE} ]; then
 if ! [ "x${SRCURL}" == "x" ]; then
 # Check if the $SRCDIR is writable at all - if not, download to $OUTPUT
 [ -w "$SRCDIR" ] || SOURCE="$OUTPUT/$(basename $SOURCE)" 
 echo "Source '$(basename ${SOURCE})' not available yet..." 
 echo "Will download file to $(dirname $SOURCE)" 
 wget -nv --connect-timeout=30 -O "${SOURCE}" "${SRCURL}" || true
 if [ $? -ne 0 -o ! -s "${SOURCE}" ]; then
 echo "Downloading '$(basename ${SOURCE})' failed... aborting the build." 
 mv -f "${SOURCE}" "${SOURCE}".FAIL
 exit 1
 fi
 else
 echo "File '$(basename ${SOURCE})' not available... aborting the build." 
 exit 1
 fi
 fi

 if [ "$P1" == "--download" ]; then
 echo "Download complete." 
 exit 0
 fi

 #################################################################################################
 # --- PACKAGE BUILDING ---

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e  '\E[01;33;40m'"extraindo arquivos"                                    ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;36;40m' 

 echo "++=================" 
 echo "|| $PRGNAM-$VERSION" 
 echo "++=================" 

 cd $TMP/tmp-$PRGNAM
 echo "Extracting the source archive(s) for $PRGNAM..." 
 if $(file ${SOURCE} | grep -q ": bzip2"); then
 tar -xjvf ${SOURCE}
 elif $(file ${SOURCE} | grep -q ": gzip"); then
 tar -xzvf ${SOURCE}
 fi
 mv ${PRGNAM}_${SRCVER} ${PRGNAM}-${VERSION}
 cd ${PRGNAM}-${VERSION}
 BUILD_DIR_BOOST=`pwd`
 chown -R root:root .
 chmod -R u+w,go+r-w,a-s .

 #################################################################################################
 mkdir -p $TMP/tmp-$ASIO # location to build the source
 rm -rf $TMP/tmp-$ASIO/* # By default we remove the remnants of previous build

 cd $TMP/tmp-$ASIO
 echo "Extracting the SOURCE_ASIO archive(s) for $ASIO..." 
 if $(file ${SOURCE_ASIO} | grep -q ": bzip2"); then
 tar -xjvf ${SOURCE_ASIO}
 elif $(file ${SOURCE_ASIO} | grep -q ": gzip"); then
 tar -xzvf ${SOURCE_ASIO}
 fi
 mv ${ASIO}_${VER_ASIO} ${ASIO}-${VER_ASIO}
 cd ${ASIO}-${VER_ASIO}
 chown -R root:root .
 chmod -R u+w,go+r-w,a-s .

 cp -a boost/ $TMP/tmp-$PRGNAM/${PRGNAM}-${VERSION}
 cp -a  libs/ $TMP/tmp-$PRGNAM/${PRGNAM}-${VERSION}

 #################################################################################################

 #################################################################################################
 mkdir -p $TMP/tmp-$GIL # location to build the source
 rm -rf $TMP/tmp-$GIL/* # By default we remove the remnants of previous build

 cd $TMP/tmp-$GIL
 echo "Extracting the SOURCE_GIL archive(s) for $GIL..." 
 if $(file ${SOURCE_GIL} | grep -q ": bzip2"); then
 tar -xjvf ${SOURCE_GIL}
 elif $(file ${SOURCE_GIL} | grep -q ": gzip"); then
 tar -xzvf ${SOURCE_GIL}
 fi

 cd ${GIL}-${VER_GIL}
 chown -R root:root .
 chmod -R u+w,go+r-w,a-s .

 cp -a boost/ $TMP/tmp-$PRGNAM/${PRGNAM}-${VERSION}
 cp -a  libs/ $TMP/tmp-$PRGNAM/${PRGNAM}-${VERSION}

 #################################################################################################

 cd $BUILD_DIR_BOOST

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e  '\E[01;33;40m'"aplicando o patch para gcc 4.2.x          "            ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;32;40m'

 cp -a $CWD/boost_bjam-gcc42_mod.patch $TMP/tmp-$PRGNAM/${PRGNAM}-${VERSION}/

 patch -p0 < boost_bjam-gcc42_mod.patch

 # echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 # echo -e  '\E[01;33;40m'"aplicando o patch para Thread          "            ;tput sgr0;
 # echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 # echo -e '\E[01;32;40m'
 # 
 # cp -a $CWD/boost-thread.patch $TMP/tmp-$PRGNAM/${PRGNAM}-${VERSION}/
 # 
 # patch -p0 < boost-thread.patch

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e  '\E[01;33;40m'"aplicando o patch para Configure          "            ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;32;40m'

 cp -a $CWD/boost-configure.patch $TMP/tmp-$PRGNAM/${PRGNAM}-${VERSION}/

 patch -p0 < boost-configure.patch

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e  '\E[01;33;40m'"aplicando o patch para boost-gcc-soname.patch    "     ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;32;40m'

 cp -a $CWD/boost-gcc-soname.patch $TMP/tmp-$PRGNAM/${PRGNAM}-${VERSION}/

 patch -p0 < boost-gcc-soname.patch

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e  '\E[01;33;40m'"aplicando o patch para boost-use-rpm-optflags.patch "  ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;32;40m'

 cp -a $CWD/boost-use-rpm-optflags.patch $TMP/tmp-$PRGNAM/${PRGNAM}-${VERSION}/

 patch -p0 < boost-use-rpm-optflags.patch

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e  '\E[01;33;40m'"Construindo BJAM                          "            ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;36;40m'

 echo Building ...
 export LDFLAGS="$SLKLDFLAGS" 
 export CFLAGS="$SLKCFLAGS" 
 export CXXFLAGS="$SLKCFLAGS" 

 BOOST_ROOT=`pwd`
 staged_dir=stage
 export BOOST_ROOT

 # First build bjam, the boost build system:
 ( cd tools/jam/src
 ./build.sh gcc 2>&1 | tee $OUTPUT/make-${PRGNAM}.log
 ) || exit $?
 BJAM=$(find tools/jam/src/ -name bjam -a -type f)

 # Create build subdirectory
 mkdir -p obj

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;33;40m'"Configure                                         "     ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;32;40m'

 #"-sBUILD=<optimization>speed <runtime-link>shared <runtime-link>static <inlining>full <threading>single/multi " 
 # Next, we build boost using bjam
 echo "Building boost now..." 
 $BJAM \
 release \
 "-d2 -sBUILD= <runtime-link>shared  <threading>multi " \
 "-sNO_COMPRESSION=0" "-sZLIB_INCLUDE=/usr/include" "-sZLIB_LIBPATH=/usr/lib" \
 "-sBZIP2_INCLUDE=/usr/include" "-sBZIP2_LIBPATH=/usr/lib" \
 --toolset=gcc --layout=system --builddir=obj \
 --prefix=/usr \
 $PYTHON_FLAGS \
 stage \
 2>&1 | tee -a $OUTPUT/make-${PRGNAM}.log

 # ./configure \
 # --with-bjam=$BJAM \
 # --with-toolset=gcc \
 # --prefix=/usr \
 # --with-libraries=all \
 # --with-python=/usr/bin/python \
 # --with-python-root=/usr \
 # --with-python-version=$PYTHON_VERSION 
 # #--with-icu \
 # #--with-icu=DIR \

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;33;40m'"Construindo boost                                 "     ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;33;40m'

 # make all

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;33;40m'"Instalando o boost em `pwd`                       "     ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;34;40m'

 echo "Installing boost now..." 
 $BJAM \
 release \
 --toolset=gcc --layout=system --link=shared --builddir=obj \
 --prefix=$PKG/usr \
 $PYTHON_FLAGS \
 install \
 2>&1 | tee $OUTPUT/install-${PRGNAM}.log

 # And then install boost..
 mkdir -p $PKG/usr/{bin,lib,include}
 mkdir -p $PKG/usr/share/${PRGNAM}-${VERSION}
 cp -a $BJAM $PKG/usr/bin

 #install lib
 for i in `find stage -type f -name \*.a`; do
 NAME=`basename $i`;
 install -p -m 0644 $i $PKG/usr/lib/$NAME;
 done;

 for i in `find stage -type f -name \*.so`; do
 NAME=$i;
 SONAME=$i.3;
 VNAME=$i.${VERSION};
 base=`basename $i`;
 NAMEbase=$base;
 SONAMEbase=$base.3;
 VNAMEbase=$base.${VERSION};
 mv $i $VNAME;
 ln -s $VNAMEbase $SONAME;
 ln -s $VNAMEbase $NAME;
 install -p -m 755 $VNAME $PKG/usr/lib/$VNAMEbase;
 mv $SONAME $PKG/usr/lib/$SONAMEbase;
 mv $NAME $PKG/usr/lib/$NAMEbase;
 done;

 ## Move incorrectly installed include files
 if [ -d $PKG/usr/include/${PRGNAM}-${VERSION} ]; then
 echo -e '\E[01;33;40m'"Movendo os Includes boost para $PKG/usr/include/  "     ;tput sgr0;
 echo -e '\E[01;34;40m'
 mv $PKG/usr/include/${PRGNAM}-${VERSION}/boost $PKG/usr/include/
 rmdir $PKG/usr/include/${PRGNAM}-${VERSION}
 fi

 # Add documentation:
 mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
 cp -a $DOCS $PKG/usr/doc/$PRGNAM-$VERSION || true
 chmod -R a-w $PKG/usr/doc/$PRGNAM-$VERSION/*

 # Strip binaries:
 cd $PKG
 find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
 find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
 cd -

 # Add a package description:
 mkdir -p $PKG/install
 cat $SRCDIR/slack-desc > $PKG/install/slack-desc
 if [ -f $SRCDIR/doinst.sh ]; then
 cat $SRCDIR/doinst.sh >> $PKG/install/doinst.sh
 fi

 # Build the package:
 cd $PKG
 makepkg --linkadd y --chown n $OUTPUT/${PRGNAM}-${VERSION}-${ARCH}-${BUILD}.tgz 2>&1 | tee $OUTPUT/makepkg-${PRGNAM}.log
 cd $OUTPUT
 md5sum ${PRGNAM}-${VERSION}-${ARCH}-${BUILD}.tgz > ${PRGNAM}-${VERSION}-${ARCH}-${BUILD}.tgz.md5
 cd -
 cat $PKG/install/slack-desc | grep "^${PRGNAM}" > $OUTPUT/${PRGNAM}-${VERSION}-${ARCH}-${BUILD}.txt

 # Clean up the extra stuff:
 if [ "$P1" = "--cleanup" ]; then
 rm -rf $TMP/tmp-$PRGNAM
 rm -rf $PKG
 fi
 tput sgr0; 

asio 0.3.7 standalone library Slackbuild

Next step: we will patch and compile asio-0.3.7.tar.gz . Use asio 0.3.7 version , is working.
#Patch asio-0.3.7 standalone

asio_openssl_init.patch

 --- ./include/asio/ssl/detail/openssl_init.hpp.orig    2006-11-15 00:10:08.000000000 +0100
 +++ ./include/asio/ssl/detail/openssl_init.hpp    2006-11-15 00:10:38.000000000 +0100
 @@ -45,13 +45,13 @@
        {
          ::SSL_library_init();
          ::SSL_load_error_strings();        
 +        ::OpenSSL_add_ssl_algorithms();

          mutexes_.resize(::CRYPTO_num_locks());
          for (size_t i = 0; i < mutexes_.size(); ++i)
            mutexes_[i].reset(new asio::detail::mutex);
          ::CRYPTO_set_locking_callback(&do_init::openssl_locking_func);

 -        ::OpenSSL_add_ssl_algorithms();
        }
      }

Getting Asio 0.3.7 library
You may open asio's homepage http://asio.sourceforge.net/ or get asio with this direct link
http://www.mirrorservice.org/sites/download.sourceforge.net/pub/sourceforge/a/as/asio/asio-0.3.7.tar.gz

asio.Slackbuild

 #!/bin/sh 

 PRGNAM=asio
 VERSION=0.3.7
 ARCH=${ARCH:-i486}
 BUILD=${BUILD:-1}
 TAG=${TAG:-MSXP}
 CWD=$(pwd)
 TMP=${TMP:-/tmp}    
 PKG=$TMP/package-$PRGNAM
 OUTPUT=${OUTPUT:-/tmp} 

 if [ "$ARCH" = "i486" ]; then
   SLKCFLAGS="-O2 -march=i486 -mtune=i686" 
 elif [ "$ARCH" = "i686" ]; then
   SLKCFLAGS="-O2 -march=i686 -mtune=i686" 
 fi

 rm -rf $PKG
 mkdir -p $TMP $PKG $OUTPUT
 cd $TMP || exit 1
 rm -rf $PRGNAM-$VERSION
 tar -xzvf $CWD/$PRGNAM-$VERSION.tar.gz || exit 1
 cd $PRGNAM-$VERSION || exit 1
 chown -R root:root .
 chmod -R u+w,go+r-w,a-s .

 echo -e '\E[01;32;40m'"****************************************************************";tput sgr0;
 echo -e '\E[01;33;40m'"aplicando o patch para $TMP/$PRGNAM-$VERSION  em`pwd` "               ;tput sgr0;
 echo -e '\E[01;32;40m'"****************************************************************";tput sgr0;
 echo -e '\E[01;32;40m'

 cp -a $CWD/asio_openssl_init.patch $TMP/$PRGNAM-$VERSION/ 

 patch -p0 < asio_openssl_init.patch

 echo -e '\E[01;32;40m'"****************************************************************";tput sgr0;
 echo -e '\E[01;33;40m'"execucao do script configure para $PRGNAM-$VERSION  em`pwd` "    ;tput sgr0;
 echo -e '\E[01;32;40m'"****************************************************************";tput sgr0;
 echo -e '\E[01;36;40m'

 CFLAGS="$SLKCFLAGS" \
 CXXFLAGS="$SLKCFLAGS" \
 ./configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --localstatedir=/var \
  --with-boost=/usr \
  --with-openssl=/usr

 echo -e '\E[01;32;40m'"****************************************************************"     ;tput sgr0;
 echo -e '\E[01;33;40m'"execucao de make configure para $PRGNAM-$VERSION  em`pwd`   "         ;tput sgr0;
 echo -e '\E[01;32;40m'"****************************************************************"     ;tput sgr0;
 echo -e '\E[01;34;40m'

 make 

 echo -e '\E[01;32;40m'"******************************************************************"     ;tput sgr0;
 echo -e '\E[01;33;40m'"execucao de make install configure para $PRGNAM-$VERSION  em`pwd` "     ;tput sgr0;
 echo -e '\E[01;32;40m'"******************************************************************"     ;tput sgr0;
 echo -e '\E[01;33;40m'

 make install DESTDIR=$PKG

 echo -e '\E[01;32;40m'"****************************************************************"     ;tput sgr0;
 echo -e '\E[01;33;40m'"Criando o pacote $PRGNAM-$VERSION  em`pwd`                  "         ;tput sgr0;
 echo -e '\E[01;32;40m'"****************************************************************"     ;tput sgr0;
 echo -e '\E[01;32;40m' 

 if [ -d $PKG/usr/man ]; then
 ( cd $PKG/usr/man
   find . -type f -exec gzip -9 {} \;
   for i in $(find . -type l) ; do ln -s $(readlink $i).gz $i.gz ; rm $i ; done
 )
 fi

 mkdir -p $PKG/install
 cat $CWD/slack-desc > $PKG/install/slack-desc

 cd $PKG
 /sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.tgz

 tput sgr0;

mxml 2.3 library Slackbuild

Next step we will download Mini XML 2.3 version on
http://www.minixml.org/software.php or in direct link
http://ftp.easysw.com/pub/mxml/2.3/mxml-2.3.tar.gz

mxml.SlackBuild

 #!/bin/sh

 # Slackware build script for mxml 
 # Original form Written by Chess Griffin <chess at chessgriffin dot com>
 # Adapted by Miguel Suarez Xavier Penteado <miguel_penteado@fca.unesp.br> 

 PRGNAM=mxml
 VERSION=2.3
 ARCH=${ARCH:-i486}
 BUILD=${BUILD:-1}
 TAG=${TAG:-MSXP}
 CWD=$(pwd)
 TMP=${TMP:-/tmp/SBo}    
 PKG=$TMP/package-$PRGNAM
 OUTPUT=${OUTPUT:-/tmp}

 if [ "$ARCH" = "i486" ]; then
   SLKCFLAGS="-O2 -march=i486 -mtune=i686" 
 elif [ "$ARCH" = "i686" ]; then
   SLKCFLAGS="-O2 -march=i686 -mtune=i686" 
 fi

 rm -rf $PKG
 mkdir -p $TMP $PKG $OUTPUT
 cd $TMP || exit 1
 rm -rf $PRGNAM-$VERSION
 tar -xzvf $CWD/$PRGNAM-$VERSION.tar.gz || exit 1
 cd $PRGNAM-$VERSION || exit 1
 chown -R root:root .
 chmod -R u+w,go+r-w,a-s .

 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e  '\E[01;33;40m'"Confire mxml in `pwd`                            ";tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e '\E[01;35;40m';

 CFLAGS="$SLKCFLAGS" \
 CXXFLAGS="$SLKCFLAGS" \
 ./configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --localstatedir=/var \
  --enable-static=no 

 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e  '\E[01;33;40m'"make mxml in `pwd`                               ";tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e '\E[01;36;40m';

 make 

 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e  '\E[01;33;40m'"make install mxml in `pwd`                        ";tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e '\E[01;37;40m';

 make install BUILDROOT=$PKG 

 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e '\E[01;33;40m'" Building packge mxml in `pwd`                    ";tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e '\E[01;35;40m'; 

 if [ -d $PKG/usr/man ]; then
 ( cd $PKG/usr/man
   find . -type f -exec gzip -9 {} \;
   for i in $(find . -type l) ; do ln -s $(readlink $i).gz $i.gz ; rm $i ; done
 )
 fi

 mkdir -p $PKG/install
 cat $CWD/slack-desc > $PKG/install/slack-desc

 cd $PKG
 /sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.tgz
 tput sgr0;

Fastcgi-2.4.0 Slackbuild

This slackbuild will install fastcgi library in your Slackware 12 ! You will need Fastcgi library plus apache modules. Lets get Library first.

You can download fcgi sorces at http://www.fastcgi.com/ or in this direct link
http://www.fastcgi.com/dist/fcgi.tar.gz You will get 2.4.0 version

Before, you must save this patch in sources tar directory

 The patch have 5.117 lines ... sorry try without him

then you may use fastcgi.Slackbuild

fastcgi.Slackbuild

 #!/bin/sh

 # Slackware build script for mysql++ 
 # Written by Chess Griffin <chess at chessgriffin dot com> 
 # Adapted by Miguel Suarez Xavier Penteado <miguel_penteado@fca.unesp.br>

 PRGNAM=fcgi
 VERSION=2.4.0
 ARCH=${ARCH:-i486}
 BUILD=${BUILD:-1}
 TAG=${TAG:-MSXP}
 CWD=$(pwd)
 TMP=${TMP:-/tmp/SBo}    
 PKG=$TMP/package-$PRGNAM
 OUTPUT=${OUTPUT:-/tmp}

 if [ "$ARCH" = "i486" ]; then
   SLKCFLAGS="-O2 -march=i486 -mtune=i686" 
 elif [ "$ARCH" = "i686" ]; then
   SLKCFLAGS="-O2 -march=i686 -mtune=i686" 
 fi

 rm -rf $PKG
 mkdir -p $TMP $PKG $OUTPUT
 cd $TMP || exit 1
 rm -rf $PRGNAM-$VERSION
 #tar -xzvf $CWD/$PRGNAM-$VERSION.tar.gz || exit 1
 tar -xzvf $CWD/$PRGNAM.tar.gz || exit 1
 cd $PRGNAM-$VERSION || exit 1
 chown -R root:root .
 chmod -R u+w,go+r-w,a-s .
 chmod a-x include/fcgios.h libfcgi/os_unix.c

 cp $CWD/fcgi-2.4.0-autotools.patch $PKG/$PRGNAM-$VERSION
 patch -p0 <  $PKG/$PRGNAM-$VERSION/fcgi-2.4.0-autotools.patch

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;33;40m'"configurando em "`pwd`                                 ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;36;40m'

 CFLAGS="$SLKCFLAGS" \
 CXXFLAGS="$SLKCFLAGS" \
 ./configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --localstatedir=/var

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;33;40m'"make em "`pwd`            ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;32;40m'
 make 

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;33;40m'"make install "`pwd`            ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;38;40m' 

 make install DESTDIR=$PKG

 if [ -d $PKG/usr/man ]; then
 ( cd $PKG/usr/man
   find . -type f -exec gzip -9 {} \;
   for i in $(find . -type l) ; do ln -s $(readlink $i).gz $i.gz ; rm $i ; done
 )
 fi

 mkdir -p $PKG/install
 cat $CWD/slack-desc > $PKG/install/slack-desc 

 cd $PKG
 /sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.tgz
 tput sgr0;

Modfastcgi-2.4.2 for apache Slackbuild

The mod_fastcgi will generate a patch for your apache 2.x.x modules

Get the module source http://www.fastcgi.com/ or directly here
http://www.fastcgi.com/dist/mod_fastcgi-2.4.2.tar.gz

patch
mod_fastcgi-2.4.2-update.patch

 sorry, to big 774 lines ... search in google, or try without it

Patch for you save in Sorce + Slackbuilds dir

_*' mod_fastcgi-2.4.2-apache2.2.patch*

 --- mod_fastcgi-2.4.2/fcgi.h    2006-03-22 16:59:55.000000000 +0000
 +++ mod_fastcgi-2.4.2/fcgi.h    2006-03-22 17:04:41.000000000 +0000
 @@ -73,6 +73,36 @@
  #define ap_reset_timeout(a)
  #define ap_unblock_alarms()

 +/* starting with apache 2.2 the backward-compatibility defines for
 + * 1.3 APIs are not available anymore. Define them ourselves here.
 + */
 +#ifndef ap_copy_table
 +
 +#define ap_copy_table apr_table_copy
 +#define ap_cpystrn apr_cpystrn
 +#define ap_destroy_pool apr_pool_destroy
 +#define ap_isspace apr_isspace
 +#define ap_make_array apr_array_make
 +#define ap_make_table apr_table_make
 +#define ap_null_cleanup apr_pool_cleanup_null 
 +#define ap_palloc apr_palloc
 +#define ap_pcalloc apr_pcalloc
 +#define ap_psprintf apr_psprintf
 +#define ap_pstrcat apr_pstrcat
 +#define ap_pstrdup apr_pstrdup
 +#define ap_pstrndup apr_pstrndup
 +#define ap_push_array apr_array_push
 +#define ap_register_cleanup apr_pool_cleanup_register
 +#define ap_snprintf apr_snprintf
 +#define ap_table_add apr_table_add
 +#define ap_table_do apr_table_do
 +#define ap_table_get apr_table_get
 +#define ap_table_set apr_table_set
 +#define ap_table_setn apr_table_setn
 +#define ap_table_unset apr_table_unset
 +
 +#endif /* defined(ap_copy_table) */
 +
  #if (defined(HAVE_WRITEV) && !HAVE_WRITEV && !defined(NO_WRITEV)) || defined WIN32
  #define NO_WRITEV
  #endif
 --- mod_fastcgi-2.4.2/Makefile.AP2    2006-03-22 17:04:55.000000000 +0000
 +++ mod_fastcgi-2.4.2/Makefile.AP2    2006-03-22 17:05:22.000000000 +0000
 @@ -20,8 +20,6 @@

  all: local-shared-build

 -install: install-modules
 -
  clean:
      -rm -f *.o *.lo *.slo *.la

Outro patch para voce slavar junto ao fonte e aos slackbuilds

_*' mod_fastcgi-2.4.2-fix_warnings.patch*

 --- mod_fastcgi-2.4.2/fcgi_config.c    2007-05-25 16:01:49.000000000 +0200
 +++ mod_fastcgi-2.4.2/fcgi_config.c    2007-05-25 16:06:42.000000000 +0200
 @@ -694,7 +694,7 @@
                  return invalid_value(tp, name, fs_path, option, err);
          }
          else if (strcasecmp(option, "-min-server-life") == 0) {
 -            if ((err = get_int(tp, &arg, &s->minServerLife, 0)))
 +            if ((err = get_u_int(tp, &arg, &s->minServerLife, 0)))
                  return invalid_value(tp, name, NULL, option, err);
          }
          else if (strcasecmp(option, "-priority") == 0) {
 @@ -763,12 +763,12 @@
      {
          if (s->group == NULL)
          {
 -            s->group = ap_psprintf(tp, "#%ld", fcgi_util_get_server_gid(cmd->server));
 +            s->group = ap_psprintf(tp, "#%d", fcgi_util_get_server_gid(cmd->server));
          }

          if (s->user == NULL)
          {
 -            s->user = ap_psprintf(p, "#%ld", fcgi_util_get_server_uid(cmd->server)); 
 +            s->user = ap_psprintf(p, "#%d", fcgi_util_get_server_uid(cmd->server)); 
          }

          s->uid = ap_uname2id(s->user);
 @@ -954,12 +954,12 @@
      {
          if (s->group == NULL)
          {
 -            s->group = ap_psprintf(tp, "#%ld", fcgi_util_get_server_gid(cmd->server));
 +            s->group = ap_psprintf(tp, "#%d", fcgi_util_get_server_gid(cmd->server)); 
         }

          if (s->user == NULL)
          {
 -            s->user = ap_psprintf(p, "#%ld", fcgi_util_get_server_uid(cmd->server));
 +            s->user = ap_psprintf(p, "#%d", fcgi_util_get_server_uid(cmd->server));
          }

          s->uid = ap_uname2id(s->user); 

fastcgi.conf

 # This is the Apache server configuration file providing FastCGI support..
 #
 # Documentation is available at <http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html>

 LoadModule fastcgi_module lib/httpd/modules/mod_fastcgi.so

 # To use FastCGI to process .fcg .fcgi & .fpl scripts
 AddHandler fastcgi-script fcg fcgi fpl

doinst.sh

 cp /etc/httpd/httpd.conf /etc/httpd/httpd.old
 echo "Include /etc/httpd/extra/fastcgi.conf" >> /etc/httpd/httpd.conf 
 echo "Restarting httpd ..." 
 sh /etc/rc.d/rc.httpd restart

slack-desc

            |-----handy-ruler------------------------------------------------------|
 mod_fastcgi: mod_fastcgi 2.4.2
 mod_fastcgi:
 mod_fastcgi: A fastcgi module for httpd
 mod_fastcgi:
 mod_fastcgi:
 mod_fastcgi:
 mod_fastcgi:
 mod_fastcgi:
 mod_fastcgi:
 mod_fastcgi:

*modfastcgi.Slackbuild

 #!/bin/sh
 #
 # $Id: mod_fastcgi-server.SlackBuild 275 2005-03-08 01:20:25Z freerock $

 CWD=`pwd`
 TMP=${TMP:-/tmp}
 PKG=$TMP/package-mod_fastcgi

 VERSION=2.4.2
 ARCH=${ARCH:-i486}
 BUILD=1

 if [ ! -d $TMP ]; then
   mkdir -p $TMP # location to build the source
 fi
 rm -rf $PKG
 mkdir -p $PKG

 if [ "$ARCH" = "i386" ]; then
   SLKCFLAGS="-O2 -march=i386 -mcpu=i686" 
 elif [ "$ARCH" = "i486" ]; then
   SLKCFLAGS="-O2 -march=i486 -mcpu=i686" 
 elif [ "$ARCH" = "s390" ]; then
   SLKCFLAGS="-O2" 
 elif [ "$ARCH" = "x86_64" ]; then
   SLKCFLAGS="-O2" 
 fi

 cd $TMP 
 tar xzvf $CWD/mod_fastcgi-$VERSION.tar.gz

 cd mod_fastcgi-$VERSION

 echo "copiando patch ..." 

 cp $CWD/mod_fastcgi-2.4.2-apache2.2.patch $TMP/mod_fastcgi-$VERSION
 cp $CWD/mod_fastcgi-2.4.2-update.patch $TMP/mod_fastcgi-$VERSION
 cp $CWD/mod_fastcgi-2.4.2-fix_warnings.patch $TMP/mod_fastcgi-$VERSION

 echo "aplicando patch ..." 

 patch -p1 < mod_fastcgi-2.4.2-apache2.2.patch
 patch -p1 < mod_fastcgi-2.4.2-update.patch
 patch -p1 < mod_fastcgi-2.4.2-fix_warnings.patch

 rm Makefile

 cat Makefile.AP2 > Makefile

 LDFLAGS=-s \
 CFLAGS="$SLKCFLAGS" \
 CXXFLAGS="$SLKCFLAGS" 

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e  '\E[01;33;40m'"make em "`pwd`                                         ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;32;40m'

 topdir=$(/usr/bin/dirname $(/usr/sbin/apxs -q exp_installbuilddir))

 make top_dir=${topdir}

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e  '\E[01;33;40m'"make install "`pwd`                                    ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;36;40m'

 make top_dir=${topdir} DESTDIR=$PKG MKINSTALLDIRS="mkdir -p"  install

 tput sgr0;

 mkdir -p $PKG/etc/httpd/extra/
 cp -a $CWD/fastcgi.conf $PKG/etc/httpd/extra/

 echo "Criando diretório de documentação ..." 
 mkdir -p $PKG/usr/doc/mod_fastcgi-$VERSION 

 echo "Copiando arquivos de documetação ..." 
 cp -a  INSTALL README CHANGES  $PKG/usr/doc/mod_fastcgi-$VERSION

 chmod 644 $PKG/usr/doc/mod_fastcgi-$VERSION/*
 chown root.root $PKG/usr/doc/mod_fastcgi-$VERSION/* 

 find $PKG -type f | xargs file | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded
 gzip -9 $PKG/usr/man/*/*

 echo "criando diretório de scripts instalação ..." 
 mkdir -p $PKG/install
 cat $CWD/slack-desc > $PKG/install/slack-desc
 cat $CWD/doinst.sh >> $PKG/install/doinst.sh 

 echo "criando o pacote ..." 
 cd $PKG
 makepkg -l y -c n $TMP/mod_fastcgi-$VERSION-$ARCH-$BUILD.tgz

 # Clean up the extra stuff:
 if [ "$1" = "--cleanup" ]; then
   rm -rf $TMP/template-$VERSION
   rm -rf $PKG
 fi

Mysql++ Slackbuild

You can get the sources of Mysql++ at http://tangentsoft.net/mysql++/ or directly in
http://tangentsoft.net/mysql++/releases/mysql++-2.3.2.tar.gz

You may need some how-to or tutorials on internet for mysql++ , so you may like this
http://www.devarticles.com/c/a/Cplusplus/Building-a-Store-Application-With-MySQL-and-C/
save this with slack-desc name in the sources + mysql++.Slacbuild directory

 # HOW TO EDIT THIS FILE:
 # The "handy ruler" below makes it easier to edit a package description.  Line
 # up the first '|' above the ':' following the base package name, and the '|' on
 # the right side marks the last column you can put a character in. You must make
 # exactly 11 lines for the formatting to be correct.  It's also customary to
 # leave one space after the ':'.

        |-----handy-ruler------------------------------------------------------|
 mysql++: mysql++-2.3.2      
 mysql++:
 mysql++: MySQL++ is a powerful C++ wrapper for MySQL's C API. 
 mysql++: Its purpose is to make working with queries as easy as working
 mysql++: with STL containers.
 mysql++:
 mysql++:
 mysql++:
 mysql++:
 mysql++:
 mysql++:

Now you can build package with mysql++.Slackbuild

*Mysql++.Slackbuild

 #!/bin/sh

 # Slackware build script for mysql++ 
 # Written by Chess Griffin <chess at chessgriffin dot com>

 PRGNAM=mysql++
 VERSION=2.3.2
 ARCH=${ARCH:-i486}
 BUILD=${BUILD:-1}
 TAG=${TAG:-MSXP}
 CWD=$(pwd)
 TMP=${TMP:-/tmp/SBo}    
 PKG=$TMP/package-$PRGNAM
 OUTPUT=${OUTPUT:-/tmp}

 if [ "$ARCH" = "i486" ]; then
   SLKCFLAGS="-O2 -march=i486 -mtune=i686" 
 elif [ "$ARCH" = "i686" ]; then
   SLKCFLAGS="-O2 -march=i686 -mtune=i686" 
 fi

 rm -rf $PKG
 mkdir -p $TMP $PKG $OUTPUT
 cd $TMP || exit 1
 rm -rf $PRGNAM-$VERSION
 tar -xzvf $CWD/$PRGNAM-$VERSION.tar.gz || exit 1
 cd $PRGNAM-$VERSION || exit 1
 chown -R root:root .
 chmod -R u+w,go+r-w,a-s .

 CFLAGS="$SLKCFLAGS" \
 CXXFLAGS="$SLKCFLAGS" \
 ./configure \
   --prefix=/usr \
   --sysconfdir=/etc \
   --localstatedir=/var

 make 

 make install DESTDIR=$PKG

 if [ -d $PKG/usr/man ]; then
 ( cd $PKG/usr/man
   find . -type f -exec gzip -9 {} \;
   for i in $(find . -type l) ; do ln -s $(readlink $i).gz $i.gz ; rm $i ; done
 )
 fi

 mkdir -p $PKG/install
 cat $CWD/slack-desc > $PKG/install/slack-desc

 cd $PKG
 /sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.tgz

ICU Slackbuild

optional

Wt-2.0.5 Slackbuild

Finally tou ready for Witty.

Get witty sources on
http://www.webtoolkit.eu/ or in direct link
http://easynews.dl.sourceforge.net/sourceforge/witty/wt-2.0.5.tar.gz

#put this description file file as slack-desc in wt.Slackbuild source directory

 # HOW TO EDIT THIS FILE:
 # The "handy ruler" below makes it easier to edit a package description.  Line
 # up the first '|' above the ':' following the base package name, and the '|' on
 # the right side marks the last column you can put a character in. You must make
 # exactly 11 lines for the formatting to be correct.  It's also customary to
 # leave one space after the ':'.

   |-----handy-ruler------------------------------------------------------|
 wt: wt-2.0.5 - Webtoolkit
 wt:
 wt: Wt (pronounced 'witty') is a C++ library and application server
 wt: for developping and deploying web applications. The API is 
 wt: widget-centric, and inspired by existing C++ Graphical User Interface 
 wt: (GUI) APIs. To the developer, it offers complete abstraction of any 
 wt: web-specific implementation details.
 wt: In contrast, a web application developed with Wt is written in only 
 wt: one compiled language (C++), from which the library generates the 
 wt: necessary HTML, Javascript, CGI, and AJAX code.
 wt:
 wt: http://www.webtoolkit.eu/
 wt:

#put this config file in Slackbuild + source directory
wt_httpd.conf

 <Directory /var/www/wt/>
     #Order Deny,Allow
     Allow from all
     # Don't show indexes for directories on publicly accessible machines (Uncomment if it's a private devshell).
     #Options -Indexes
     # Enable CGIs to be executed 
     Options ExecCGI
 </Directory> 

#put this post-install script file in Slackbuild + source directory
doinst.sh

 echo "backup /etc/httpd/httpd.conf as httpd.conf.old ..." 
 cp /etc/httpd/httpd.conf /etc/httpd/httpd.conf.old 
 echo "Including /etc/httpd/extra/wt_httpd.conf in httpd.conf ..." 
 echo "Include /etc/httpd/extra/wt_httpd.conf" >> /etc/httpd/httpd.conf  
 echo "Reloading Apache httpd ..." 
 sh /etc/rc.d/rc.httpd restart

wt.Slackbuild

 #!/bin/sh
 # Slackware build script for wt.
 NAME=wt

 # Get the current and temporary directories
 CWD=`pwd`
 if [ "$TMP" = "" ]; then
   TMP=/tmp
 fi
 PKG=$TMP/package-$NAME

 VERSION=${VERSION:-2.0.5}
 ARCH=${ARCH:-i486}
 BUILD=${BUILD:-1}

 if [ "$ARCH" = "i386" ]; then
   SLKCFLAGS="-O2 -m32 -march=i386 -mcpu=i386" 
 elif [ "$ARCH" = "i486" ]; then
   SLKCFLAGS="-O2 -m32 -march=i486 -mtune=i686" 
 elif [ "$ARCH" = "s390" ]; then
   SLKCFLAGS="-O2" 
 elif [ "$ARCH" = "x86_64" ]; then
   SLKCFLAGS="-O2" 
 fi

 if [ ! -d $TMP ]; then
   mkdir -p $TMP # location to build the source
 fi

 # Clean up a previous build
 rm -rf $PKG
 mkdir -p $PKG 

 # Decompress
 cd $TMP
 rm -rf $NAME-$VERSION
 tar xvf $CWD/$NAME-$VERSION.tar.gz || exit 1
 cd $NAME-$VERSION

 # Fix
 chown -R root:root .
 find . -perm 666 -exec chmod 644 {} \;
 find . -perm 664 -exec chmod 644 {} \;
 find . -perm 600 -exec chmod 644 {} \;
 find . -perm 444 -exec chmod 644 {} \;
 find . -perm 400 -exec chmod 644 {} \;
 find . -perm 440 -exec chmod 644 {} \;
 find . -perm 777 -exec chmod 755 {} \;
 find . -perm 775 -exec chmod 755 {} \;
 find . -perm 511 -exec chmod 755 {} \;
 find . -perm 711 -exec chmod 755 {} \;
 find . -perm 555 -exec chmod 755 {} \;

 mkdir -p $PKG/var/www/wt
 mkdir -p $PKG/etc/wt

 mkdir $PKG/usr/src/wt
 cp $CWD/wt.Slackbuild $PKG/usr/src/wt

 mkdir `pwd`/build
 cd `pwd`/build

 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e  '\E[01;33;40m'"execucao do script  cmake para wt em "`pwd`            ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************"     ;tput sgr0;
 echo -e '\E[01;36;40m'

 cmake -D DEPLOYROOT=/var/www/wt \
 -D WEBUSER=apache \
 -D BUILD_SHARED_LIBS=ON \
 -D CONFIGURATION=/etc/wt \
 -D BOOST_COMPILER=gcc \
 -D BOOST_VERSION=1_34_1 \
 -D BOOST_DIR=/usr \
 -D RUNDIR=/var/run \
 -D CMAKE_INSTALL_PREFIX=/usr \
 -D HTTP_WITH_SSL=true \
 -D CONNECTOR_FCGI=true \
 -D EXAMPLES_CONNECTOR=wthttp \
 -D WEBGROUP=users ../
 #-D EXECUTABLE_OUTPUT_PATH=/var/www/wt/bin \

 # Build

 echo -e '\E[01;32;40m'"**************************************************" ; tput sgr0;
 echo -e  '\E[01;33;40m'"        Compilando wt com make em " `pwd`          ; tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************" ; tput sgr0;
 echo -e '\E[01;34;40m';

 make

 echo -e '\E[01;32;40m'"**************************************************" ; tput sgr0;
 echo -e  '\E[01;33;40m'"        Compilando exemplos com make em " `pwd`          ; tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************" ; tput sgr0;
 echo -e '\E[01;32;40m';

 make -C examples

 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e  '\E[01;33;40m'"instalado wt  em $PKG com o make  install"        ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e '\E[01;35;40m';

 make install DESTDIR=$PKG

 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e  '\E[01;33;40m'"instalado wt examples  em $PKG             "      ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e '\E[01;32;40m';

 mkdir -p $PKG/usr/share/$NAME-$VERSION/examples
 cp -a $TMP/$NAME-$VERSION/build/examples $PKG/usr/share/$NAME-$VERSION/

 echo -e '\E[01;32;40m'"**************************************************";tput sgr0;
 echo -e  '\E[01;33;40m'"Montando o pacote"                                ;tput sgr0;
 echo -e '\E[01;32;40m'"**************************************************";tput sgr0; 

 # Clean up a previous build
 rm -rf $PKG/etc/wt
 mkdir -p $PKG/etc/wt 

 rm -rf $PKG/var/www/wt
 mkdir -p $PKG/var/www/wt

 mkdir -p $PKG/etc/httpd/extra
 cp $CWD/wt_httpd.conf $PKG/etc/httpd/extra

 # Gzip man pages
 find $PKG/usr/man -name "*.[123456789]" -exec gzip -9 {} \;

 # Strip binaries
 ( cd $PKG
   find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
   find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
 )

 # Copy Slackware package files
 mkdir -p $PKG/install
 cat $CWD/slack-desc > $PKG/install/slack-desc
 cat $CWD/doinst.sh >> $PKG/install/doinst.sh

 # Create package
 echo "Creating package" 
 cd $PKG
 makepkg -l y -c n ../$NAME-$VERSION-$ARCH-$BUILD.tgz 

 # Clean up
 if [ "$1" = "--cleanup" ]; then 
     rm -rf $TMP/$NAME-$VERSION
     rm -rf $PKG
 fi

Testing Witty without apache

open a konsole window and

 cd /usr/share/wt-2.0.5/examples/
 cd hello
 sh deploy.sh

then go to

 cd /var/www/wt/hello
 cd /var/www/wt/hello/
 ./hello.wt --docroot . --http-address your.ip.com --http-port 8080

and open your browser at http://you.ip.com:8080

Have a fun !!!


Installing Wt on Solaris with Sun CC Compiler and stlport4

Overview

Installing Wt on Solaris with Sun CC Compiler compiled and linked with stlport4.

successful builded on Solaris 10 sparc with Sun C++ compiler 5.9

Dependencies

install this programs for example into the $WT_ROOT path (see below).

prepare the install directory

We don't need to build and install the libraries as root.

You need only run this two commands as root (or ask your system admin to do that):

mkdir /opt/WT
chown <user>:<group> /opt/WT
chmod 755 /opt/WT

<user> and <group> have to be a valid system user and group

Now you can build and install the libs as <user>. Loggin as <user>

set environment

WT_ROOT=/opt/WT
BUILD_DIR=$WT_ROOT/build
ZLIB_ROOT=$WT_ROOT
SSL_ROOT=$WT_ROOT
BOOST_CFG=sw-mt
BOOST_COMPILER=sw
BOOST_ROOT=$WT_ROOT
BOOST_VERSION=1_39
FCGI_ROOT=$WT_ROOT
PATH=$WT_ROOT/bin:$PATH
LD_LIBRARY_PATH=$WT_ROOT/lib:$LD_LIBRARY_PATH
mkdir $BUILD_DIR
mkdir $WT_ROOT/bin
mkdir $WT_ROOT/lib
export WT_ROOT BUILD_DIR ZLIB_ROOT SSL_ROOT BOOST_CFG BOOST_COMPILER BOOST_ROOT BOOST_VERSION FCGI_ROOT PATH LD_LIBRARY_PATH

download sources to $BUILD_DIR as example with wget

cd $BUILD_DIR
wget http://www.zlib.net/zlib-1.2.3.tar.gz
wget http://www.openssl.org/source/openssl-0.9.8k.tar.gz
wget http://switch.dl.sourceforge.net/sourceforge/boost/boost-jam-3.1.17.tgz
wget http://switch.dl.sourceforge.net/sourceforge/boost/boost_1_39_0.tar.gz
wget http://ftp.de.debian.org/debian/pool/main/libf/libfcgi/libfcgi_2.4.0.orig.tar.gz
wget http://ftp.de.debian.org/debian/pool/main/libf/libfcgi/libfcgi_2.4.0-7.diff.gz
wget http://switch.dl.sourceforge.net/sourceforge/witty/wt-2.2.4.tar.gz

build libs

zlib

cd $BUILD_DIR
gzip -dc zlib-1.2.3.tar.gz | tar xpf -
cd zlib-1.2.3
gmake all install

openssl

cd $BUILD_DIR
gzip -dc openssl-0.9.8k.tar.gz | tar xpf -
cd openssl-0.9.8k
./config --prefix=$SSL_ROOT --openssldir=$SSL_ROOT/share/ssl shared threads zlib
gmake all install

bjam

cd $BUILD_DIR
gzip -dc boost-jam-3.1.17.tgz | tar xpf -
cd boost-jam-3.1.17
./build.sh sunpro
cp $WT_ROOT/bin

boost

cd $BUILD_DIR
gzip -dc boost_1_39_0.tar.gz | tar xpf -
cd boost_1_39_0
echo "import toolset : using ;" >tools/build/v2/user-config.jam
echo "using sun : : CC : <stdlib>sun-stlport <cxxflags>\"-library=stlport4 \
  -xcode=pic32 -erroff=wvarhidemem,hidevf,hidevfinvb -errtags=yes\" <linkflags>\"-library=stlport4 \
  -xcode=pic32\" ;" >> tools/build/v2/user-config.jam
gpatch boost/thread/detail/thread.hpp <<EOF
107c107
<     private:
---
>     public:
108a109,110
>     private:
>         // need to be public: thread(thread&);
EOF
bjam install -d2 --prefix=$BOOST_ROOT \
  toolset=sun stdlib=sun-stlport \
  variant=release,debug threading=multi link=shared \
  -sNO_COMPRESSION=0 -sNO_BZIP2=1 -sNO_ZLIB=0 \
  -sZLIB_INCLUDE=$ZLIB_ROOT/include -sZLIB_LIBPATH=$ZLIB_ROOT/lib -sZLIB_BINARY=z

fcgi

To build fcgi we use sources and patches from debian http://packages.debian.org/stable/libfcgi-dev, which is working well.
The orginal source file from http://www.fastcgi.com/dist will not build on solaris.

cd $BUILD_DIR
gzip -dc libfcgi_2.4.0.orig.tar.gz | tar xpf -
mv libfcgi-2.4.0.orig libfcgi-2.4.0
cd libfcgi-2.4.0
gzip -dc ../libfcgi_2.4.0-7.diff.gz | gpatch -p1
CXXFLAGS=-library=stlport4 ./configure --prefix=$WT_ROOT --disable-static
gmake all install

wt

cd $BUILD_DIR
gzip -dc wt-2.2.4.tar.gz | tar xpf -
cd wt-2.2.4
gpatch -p1 <<EOF
diff -Nurp wt-2.2.4.org/src/Wt/WAbstractItemModel.C wt-2.2.4/src/Wt/WAbstractItemModel.C
--- wt-2.2.4.org/src/Wt/WAbstractItemModel.C    2009-03-04 12:00:30.000000000 +0100
+++ wt-2.2.4/src/Wt/WAbstractItemModel.C        2009-05-03 14:22:46.993329000 +0200
@@ -4,6 +4,7 @@
  * See the LICENSE file for terms of use.
  */

+#include <stdio.h>
 #include <boost/lexical_cast.hpp>
 #include <boost/algorithm/string/predicate.hpp>

diff -Nurp wt-2.2.4.org/src/Wt/WModelIndex.C wt-2.2.4/src/Wt/WModelIndex.C
--- wt-2.2.4.org/src/Wt/WModelIndex.C   2009-03-04 12:00:30.000000000 +0100
+++ wt-2.2.4/src/Wt/WModelIndex.C       2009-05-03 14:48:04.304612000 +0200
@@ -3,6 +3,7 @@
  *
  * See the LICENSE file for terms of use.
  */
+#include <string.h>
 #include <iostream>

 #include "Wt/WModelIndex" 
diff -Nurp wt-2.2.4.org/src/http/WServer.C wt-2.2.4/src/http/WServer.C
--- wt-2.2.4.org/src/http/WServer.C     2009-03-04 12:00:30.000000000 +0100
+++ wt-2.2.4/src/http/WServer.C 2009-05-03 17:26:09.978681000 +0200
@@ -11,6 +11,9 @@
 #include <string>

 #if !defined(_WIN32)
+#ifdef __SUNPRO_CC
+#  define _POSIX_PTHREAD_SEMANTICS
+#endif
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/wait.h>
EOF
mkdir build
cd build
cmake \
  -DCMAKE_CXX_FLAGS:STRING=-library=stlport4 \
  -DCMAKE_EXE_LINKER_FLAGS:STRING=-library=stlport4 \
  -DCMAKE_MODULE_LINKER_FLAGS:STRING=-library=stlport4 \
  -DCMAKE_SHARED_LINKER_FLAGS:STRING=-library=stlport4 \
  -DBOOST_COMPILER=$BOOST_COMPILER \
  -DBOOST_DIR=$BOOST_ROOT \
  -DBOOST_VERSION=$BOOST_VERSION \
  -DCMAKE_INSTALL_PREFIX=$WT_ROOT \
  -DCMAKE_VERBOSE_MAKEFILE=TRUE \
  -DCONFIGDIR=$WT_ROOT/etc \
  -DCONFIGURATION=$WT_ROOT/etc/wt_config.xml \
  -DCONNECTOR_FCGI=ON \
  -DCONNECTOR_HTTP=ON \
  -DDEPLOYROOT=$WT_ROOT/deploy \
  -DEXAMPLES_CONNECTOR=wtfcgi \
  -DFCGIPP_LIB=$FCGI_ROOT/lib/libfcgi++.so \
  -DFCGI_INCLUDE_DIR=$FCGI_ROOT/include \
  -DFCGI_LIB=$FCGI_ROOT/lib/libfcgi.so \
  -DMULTI_THREADED=ON \
  -DRUNDIR=$WT_ROOT/run \
  -DUSERLIB_ROOT=$WT_ROOT/lib \
  -DSSL_INCLUDE_DIRS=$SSL_ROOT/include \
  -DSSL_LIB=$SSL_ROOT/lib/libssl.so \
  -DZLIB_INCLUDE=$ZLIB_ROOT/include \
  -DZLIB_LIB=$ZLIB_ROOT/lib/libz.so \
  -DWTHTTP_CONFIGURATION=$WT_ROOT/etc ..
gmake
gmake -C examples
gmake install

thanks Koen Deforche for the CMAKE_CXX_FLAGS help: http://sourceforge.net/mailarchive/message.php?msg_name=205a79980904172331u167bd2derc0f56d85954a0165%40mail.gmail.com


Installing Wt on Ubuntu

For installation of Wt on Ubuntu, you have the choice between the official package available in Ubuntu, prebuilt packages by Pau Garcia i Quiles (always updated to the newest Wt version) or installation from source.

Installing from the official package

Since Ubuntu Intrepid (8.10), official packages for Ubuntu are available. To install Wt, run:

 $ sudo aptitude install witty witty-dbg witty-dev witty-doc

This will automatically install all the required dependencies. If you only want the runtime library, you only need to install the witty package. The witty-dbg package contains the debug versions of the libraries. Make sure you install witty-dev (or libwtwhatever-dev) if you want to develop Wt applications.

The official package is usually a bit outdated due to the stabilization periods Debian and Ubuntu need prior to release. If you want to use the newest version of Wt and not build from source, read on.

Installing from prebuilt packages

Since Wt 2.0.3, unofficial packages for Ubuntu are being built by Pau Garcia i Quiles. To install Wt, add the Wt PPA to your repositories (check "Adding this PPA to your system" in the Wt PPA page). After adding the repository to your system, run:

 $ sudo apt-get update
 $ sudo aptitude install libwt*

This will automatically install all the required dependencies. If you only want the runtime library, you only need to install the libwt24, libwthttp24, libwtext24, etc packages (no -dev, -doc or -dbg packages). The libwt-dbg package contains the debug versions of the libraries.

These packages are built by the maintainer of the official Debian and Ubuntu packages and are always updated to the latest version of Wt. If you want to use the newest version of Wt and not build from source, this is the preferred method.

Please note in the past packages were named witty, witty-dev, witty-doc and witty-dbg. These package still exist but only as transitional packages and will be removed in the future. It is recommended that you install libwt*.

Installing from sources

Howto for wthttpd on gutsy

I made this for a freshly installed ubuntu 7.10 (gutsy gibbon).
It's without unicode,mysql and extjs support.
Should work similar for debian 4.0 etch.
As I wrote this down after installation, I hope all steps are correct. If you encounter problems, please let me know.

installing system dependencies

Note : this information is partially out of date. Instead of installing the 1.34 versions of the boost projects, use the 1.35 ones (also in ubuntu with sudo apt-get install libboost1.35-dev)

Open a terminal and enter the following commands:

 sudo apt-get install gcc
 sudo apt-get install g++
 sudo apt-get install zlib1g
 sudo apt-get install zlib1g-dev
 sudo apt-get install cmake
 sudo apt-get install libboost-date-time-dev libboost-date-time1.34.1
 sudo apt-get install libboost-program-options-dev libboost-program-options1.34.1
 sudo apt-get install libboost-regex-dev libboost-regex1.34.1
 sudo apt-get install libboost-signals-dev libboost-signals1.34.1
 sudo apt-get install libboost-thread-dev libboost-thread1.34.1
 sudo apt-get remove libgd-noxpm-dev (as libgd therein seems to be to old for examples - see link below)
 sudo apt-get install libgd2-xpm libgd2-xpm-dev
 sudo apt-get install libssl-dev
 sudo apt-get install libboost-filesystem-dev libboost-filesystem1.34.1
 sudo apt-get install libboost-test-dev libboost-test1.34.1

If you also want support for deploying applications using FastCGI, you'll need the following library, and set FCGI to true when configuring Wt:

 sudo apt-get install libfcgi-dev

getting external sources

get asio (http://asio.sourceforge.net)

 wget -c http://kent.dl.sourceforge.net/sourceforge/asio/asio-0.3.9.tar.bz2
 tar xvfj asio-0.3.9.tar.bz2

get Wt (http://www.webtoolkit.eu/wt)

 wget -c http://kent.dl.sourceforge.net/sourceforge/witty/wt-2.1.0.tar.gz
 tar xvfz wt-2.1.0.tar.gz

buidling and installing sources

asio

 cd asio-0.3.9
 ./configure
 sudo make install
 sudo ldconfig

Wt

 cd wt-2.1.0
 mkdir build; cd build
 cmake ..
 make
 sudo make install
 sudo ldconfig

Try the examples

From the prebuilt packages:

  cmake -DWT_SOURCE_DIR=/usr/share/doc/witty-doc/ -DEXAMPLES_CONNECTOR="wt;wthttp" /usr/share/doc/witty-doc/examples
  $ mkdir /home/user/dev/wtexamples
  $ cd /home/user/dev/wtexamples
  $ cmake -DWT_SOURCE_DIR=/usr/share/doc/witty-doc/ -DEXAMPLES_CONNECTOR="wt;wthttp" /usr/share/doc/witty-doc/examples
  $ make
  $ cd /usr/share/doc/witty-doc/examples/charts
  $ /home/user/dev/wtexamples/charts/charts.wt --http-port 10000 --http-addr 0.0.0.0 --docroot .

From the sources:

Special cases:

Using 'ccmake' to edit build options

This is an easy, graphical way to edit the build options

 cd build
 ccmake .

if it fails with SSL problem (as mine did)

Edit the HTTP_WITH_SSL to OFF, and try again (or you could install openssl-dev and try again)

 CMake Error: This project requires some variables to be set,
 and cmake can not find them.
 Please set the following variables:
 OPENSSL_INCLUDE

OPENSSL_LIB

Ubuntu's official documentation

You can find it here


ISAPI on Microsoft IIS

From Wt 3.1.4 onward, Wt is delivered with an ISAPI connector for easy integration with Microsoft IIS. ISAPI was preferred above FCGI on Windows because existing FCGI implementations (client libraries and servers) turned out to result in suboptimal solutions. Note that Wt does not support FCGI on Windows.

Wt beautifully integrates with IIS's asynchronous architecture, and even specialized features such as server push, the internal path API, static resources, multiple deploy paths, ... work perfectly with IIS. The Wt ISAPI connector is fully asynchronous, and therefore causes no performance or scalability problems for IIS's internal architecture.

Using the connector

Building the connector

Follow the general build instructions for Installing Wt on MS Windows. When configuring Wt with CMake, ensure that CONNECTOR_ISAPI is set to true (the default). If you want to compile all examples with the ISAPI connector, set EXAMPLES_CONNECTOR to wtisapi. By default, the examples will use the wthttpd connector, which turns every example in a standalone web server.

Building your Wt application - General

To use the ISAPI connector in your own projects, the following steps are required:

The source code of your Wt application needs no changes to use the ISAPI connector.

Important remark regarding the Current Working Directory

The CWD of your Wt application will be whatever CWD that IIS decides to assign it. You cannot control the CWD on a per-application basis. Therefore, you should avoid the use of any relative path names in your Wt application. We have implemented an 'approot' mechanism that helps you to achieve this.

'approot' is a configuration property (see WApplication::readConfigurationProperty()). Instead of accessing it through the readConfigurationProperty() method, use the WApplication::appRoot() function, or WServer::appRoot() if an application object does not yet exist, e.g. in your main() function. The result of appRoot() is guaranteed to end on a '/', and it will be empty if the approot property has not been set. Therefore, you can now use absolute paths anywhere you access a local file:

messageResourceBundle().use(appRoot() + "text");
Wt::Dbo::backend::Sqlite3 sqlite3_(approot() + "planner.db");
std::ifstream file(approot() + "myfile.csv");

The approot property can be set in serveral ways:

Using CMake to build your application

We suggest the use creative use of CMake functions to quickly switch between the httpd and the ISAPI connector. For example, Wt uses a function similar to this one to define its examples:

FUNCTION(WT_ADD_APPLICATION name)
  IF(${WT_CONNECTOR} STREQUAL "wtisapi")
    LIST(INSERT ARGV 1 "SHARED")
    ADD_LIBRARY(${ARGV})
    SET_TARGET_PROPERTIES(${name}
      PROPERTIES
        LINK_FLAGS
         "/EXPORT:HttpExtensionProc /EXPORT:GetExtensionVersion /EXPORT:TerminateExtension" 
    )
  ELSE(${WT_CONNECTOR} STREQUAL "wtisapi")
    ADD_EXECUTABLE(${ARGV})
  ENDIF(${WT_CONNECTOR} STREQUAL "wtisapi")
  TARGET_LINK_LIBRARIES(${name} wt ${WT_CONNECTOR})
ENDFUNCTION(WT_ADD_APPLICATION)

Wt applications can then be defined as follows:

SET(WT_CONNECTOR
#  "wthttp" # uncomment if you want to use the standalone connector instead
  "wtisapi" 
)
# now use WT_ADD_APPLICATION instead of ADD_EXECUTABLE
WT_ADD_APPLICATION(MyApp src1.C src2.C src3.C)

An alternative approach is to always build both the http and isapi versions of your application:

ADD_LIBRARY(MyAppAsLib STATIC src1.C src2.C src3.C)

ADD_LIBRARY(MyAppIsapi SHARED main.C MyApp.def) # Using a .def file for exported symbols instead of linker options
TARGET_LINK_LIBRARIES(MyAppIsapi wt wtisapi MyAppAsLib)

ADD_EXECUTABLE(MyAppHttp main.C) # Could we build apps without a single .C file?
TARGET_LINK_LIBRARIES(MyAppHttp wt wthttp MyAppAsLib)

Debugging your WtIsapi program

It is recommended to debug your Wt application using the http connector. This is very natural and easy to interact with(just run it from within the MSVC IDE). Your development cycle will be shorter than when you take IIS in the picture. Remember, it is easy to switch between the http and isapi connector: just link to a different library.

For some problems, you may need to debug your application in the same way as it is deployed in IIS. A google search will yield many options to debug an ISAPI application. In essence, the easiest way to debug an ISAPI extension is to attach your debugger to a running process (MSVC: Debug->Attach to process. Note that this feature is available in MSVC Express Editions version 2005 and 2008, but was removed from the 2010 Express Edition).

The big question is of course: what process should I attach to? You can find this in the logfile of Wt. This example shows a Wt process running within the context of the process with ID 6844:

[2010-Jul-14 15:17:43.187500] 6844 - [notice] "Reading Wt config file: c:/witty/wt_config.xml (location = '\\?\C:\wt-build\examples\hello\hello.wt.dll')" 

It is hard to find the process by name. The process name depends on your IIS version and deployment configuration. You can look this up in the manual of your IIS, and still gamble between processes with identical names, or you could let your application tell you what the correct process ID is. I particularly liked the following code snippet for this purpose:
  std::stringstream ss;
  ss << "Please attach a debugger to the process " << GetCurrentProcessId() << " and click OK" << std::endl;
  MessageBox(NULL, ss.str().c_str(), "Wt/ISAPI Debug Time!", MB_OK|MB_SERVICE_NOTIFICATION);

You can add this to your main() function, but if it is added to GetExtensionVersion() in src/isapi/Isapi.C (you'll have to recompile Wt then), this even waits for you to connect at the moment that your DLL is first loaded.

On Vista and Windows 7, MessageBox() will send the message to the event log rather than a dialog on the screen. You may have more success using WTSSendMessage() on those systems.

Background information and Architecture overview

IIS expects a DLL to run the web application, whereas Wt's other connectors (httpd, fcgi) result in an executable. This means that there are a few important points to take into account when using this connector (e.g. build a DLL instead of an EXE). On the other hand, we made sure that the connectors can still be interchanged, meaning that you're not required to make any changes to your Wt application in order to use the new connector.

In Wt's architecture, the connector is a library that is separate from the rest of the system. The same is true for ISAPI: the connector library is wtisapi.lib. This is a static library which provides the entry functions for ISAPI (GetExtensionVersion(), TerminateExtension(), HttpExtensionProc()). IIS will search for these functions in your DLL so you must make sure that your DLL exports them. That is also one of the reasons why wtisapi is only available as a static library: the symbols must be embedded in your DLL.

Upon initialization, IIS calls GetExtensionVersion(). The connector starts a thread, which invokes the main() function of your Wt application. During this invocation, argc will be 1 and argv[0] contains the path of the ISAPI DLL. This thread keeps running until the server is terminated and main() returns.
When IIS is shut down, IIS calls TerminateExtension() and the Wt server will be terminated. This means that all WApplication objects will be properly destroyed when IIS shuts down in a normal way.

The Wt ISAPI application runs inside a server process. Whereas it is unimportant whether the extension runs inside the servers process or in a separate process, it is important to ensure that all HTTP requests for a single Wt application will be served by the same process. It is therefore mandatory to properly configure IIS6/7 to avoid the use of a so-called Web Garden for the Wt application. If you do use a Web Garden, requests will eventually end up in a process that did not initiate the session, causing failing (restarting) web applications. Wt applications do not suffer from not running in a Web Garden. If you want a Wt application to benefit from multi-core servers, modify the number of worker threads, which is by default 10. This is the num-threads option in the connector-isapi section of wt_config.xml.

IIS does not foresee a method to unload an ISAPI extension: once loaded, it is loaded until the server shuts down.

Configuring Microsoft Internet Information Services

General remarks:

IIS 7.5 (Windows 7)

Configuring the Application Pool

While the default configuration of application pools on IIS 7.5 is pretty decent for Wt, we recommend to make a few changes (select your application pool, right-click on it, and select 'Advanced Settings...'). Verify the following settings (in order of importance):

Running the examples

Wt examples are best executed from within their source directory. Therefore, we recommend to copy the .dll files to the source example folders after building. Using cygwin, you can do this with this command, executed from within the build directory:

for i in `find . -name \*dll`; do cp $i ../wt/`echo $i | sed s/Debug//`; done

Most examples require files from the 'resources' directory to run correctly. Simply copy the wt-x.y.z/resources folder to every example directory. You can do this with many mouse clicks, or with a single line in a cygwin shell:

for i in `find examples -type d`; do cp -r resources $i; done

Some examples need extra dependencies: ExtJS (widgetgallery, extkitchen) and tinyMCE (widgetgallery). These are not delivered with Wt; download them from the appropriate place and have a look in the Frequently Asked Questions on this wiki.

Next, add a virtual directory to your server that points to all the examples. In the Internet Information Services Manager, right-click on your web site (e.g. Default Web Site), select 'Add Virtual Directory', choose an alias (e.g. examples), and point the 'Physical Path' to the wt examples source directory (wt-x.y.z/examples).

It is easier to browse through the examples if you enable directory browsing: click on your virtual folder ('examples'), double-click the 'Directory Browsing' icon, and click 'Enable' in the right column.

Enable permissions to execute isapi dlls in your virtual directory: double-click on 'Handler Mappings', then click on 'Edit Feature Permissions', check 'Execute' and click 'Ok'.

Now you can browse the examples folder (surf to http://localhost/examples), but you will get a 404.2 error when you click a DLL. Every ISAPI DLL must be explicitly granted execute permissions in IIS. Click on your IIS machine (toplevel icon in the tree on the left), double-click the 'ISAPI and CGI Restrictions' icon. A cautious system administrator adds every single DLL to this list, but a brave (or lazy) one clicks 'Edit Feature Settings...' in the right column and selects 'Allow Unspecified ISAPI Modules'.

Now there's one more issue left: access of local files. Many examples require access to resource bundles (.xml files), csv files, sqlite3 .db files, ... As described in the 'Important remark regarding the Current Working Directory' section above, the examples can't just use CWD. Wt examples use the appRoot() function to transform every relative local path to an absolute path, but you must set the approot variable correctly. The easiest method is to add a .ini file in every directory with the appropriate approot setting. Additionally, some examples use dbo to create sqlite3 databases. The IIS process can normally not write to the directories where these databases are located, so you must give the user of the IIS process write rights to those example directories. Examples that use dbo databases are blog, planner and wt-homepage (this list may be outdated at any time). Fix the permissions of the approot for those examples, so that the IIS process is granted sufficient rights to create and write to the databases.

IIS 7 (Vista)

IIS 5.1 (Windows XP)

Configuring the Application Pool

IIS 5.1 does not have application pools like the newer versions. But you can define an 'Application Protection' level, which can be set to one of three choices:

A Wt ISAPI extension will run correctly with any of the three settings. We recommend to use the 'High' setting until you have thoroughly tested your application.

Running the examples

This is similar to the description above for IIS 7.5: copy the DLLs from the build directory to the examples src directory, create a virtual directory that points to the examples directory, and allow execution of ISAPI. Make sure to enable the 'Execute' rights on the Virtual Directory when you create it (Right-click on 'Default Web Site', New -> Virtual Directory). As described for IIS 7.5, some examples require extra dependencies (ext, tinymce), which should be copied to the src directory or the examples will not work. Also give the IIS user write rights to the dbo examples directories in order to create and update the database files.

Allow 'Directory Browsing' in the virtual directory (right-click the virtual directory -> Properties -> Virtual Directory -> check Directory Browsing) to allow to browse through the examples.

Compatibility with other web servers

The connector was not designed to work with other web servers. More specifically, wtisapi.lib will not work with Apache due to how Apache handles processes and threads. When using Apache, we recommend to configure it as a reverse proxy to talk to forward requests to the built-in httpd connector.


LibHaru

Wt requires the following patch for libHaru to render arcs correctly. This patch has been tested against libhar 2.1.0 and 2.2.0

--- libharu-2.1.0/src/hpdf_page_operator.c    2008-05-27 20:23:31.000000000 +0200
+++ libharu-2.1.0-patched/src/hpdf_page_operator.c    2010-07-22 10:05:21.000000000 +0200
@@ -2192,7 +2192,7 @@

     HPDF_PTRACE ((" HPDF_Page_Arc\n"));

-    if (ang1 >= ang2 || (ang2 - ang1) >= 360)
+    if (fabs(ang2 - ang1) >= 360)
         HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);

     if (ret != HPDF_OK)
@@ -2205,10 +2205,10 @@

     for (;;) {
-        if (ang2 - ang1 <= 90)
+        if (fabs(ang2 - ang1) <= 90)
             return InternalArc (page, x, y, ray, ang1, ang2, cont_flg);
         else {
-            HPDF_REAL tmp_ang = ang1 + 90;
+        HPDF_REAL tmp_ang = (ang2 > ang1 ? ang1 + 90 : ang1 - 90);

             if ((ret = InternalArc (page, x, y, ray, ang1, tmp_ang, cont_flg))
                     != HPDF_OK)
@@ -2217,7 +2217,7 @@
             ang1 = tmp_ang;
         }

-        if (ang1 >= ang2)
+        if (fabs(ang1 - ang2) < 0.1)
             break;

         cont_flg = HPDF_TRUE;
@@ -2280,7 +2280,11 @@
         pbuf = HPDF_FToA (pbuf, (HPDF_REAL)x0, eptr);
         *pbuf++ = ' ';
         pbuf = HPDF_FToA (pbuf, (HPDF_REAL)y0, eptr);
-        pbuf = (char *)HPDF_StrCpy (pbuf, " m\012", eptr);
+
+    if (attr->gmode == HPDF_GMODE_PATH_OBJECT)
+      pbuf = (char *)HPDF_StrCpy (pbuf, " l\012", eptr);
+    else
+      pbuf = (char *)HPDF_StrCpy (pbuf, " m\012", eptr);
     }

     pbuf = HPDF_FToA (pbuf, (HPDF_REAL)x1, eptr);

LiteSpeed Web Server

This is preliminary information:

At this Litespeed Web Server release (4.0.1)...

For wthttp:

  â—¦  If Apache configurations are used for virtual hosts,rewrite rules can
     be used (e.g. RewriteRule /(.*) http://127.0.0.1:port/$1 [p]),
     as mod_proxy directives are not supported 
   ("per customer support":http://www.litespeedtech.com/support/forum/showthread.php?t=2879, not tested yet)
  â—¦  Otherwise, you should be able to set it up through the admin
     console: "Virtual Host"->"External Apps" & "Virtual Host"->"Context" 

For FastCGI:
  â—¦  Apache config: start Wt app using --socket option
     e.g. ./hello.wt --socket=/usr/wt/run/hello-fcgi

â—¦ Otherwise, same as wthttp instructions, selecting "Web server" as External App type


Main Page

Welcome to Wt (pronounced as witty, a C++ web toolkit) wiki.

Getting Started

Support

Other


Other source code widgets and projects

This page lists links to other projects that use Wt to implement reusable widgets, or complete applications. Add your own forum, photo gallery, blog, movie player, CMS, ...

General projects

Database add-ons


Sample Wt Applications

List of applications developed with Wt and available on the web.


SimpleChat made easy - Part 1

Currently the situation with Wt's Comet is that you have to track the sessions you want to push data to yourself.
I have written some classes that help dealing with this issue and simplifies building the simple chat example.
We start with coding a new application type that is derived from Wt application, a Wt application that uses my comet example should use this application class instead of the normal WApplication class.

CometApplication.hpp

#ifndef CometApplication_HPP
#define CometApplication_HPP

// <STL>
#include <list>
#include <string>
#include <map>
// </STL>

// <Boost>
#include <boost/unordered_map.hpp>
// </Boost>

// <Wt>
#include <Wt/WApplication>
#include <Wt/WWidget>
// </Wt>

namespace UI
{
    namespace Widgets
    {
                // Forward declerations
        class CometWidget;

        template <class>
        class CometWidgetFactory;
    }

    namespace Application
    {
        class CometApplication : public Wt::WApplication
        {
        public:
            CometApplication(const Wt::WEnvironment &env); // Ctor, passes enviorment variables to WApplication
            ~CometApplication(); // Dtor

            friend class Widgets::CometWidget; // Befriending with CometWidget so it can access the widget map

            template <class>
            friend class Widgets::CometWidgetFactory; // Same here
        private:
            typedef std::pair<int, Wt::WWidget *> WidgetEntryType;
            typedef boost::unordered_multimap<CometApplication *, WidgetEntryType > WidgetMapType;
            typedef boost::unordered_multimap<CometApplication *, WidgetEntryType >::iterator WidgetMapIteratorType;
            typedef std::pair<WidgetMapIteratorType, WidgetMapIteratorType> WidgetRangeType;

            static WidgetMapType widgets;

            // Pushes a new widget to the current session with group id and the widget itself
            inline void registerWidget(unsigned long int id, Wt::WWidget *w)
            {
                boost::mutex::scoped_lock  lock(CometMutex);

                widgets.insert(WidgetMapType::value_type(this, WidgetEntryType(id, w)));
            }

            // Searches for the widget of the group id for the current session and erases it
            inline void unregisterWidget(unsigned long int id)
            {
                boost::mutex::scoped_lock  lock(CometMutex);

                WidgetRangeType range = widgets.equal_range(this);

                for ( WidgetMapIteratorType iter = range.first; iter != range.second; ++iter )
                {
                    if ( iter->second.first == id )
                    {
                        widgets.erase(iter);
                        break;
                    }
                }
            }

            // Searches for a widget in the current session, casts it to the right widget type and returns it
            template <class T>
            inline T *getWidget(unsigned long int id)
            {
                boost::mutex::scoped_lock  lock(CometMutex);

                WidgetRangeType range = widgets.equal_range(this);

                for ( WidgetMapIteratorType iter = range.first; iter != range.second; ++iter )
                    if ( iter->second.first == id )
                        return dynamic_cast<T *>(iter->second.second);

                return NULL;
            }

            static boost::mutex CometMutex;
        };
    }
}

#endif

CometApplication.cpp

#include "CometApplication.hpp" 

namespace UI
{
    namespace Application
    {
        CometApplication::CometApplication(const Wt::WEnvironment &env)
        : WApplication(env)
        {
            enableUpdates(); // Enables ajax-push for the current session
        }

        CometApplication::~CometApplication()
        {
            boost::mutex::scoped_lock  lock(CometMutex);

            if ( widgets.find(this) != widgets.end() ) // Erases the current session from the widget map
                widgets.erase(this);
        }

        CometApplication::WidgetMapType CometApplication::widgets;
        CometApplication::boost::mutex CometMutex;
    }
}

Code Review

I have created an unordered multimap that might look a little strange to you guys but I'm going to elaborate about it in a minute.
  1. The multimap key is the pointer to the current session which is represented by CometApplication, because as you guys already know, a session is an application instance. That way I can access the current session's widgets using this or iterate through all sessions.
  2. The value of the multimap is a pair of a group id and a widget. Different widgets in different sessions with the same group id can be accessed this way.

As you can see the CometApplication instance only refers to this, which means only to the current session.
I have befriended all other classes because registerWidget, unregisterWidget and getWidget should only be accessed by those classes.
This doesn't indicate that my code has a design problem in my opinion.
Sometimes you actually have to use class friendship.
It makes sense that the end user will not control anything related to registering/unregistering widgets as you will see.

After that we create a factory which will instanciate a widget for each session.
Here the magic is introduced into the system.

CometWidgetFactory.hpp

#ifndef CometWidgetFactory_HPP
#define CometWidgetFactory_HPP

#include <Wt/WApplication>
#include <Wt/WWidget>

#include <boost/thread/mutex.hpp>

#include "CometApplication.hpp" 

namespace UI
{
    namespace Widgets
    {
        // CometWidgetFactory creates a widget of type WidgetType, WidgetType is derived from CometWidget
        template <class WidgetType>
        class CometWidgetFactory
        {
        private:
            static unsigned long int idCounter; // Counts how many ids there are

            unsigned long int id; // Group id
        public:
            CometWidgetFactory()
            : id(idCounter)
            {
                idCounter++; // New factory instance has been created.
            }

            ~CometWidgetFactory()
            {
                idCounter--; // New factory instance has been destroyed
            }

            void create()
            {
                WidgetType *w = new WidgetType; // Creates a new widget
                w->id = id; // Assigns the group id

                // Registers the widget to the current session
                dynamic_cast<UI::Application::CometApplication *>(wApp)->registerWidget(id, w); 
            }

            void destroy()
            {
                // Unregisters the widget from the current session
                dynamic_cast<UI::Application::CometApplication *>(wApp)->unregisterWidget(id);
            }

            // Those operator overloadings make the factory "point" to the current widget we're refering to in the current session
            WidgetType *operator->()
            {
                return dynamic_cast<UI::Application::CometApplication *>(wApp)->getWidget<WidgetType>(id);
            }

            operator Wt::WWidget *()
            {
                return dynamic_cast<UI::Application::CometApplication *>(wApp)->getWidget<WidgetType>(id);
            }
        };

        template <class T>
        unsigned long int CometWidgetFactory<T>::idCounter = 0;
    }
}

#endif

Code Review

This class looks very simple but it has a trick.
If you declare it as static on your target widget it will create a group id for a certain type of widgets for all sessions.
For example:

class someWidget : public CometWidget<Wt::LineEdit>
{
//...
};

class MyPage : Wt::WContainer
{
private:
  static CometWidgetFactory<someWidget> myWidget;
public:
  MyPage()
  {
    myWidget.create(); // Creates a widget on the same group id
  }

  ~MyPage()
  {
    myWidget.destroy();
  }
};

For each session a someWidget will be created and you can access the widget on the current session.

CometWidget.hpp

#ifndef CometWidget_HPP
#define CometWidget_HPP

#include <string>

#include <boost/thread/mutex.hpp>

#include <Wt/WContainerWidget>

#include "CometApplication.hpp" 

namespace UI
{
    namespace Widgets
    {
        template <class WidgetType>
        class CometWidget : public WidgetType
        {
        protected:
            virtual void updateOthers()
            {
        boost::mutex::scoped_lock  lock(CometMutex);

                for ( Application::CometApplication::WidgetMapIteratorType iter = Application::CometApplication::widgets.begin(); iter != Application::CometApplication::widgets.end(); ++iter )
                {
                    Application::CometApplication::WidgetRangeType range = Application::CometApplication::widgets.equal_range(iter->first);

                    for ( Application::CometApplication::WidgetMapIteratorType iter2 = range.first; iter2 != range.second; ++iter2 )
                    {
                        if ( iter2->second.first == id )
                        {
                            Wt::WApplication::UpdateLock uiLock = iter->first->getUpdateLock();
                            dynamic_cast<CometWidget *>(iter2->second.second)->updateWidget();
                            iter->first->triggerUpdate();
                        }
                    }
                }
            }

            virtual void updateWidget() = 0; // TBD: Convert this to a signal/slot instead of a virtual function

            template <class>
            friend class CometWidgetFactory;
        private:
            unsigned long int id; // Group ID

            boost::mutex CometMutex;
        };
    }
}

#endif

Code Review

updateOthers() updates each widget in the widget group and it should be called whenever a change was made in the widget.
updateWidget should be a slot that will be connected to signals that update the widget itself.

In the next part of the article I will demonstrate how to re-write the SimpleChat example very simply.


Tips and Tricks

Making a hard-copy of painted graphics

The primary use for the Wt painting API is to paint on a WPaintedWidget. Internally, this uses either a VML, SVG or HTML 5 canvas painting device to deliver the painting to the browser.

It is also possible to paint directly to an SVG image, which is a standardized generic vector graphics format, and increasingly supported by various tools.

You could use the SVG image as a starting point for exporting the painted graphics to raster format. Using the imagemagick or graphicsmagick libraries, you can convert from SVG to other formats using the library API or using the command line 'convert' tool. Using inkscape, a sophisticated SVG editor, you may get high quality SVG rendering (with, compared to imagemagick, much better font support) from the command-line (see the manpage). Another option may be librsvg.

The WSvgImage class allows you to easily create an SVG image, and save it to a (file) stream, using the following template:

WSvgImage image(400, 300);
WPainter painter(&image);

// paint things on the painter, like you normally do in WPaintedWidget::paintEvent().
//
// e.g. you could do WCartesianChart *c = ...
// c->paint(painter);

painter.end();
std::ofstream f("image.svg");
image.write(f);
f.close();

Creating .CUR files

Creating .CUR files which are valid in Firefox and Chrome can be quite a pickle, especially if you want to specify a custom hotspot.
This program allows you to create such .CUR files:
http://www.rw-designer.com/cursor-maker

Assert

Under some environments, when linking to the Wt library, 'assert' is removed from the code. This page shows a custom assert to be used with Wt: http://richelbilderbeek.nl/CppWtAssert.htm


Using CMake

In this example we are going to see how to use CMake to compile a very simple Wt project where you have a source directory with all your files
and a build directory to generate your application.

If you don't care where your files are located or you are looking for an even simpler example you can go Frequently_Asked_Questions.

Directory Structure

Before starting make sure that your project main directory (In this example the main directory is called main) looks like this:

main
|
+--source..................you have all your files here
    |
    + -- CMakeLists.txt .. a text file where we will write CMake commands (empty) 
+--build.................. build directory (initially, this directory is empty)
+--CMakeLists.txt ........ a text file where we will write CMake commands (empty)

CMakeLists.txt in the main directory

These are the contents of the CMakeLists.txt file that you should write on the main directory

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

PROJECT(WT_EXAMPLE)

SET (WT_CONNECTOR "wtfcgi" CACHE STRING "Connector used (wthttp or wtfcgi)")

ADD_SUBDIRECTORY(source)
SET(VARIABLE_NAME default_value CACHE type "help message")

The syntax is:

 ADD_SUBDIRECTORY(subdir)

You need to make sure that there is a CMakeLists.txt file in the subdirectory that you are referencing, so that sub CMakeLists.txt will be executed.

In our example as we have one subdirectory (source) we will have a correspondant CMakeLists.txt file in there.

CMakeLists.txt in the source directory

This is an example of the CMakeLists.txt file that goes in the source directory

SET(WT_PROJECT_SOURCE
File1.h
File1.cpp
File2.h
File2.cpp
Main.C
)

SET(WT_PROJECT_TARGET wt_project.wt)

ADD_EXECUTABLE(${WT_PROJECT_TARGET} ${WT_PROJECT_SOURCE})

TARGET_LINK_LIBRARIES(${WT_PROJECT_TARGET} ${WT_CONNECTOR} wt)

INCLUDE_DIRECTORIES(/usr/local/include/Wt)

Let's break this down:

Variables in a CMake script

WT_PROJECT_SOURCE and WT_PROJECT_TARGET are two variables and you can change the names as you like as long as you make sure that you change them everywhere in your script.

SET instruction

The CMake SET instruction allows to associate any number of strings with a CMake variable. The syntax is:

SET(CMAKE_VARIABLE string1 string2 ... stringN)

In our example we have two SET instructions. The first one is allowing us to associate all our source file names with WT_PROJECT_SOURCE. The second SET instruction is associating the string wt_project.wt with WT_PROJECT_TARGET.

ADD_EXECUTABLE instruction

The ADD_EXECUTABLE instruction configures the executable file you are about to compile. The syntax is:

ADD_EXECUTABLE(EXECUTABLE_NAME file1 file2 ... fileN)

However given that we have our source list in the variable WT_PROJECT_SOURCE, we can write:

ADD_EXECUTABLE(EXECUTABLE_NAME ${WT_PROJECT_SOURCE})

In this case we see the way CMake variables can be used. Every time that you want to refer to any variable contents you just need to use the ${} syntax around the variable name.

TARGET_LINK_LIBRARIES instruction

The TARGET_LINK_LIBRARIES instruction allows to link our executable file with the depending libraries. The syntax is:

TARGET_LINK_LIBRARIES(EXECUTABLE_NAME lib1 lib2 ... libN)

In our case we need to make sure that the our executable links to Wt (wt library) and one of the connectors (wthttp library or wtfcgi library). In our example, the connector name is stored in the variable WT_CONNECTOR.

INCLUDE_DIRECTORIES instruction

The INCLUDE_DIRECTORIES instruction adds the given directories to those searched by the compiler for include files. The syntax is:

INCLUDE_DIRECTORIES(dir1 dir2 ... dirN)

For the sake of the example, I have added the directory /usr/local/include/Wt. This is where all the Wt header files live in my Ubuntu installation. However this might not be the case for you and you might want to decipher where these files are in your system. The general solution for this is to use

TODO: Talk about FIND_PACKAGE

Project files/Makefiles generation

Once you are finished editing the source/CMakeLists.txt file you should go to the build directory and type:

cmake ..

You will see the initial CCMake screen on your terminal console:

<pre>
                                                     Page 0 of 1
 EMPTY CACHE
</pre>

EMPTY CACHE:
Press [enter] to edit option                         CMake Version 2.6 - patch 4
Press [c] to configure
Press [h] for help         Press [q] to quit without generating
Press [t] to toggle advanced mode (Currently Off)

Here you need to run the configuration option by pressing [c]

This will take you to the next screen:

<pre>
                                                     Page 1 of 1
 CMAKE_BUILD_TYPE                                                         
 CMAKE_INSTALL_PREFIX             /usr/local                                   
 WT_CONNECTOR                     wtfcgi                                       
</pre>

CMAKE_BUILD_TYPE: Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
Press [enter] to edit option                         CMake Version 2.6 - patch 4
Press [c] to configure
Press [h] for help         Press [q] to quit without generating
Press [t] to toggle advanced mode (Currently Off)

At this point, you need to define the type of build (CMAKE_BUILD_TYPE) you are going to do. Options are:

Next we see that the variable WT_CONNECTOR that was defined in the main directory CMakeLists.txt file appears. As stated before, options for this variable are:

Once you are set this properties, for instance selecting Debug and wtfcgi respectively, you need to configure again (by pressing *). This time an aditional option *[g] appears:

<pre>
                                                     Page 1 of 1
 CMAKE_BUILD_TYPE                 Debug                                        
 CMAKE_INSTALL_PREFIX             /usr/local                                   
 WT_CONNECTOR                     wtfcgi                                       
</pre>

CMAKE_BUILD_TYPE: Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
Press [enter] to edit option                         CMake Version 2.6 - patch 4
Press [c] to configure     Press [g] to generate and exit
Press [h] for help         Press [q] to quit without generating
Press [t] to toggle advanced mode (Currently Off)

At this point you press [g] to generate your project. This step takes care of the files that need to be generated in order to compile your project on the platform you are working on. For example if you were working on Visual Studio under Windows, then the project and solution files would be generated. On Linux you will see that there is a set of Makefiles that you will use to compile your project.

After pressing [g] you will end up in the build directory again. This time we just do a regular make. The output should be something similar to this:
cg

make
[ 50%] Building CXX object src/CMakeFiles/App.wt.dir/App.cpp.o
[100%] Building CXX object src/CMakeFiles/App.wt.dir/Main.C.o
Linking CXX executable App.wt
[100%] Built target App.wt

Now your application is ready to go. To execute your application you need to follow the guidelines for the case where you are using the built-in Wt server or any FastCGI supporting web server.

Summary

Well that is basically it. I hope this had been helpful to understand a little bit more what CMake is about. As this is the first version of this document please feel free to make any comments, suggestion, or corrections.

If you want to learn more about the different instructions that CMake offers I advise you to visit:


Using CSS

Introduction

If you are a typical C++ programmer then Wt is probably your first foray into the field of web applications, or at least this have been the case with me. In this text I'll try to explain the ideas and methods of work regarding the Cascading Style Sheets, or CSS from the Wt programmer's point of few. Learning and applying CSS to my application has taken me a few days, I hope that thanks to this text you'll be able to cut that time down to a few hours and I assure you that these will be a few hours well spent.

What is CSS and why do we need it?

First a bit of a history. In bad old times the specific look and layout of a web page has been achieved by using some special HTML tags, like font, b, i, table etc. This led to several problems, like having to repeat the formatting information in every place you need specific look. If the look description was complicated this resulted in serious overhead, also changes to the layout required modifying the tags on all pages. And the only way to achieve a specific layout were tables and frames.

The bad thing got just worse when browser wars have erupted. Microsoft and Netscape started creatively reinterpreting standards and largely forced web designers to develop pages specifically for one browser - namely Internet Explorer. Creating universal layout, or even any good looking layouts, had become a kind of dark magic.

CSS, short for Cascading Style Sheets, is what was created by W3 consortium as a solution to this problem. It is a technique used to describe how HTML (or even other XML) document is presented. I wrote "presented", not "displayed" because in theory it allows you to use different styles for different output devices, including computer displays, TVs, cell phones but also printers, Braille displays and speech synthesizers, although Wt doesn't allow specifying multiple CSSes in current version. During the last few years CSS has become the main method for creating web page looks and layouts because: Wt already uses CSS, so called inline CSS, to implement specified widget decorations and positioning. In this way, one could style the program mostly through C++ code. Still using external CSS will give you a lot of advantages:

Short description of the CSS

CSS is grammatically a very simple language. Let's take look at an example:

body {
<pre>
    color:black;
    font-family:sans-serif;
    font-size:x-small;
    font-size-adjust:none;
    font-style:normal;
    font-variant:normal;
</pre>
//    font-weight:normal;
/*    line-height:normal;*/
}

So, "body" selects types of elements to which the style applies. In this case it applies to everything enclosed in body tags - that means the whole page. You may refine the selectors by appending other stuff, or combining several selectors:

If you do not care about the element type (a good habit), you can use "*" to select any type, and rely only on the style class. For example, "*.emphasized" selects all elements with style class "emphasized".

After the element selector, in curly braces, there is the style description, build of lines in form of "property: value;". Then "//" and "/* */" are, as you might guess comments.

An element gets its style from several sources: built-in browser style, external style sheet, internal style sheet, some elements from its parent style and finally the inline style. When two styles specify the same property, the one from the style defined closer to the element is taken.

To learn more about CSS go to W3schools - you will find a tutorial a lot of examples and (most important) a CSS reference - much better than what I could ever write myself.

CSS and Wt for programmers

Part 1 - Inspiration

It is a common practice to have first an artist prepare the website design in some graphic program and then a web designer convert it to a CSS. It is quite possible that you don't have such luck and yourself are an aesthetically impaired programmer. In that case I suggest you go to some site offering a free web designs, the two I know are: Open Source Web Designs and Open Web Design. You can also go to CSS Zen Garden - their styles are very original and inspiring, still very elaborate and designed for one specific document, so they will need a lot of remaking to fit with your project. I'm also not sure about the copyright that they use. Still you should definitely visit the Zen Garden, even if only for your personal amusement.

One more advice - when looking for a nice web design look rather for one that pleases you visually, not necessary one that could perhaps easily fit with your project. To work with Wt you'll still have to adjust it heavily, so you can as well modify it's layout. Oh, and don't tell anyone that I've told you this, but in many cases you can just easily grab a CSS of any web page you find pretty - just take a look at the header.

Part 2 - Adaptation

So, you've downloaded some nice web design and want to adapt it for your application, possibly with an example HTML. The design will probably need some refurbishing first, and we will use the example HTML for that. We will also need two tools: CSS validator and a good DOM and CSS inspector. You'll also need a web browser, or even better, a few of them.

Before you do anything, you'll also have to make a decision: do you want a fixed design (for specific resolution) or a liquid one (adapting to current resolution of the screen). In fixed designs you specify dimensions in pixels, which makes them easier and allows for some more elaborate looks that need pixel-perfect precision in positioning. In liquid designs you specify dimensions in percents of the screen size and in font elements (em), or use the descriptive font specifiers - it almost completely denies tricks requiring pixel-perfect precision, but it can better adapt to changing screen and font sizes. In neither designs you use the pt unit - this one should be only used in Style Sheets for printers. You can also use a mixed approach - it contains all problems of both designs and some of their advantages too - unfortunately this is the approach artists creating those free web designs usually take.

So, now you should go through the whole CSS and change the dimensions accordingly. If you want to use a liquid design I'm afraid you might have to remove the background image if i.e. it included shades for the text boxes.

Next thing is changing the selectors. Most designs use tag types for look&feel style part - thats OK with us. But then they usually use #elementids for positioning styles and thats a problem. It is a problem because Wt automatically assigns some ids to elements, as a programmer we are only able to set the element class. But thats simple - just change the ids for classes, both in CSS and HTML.

Part 3 - Repositioning

Now the fun part begins - we'll be changing the layout to fit to our application. It may help to know the tags generated by Wt for different widgets, although use of the "*" selector in general suffices. They are: Still the easiest way to specify the style is usually using the class selector. If you haven't read already about the CSS positioning, here is a very quick tutorial. Now, I'll share with you some tips&tricks I've learned:

After finishing this stage, you should have something like this.

Part 4 - Applying

If you've done everything so far the last stage should be quite straightforward. Use the WApplication::useStyleSheet() function to apply your CSS, then work your way from the widgets root down and use WWidget::setStyleClass to set proper styles, optionally removing all the WTables you might have used for positioning before, as well as positioning methods. If some widgets aren't yet implemented simply use WContainerWidget with a Lorem Ipsum WText inside instead.

FireBug (an extension plugin for FireFox) is useful to pinpoint any problems, and to try to fix them first interactively by modifying the style of a single element. It is very useful, as it lets you browse the DOM tree that is dynamically created with Ajax requests. Use its 'Inspect' feature to get to the widget you wish to examine. The tips from Part 3 also apply here.

When you're done try to think about some finishing touches - this is when you'll be able to fully appreciate CSS flexibility.

Summary

So, this is pretty much it. I hope you've managed to learn something from this, or at least you've got some new interesting links. I'm also sure your application will look much better in foreseeable future. If you want to take a look at the effects of my work, go to Astariand RPG - this is a work in progress, so I can't really tell what will it look like when you read this, but at the moment of writing you can use WikiName: TestDrive and Password: witty to login. If it doesn't work consider registering yourself at Astariand RPG.


Using HAproxy as a reverse proxy

HAproxy has a great feature set when used in conjunction with Wt:

You need a fairly recent of haproxy for the options 'http-server-close' and 'http-pretend-keepalive' to work, which is needed for reliable load-balancing.

Basic setup

global
        log 127.0.0.1 local0
        log 127.0.0.1 local1 notice
        maxconn 4096
        user haproxy
        group haproxy
        daemon

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        option  http-server-close
        option  http-pretend-keepalive
        option  forwardfor
        option  originalto
        retries 3
        option redispatch
        maxconn 2000
        contimeout      5000
        clitimeout      50000
        srvtimeout      50000

listen 0.0.0.0:8181
        server srv1 0.0.0.0:9090 check

Using session affinity

All of the built-in mechanisms in HAproxy for session affinity using the appsession option rely on cookies, but cookies are not our preferred method since this does not give an intuitive user experience (e.g. a user cannot open multiple sessions), are not entirely reliable (a user can disable cookies) and a source of security risks (CSRF).

Luckily there is a work-around: using Wt's ability to generate session-id's that have a prefix which identifies the back-end, we can have HAproxy match on this prefix in the request URL and send the requests to the correct server.

Below is an example configuration for two back-end servers.

global
    log 127.0.0.1 local0 
    log 127.0.0.1 local1 notice
    maxconn 4096
    user haproxy
    group haproxy
    daemon

defaults
    log    global
    mode    http
    option    httplog
    option    dontlognull
        option  http-server-close
        option  http-pretend-keepalive
        option  forwardfor
        option  originalto
    retries    3
    option redispatch
    maxconn    2000
    contimeout    5000
    clitimeout    50000
    srvtimeout    50000

frontend wt
        bind 0.0.0.0:80
        acl srv1 url_sub wtd=wt1
        acl srv2 url_sub wtd=wt2
        acl srv1_up nbsrv(bck1) gt 0
        acl srv2_up nbsrv(bck2) gt 0
        use_backend bck1 if srv1_up srv1
        use_backend bck2 if srv2_up srv2
        default_backend bck_lb

backend bck_lb
        balance roundrobin
        server srv1 0.0.0.0:9090 track bck1/srv1
        server srv2 0.0.0.0:9091 track bck2/srv2

backend bck1
        balance roundrobin
        server srv1 0.0.0.0:9090 check

backend bck2
        balance roundrobin
        server srv2 0.0.0.0:9091 check

And start the two Wt httpd servers using:

$ app.wt --session-id-prefix=wt1 --http-port 9090 ...
$ app.wt --session-id-prefix=wt2 --http-port 9091 ...

Wt Deployment

This page lists various deployment options.

Your first choice with respect to deployment is a choice of one of the available connectors: FastCGI, ISAPI or built-in httpd.

Deployment using FastCGI

The FastCGI configuration is highly dependent on the web server.

Deployment using ISAPI

Reverse proxy + built-in HTTPD

While the built-in httpd serves as a standalone deployment option, it is often used in conjunction with a (load-balancing) reverse proxy web server for production.


Wt embedded

Find here information on running Wt in resource constrained embedded systems: performance, code size, memory usage, and other information.

General

Wt can easily be built for and deployed on embedded POSIX systems, such as embedded Linux.

Cross-building

Using CMake with a cross compilation environment: to be completed...

Instructions for cross compiling with cmake can be found on the CMake Wiki.

Wt user Alistair of QuickForge has written a blog about cross-compiling for ARM on Windows, and uses Wt as an example in his blog post Exploration of Cross-Compiling on Windows for ARM Linux Distributions

Optimizing executable size

Points to consider when optimizing the executable size.

For building Boost: For building Wt:

Measuring performance

To report the run-time performance of Wt on a particular embedded platform, you must connect to the device using a local area connection (through at most one switch), and measure the time between transmission and reception of packets (using a packet sniffer). For the measurements, we use two examples that are included in the Wt distribution: hello (as an example of a minimal application), and composer (as an example of a simple, yet functional, application).

We propose to measure the time to create a new session, and the time of a small event.

Runtime: new session

Wt starts a new session by serving a small page to determines browser capabilities, and then triggers a second call to get the "main page", that has all visible content. To compare the relative performance for a particular platform, you should measure this "load" time, as the total duration of these two requests. You should measure the time from sending the first request, to sending the third request. The third request is either a GET request for auxiliary content (CSS or images), a GET request to a Wt resource, or a POST request to load invisible content in the background.

Runtime: event

We estimate the time needed to process a small event, such as a click on the "Greet me" button in hello, and "Save now" in composer, by measuring the total time for the packet exchange triggered by such an event.

Memory usage: basis

Measuring memory usage is a tricky thing, since code and read-only data memory used by shared libraries is effectively shared between processes, while writable data segments are obviously private to each process.

Therefore, we use pmap to study the memory in different segments. The basis RAM usage is divided between read-only segments, and writable segments. Only the latter are really constrained by physical RAM. We get the total writable size by summing the size of all writable segments, indicated by pmap with a w. The total size reported by pmap and top, minus the size of all writable segments is then the read-only RAM usage. Thus, this number includes shared libraries, and thus overestimates actual RAM usage.

Memory usage: per session

Compare the memory usage after starting 10 sessions with base memory usage, and divide the difference by 10 to estimate the memory used by a single session.

Platforms

ARM926EJ-S

Processor features

Configurations are ordered chronically, latest first.

Configuration 3: minimal (15/12/2010)

Setup
Performance results
Runtime-performance
Program New session (http) Event (http)
hello 0.19 s 0.06 s
composer 0.60 s 0.07 s

Configuration 2: minimal (16/03/2010)

Setup
Performance results
Code size and RAM usage (in KBytes)
Program Code size (strip) Code size (strip + upx) RAM: basis † (read-only) RAM: basis (writable) RAM: per session
hello 1214 362 2544 228 14.8
composer 1462 420 2796 232 83.6

† includes shared libraries !

Runtime-performance
Program New session (http) Event (http)
hello 0.26 s 0.07 s
composer 0.69 s 0.08 s

Configuration 1: minimal (18/03/2008)

Setup
Performance results
Code size and RAM usage (in KBytes)
Program Code size (strip) Code size (strip + upx) RAM: basis † (read-only) RAM: basis (writable) RAM: per session
hello 1130 304 2580 372 28
composer 1265 332 2712 372 126

† includes shared libraries !

Runtime-performance
Program New session (http) Event (http)
hello 0.58 s 0.15 s
composer 1.8 s 0.15 s

Wt Installation

Generic installation instructions

You may follow the generic installation procedure, or see further for platform specific instructions.

Platform specific installation instructions

Third-party library installation instructions

Deployment using the various connectors

See Wt Deployment


Wt Tutorials

Internal

External