Main  /  Edit  /  History  /   /  Users Area

Templates: Building and Loading

Overview

The process of building CppCMS templates is following:

  1. Compile all sources of specific view together into single C++ file using cppcms_tmpl_cc.
  2. Compile C++ file into object file.
  3. Link it together with program or create dynamically loadable object that can be loaded by CppCMS program.

Creation of C++ code

Can be done by invoking cppcms_tmpl_cc with a list of files, for example:

cppcms_tmpl_cc -o view.cpp main.tmpl page.tmpl article.tmpl

Note, when you derive classes from parents, you should compile them together in correct order.

For example for following hierarchy.

            [master]
          /         \
    [page]           [summary]
    /    \           /       \
[post] [info.] [archive] [recent_posts]

You should compile files as:

cppcms_tmpl_cc master.tmpl page.tmpl post.tmpl \
               info.tmpl summary.tmpl archive.tmpl \
               recent_posts.tmpl -o my_view.cpp

When you share some templates between various skins, and compile all then in namespace vary. You should specify parameter: -n view_name.

By default, templates compiler puts all translation strings in the domain that is named by template name. So if you compile with -n skin1 all you strings would be taken from skin1 domain. It can be overridden by specifying -d domain_name switch.

Generally you want to put all templates to same domain as the main program.

How templates are loaded

Each C++ file that is generated from the template includes static global constructor that registers all classes of specific view in libcppcms.

When programmer wants to use come class from specific view he calls render() function of worker_thread class that seeks for registered views and uses them.

Thus, everything you need to do is link this object with your library or load it dynamically.

Static Linking with Compiled Object

This is the simplest way to add the template, for example:

cppcms_tmpl_cc -o view.cpp master.tmpl ...
g++ -O2 -Wall view.cpp -o view.o
g++ application_objects.o view.o -lcppcms -o app

Using Libraries of Views

Sometimes, you may create a library of several views and try to link with them. For example:

g++ -fPIC -DPIC view1.cpp -o view1.o
g++ -fPIC -DPIC view2.cpp -o view2.o
g++ -shared view1.o view2.o -lcppcms -o libview.so

Now you link this library directly with your program:

g++ application_objects.o -L. -lview -lcppcms -o app

You can also create static library and link with it.

g++ view1.cpp -o view1.o
g++ view2.cpp -o view2.o
ar cru libview.a view1.o view2.o
ranlib libview.a

Now, if you link static the library as is, it would not work!!! At least with GNU linker.

GNU linker "optimizes" the code and discovers that there is no symbols in application objects that refer to the symbols of libview.a and would not include it in link process.

In order to make everything work you should link as following:

g++ application_objects.o \
  -Wl,--whole-archive libview.a -Wl,--no-whole-archive \
  -lcppcms -o app

It would force the linker include all objects form libview.a and cause everything work correctly.

Note: You do not need this for dynamically loaded libraries like so or dll. Because, by default they include whole archive.

Dynamic Loading of Views

You have an option load all views dynamically from shared object or dll. This option have following restrictions:

  1. You should compile your program with --export-dynamic option, otherwise dynamic casting would not work and you'll get error "incorrect content type" trying to render your views.
  2. Windows/Cygwin has strong restriction on undefined symbols in dll's. Thus you should not refer directly to any non-virtual member functions of your content objects, otherwise you would get linker errors trying to build dll.

For example:

Build your loadable view:

cppcms_tmpl_cc -o view.cpp master.tmpl ...
g++ -fPIC -DPIC view.cpp -o view.o
g++ -shared view.o -lcppcms -o libview.so

Link your program

g++ --export-dynamic app_objects.o -lcppcms -o app

Now add to your configuration file path to directory where libview.so is placed:

templates.dirs = { "/usr/local/lib/youapp" }

When application starts, it would try to load any shared object that is placed in this path. Thus, it is not good idea to save put your views into directory with other non-related libraries.

About

CppCMS is a web development framework for performance demanding applications.

Support This Project

SourceForge.net Logo

Поддержать проект

CppCMS needs You


Navigation

Main Page



Valid CSS | Valid XHTML 1.0