<!--toc--> |
|
## 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](/wikipp/en/page/ref_utils#tmpl). |
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](/wikipp/en/page/ref_utils#tmpl) 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](/wikipp/en/page/ref_utils#tmpl) 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. |
|
|