13edf322468200800bb065b154c4630ad1bd40f5
[AGL/documentation.git] / docs / 3_Developer_Guides / 5_Using_CMAKE_Applications_Module / 3_Advanced_Usage.md
1 ---
2 title: Advanced Usage
3 ---
4
5 This topic describes some advanced ways of using the CMake templates.
6
7 ## Building a Widget
8
9 To build a widget, you need a `config.xml` file that describes
10 your application (widget) and how the Application Framework launches it.
11 Your repository contains a simple default file named
12 `config.xml.in` that should work for simple applications and should
13 not require interactions with other bindings.
14
15 It is also recommended that you use the sample configuration
16 file that you can find in the location.
17 This file is named `config.xms.in.sample` and is more complete.
18 Copy the sample file to your `conf.d/wgt` directory and name it
19 `config.xml.in`.
20 Once you have your copy, edit the file to fit your needs.
21
22 **CAUTION:** The default file is only meant to be used for a
23 simple widget application.
24 For more complicated applications that need to export
25 their API, or ship several applications in one widget
26 need to use the provided `config.xml.in.sample` file, which has
27 all new Application Framework features explained and provides
28 examples.
29
30 ## Using CMake Template Macros
31
32 To leverage all CMake template features, you must specify properties
33 on your targets.
34 Some macros do not work unless you specify the target type.
35 If you do not specify a type (e.g. a custom target such as an
36 HTML5 application), the macro uses the `LABELS` property to
37 determine the target type.
38
39 Aside from those values, the following optional values can be
40 assigned to the `LABELS` property.
41 These values define the resource types that make up your test materials:
42
43 - **TEST-CONFIG**: JSON configuration files used by the `afb-test`
44  binding.
45  These files execute the tests.
46 - **TEST-DATA**: Resources used to test your binding.
47  Minimally, you need a test plan.
48  You should also consider fixtures and any files required by your tests.
49  These required files appear as part of a separate test widget.
50 - **TEST-PLUGIN**: A shared library used as a binding plugin.
51  A binding loads the library as a plugin to extend the binding's functionality.
52  You should use a special file extension when you name the library
53  by using the `SUFFIX` CMake target property.
54  If you do not choose an extension, `.ctlso` is used by default.
55 - **TEST-HTDOCS**: The root directory of a web application.
56  This target has to build its directory and put its files in
57  the `${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}` directory.
58 - **TEST-EXECUTABLE**: The entry point of your application executed by the AGL
59  Application Framework.
60 - **TEST-LIBRARY**: An external third-party library bundled with the binding
61  for its own purpose.
62  The platform does not provide this library.
63
64 Following is a mapping between `LABELS` and directories where files reside in
65 the widget:
66
67 - **EXECUTABLE** : `<wgtrootdir>/bin`
68 - **BINDING-CONFIG** : `<wgtrootdir>/etc`
69 - **BINDING** | **BINDINGV2** | **BINDINGV3** | **LIBRARY** : `<wgtrootdir>/lib`
70 - **PLUGIN** : `<wgtrootdir>/lib/plugins`
71 - **HTDOCS** : `<wgtrootdir>/htdocs`
72 - **BINDING-DATA** : `<wgtrootdir>/var`
73 - **DATA** : `<wgtrootdir>/var`
74
75 Following is a mapping between test-dedicated `LABELS` and directories where
76 files reside in the widget:
77
78 - **TEST-EXECUTABLE** : `<wgtrootdir>/bin`
79 - **TEST-CONFIG** : `<TESTwgtrootdir`>/etc`
80 - **TEST-PLUGIN** : `<wgtrootdir>/lib/plugins`
81 - **TEST-HTDOCS** : `<wgtrootdir>/htdocs`
82 - **TEST-DATA** : `<TESTwgtrootdir>/var`
83
84 **TIP:** Use the prefix `afb-` (Application Framework Binding)
85 with your **BINDING** targets.
86
87 Following is an example that sets the `LABELS` and `OUTPUT_NAME` properties:
88
89 ```cmake
90 SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
91                 LABELS "HTDOCS"
92                 OUTPUT_NAME dist.prod
93         )
94 ```
95
96 **NOTE**: You do not need to specify an **INSTALL** command for these
97   targets.
98   Installation is handled by the template and installs using the
99   following path : **${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}**
100
101   Also, if you want to set and use `rpath` with your target, you should use
102   and set the target property `INSTALL_RPATH`.
103
104 ## Adding an External Third-Party Library
105
106 You can add an external third-party library that is built, linked,
107 and shipped with the project.
108 Or, you can link and ship the library only with the project.
109
110 ### Building, Linking, and Shipping an External Library with the Project
111
112 If you need to include an external library that is not shipped
113 with the project, you can bundle the required library in the
114 `lib` widget directory.
115
116 Templates includes facilities to help you work with external
117 libraries.
118 A standard method is to declare as many CMake ExternalProject
119 modules as you need to match the number of needed libraries.
120
121 An ExternalProject module is a special CMake module that lets you define how
122 to download, update, patch, configure, build, and install an external project.
123 The project does not need to be a CMake project.
124 Additionally, you can provide custom steps to account for special
125 needs using ExternalProject step.
126 See the CMake
127 [ExternalProject documentation site](https://cmake.org/cmake/help/v3.5/module/ExternalProject.html?highlight=externalproject)
128 for more information.
129
130 Following is an example that includes the `mxml` library for the
131 [unicens2-binding](https://github.com/iotbzh/unicens2-binding)
132 project:
133
134 ```cmake
135 set(MXML external-mxml)
136 set(MXML_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mxml)
137 ExternalProject_Add(${MXML}
138     GIT_REPOSITORY https://github.com/michaelrsweet/mxml.git
139     GIT_TAG release-2.10
140     SOURCE_DIR ${MXML_SOURCE_DIR}
141     CONFIGURE_COMMAND ./configure --build x86_64 --host aarch64
142     BUILD_COMMAND make libmxml.so.1.5
143     BUILD_IN_SOURCE 1
144     INSTALL_COMMAND ""
145 )
146
147 PROJECT_TARGET_ADD(mxml)
148
149 add_library(${TARGET_NAME} SHARED IMPORTED GLOBAL)
150
151 SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
152     LABELS LIBRARY
153     IMPORTED_LOCATION ${MXML_SOURCE_DIR}/libmxml.so.1
154     INTERFACE_INCLUDE_DIRECTORIES ${MXML_SOURCE_DIR}
155 )
156
157 add_dependencies(${TARGET_NAME} ${MXML})
158 ```
159
160 The example defines an external project that drives the building of the library.
161 The example also defines a new CMake target whose type is **IMPORTED**.
162 The **IMPORTED** target type indicates the target has yet to be built using
163 CMake but is available at the location defined using the **IMPORTED_LOCATION**
164 target property.
165
166 You might want to build the library as **SHARED** or **STATIC** depending on your needs
167 and goals.
168 Next, the example only has to modify the external project configure step and change
169 the filename used by **IMPORTED** library target defined after external project.
170
171 The target's **LABELS** property is set to **LIBRARY** to ship it in the widget.
172
173 In this example, the Unicens project also needs header
174 information from this library.
175 Consequently, the **INTERFACE_INCLUDE_DIRECTORIES** target property
176 is used.
177 Setting that property when another target links to that imported target
178 allows access to included directories.
179
180 Finally, the example binds the target to the external project
181 by using a CMake dependency.
182
183 The target can now be linked and used like any other CMake target.
184
185 ### Link and Ship an External Library with the Project
186
187 If you already have a binary version of the library that you want to use and you
188 cannot or do not want to build the library, you can use the **IMPORTED**
189 library target.
190
191 To illustrate, consider the same example in the previous section.
192 Following are the relevant modifications:
193
194 ```cmake
195 PROJECT_TARGET_ADD(mxml)
196
197 add_library(${TARGET_NAME} SHARED IMPORTED GLOBAL)
198
199 SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
200     LABELS LIBRARY
201     IMPORTED_LOCATION /path_to_library/libmxml.so.1
202     INTERFACE_INCLUDE_DIRECTORIES /path_to_mxml/include/dir
203 )
204 ```
205
206 In the previous example, notice the changes to the
207 `IMPORTED_LOCATION` and `INTERFACE_INCLUDE_DIRECTORIES` statements.
208 These locate the binary version of the library.
209
210 Finally, you can link any other library or executable target with this imported
211 library just as you would for any other target.
212
213 ## Macro Reference
214
215 Following are several macros that are useful for advanced CMake usage.
216
217 ### PROJECT_TARGET_ADD
218
219 This macro adds the target to your project.
220 Following is a typical example that adds the target to your project.
221 You need to provide the name of your target as the macro's parameter:
222
223 Example:
224
225 ```cmake
226 PROJECT_TARGET_ADD(low-can-demo)
227 ```
228
229 The macro makes the variable `${TARGET_NAME}` available and it is defined
230 using the specified name (e.g. `low-can-demo`).
231 The variable changes each time the `PROJECT_TARGET_ADD` macro is called.
232
233 ### project_subdirs_add
234
235 This macro searches within specified subfolders of the CMake project for
236 any `CMakeLists.txt` file.
237 If the file is found, it is added to your project.
238 You can use this macro in a hybrid application (e.g. where the binding
239 exists in a subfolder).
240
241 The following example searches within all subfolders:
242
243 Usage :
244
245 ```cmake
246 project_subdirs_add()
247 ```
248
249 You might want to restrict the subfolders being searched.
250 If so, you can specify a
251 [globbing](https://en.wikipedia.org/wiki/Glob_(programming)) pattern
252 as the argument.
253 Doing so effectively creates a search filter.
254
255 Following is an example that specifies all directories that begin
256 with a number, are followed by the dash character, and then followed
257 by any characters:
258
259 ```cmake
260 project_subdirs_add("[0-9]-*")
261 ```
262
263 ### set_openapi_filename
264
265 This macro is used with a **BINDINGV2** target and defines the
266 binding definition filename.
267 You can use it to also define a relative path to
268 the current `CMakeLists.txt` file.
269
270 If you do not use this macro to specify the name of your definition file,
271 the default one is used, which is `${OUTPUT_NAME}-apidef` and uses
272 **OUTPUT_NAME** as the [target property].
273
274 **CAUTION** When specifying the binding definition filename,
275 you must not use the file's extension as part of the name.
276 Following is an example:
277
278 ```cmake
279 set_openapi_filename('binding/mybinding_definition')
280 ```
281
282 [target property]: https://cmake.org/cmake/help/v3.6/prop_tgt/OUTPUT_NAME.html "OUTPUT_NAME property documentation"
283
284 ### add_input_files
285
286 This macro creates a custom target dedicated for HTML5 and data resource files.
287 The macro provides syntax and schema verification for different languages that
288 include LUA, JSON and XML.
289
290 Alongside the macro are tools used to check files.
291 You can configure the tools by setting the
292 following variables:
293
294 - XML_CHECKER: Uses **xmllint** that is provided with major linux distributions.
295 - LUA_CHECKER: Uses **luac** that is provided with major linux distributions.
296 - JSON_CHECKER: Currently, not used by any tools.
297
298 Following is an example:
299
300 ```cmake
301 add_input_file("${MY_FILES_LIST}")
302 ```
303
304 **NOTE**: If an issue occurs during the "check" step of the macro,
305 the build halts.