diff options
Diffstat (limited to 'docs/3_Developer_Guides')
37 files changed, 4462 insertions, 0 deletions
diff --git a/docs/3_Developer_Guides/1_AGL_Layers/1_Overview.md b/docs/3_Developer_Guides/1_AGL_Layers/1_Overview.md new file mode 100644 index 0000000..861f743 --- /dev/null +++ b/docs/3_Developer_Guides/1_AGL_Layers/1_Overview.md @@ -0,0 +1,34 @@ +--- +edit_link: '' +title: Overview +origin_url: >- + https://git.automotivelinux.org/AGL/meta-agl/plain/docs/../agl-layers-overview.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/meta-agl-developer-guides-devguides-book.yml --> + +Overview +======== + +The +[AGL Project](https://www.automotivelinux.org/) is an automotive-specific +development environment that provides a Linux distribution +[(AGL UCB](https://www.automotivelinux.org/software/unified-code-base)). + +AGL uses layers designed to be compatible with the +[Yocto Project](https://www.yoctoproject.org) and the +[OpenEmbedded Project (OE)](https://www.openembedded.org/wiki/Main_Page). + +This section provides information about the layers used by the AGL Project: + +* **`meta-agl`**: Minimal set of software needed to create an AGL distribution + used to boot a system. + AGL profiles are built on top of this minimal set of software. + +* **`meta-agl-demo`**: Provides a reference or demo platform and applications + for the AGL Distribution. + The reference UI is part of the `meta-agl-demo` layer. + +* **`meta-agl-devel`**: Contains components under development or being tested. + This layer also contains software packages that OEMs need but do not exist + in AGL. diff --git a/docs/3_Developer_Guides/1_AGL_Layers/2_meta-agl.md b/docs/3_Developer_Guides/1_AGL_Layers/2_meta-agl.md new file mode 100644 index 0000000..f46542f --- /dev/null +++ b/docs/3_Developer_Guides/1_AGL_Layers/2_meta-agl.md @@ -0,0 +1,129 @@ +--- +edit_link: '' +title: meta-agl +origin_url: >- + https://git.automotivelinux.org/AGL/meta-agl/plain/docs/../meta-agl.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/meta-agl-developer-guides-devguides-book.yml --> + +## Introduction + +The `meta-agl` layer provides the minimal set of software +to boot an AGL Distribution system. +You use this layer as the minimal core on which to build AGL profiles. + +**NOTE:** The `meta-agl` layer does not include a reference UI. + The reference UI is included as part of the + [`meta-agl-demo`](./meta-agl-demo.html) layer. + Furthermore, `meta-agl` does not include additional components, such + as security, which are part of the + `meta-agl-extra` layer. + +## Sub-Layers + +The `meta-agl` layer itself contains many sub-layers and files. +Following is a "tree" look at the layer: + +``` +. +├── docs +├── meta-agl +├── meta-agl-bsp +├── meta-agl-distro +├── meta-agl-profile-cluster +├── meta-agl-profile-cluster-qt5 +├── meta-agl-profile-core +├── meta-agl-profile-graphical +├── meta-agl-profile-graphical-html5 +├── meta-agl-profile-graphical-qt5 +├── meta-agl-profile-hud +├── meta-agl-profile-telematics +├── meta-app-framework +├── meta-netboot +├── meta-security +├── README-AGL.md +├── README.md +├── scripts +├── templates +``` + +This list provides some overview information on the files and sub-layers +in `meta-agl`: + +* `docs`: Contains files that support AGL documentation. +* `meta-agl`: Contains layer configuration for the `meta-agl` layer. +* `meta-agl-bsp`: Contains adaptations for recipes and required packages + to boot an AGL distribution on targeted hardware and emulation (i.e. QEMU). +* `meta-agl-distro`: Contains distro configuration and supporting scripts. +* `meta-agl-profile-cluster`: The middleware for the AGL cluster profile. + The set of packages required for AGL Cluster Distribution. + Profiles include support for Wayland images. +* `meta-agl-profile-cluster-qt5`: The middleware for the AGL Qt5-based cluster profile. + The set of packages required for AGL Qt5-based Cluster Distribution. + Profiles include support for Wayland images with Qt5. +* `meta-agl-profile-core`: Configuration and recipes for the AGL core profiles. +* `meta-agl-profile-graphical`: Configuration and recipes supporting graphical user + interfaces. +* `meta-agl-profile-graphical-html5`: Configuration and recipes supporting profiles + with HTML user interface support. +* `meta-agl-profile-graphical-qt5`: Configuration and recipes supporting profiles + with Qt5-based user interface support. +* `meta-agl-profile-hud`: Configuration and recipes supporting profiles with + Head-Up-Display (HUD) support. +* `meta-agl-profile-telematics`: Configuration and recipes supporting profiles with + telematics support. +* `meta-app-framework`: Configuration and recipes supporting the AGL Application + Framework. +* `meta-netboot`: Contains recipes and configuration adjustments to allow network + boot through network block device (NBD) since network file system (NFS) does not + support security labels. +* `meta-security`: Configuration and recipes supporting security applications. +* `scripts`: AGL development setup and support scripts. +* `templates`: Base, feature, and machine templates used in the AGL development + environment. + +## Packagegroups + +This section describes the AGL +[packagegroup](https://yoctoproject.org/docs/2.4.4/dev-manual/dev-manual.html#usingpoky-extend-customimage-customtasks) +design: + +* packagegroup-agl-image-minimal + + packagegroup-agl-core-automotive.bb + packagegroup-agl-core-connectivity.bb + packagegroup-agl-core-graphics.bb + packagegroup-agl-core-kernel.bb + packagegroup-agl-core-multimedia.bb + packagegroup-agl-core-navi-lbs.bb + packagegroup-agl-core-os-commonlibs.bb + packagegroup-agl-core-security.bb + packagegroup-agl-core-speech-services.bb + + The previous list of Packagegroups are used to create the `agl-image-minimal` image, + which is a small image just capable of allowing a device to boot. + + Subsystem should maintain packagegroup-agl-core-[subsystem].bb which should + hold sufficient packages to build `agl-image-minimal`. + +* packagegroup-agl-image-ivi + + packagegroup-agl-ivi-automotive.bb + packagegroup-agl-ivi-connectivity.bb + packagegroup-agl-ivi-graphics.bb + packagegroup-agl-ivi-kernel.bb + packagegroup-agl-ivi-multimedia.bb + packagegroup-agl-ivi-navi-lbs.bb + packagegroup-agl-ivi-os-commonlibs.bb + packagegroup-agl-ivi-security.bb + packagegroup-agl-ivi-speech-services.bb + + The previous list of Packagegroups are used to create the `agl-image-ivi` + image, which is a baseline image (i.e. Service Layer and Operating System + Layer defined in AGL Spec v1.0) for the AGL profiles. + +* packagegroup-agl-test.bb + + Additional tools used in QA tests (for agl-image*-qa). + diff --git a/docs/3_Developer_Guides/1_AGL_Layers/3_meta-agl-demo.md b/docs/3_Developer_Guides/1_AGL_Layers/3_meta-agl-demo.md new file mode 100644 index 0000000..232cd1d --- /dev/null +++ b/docs/3_Developer_Guides/1_AGL_Layers/3_meta-agl-demo.md @@ -0,0 +1,169 @@ +--- +edit_link: '' +title: meta-agl-demo +origin_url: >- + https://git.automotivelinux.org/AGL/meta-agl-demo/plain/docs/../meta-agl-demo.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/meta-agl-demo-guides-devguides-book.yml --> + +## Introduction + +The `meta-agl-demo` layer is the reference user interface layer for the DEMO +platform of Automotive Grade Linux (AGL). +The layer provides a reference platform and applications. +The BitBake target name for the DEMO platform is `agl-demo-platform`, which is +the full DEMO platform image. + +## Layer Dependencies + +This section describes dependencies for the `meta-agl-demo` layer. +Dependencies are grouped into base, hardware, and feature dependencies. + +### Base Dependencies + +The `meta-agl-demo` layer has the following base dependencies: + +* Yocto Project Release: + + - URI: git://git.yoctoproject.org/poky + - Branch: "thud" + - Tested Revision: See the [`default.xml`](https://github.com/leon-anavi/AGL-repo/blob/master/default.xml) + manifest file for the `AGL-repo` repository for revision + information.<br/><br/> + +* AGL `meta-agl` Layer: + + - URI: https://gerrit.automotivelinux.org/gerrit/AGL/meta-agl + - Branch: "master"<br/><br/> + +* OpenEmbedded `meta-openembedded` Layer: + + - Branch: "thud" + - Tested Revision: See the [`default.xml`](https://github.com/leon-anavi/AGL-repo/blob/master/default.xml) + manifest file for the `AGL-repo` repository for revision + information. + + Specifically, out of `meta-openembedded`, these sub-layers are used: + + - `meta-oe` + - `meta-multimedia` + - `meta-networking` + - `meta-python`<br/><br/> + +* Yocto Project `meta-qt5` Layer from the + [OpenEmbedded Layer Index](https://layers.openembedded.org/layerindex/branch/master/layers/): + + - URI: https://github.com/meta-qt5/meta-qt5.git + - Branch: "thud" + - Tested Revision: See the [`default.xml`](https://github.com/leon-anavi/AGL-repo/blob/master/default.xml) + manifest file for the `AGL-repo` repository for revision + information.<br/><br/> + +### Hardware Dependencies + +Aside from the previously listed base dependencies, if you are using a +[supported Renesas board](../getting_started/reference/getting-started/machines/renesas.html) +supported Renesas board, these dependencies exist: + +* AGL's `meta-renesas` Layer: + + - URI: https://gerrit.automotivelinux.org/gerrit/AGL/meta-renesas + +### Feature Dependencies + +The `meta-agl-demo` layer has the following AGL +[feature](../getting_started/reference/getting-started/image-workflow-initialize-build-environment.html#agl-features) +dependencies: + +* Yocto Project `meta-security` Layer: + + - URI: https://git.yoctoproject.org/cgit/cgit.cgi/meta-security + - Branch: "master" + - Tested Revision: See the [`default.xml`](https://github.com/leon-anavi/AGL-repo/blob/master/default.xml) + manifest file for the `AGL-repo` repository for revision + information.<br/><br/> + +* AGL's `meta-app-framework` Layer within the `meta-agl` Layer: + + - URI: https://gerrit.automotivelinux.org/gerrit/gitweb?p=AGL/meta-agl.git + - Branch: "master"<br/><br/> + +**The `agl-sota` Feature:** + +* Here Technologies' `meta-updater` Layer: + + - URI: https://github.com/advancedtelematic/meta-updater/ + - Branch: "thud"<br/><br/> + +* Here Technologies' `meta-updater-qemux86-64` Layer: + + - URI: https://github.com/advancedtelematic/meta-updater-qemux86-64/ + - Branch: "thud"<br/><br/> + +* OpenEmbedded's `meta-openembedded` Layer: + + - URI: https://github.com/openembedded/meta-openembedded + - Branch: "thud" + - Tested Revision: See the [`default.xml`](https://github.com/leon-anavi/AGL-repo/blob/master/default.xml) + manifest file for the `AGL-repo` repository for revision + information. + + Specifically, out of `meta-openembedded`, these sub-layers are used: + + - `meta-filesystems` + - `meta-oe` + - `meta-python`<br/><br/> + +**The `agl-netboot` Feature:** + +* AGL's `meta-netboot` Layer within the `meta-agl` Layer: + + - URI: https://gerrit.automotivelinux.org/gerrit/gitweb?p=AGL/meta-agl.git + - Branch: "master" + + +## Packagegroups + +AGL DEMO Platform's +[packagegroups](https://www.yoctoproject.org/docs/2.4.4/dev-manual/dev-manual.html#usingpoky-extend-customimage-customtasks) +consist of the following: + +### packagegroup-agl-demo-platform + +This packagegroup is used for generating the `agl-demo-platform` image, +which is the full image for the AGL distributions IVI profile. +You can see the recipe (i.e. `agl-demo-platform.bb`) that installs +the `packagegroup-agl-demo-platform` packagegroup +[here](https://git.automotivelinux.org/AGL/meta-agl-demo/tree/recipes-platform/images/agl-demo-platform.bb). + +As meta-agl's design of packagegroups, the `agl-demo-platform.bb` recipe installs +only `packagegroup-agl-demo-platform` and the packages of the DEMO applications. + +``agl-demo-platform`` contains the following three packagegroups: + + * `packagegroup-agl-image-minimal` + * `packagegroup-agl-image-ivi` + * `packagegroup-agl-demo-platform` + +### packagegroup-agl-appfw* + +These packagegroups contain packages for the AGL distribution's +Application Framework. +Subsystem should maintain `packagegroup-agl-appfw-[subsystem].bb`, which +should hold sufficient packages for the Application Framework. + +Subsystems also can maintain their own packagegroups using appropriate +`recipes-*/`. +For example, Qt5 has two packagegroups in `meta-agl-demo`: +`packagegroup-agl-appfw-native-qt5` and `packagegroup-agl-demo-qt-examples`, +which are under `recipes-qt/`. + +The `packagegroup-agl-appfw-native-qt5` is included by +`packagegroup-agl-appfw-native` because Qt5 belongs to native application +framework of AGL Distro. + +Because the `packagegroup-agl-demo-qt-examples` is not mandatory for +the AGL Application Framework and the AGL DEMO, the packagegroup is added +to the layer's `local.conf` file only when needed. + diff --git a/docs/3_Developer_Guides/1_AGL_Layers/4_meta-agl-devel.md b/docs/3_Developer_Guides/1_AGL_Layers/4_meta-agl-devel.md new file mode 100644 index 0000000..a51d47c --- /dev/null +++ b/docs/3_Developer_Guides/1_AGL_Layers/4_meta-agl-devel.md @@ -0,0 +1,148 @@ +--- +edit_link: '' +title: meta-agl-devel +origin_url: >- + https://git.automotivelinux.org/AGL/meta-agl-devel/plain/docs/../meta-agl-devel.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/meta-agl-devel-guides-devguides-book.yml --> + +## Introduction + +The `meta-agl-devel` layer contains components that are being tested or +still in development. +The layer also contains software packages that Original Equipment +Manufacturers (OEMs) need but are not included in the AGL software. + +## Sub-Layers + +The `meta-agl-devel` layer contains the following files and sub-layers: + +``` +. +├── meta-agl-telemetry +├── meta-audio-4a-framework +├── meta-audio-soundmanager-framework +├── meta-egvirt +├── meta-gstrecorder-rcar-gen3 +├── meta-hmi-framework +├── meta-oem-extra-libs +├── README.md +├── templates +``` + +The following list provides a summary of these sub-layers: + +* `meta-agl-telemetry`: Provides the smallest AGL image. + The image is designed to be used when a device requires restricted + scope of responsibilites (e.g. collecting vehicle telemetry). + +* `meta-audio-4a-framework`: A collection of recipes used for the + first integration of 4A (i.e. Advanced AGL Audio Architecture). + +* `meta-pipewire`: A collection of recipes used for the integration + of the pipewire sound system. + +* `meta-audio-soundmanager-framework`: Supports the Soundmanager + Audio Framework features, which maps to the `agl-audio-soundmanager-framework` + AGL feature. + +* `meta-egvirt`: The AGL Virtualization Expert Group (EG-VIRT) layer. + This layer supports the design, test, implementation, and assessment + of virtualization technologies (e.g. containers, hypervisors, system + partitioners, and so forth) aimed at AGL ARMv8 and Intel platforms. + +* `meta-gstrecorder-rcar-gen3`: Supports streaming audio and video for + the Pro and Premier board kits (e.g. + [Renesas R-Car Starter Kit Pro Board](https://www.elinux.org/R-Car/Boards/M3SK) + and + [Renesas R-Car Starter Kit Premier Board](https://www.elinux.org/R-Car/Boards/H3SK)). + +* `meta-hmi-framework`: Provides AGL's Human Machine Interface (HMI) framework + through resource management consisting of sounds, windows, and input control. + For more information, see the + [HMI-Framework Page](https://wiki.automotivelinux.org/hmiframework) of the + AGL Wiki. + +* `meta-oem-extra-libs`: Provides libraries and software packages needed by + OEMs but not provided by the AGL software. + +* `templates`: Feature templates that support the `meta-agl-devel` layer. + +## Additional Sub-Layer Information + +This section provides additional information for the `meta-egvirt`, +`meta-oem-extra-libs`, and `meta-hmi-framework` layers. + +### Virtualization Support + +The `meta-egvirt` layer enables virtualization support in AGL. +The AGL Virtualization Expert (EG-VIRT) group is responsible +for design and implementation of AGL virtualization solutions +(.e.g the Virtualization platform architecture of AGL). +You can read about EG-VERT's efforts on the +"[Virtualization Expert Group's](https://wiki.automotivelinux.org/eg-virt)" +page of the AGL wiki. + +Additionally, you can learn more about virtualization as it applies to AGL +by reading +"[The Automotive Grade Linux Software Defined Connected Car Architecture](https://www.automotivelinux.org/wp-content/uploads/sites/4/2018/06/agl_software_defined_car_jun18.pdf)" +whitepaper. + +### OEM Extra Libraries + +The `meta-oem-extra-libs` layer provides additional software packages many OEMs need +but are not part of the AGL source. +Following is the list of packages this layer provides: + + * boost + * fixesproto + * imagemagick + * iptables + * Xorg-macros + * zlib + * eglibc = glibc + * libcurl + * libgif + * libneon + * mongoose + * fuse + * protocol buffers + * bsdiff + * module-init-tools + * libcroco + * libtiff + * librsvg + * libpcap + +To add these packages to your library, you need to include the +`agl-oem-extra-libs` AGL feature when you initialize your build +environment using the `aglsetup.sh` script. + +For information on how to use the `aglsetup.sh` script to initialize +your build environment, see the +"[Initializing Your Build Environment](../getting_started/reference/getting-started/image-workflow-initialize-build-environment.html)" +section. + +Once you have included the AGL feature, you can build your image. + +### HMI Framework + +The `meta-hmi-framework` layer supports the Human-Machine Interface (HMI) Framework. +The HMI-Framework is the User Interface (UI) to control the Infotainment System. +Work continues to close the gap between the user experience of a smart phone +and the Infotainment System in a vehicle, for example. + +You can find more out about HMI Framework progress on the +"[HMI Framework](https://wiki.automotivelinux.org/hmiframework)" page on the AGL Wiki. + +To add HMI Framework support to your image, you need to include the +`hmi-framework` AGL feature when you initialize your build +environment using the `aglsetup.sh` script. + +For information on how to use the `aglsetup.sh` script to initialize +your build environment, see the +"[Initializing Your Build Environment](../getting_started/reference/getting-started/image-workflow-initialize-build-environment.html)" +section. + +Once you have included the AGL feature, you can build your image. diff --git a/docs/3_Developer_Guides/2_Building_Microservices_Natively/0_build-microservice-overview.md b/docs/3_Developer_Guides/2_Building_Microservices_Natively/0_build-microservice-overview.md new file mode 100644 index 0000000..a1c6edc --- /dev/null +++ b/docs/3_Developer_Guides/2_Building_Microservices_Natively/0_build-microservice-overview.md @@ -0,0 +1,64 @@ +--- +edit_link: '' +title: Overview +origin_url: >- + https://raw.githubusercontent.com/automotive-grade-linux/docs-sources/master/agl-documentation/host-configuration/docs/0-build-microservice-overview.md +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/host-configuration-developer-guides-devguides-book.yml --> + +# Overview + +You can develop Microservices on your native Linux machine quickly +by following the workflow in this section. +This workflow takes advantage of RPM or Debian packages,which are available +through the +[OpenSUSE Build Service (OBS)](https://build.opensuse.org/). +You can install these +[packages](https://build.opensuse.org/project/subprojects/isv:LinuxAutomotive) +and bypass the +[Yocto Project](https://yoctoproject.org) build cycles described in the +"[Developing an AGL Image](../../getting_started/reference/getting-started/image-workflow-intro.html)" section. + +Using this workflow, you can start to code, execute, and debug Microservice +bindings directly on your host. This flow works for many cases for which +no specific hardware is required, or when you can plug hardware directly +into your native Linux host's USB port such as a Controller Area Network +([CAN](https://en.wikipedia.org/wiki/CAN_bus)) bus Adapter or a Media +Oriented Systems Transport +([MOST](https://en.wikipedia.org/wiki/MOST_Bus)) Controller. + +The following figure and list overview the Microservice Native Development +process. +You can learn about the steps in the process by reading through the +remaining sections. + +<center><img src="pictures/microservice-workflow-native.png"></center> + +1. **Verify Your Build Host:** + Make sure you have a native Linux host. + For the example used in this section (i.e. `helloworld-service`), be sure your + Linux distribution is a recent version of Debian, Ubuntu, OpenSUSE, or Fedora. + +2. **Download and Install AGL Packages:** + Download and install the + [near-zero](https://en.wikipedia.org/wiki/Zero_Install) packages + from the OBS. + +3. **Install the Binder Daemon:** + Install the Binder Daemon, which is a part of the + [AGL Application Framework (AFM)](../../apis_services/reference/af-main/0-introduction.html). + The daemon allows you to connect applications to required services. + +4. **Get Your Source Files:** + For this section, you clone the `helloworld-service` binding repository. + You also need to make sure you have some other required packages to build + that specific binding. + +5. **Build and Run Your Service Natively (Optional Tool Use):** + Build your binding on your Linux host using native tools. + Once the binding is built, you can run it to make sure it functions + as expected. + + Optionally use extra tools once your binding is building and running + smoothly in the native environment. diff --git a/docs/3_Developer_Guides/2_Building_Microservices_Natively/1_verify-build-host.md b/docs/3_Developer_Guides/2_Building_Microservices_Natively/1_verify-build-host.md new file mode 100644 index 0000000..401a5bc --- /dev/null +++ b/docs/3_Developer_Guides/2_Building_Microservices_Natively/1_verify-build-host.md @@ -0,0 +1,33 @@ +--- +edit_link: '' +title: Verify Your Build Host +origin_url: >- + https://raw.githubusercontent.com/automotive-grade-linux/docs-sources/master/agl-documentation/host-configuration/docs/1-verify-build-host.md +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/host-configuration-developer-guides-devguides-book.yml --> + +# Verify Your Build Host + +In order to build a Microservice binding natively, you need to be using a +supported Linux distribution. +In general, a recent version of Debian, Ubuntu, OpenSUSE, and Fedora works. +Following is a specific list of supported distributions: + +* [Debian](https://www.debian.org/releases/) 9.0 +* [Ubuntu](https://wiki.ubuntu.com/Releases) 16.04, 16.10, 17.10, and 18.04 +* [OpenSUSE](https://en.opensuse.org/openSUSE:Roadmap) Leap 15.0 and Tumbleweed +* [Fedora](https://fedoraproject.org/wiki/Releases) 27, 28, 29, and Rawhide. + +Exporting the `DISTRO` environment variable defines the distribution. +Following are examples: + +```bash +export DISTRO="Debian_9.0" +export DISTRO="xUbuntu_16.04" +export DISTRO="xUbuntu_16.10" +export DISTRO="xUbuntu_17.10" +export DISTRO="xUbuntu_18.04" +``` + +Set the `DISTRO` environment appropriately. diff --git a/docs/3_Developer_Guides/2_Building_Microservices_Natively/2_download-packages.md b/docs/3_Developer_Guides/2_Building_Microservices_Natively/2_download-packages.md new file mode 100644 index 0000000..c1502d2 --- /dev/null +++ b/docs/3_Developer_Guides/2_Building_Microservices_Natively/2_download-packages.md @@ -0,0 +1,239 @@ +--- +edit_link: '' +title: Download Packages +origin_url: >- + https://raw.githubusercontent.com/automotive-grade-linux/docs-sources/master/agl-documentation/host-configuration/docs/2-download-packages.md +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/host-configuration-developer-guides-devguides-book.yml --> + +# Download Packages + +Different repositories exist for different AGL releases.\ +You need to download and install the packages based on your version +of AGL. + +## Set the `REVISION` Environment Variable + +All the packages reside in repositories managed by the +[OpenSUSE Build Service (OBS)](https://build.opensuse.org/).\ +You can see the packages +[here](https://build.opensuse.org/project/subprojects/isv:LinuxAutomotive#). + +Currently, support exists for the following AGL releases: + +* ElectricEel +* FunkyFlounder +* GrumpyGuppy +* HappyHalibut +* Master + +You need to set the `REVISION` environment variable to the AGL release you +are using.\ +For this example, set and export `REVISION` as "Master". + +```bash +export REVISION=Master +``` + +For additional details about OBS, see +[LinuxAutomotive page on OBS](https://build.opensuse.org/project/show/isv:LinuxAutomotive). + +## Make Sure Your `DISTRO` Environment Variable is Set + +The `DISTRO` environment variable needs to be correctly set for your +Linux distribution.\ +See the +"[Verify Your Build Host](./1-verify-build-host.html)" +section for information on how to set this variable. + +## Install the Repository + +```bash +Hit:1 https://deb.nodesource.com/node_10.x xenial InRelease +Hit:2 https://download.docker.com/linux/ubuntu xenial InRelease +Hit:3 http://security.ubuntu.com/ubuntu xenial-security InRelease +Hit:4 http://us.archive.ubuntu.com/ubuntu xenial InRelease +Ign:5 http://download.opensuse.org/repositories/isv:/LinuxAutomotive:/AGL_FunkyFlounder/xUbuntu_16.04 ./ InRelease +Hit:6 http://us.archive.ubuntu.com/ubuntu xenial-updates InRelease +Hit:7 http://download.opensuse.org/repositories/isv:/LinuxAutomotive:/AGL_FunkyFlounder/xUbuntu_16.04 ./ Release +Hit:8 http://us.archive.ubuntu.com/ubuntu xenial-backports InRelease +Reading package lists... Done +``` + +Not sure why you get the `Ign` on line 5.\ +I guess InRelease does not exist. + +If you don't have a `/etc/apt/sources.list.d/AGL.list` file to even start with, +and you run through the whole thing, you get the following output: + +```bash +$ sudo apt-get update +Hit:1 https://deb.nodesource.com/node_10.x xenial InRelease +Hit:2 https://download.docker.com/linux/ubuntu xenial InRelease +Hit:3 http://us.archive.ubuntu.com/ubuntu xenial InRelease +Get:4 http://us.archive.ubuntu.com/ubuntu xenial-updates InRelease [109 kB] +Get:5 http://security.ubuntu.com/ubuntu xenial-security InRelease [107 kB] +Ign:6 http://download.opensuse.org/repositories/isv:/LinuxAutomotive:/AGL_FunkyFlounder/xUbuntu_16.04 ./ InRelease +Hit:7 http://download.opensuse.org/repositories/isv:/LinuxAutomotive:/AGL_FunkyFlounder/xUbuntu_16.04 ./ Release +Get:9 http://us.archive.ubuntu.com/ubuntu xenial-backports InRelease [107 kB] +Get:10 http://us.archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [902 kB] +Fetched 1,225 kB in 1s (803 kB/s) +Reading package lists... Done +``` + +Following are example commands that show how to install the package repository +based on various values of `DISTRO` and `REVISION`: + +### Ubuntu and "Master" + +```bash +export REVISION=Master +export DISTRO="xUbuntu_18.04" +wget -O - http://download.opensuse.org/repositories/isv:/LinuxAutomotive:/AGL_${REVISION}/${DISTRO}/Release.key | sudo apt-key add - +sudo bash -c "cat >> /etc/apt/sources.list.d/AGL.list <<EOF +#AGL +deb http://download.opensuse.org/repositories/isv:/LinuxAutomotive:/AGL_${REVISION}/${DISTRO}/ ./ +EOF" +sudo apt-get update +``` + +You can see the installed repository using the following command: + +```bash +cat /etc/apt/sources.list.d/AGL.list +``` + +### OpenSUSE and "Master" + +```bash +export DISTRO="openSUSE_Leap_15.0" +export REVISION=Master +source /etc/os-release; export DISTRO=$(echo $PRETTY_NAME | sed "s/ /_/g") +sudo zypper ar http://download.opensuse.org/repositories/isv:/LinuxAutomotive:/AGL_${REVISION}/${DISTRO}/isv:LinuxAutomotive:AGL_${REVISION}.repo +sudo zypper --gpg-auto-import-keys ref +``` + +You can see the installed repository using the following command: + +```bash +zypper repos | grep AGL +``` + +### Fedora and "Master" + +```bash +export DISTRO="Fedora_28" +export REVISION=Master +source /etc/os-release ; export DISTRO="${NAME}_${VERSION_ID}" +sudo wget -O /etc/yum.repos.d/isv:LinuxAutomotive:AGL_${REVISION}.repo http://download.opensuse.org/repositories/isv:/LinuxAutomotive:/AGL_${REVISION}/${DISTRO}/isv:LinuxAutomotive:AGL_${REVISION}.repo +``` + +You can see the installed repository using the following command: + +```bash +dnf repolist --all | grep AGL +``` + +## Switching Between Repositories + +The commands in the previous section showed you how to install the packages +from a specific repository and how to verify whether or not the packages +are enabled or disabled. +You can switch between different repositories. +You must disable your current AGL repository and then enable the repository +designated for the switch. + +Following is an example for Debian distributions: + +### Example for Debian distro + +Suppose you are on "master" and you want the "ElectricEel" AGL revision. + +```bash +export OLDR=Master +export NEWR=ElectricEel +sudo sed -i "s/${OLDR}/${NEWR}/g" /etc/apt/sources.list.d/AGL.list +sudo apt-get update +``` + +### Example for openSuse distro + +```bash +# | Alias | Name | Enabled | GPG Check | Refresh +---+-------------------------------------+-------------------------------------------------------------------------------------------+---------+-----------+-------- + 1 | Atom | Atom Editor | Yes | (r ) Yes | No + 2 | code | Visual Studio Code | Yes | (r ) Yes | No + 3 | http-ftp.uni-erlangen.de-e3cebb6d | Packman Repository | Yes | (r ) Yes | Yes + 4 | isv_LinuxAutomotive_AGL_ElectricEel | isv:LinuxAutomotive:AGL_ElectricEel (openSUSE_Leap_15.0) | Yes | (r ) Yes | No + 5 | isv_LinuxAutomotive_AGL_Master | Automotive Grade Linux Application Development tools - master branch (openSUSE_Leap_15.0) | No | ---- | ---- + 6 | openSUSE-Leap-15.0-1 | openSUSE-Leap-15.0-1 | No | ---- | ---- + 7 | repo-debug | openSUSE-Leap-15.0-Debug | No | ---- | ---- + 8 | repo-debug-non-oss | openSUSE-Leap-15.0-Debug-Non-Oss | No | ---- | ---- + 9 | repo-debug-update | openSUSE-Leap-15.0-Update-Debug | No | ---- | ---- +10 | repo-debug-update-non-oss | openSUSE-Leap-15.0-Update-Debug-Non-Oss | No | ---- | ---- +11 | repo-non-oss | openSUSE-Leap-15.0-Non-Oss | Yes | (r ) Yes | Yes +12 | repo-oss | openSUSE-Leap-15.0-Oss | Yes | (r ) Yes | Yes +13 | repo-source | openSUSE-Leap-15.0-Source | No | ---- | ---- +14 | repo-source-non-oss | openSUSE-Leap-15.0-Source-Non-Oss | No | ---- | ---- +15 | repo-update | openSUSE-Leap-15.0-Update | Yes | (r ) Yes | Yes +16 | repo-update-non-oss | openSUSE-Leap-15.0-Update-Non-Oss | Yes | (r ) Yes | Yes +``` + +Now, you want your "master" repository enabled. +In the above output, the "ElectricEel" repository is at the fourth line +and the "master" repository is at the fifth line. +Thus, enter the following: + +```bash +$ sudo zypper mr -d 4 && sudo zypper mr -e 5 +Repository 'isv_LinuxAutomotive_AGL_ElectricEel' has been successfully disabled. +Repository 'isv_LinuxAutomotive_AGL_Master' has been successfully enabled. +sudo zypper refresh +``` + +**NOTE:** In the previous command, the "-d" option is used for "disable" and the +"-e" option is used for "enable". + +Following are the results: + +```bash +# | Alias | Name | Enabled | GPG Check | Refresh +---+-------------------------------------+-------------------------------------------------------------------------------------------+---------+-----------+-------- + 1 | Atom | Atom Editor | Yes | (r ) Yes | No + 2 | code | Visual Studio Code | Yes | (r ) Yes | No + 3 | http-ftp.uni-erlangen.de-e3cebb6d | Packman Repository | Yes | (r ) Yes | Yes + 4 | isv_LinuxAutomotive_AGL_ElectricEel | isv:LinuxAutomotive:AGL_ElectricEel (openSUSE_Leap_15.0) | No | ---- | ---- + 5 | isv_LinuxAutomotive_AGL_Master | Automotive Grade Linux Application Development tools - master branch (openSUSE_Leap_15.0) | Yes | (r ) Yes | No + 6 | openSUSE-Leap-15.0-1 | openSUSE-Leap-15.0-1 | No | ---- | ---- + 7 | repo-debug | openSUSE-Leap-15.0-Debug | No | ---- | ---- + 8 | repo-debug-non-oss | openSUSE-Leap-15.0-Debug-Non-Oss | No | ---- | ---- + 9 | repo-debug-update | openSUSE-Leap-15.0-Update-Debug | No | ---- | ---- +10 | repo-debug-update-non-oss | openSUSE-Leap-15.0-Update-Debug-Non-Oss | No | ---- | ---- +11 | repo-non-oss | openSUSE-Leap-15.0-Non-Oss | Yes | (r ) Yes | Yes +12 | repo-oss | openSUSE-Leap-15.0-Oss | Yes | (r ) Yes | Yes +13 | repo-source | openSUSE-Leap-15.0-Source | No | ---- | ---- +14 | repo-source-non-oss | openSUSE-Leap-15.0-Source-Non-Oss | No | ---- | ---- +15 | repo-update | openSUSE-Leap-15.0-Update | Yes | (r ) Yes | Yes +16 | repo-update-non-oss | openSUSE-Leap-15.0-Update-Non-Oss | Yes | (r ) Yes | Yes +``` + +### Example for Fedora distro + +```bash +isv_LinuxAutomotive_AGL_FunkyFlounder isv:LinuxAutomotive:AGL disabled +isv_LinuxAutomotive_AGL_Master Automotive Grade Linux enabled +``` + +The following commands enable the "ElectricEel" repository: + +```bash +dnf config-manager --set-disabled isv_LinuxAutomotive_AGL_Master +dnf config-manager --set-enabled isv_LinuxAutomotive_AGL_FunkyFlounder +``` + +```bash +$ dnf repolist --all | grep AGL +isv_LinuxAutomotive_AGL_FunkyFlounder isv:LinuxAutomotive:AGL enabled +isv_LinuxAutomotive_AGL_Master Automotive Grade Linux disabled +``` diff --git a/docs/3_Developer_Guides/2_Building_Microservices_Natively/3_installing-binder-daemon.md b/docs/3_Developer_Guides/2_Building_Microservices_Natively/3_installing-binder-daemon.md new file mode 100644 index 0000000..094cb18 --- /dev/null +++ b/docs/3_Developer_Guides/2_Building_Microservices_Natively/3_installing-binder-daemon.md @@ -0,0 +1,89 @@ +--- +edit_link: '' +title: Installing the Binder Daemon +origin_url: >- + https://raw.githubusercontent.com/automotive-grade-linux/docs-sources/master/agl-documentation/host-configuration/docs/3-installing-binder-daemon.md +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/host-configuration-developer-guides-devguides-book.yml --> + +# Installing the Binder Daemon + +The Application Framework Binder Daemon (`afb-daemon`), which is a part of +the AGL Application Framework, provides a way to connect applications to +required services.\ +It provides a fast way to securely offer APIs to applications that are +written in any language and that can run almost anywhere. + +You can learn more about the AGL Application Framework in the +"[AGL Framework Overview](../../apis_services/reference/af-main/0-introduction.html)" +section.\ +You can learn more about the `aft-daemon` in the +"[Binder Overview](../../apis_services/reference/af-binder/afb-overview.html)" +section. + +## Installing on Debian + +Use the following commands if your native Linux machine uses the Debian +distribution: + +```bash +sudo apt-get install agl-app-framework-binder-dev +``` + +## Installing on OpenSUSE + +Use the following commands if your native Linux machine uses the OpenSUSE +distribution: + +```bash +sudo zypper install agl-app-framework-binder-devel +``` + +## Installing on Fedora + +Use the following commands if your native Linux machine uses the Fedora +distribution: + +```bash +sudo dnf install agl-app-framework-binder-devel +``` + +## Setting Your Environment Variables + +Regardless of your system's distribution, you need to set certain environment +variables correctly in order to use the daemon (i.e. `app-framework-binder`). + +Commands that define and export these environment variables exist in the +`agl-app-framework-binder.sh` file, which is created when +you install the daemon: + +```bash +#---------- AGL %{name} options Start ---------" +# Object: AGL cmake option for binder/bindings +export LD_LIBRARY_PATH=/opt/AGL/lib64:${LD_LIBRARY_PATH} +export LIBRARY_PATH=/opt/AGL/lib64:${LIBRARY_PATH} +export PKG_CONFIG_PATH=/opt/AGL/lib64/pkgconfig:${PKG_CONFIG_PATH} +export PATH=/opt/AGL/bin:$PATH +#---------- AGL options End --------- +``` + +You can make sure these environment variables are correctly set by doing +one of the following: + +* **Logout and Log Back In:** + + Logging out and then logging back in correctly sets the environment + variables. + +* **Manually Source the `agl-app-framework-binder.sh` File:** + + Source the following command: + + ```bash + source /etc/profile.d/agl-app-framework-binder.sh + ``` + + **NOTE:** + Creating a new session automatically sources the `agl-app-framework-binder.sh` + file. diff --git a/docs/3_Developer_Guides/2_Building_Microservices_Natively/4_getting-source-files.md b/docs/3_Developer_Guides/2_Building_Microservices_Natively/4_getting-source-files.md new file mode 100644 index 0000000..b59cec0 --- /dev/null +++ b/docs/3_Developer_Guides/2_Building_Microservices_Natively/4_getting-source-files.md @@ -0,0 +1,74 @@ +--- +edit_link: '' +title: Getting Your Source Files +origin_url: >- + https://raw.githubusercontent.com/automotive-grade-linux/docs-sources/master/agl-documentation/host-configuration/docs/4-getting-source-files.md +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/host-configuration-developer-guides-devguides-book.yml --> + +# Getting Your Source Files + +Now that you have your host ready, packages installed, and the binder +daemon ready, you can get your source files together. +This example uses the `helloworld-service` binding, which is +a project hosted on GitHub, is written in the C programming language, +depends on the `libjson-c` library, and uses `cmake` for building. + +## Install Programs and Libraries You Need for this Example + +For this example, you need to have the following installed on your host: + +```bash +git +cmake +pkg-config +gcc +g++ +json-c +``` + +**NOTE:** If you are building a different binding, you need to make sure +you have all the programs and libraries needed to build that particular +binding. + +### Installing on Debian + +Use the following commands if your native Linux machine uses the Debian +distribution: + +```bash +sudo apt-get install git cmake pkg-config gcc g++ libjson-c-dev +``` + +### Installing on OpenSUSE + +Use the following commands if your native Linux machine uses the OpenSUSE +distribution: + +```bash +sudo zypper install git cmake pkg-config gcc gcc-c++ libjson-c-devel +``` + +### Installing on Fedora + +Use the following commands if your native Linux machine uses the Fedora +distribution: + +```bash +sudo dnf install git cmake pkg-config gcc gcc-c++ json-c-devel.x86_64 +``` + +## Cloning the helloworld-service repository + +Use Git to create a local repository of the +[helloworld-service](https://github.com/iotbzh/helloworld-service) binding from +[IoT.BZH](https://iot.bzh/en/). +The following command creates a repository named `helloworld-service` in the +current directory. +The "--recurse-submodules" option ensures that all submodules (i.e. repositories +within `helloworld-service`) are initialized and cloned as well. + +```bash +git clone https://github.com/iotbzh/helloworld-service.git --recurse-submodules +``` diff --git a/docs/3_Developer_Guides/2_Building_Microservices_Natively/5_building-and-running-service-natively.md b/docs/3_Developer_Guides/2_Building_Microservices_Natively/5_building-and-running-service-natively.md new file mode 100644 index 0000000..3768037 --- /dev/null +++ b/docs/3_Developer_Guides/2_Building_Microservices_Natively/5_building-and-running-service-natively.md @@ -0,0 +1,119 @@ +--- +edit_link: '' +title: Building and Running Your Service Natively +origin_url: >- + https://raw.githubusercontent.com/automotive-grade-linux/docs-sources/master/agl-documentation/host-configuration/docs/5-building-and-running-service-natively.md +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/host-configuration-developer-guides-devguides-book.yml --> + +# Building and Running Your Service Natively + +The next step in the binder development process is to build your +binder and run it using your native Linux system. + +**NOTE:** This section assumes using the `helloworld-service` example +and completion of the previous steps in this +"[Building Microservices Natively](./0-build-microservice-overview.html)" +section. + +## Building the Service + +Move to the cloned `helloworld-service` repository and build the service +using either of the following methods: + +* ```bash + cd helloworld-service + ./conf.d/autobuild/linux/autobuild package + ``` + +* ```bash + cd helloworld-service + mkdir build + cd build + cmake .. + make + ``` + +## Running the Service + +You use the Application Framework Binder Daemon (`afb-daemon`) to +bind one instance of an application or service to the rest of the system. +In this example, you are binding an instance of `helloworld-service` +to the rest of the system: + +```bash +afb-daemon --binding helloworld.so --port 3333 --token '' +``` + +The previous command starts `afb-daemon` and loads the `helloworld.so` +binding. +The daemon is now listening on port 3333 of the `localhost`. + +## Testing the Service + +Refer to the +[AGL Test Framework](../../apis_services/#agl-test-framework) topic in the +"APIs & Services" topic. +You can test your `helloworld-service` binding using the `afm-test` tool. + +Examine the generic example describing how to launch the tests suite +[here](../../apis_services/reference/afb-test/3_Launch_the_tests.html). +This example can help you understand how to test your helloworld binding +instance. + +## Using Optional Tools + +Once you have built and run your micro-service successfully using your +native Linux system, you should consider using some additional +development tools: X(Cross) Development System (XDS) and +the Controller Area Network (CAN) Development Studio (CANdevStudio). + +* **XDS:** Cross-compiles and ports your AGL image to your target hardware. +For information on XDS, see the +"[X(cross) Development System: User's Guide](../reference/xds/part-1/xds-overview.html)" +section. + +* **CANdevStudio:** Simulates CAN signals such as ignition status, +doors status, or reverse gear by every automotive developer. +For information on CANdevStudio, see the +"[CANdevStudio Quickstart](../../apis_services/reference/candevstudio/1_Usage.html)" +section. + +## Troubleshooting + +### systemd and/or libmicrohttpd + +If you encounter an error message similar to the following, +you need to make some changes to your `cmake` file: + +```shell +-- Checking for module 'libmicrohttpd>=0.9.60' +-- No package 'libmicrohttpd' found +CMake Error at /usr/share/cmake/Modules/FindPkgConfig.cmake:415 (message): + A required package was not found +Call Stack (most recent call first): + /usr/share/cmake/Modules/FindPkgConfig.cmake:593 (_pkg_check_modules_internal) + conf.d/app-templates/cmake/cmake.d/01-build_options.cmake:92 (PKG_CHECK_MODULES) + conf.d/app-templates/cmake/common.cmake:77 (include) + conf.d/cmake/config.cmake:184 (include) + CMakeLists.txt:3 (include) +``` + +Open the `config.cmake` file located in `helloworld-service/conf.d/cmake/` directory +and add a hash character (i.e. #) to the beginning of the "libsystemd>=222" +and "libmicrohttpd>=0.9.60" strings. +Following is an example of the edits: + +```CMake + set (PKG_REQUIRED_LIST + json-c + #libsystemd>=222 + afb-daemon + #libmicrohttpd>=0.9.60 + ) +``` + +After making these changes, rebuild the service again as described in the +"[Building the Service](./4-getting-source-files.html#building-the-service)" +section previously on this page. diff --git a/docs/3_Developer_Guides/2_Building_Microservices_Natively/pictures/microservice-workflow-native.png b/docs/3_Developer_Guides/2_Building_Microservices_Natively/pictures/microservice-workflow-native.png Binary files differnew file mode 100644 index 0000000..1c38d2a --- /dev/null +++ b/docs/3_Developer_Guides/2_Building_Microservices_Natively/pictures/microservice-workflow-native.png diff --git a/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /1_Overview.md b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /1_Overview.md new file mode 100644 index 0000000..ffb1036 --- /dev/null +++ b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /1_Overview.md @@ -0,0 +1,34 @@ +--- +edit_link: '' +title: Overview +origin_url: >- + https://git.automotivelinux.org/src/cmake-apps-module/plain/docs/dev_guide/cmake-overview.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/cmake-apps-module-guides-devguides-book.yml --> + +# Overview + +The CMake AGL Framework Template Module +helps to build applications or bindings for the +AGL Application Framework. +You can use the template module to easily build a widget and its related +test widget for running on top of the AGL Application Framework. + +This topic consists of the following: + +- [Installing CMake Templates](installing-cmake.html). + +- [Using CMake Templates](using-cmake.html). + +- [Configuring CMake](configuring-cmake.html). + +- [Project Architecture](project-architecture.html). + +- [Advanced Usage](advanced-usage.html). + +- [Advanced Customization](advanced-customization.html). + +- [Autobuild](autobuild.html). + + diff --git a/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /2_Installing CMake Templates.md b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /2_Installing CMake Templates.md new file mode 100644 index 0000000..a2c18d4 --- /dev/null +++ b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /2_Installing CMake Templates.md @@ -0,0 +1,59 @@ +--- +edit_link: '' +title: Installing CMake Templates +origin_url: >- + https://git.automotivelinux.org/src/cmake-apps-module/plain/docs/dev_guide/installing-cmake.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/cmake-apps-module-guides-devguides-book.yml --> + +# Installing CMake Templates + +You can install CMake templates on your native Linux system. + +In order to use the templates, you need to install them as +a CMake module. +On your native Linux system, use your distribution's package manager. +See the +"[Prerequisites](../../2-download-packages.html)" +section for how to install packages using your distribution's package +manager. +Be sure to use the following with you install the packages: + +```bash +export DISTRO="xUbuntu_16.10" +export REVISION=Master +``` + +**NOTE:** In order to use the CMake templates, you must be using the +AGL Guppy release. +You cannot use prior releases. + +## Installing on Debian or Ubuntu + +Use the following command to install AGL's CMake Application Module +on a native Debian or Ubuntu system: + +```bash +sudo apt-get install agl-cmake-apps-module-bin +``` + +## Installing on OpenSUSE + +Use the following command to install AGL's CMake Application Module +on a native OpenSUSE system: + +```bash +sudo zypper install agl-cmake-apps-module +``` + +## Installing on Fedora + +Use the following command to install AGL's CMake Application Module +on a native Fedora system: + +```bash +sudo dnf install agl-cmake-apps-module +``` + + diff --git a/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /3_Using_CMake_Templates.md b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /3_Using_CMake_Templates.md new file mode 100644 index 0000000..3be04e3 --- /dev/null +++ b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /3_Using_CMake_Templates.md @@ -0,0 +1,82 @@ +--- +edit_link: '' +title: Using CMake Templates +origin_url: >- + https://git.automotivelinux.org/src/cmake-apps-module/plain/docs/dev_guide/using-cmake.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/cmake-apps-module-guides-devguides-book.yml --> + +# Using CMake Templates + +You can use CMake templates in a cross-compilation environment +or from BitBake recipes. + +## Using CMake Templates in a Cross-Compilation Environment + +Beginning with the `Grumpy Guppy`, version 7, the CMakeAfbTemplates CMake module +is installed by default in the SDKs supplied by AGL. +Consequently, you do not need to take steps to install the modules. + +Following are links to the latest SDKs on the AGL master branch: + +* [dra7xx-evm](https://download.automotivelinux.org/AGL/snapshots/master/latest/dra7xx-evm/deploy/sdk/) +* [intel-corei7-64](https://download.automotivelinux.org/AGL/snapshots/master/latest/intel-corei7-64/deploy/sdk/) +* [m3ulcb-nogfx](https://download.automotivelinux.org/AGL/snapshots/master/latest/m3ulcb-nogfx/deploy/sdk/) +* [qemux86-64](https://download.automotivelinux.org/AGL/snapshots/master/latest/qemux86-64/deploy/sdk/) +* [raspberrypi3](https://download.automotivelinux.org/AGL/snapshots/master/latest/raspberrypi3/deploy/sdk/) + +## Using CMake Templates from BitBake Recipes + +If you have developed an application and you want to include it in an AGL image, +you must add a BitBake recipe in one of the following layers: + +* [meta-agl](https://gerrit.automotivelinux.org/gerrit/#/admin/projects/AGL/meta-agl): + meta-agl layer (core AGL) +* [meta-agl-cluster-demo](https://gerrit.automotivelinux.org/gerrit/#/admin/projects/AGL/meta-agl-cluster-demo): + cluster demo specific recipes and configuration +* [meta-agl-demo](https://gerrit.automotivelinux.org/gerrit/#/admin/projects/AGL/meta-agl-demo): + meta-agl-demo layer (demo/staging/"one-shot") +* [meta-agl-devel](https://gerrit.automotivelinux.org/gerrit/#/admin/projects/AGL/meta-agl-devel): + meta-agl-devel (Development and Community BSPs) +* [meta-agl-extra](https://gerrit.automotivelinux.org/gerrit/#/admin/projects/AGL/meta-agl-extra): + meta-agl-extra (additional/optional components for AGL) + +Once you have the recipe in place, edit it to include the following +line to cause the `aglwgt` class to be inherited: + +```bb +inherit aglwgt +``` + +Following is an example that uses the HVAC application recipe (i.e. `hvac.bb`), which +builds the HVAC application: + +```bb +SUMMARY = "HVAC Service Binding" +DESCRIPTION = "AGL HVAC Service Binding" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/agl-service-hvac" +SECTION = "apps" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +SRC_URI = "gitsm://gerrit.automotivelinux.org/gerrit/apps/agl-service-hvac;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "${AGL_APP_REVISION}" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git" + +DEPENDS = "json-c" +RDEPENDS_${PN} += "agl-service-identity-agent" + +inherit cmake aglwgt pkgconfig +``` + +The following links provide more examples of recipes that use the +CMake templates: + +* [agl-service-helloworld](https://gerrit.automotivelinux.org/gerrit/admin/repos/apps/agl-service-helloworld) +* [agl-service-audio-4a](https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/agl-service-audio-4a) +* [agl-service-unicens](https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/agl-service-unicens) +* [4a-hal-unicens](https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/4a-hal-unicens) diff --git a/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /4_Configuring_AGL_CMake_Templates.md b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /4_Configuring_AGL_CMake_Templates.md new file mode 100644 index 0000000..2630693 --- /dev/null +++ b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /4_Configuring_AGL_CMake_Templates.md @@ -0,0 +1,147 @@ +--- +edit_link: '' +title: Configuring AGL CMake Templates +origin_url: >- + https://git.automotivelinux.org/src/cmake-apps-module/plain/docs/dev_guide/configuring-cmake.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/cmake-apps-module-guides-devguides-book.yml --> + +# Configuring AGL CMake Templates + +Configuration consists of editing the `config.cmake` file for your +specific project. + +## Creating Your `config.cmake` File + +First, you need to create a `confd/cmake` file in your CMake project +directory. + +```bash +mkdir -p conf.d/cmake +``` + +Next, use one of the following commands to copy a `cmake.sample` file to +your `config.cmake` file. +The first command applies if you have the SDK installed, while the +second command applies if you installed the modules on your native Linux system. + +**NOTE:** The `OECORE_NATIVE_SYSROOT` variable is defined once you have +a project folder, the AGL SDK source files, and the CMake modules installed. + +```bash +mkdir -p conf.d/cmake +# From the SDK sysroot >= RC2 of the 7.0.0 Guppy release +cp ${OECORE_NATIVE_SYSROOT}/usr/share/doc/CMakeAfbTemplates/samples.d/config.cmake.sample conf.d/cmake/config.cmake +# From a native installation +cp /usr/share/doc/CMakeAfbTemplates/samples.d/config.cmake.sample conf.d/cmake/config.cmake +``` + +Once you have created your `config.cmake` file, you need to make the changes +specific to your project. + +## Creating Your `CMakeLists.txt` File + +To create this file, use the example in the **cmake module**. +Use one of the following two commands to create your file. +The first command applies if you have the SDK installed, while the +second command applies if you installed the modules on your native Linux system. + +**NOTE:** The `OECORE_NATIVE_SYSROOT` variable is defined once you have +a project folder, the AGL SDK source files, and the CMake modules installed. + +```bash +# From the SDK sysroot >= RC2 of the 7.0.0 Guppy release +cp ${OECORE_NATIVE_SYSROOT}/usr/share/doc/CMakeAfbTemplates/samples.d/CMakeLists.txt.sample CMakeLists.txt +# From a native installation +cp /usr/share/doc/CMakeAfbTemplates/samples.d/CMakeLists.txt.sample CMakeLists.txt +``` + +## Creating Your CMake Targets + +Creating a CMake target is the result of editing your `CMakeLists.txt` file. + +For each target that is part of your project, you need to use the +***PROJECT_TARGET_ADD*** statement. +Using this statement includes the target in your project. + +Using the ***PROJECT_TARGET_ADD*** statement makes the CMake ***TARGET_NAME*** +variable available until the next ***PROJECT_TARGET_ADD*** statement is +encountered that uses a new target name. + +Following is typical use within the `CMakeLists.txt` file to create a target: + +```cmake +PROJECT_TARGET_ADD(target_name) --> Adds *target_name* to the project. +*target_name* is a sub-folder in the CMake project. + +add_executable/add_library(${TARGET_NAME}.... --> Defines the target sources. + +SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES.... --> Configures the target properties +so they can be used by macros. + +INSTALL(TARGETS ${TARGET_NAME}.... +``` + +## Target Properties + +Target properties are used to determine the nature of the +target and where the target is stored within the package being built. + +Use the **LABELS** property to specify the target type that you want +included in the widget package. +You can choose the following target types: + +Choose between: + +- **BINDING**: A shared library loaded by the AGL Application Framework. +- **BINDINGV2**: A shared library loaded by the AGL Application Framework. + This library must be accompanied by a JSON file named similar to the + *${OUTPUT_NAME}-apidef* of the target, which describes the API with OpenAPI + syntax (e.g: *mybinding-apidef*). + Alternatively, you can choose the name without the extension using the + **set_openapi_filename** macro. + If you use C++, you must set **PROJECT_LANGUAGES** through *CXX*. +- **BINDINGV3**: A shared library loaded by the AGL Application Framework. + This library must be accompanied by a JSON file named similar to the + *${OUTPUT_NAME}-apidef* of the target, which describes the API with OpenAPI + syntax (e.g: *mybinding-apidef*). + Alternatively, you can choose the name without the extension using the + **set_openapi_filename** macro. + If you use C++, you must set **PROJECT_LANGUAGES** through *CXX*. +- **PLUGIN**: A shared library meant to be used as a binding plugin, which + would load the library as a plugin consequently extending its + functionalities. + You should name the binding using a special extension that you choose + with `SUFFIX cmake target property`. + If you do not use the special extension, it defaults to **.ctlso**. +- **HTDOCS**: The root directory of a web application. + This target has to build its directory and puts its files in the + **${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}**. +- **DATA**: Resources used by your application. + This target has to build its directory and puts its files in the + **${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}**. +- **EXECUTABLE**: The entry point of your application executed by the AGL + Application Framework. +- **LIBRARY**: An external third-party library bundled with the binding. + The library is bundled in this manner because the platform does not + provide bundling. +- **BINDING-CONFIG**: Any files used as configuration by your binding. + +**TIP:** you should use the prefix _afb-_ (**Application Framework Binding**) +with your *BINDING* targets. + +Following is an example that uses the **BINDINGV3** property: + +```cmake +SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + PREFIX "afb-" + LABELS "BINDINGV3" + OUTPUT_NAME "file_output_name") +``` + +**CAUTION**: You do not need to specify an **INSTALL** command for these +targets. +Installation is performed by the template. +Targets are installed in the **${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}** +directory. diff --git a/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /5_Project_Architecture.md b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /5_Project_Architecture.md new file mode 100644 index 0000000..6079a3d --- /dev/null +++ b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /5_Project_Architecture.md @@ -0,0 +1,84 @@ +--- +edit_link: '' +title: Project Architecture +origin_url: >- + https://git.automotivelinux.org/src/cmake-apps-module/plain/docs/dev_guide/project-architecture.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/cmake-apps-module-guides-devguides-book.yml --> + +# Project Architecture + +The following tree structure represents a typical CMake project +directory structure: + +```tree +<project-root-path> +| +├── CMakeLists.txt +│ +├── autobuild/ +│ ├── agl +│ │ └── autobuild +│ ├── linux +│ │ └── autobuild +│ └── windows +│ └── autobuild +├── conf.d/ +│ ├── packaging/ +│ │ ├── rpm +│ │ │ └── package.spec +│ │ └── deb +│ │ ├── package.dsc +│ │ ├── debian.package.install +│ │ ├── debian.changelog +│ │ ├── debian.compat +│ │ ├── debian.control +│ │ └── debian.rules +│ ├── cmake +│ │ ├── 00-debian-osconfig.cmake +│ │ ├── 00-suse-osconfig.cmake +│ │ ├── 01-default-osconfig.cmake +│ │ └── config.cmake +│ └── wgt +│ ├── icon.png +│ └── config.xml.in +├── <target> +│ └── <files> +├── <target> +│ └── <file> +└── <target> + └── <files> +``` + +| File or Directory | Parent | Description | +|----|----|----| +| *root_path* | n/a | CMake project root path. Holds the master CMakeLists.txt file and all general project files. +| CMakeLists.txt | The master CMakeLists.txt file. +| autobuild/ | *root_path* | Scripts generated from app-templates to build packages the same way for differents platforms. +| conf.d/ | *root_path* | Holds needed files to build, install, debug, and package an AGL application project. +| packaging/ | conf.d/ | Contains output files used to build packages. +| cmake/ | conf.d/ | Minimally contains the config.cmake file, which is modified from the sample provided in the app-templates submodule. +| wgt/ | conf.d/ | Contains config.xml.in and optionaly the test-config.xml.in template files that are modified from the sample provided with the CMake module for the needs of the project. For more details, see the config.xml.in.sample and test-config.xml.in.sample files. +| *target* | *root_path* | A target to build, which is typically a library or executable. + +When building projects using CMake, the build process automatically detects +the `CMakeLists.txt` and `*.cmake` files. +To help with this process, the `PROJECT_SRC_DIR_PATTERN` variable +is used for recursive pattern searching from the CMake project's +*root_path* downward. +Each sub-folder below *root_path* in the project is searched and included +during compilation. +The directories matching the pattern `PROJECT_SRC_DIR_PATTERN` variable +are scanned. + +**NOTE:** The `PROJECT_SRC_DIR_PATTERN` variable defaults to "*". + +When the `CMakeLists.txt` file is found, the directory in which it is found +is automatically added to the CMake project. + +Similarly, when a file whose extension is `.cmake` is found, the directory in +which that file resides is also added to the CMake project. + + + diff --git a/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /6_Advanced_Usage.md b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /6_Advanced_Usage.md new file mode 100644 index 0000000..3a61b96 --- /dev/null +++ b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /6_Advanced_Usage.md @@ -0,0 +1,316 @@ +--- +edit_link: '' +title: Advanced Usage +origin_url: >- + https://git.automotivelinux.org/src/cmake-apps-module/plain/docs/dev_guide/advanced-usage.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/cmake-apps-module-guides-devguides-book.yml --> + +# Advanced Usage + +This topic describes some advanced ways of using the CMake templates. + +## Building a Widget + +To build a widget, you need a `config.xml` file that describes +your application (widget) and how the Application Framework launches it. +Your repository contains a simple default file named +`config.xml.in` that should work for simple applications and should +not require interactions with other bindings. + +It is also recommended that you use the sample configuration +file that you can find in the location. +This file is named `config.xms.in.sample` and is more complete. +Copy the sample file to your `conf.d/wgt` directory and name it +`config.xml.in`. +Once you have your copy, edit the file to fit your needs. + +**CAUTION:** The default file is only meant to be used for a +simple widget application. +For more complicated applications that need to export +their API, or ship several applications in one widget +need to use the provided `config.xml.in.sample` file, which has +all new Application Framework features explained and provides +examples. + +## Using CMake Template Macros + +To leverage all CMake template features, you must specify properties +on your targets. +Some macros do not work unless you specify the target type. +If you do not specify a type (e.g. a custom target such as an +HTML5 application), the macro uses the `LABELS` property to +determine the target type. + +The `LABELS` property can be set to the values shown in the +[Target Properties](configuring-cmake.html#target-properties) +Section. + +Aside from those values, the following optional values can be +assigned to the `LABELS` property. +These values define the resource types that make up your test materials: + +- **TEST-CONFIG**: JSON configuration files used by the `afb-test` + binding. + These files execute the tests. +- **TEST-DATA**: Resources used to test your binding. + Minimally, you need a test plan. + You should also consider fixtures and any files required by your tests. + These required files appear as part of a separate test widget. +- **TEST-PLUGIN**: A shared library used as a binding plugin. + A binding loads the library as a plugin to extend the binding's functionality. + You should use a special file extension when you name the library + by using the `SUFFIX` CMake target property. + If you do not choose an extension, `.ctlso` is used by default. +- **TEST-HTDOCS**: The root directory of a web application. + This target has to build its directory and put its files in + the `${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}` directory. +- **TEST-EXECUTABLE**: The entry point of your application executed by the AGL + Application Framework. +- **TEST-LIBRARY**: An external third-party library bundled with the binding + for its own purpose. + The platform does not provide this library. + +Following is a mapping between `LABELS` and directories where files reside in +the widget: + +- **EXECUTABLE** : \<wgtrootdir\>/bin +- **BINDING-CONFIG** : \<wgtrootdir\>/etc +- **BINDING** | **BINDINGV2** | **BINDINGV3** | **LIBRARY** : \<wgtrootdir\>/lib +- **PLUGIN** : \<wgtrootdir\>/lib/plugins +- **HTDOCS** : \<wgtrootdir\>/htdocs +- **BINDING-DATA** : \<wgtrootdir\>/var +- **DATA** : \<wgtrootdir\>/var + +Following is a mapping between test-dedicated `LABELS` and directories where +files reside in the widget: + +- **TEST-EXECUTABLE** : \<wgtrootdir\>/bin +- **TEST-CONFIG** : \<TESTwgtrootdir\>/etc +- **TEST-PLUGIN** : \<wgtrootdir\>/lib/plugins +- **TEST-HTDOCS** : \<wgtrootdir\>/htdocs +- **TEST-DATA** : \<TESTwgtrootdir\>/var + +**TIP:** Use the prefix `afb-` (Application Framework Binding) +with your **BINDING** targets. + +Following is an example that sets the `LABELS` and `OUTPUT_NAME` properties: + +```cmake +SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + LABELS "HTDOCS" + OUTPUT_NAME dist.prod + ) +``` + +**NOTE**: You do not need to specify an **INSTALL** command for these + targets. + Installation is handled by the template and installs using the + following path : **${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}** + + Also, if you want to set and use `rpath` with your target, you should use + and set the target property `INSTALL_RPATH`. + +## Adding an External Third-Party Library + +You can add an external third-party library that is built, linked, +and shipped with the project. +Or, you can link and ship the library only with the project. + +### Building, Linking, and Shipping an External Library with the Project + +If you need to include an external library that is not shipped +with the project, you can bundle the required library in the +`lib` widget directory. + +Templates includes facilities to help you work with external +libraries. +A standard method is to declare as many CMake ExternalProject +modules as you need to match the number of needed libraries. + +An ExternalProject module is a special CMake module that lets you define how +to download, update, patch, configure, build, and install an external project. +The project does not need to be a CMake project. +Additionally, you can provide custom steps to account for special +needs using ExternalProject step. +See the CMake +[ExternalProject documentation site](https://cmake.org/cmake/help/v3.5/module/ExternalProject.html?highlight=externalproject) +for more information. + +Following is an example that includes the `mxml` library for the +[unicens2-binding](https://github.com/iotbzh/unicens2-binding) +project: + +```cmake +set(MXML external-mxml) +set(MXML_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mxml) +ExternalProject_Add(${MXML} + GIT_REPOSITORY https://github.com/michaelrsweet/mxml.git + GIT_TAG release-2.10 + SOURCE_DIR ${MXML_SOURCE_DIR} + CONFIGURE_COMMAND ./configure --build x86_64 --host aarch64 + BUILD_COMMAND make libmxml.so.1.5 + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "" +) + +PROJECT_TARGET_ADD(mxml) + +add_library(${TARGET_NAME} SHARED IMPORTED GLOBAL) + +SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + LABELS LIBRARY + IMPORTED_LOCATION ${MXML_SOURCE_DIR}/libmxml.so.1 + INTERFACE_INCLUDE_DIRECTORIES ${MXML_SOURCE_DIR} +) + +add_dependencies(${TARGET_NAME} ${MXML}) +``` + +The example defines an external project that drives the building of the library. +The example also defines a new CMake target whose type is **IMPORTED**. +The **IMPORTED** target type indicates the target has yet to be built using +CMake but is available at the location defined using the **IMPORTED_LOCATION** +target property. + +You might want to build the library as **SHARED** or **STATIC** depending on your needs +and goals. +Next, the example only has to modify the external project configure step and change +the filename used by **IMPORTED** library target defined after external project. + +The target's **LABELS** property is set to **LIBRARY** to ship it in the widget. + +In this example, the Unicens project also needs header +information from this library. +Consequently, the **INTERFACE_INCLUDE_DIRECTORIES** target property +is used. +Setting that property when another target links to that imported target +allows access to included directories. + +Finally, the example binds the target to the external project +by using a CMake dependency. + +The target can now be linked and used like any other CMake target. + +### Link and Ship an External Library with the Project + +If you already have a binary version of the library that you want to use and you +cannot or do not want to build the library, you can use the **IMPORTED** +library target. + +To illustrate, consider the same example in the previous section. +Following are the relevant modifications: + +```cmake +PROJECT_TARGET_ADD(mxml) + +add_library(${TARGET_NAME} SHARED IMPORTED GLOBAL) + +SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + LABELS LIBRARY + IMPORTED_LOCATION /path_to_library/libmxml.so.1 + INTERFACE_INCLUDE_DIRECTORIES /path_to_mxml/include/dir +) +``` + +In the previous example, notice the changes to the +`IMPORTED_LOCATION` and `INTERFACE_INCLUDE_DIRECTORIES` statements. +These locate the binary version of the library. + +Finally, you can link any other library or executable target with this imported +library just as you would for any other target. + +## Macro Reference + +Following are several macros that are useful for advanced CMake usage. + +### PROJECT_TARGET_ADD + +This macro adds the target to your project. +Following is a typical example that adds the target to your project. +You need to provide the name of your target as the macro's parameter: + +Example: + +```cmake +PROJECT_TARGET_ADD(low-can-demo) +``` + +The macro makes the variable `${TARGET_NAME}` available and it is defined +using the specified name (e.g. `low-can-demo`). +The variable changes each time the `PROJECT_TARGET_ADD` macro is called. + +### project_subdirs_add + +This macro searches within specified subfolders of the CMake project for +any `CMakeLists.txt` file. +If the file is found, it is added to your project. +You can use this macro in a hybrid application (e.g. where the binding +exists in a subfolder). + +The following example searches within all subfolders: + +Usage : + +```cmake +project_subdirs_add() +``` + +You might want to restrict the subfolders being searched. +If so, you can specify a +[globbing](https://en.wikipedia.org/wiki/Glob_(programming)) pattern +as the argument. +Doing so effectively creates a search filter. + +Following is an example that specifies all directories that begin +with a number, are followed by the dash character, and then followed +by any characters: + +```cmake +project_subdirs_add("[0-9]-*") +``` + +### set_openapi_filename + +This macro is used with a **BINDINGV2** target and defines the +binding definition filename. +You can use it to also define a relative path to +the current `CMakeLists.txt` file. + +If you do not use this macro to specify the name of your definition file, +the default one is used, which is `${OUTPUT_NAME}-apidef` and uses +**OUTPUT_NAME** as the [target property]. + +**CAUTION** When specifying the binding definition filename, +you must not use the file's extension as part of the name. +Following is an example: + +```cmake +set_openapi_filename('binding/mybinding_definition') +``` + +[target property]: https://cmake.org/cmake/help/v3.6/prop_tgt/OUTPUT_NAME.html "OUTPUT_NAME property documentation" + +### add_input_files + +This macro creates a custom target dedicated for HTML5 and data resource files. +The macro provides syntax and schema verification for different languages that +include LUA, JSON and XML. + +Alongside the macro are tools used to check files. +You can configure the tools by setting the +following variables: + +- XML_CHECKER: Uses **xmllint** that is provided with major linux distributions. +- LUA_CHECKER: Uses **luac** that is provided with major linux distributions. +- JSON_CHECKER: Currently, not used by any tools. + +Following is an example: + +```cmake +add_input_file("${MY_FILES_LIST}") +``` + +**NOTE**: If an issue occurs during the "check" step of the macro, +the build halts. diff --git a/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /7_Advanced_Customization.md b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /7_Advanced_Customization.md new file mode 100644 index 0000000..88f8c15 --- /dev/null +++ b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /7_Advanced_Customization.md @@ -0,0 +1,123 @@ +--- +edit_link: '' +title: Advanced Customization +origin_url: >- + https://git.automotivelinux.org/src/cmake-apps-module/plain/docs/dev_guide/advanced-customization.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/cmake-apps-module-guides-devguides-book.yml --> + +# Advanced Customization + +Beyond the configurations described in the +[Configuring CMake Templates](configuring-cmake.html) section, +you can provide some advanced configurations. + +This section describes how you can include additional CMake files +and custom template scripts. + +## Including Additional CMake Files + +You can include machine and system custom CMake files and +operating system custom CMake files. + +### Machine and System Custom CMake Files + +Advanced configuration is possible by automatically including +additional CMake files from specific locations. +Following are the locations from which you can add CMake +files. +Inclusions occur in the order shown here: + +- `<project-root-path>/conf.d/app-templates/cmake/cmake.d` - normally located CMake project files +- `$HOME/.config/app-templates/cmake.d` - the home location +- `/etc/app-templates/cmake.d` - the system location + +The CMake files you include must be named using either of the following conventions: + +- `XX-common*.cmake` +- `XX-${PROJECT_NAME}*.cmake` + +In both formats, `XX` are numbers and indicate the order in which the file +is included. +The `*` character represents the filename. + +When naming the file, consider the projects in which the file needs to be +included. +If you want to include the file in all projects, use the keyword `common`. +If you want to include the file in a specific project, use the `${PROJECT_NAME}` +value. + +For example, if you want a CMake file whose name is `my_custom_file` +included first and you want it included in all projects, name the file +`01-common-my_custom_file.cmake`. +If you want the same file included in a single project defined by the +`PROJECT_NAME` variable, and you want it included after all other files, +name the file `99-${PROJECT_NAME}-my_custom_file.cmake`. + +When you include CMake files that use CMake variables, the values override +variables with the same name. +The exception to this rule is if you use a cached variable. +Following is an example: + +```cmake +set(VARIABLE_NAME 'value string random' CACHE STRING 'docstring') +``` + +In this example, the `VARIABLE_NAME` variable is defined as a cached +variable by using the **CACHE** keyword. +Consequently, `VARIABLE_NAME` does not get overridden as a result of +including a CMake file that sets the same variable. + +### Operating System Custom CMake Files + +Including custom CMake files based on the operating system +lets you personalize a project depending on the operating system +you are using. + +At the end of the `config.cmake` file `common.cmake` includes +CMake files to customize your project build depending on your platform. +The operating system is detected by using `/etc/os-release`, +which is the default method used in almost all Linux distributions. +Consequently, you can use the value of field **ID_LIKE** to +add a CMake file for that distribution. +The file comes from your `conf.d/cmake/` directory or relatively +from your `app-templates` submodule path `app-templates/../cmake/`. + +**NOTE:** If the **ID_LIKE** field does not exist, you can use the +**ID** field. + +Files that you add must be named according to the following file naming +convention: + +- `XX-${OSRELEASE}*.cmake` + +In the naming convention, `XX` represents numbers and is the order in which +you want a file included. +The ${OSRELEASE} value is taken from either the **ID_LIKE** or **ID** field +of the `/etc/os-release` file. + +You can also configure a CMake file to be included in cases where no +specific operating system can be found. +To do so, name your CMake file as follows: + +- `XX-default*.cmake` + +A good use case example for these two naming conventions is when you have +a several Linux distributions and all but one can use the same module. +For that case, name one CMake file using the `${OSRELEASE}` value and +name the CMake file to be used with the other distributions using +the `XX-default*.cmake` method. + +## Including Custom Template Scripts + +You can include your own custom template scripts that are passed to the +CMake command `configure_file`. + +Just create your own script and place it in either of the following directories: + +- `$HOME/.config/app-templates/scripts` - the home location +- `/etc/app-templates/scripts` - the system location + +Scripts only need to use the extension `.in` to be parsed and configured by +CMake. diff --git a/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /8_Autobuild.md b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /8_Autobuild.md new file mode 100644 index 0000000..6c02d1b --- /dev/null +++ b/docs/3_Developer_Guides/3_Using_the_CMAKE_Applications_Module /8_Autobuild.md @@ -0,0 +1,159 @@ +--- +edit_link: '' +title: Autobuild +origin_url: >- + https://git.automotivelinux.org/src/cmake-apps-module/plain/docs/dev_guide/autobuild.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/cmake-apps-module-guides-devguides-book.yml --> + +# Autobuild + +Applications based on the AGL framework should have a +full build and packaging solution that is independent of the +[Yocto Project](https://www.yoctoproject.org) workflow. + +You can create a script named **autobuild** to control applications +build operations. +AGL provides a BitBake class file (`aglwgt.bbclass`) that calls the +**autobuild** script for all operations. +The class file is located at the top level of the application repository. + +You can write the **autobuild** script using any of the following languages: + +* Makefile +* Bash +* Python + +The script executes directly after applying a `chmod()` command. +The caller, which can be the `aglwgt.bbclass`, a Jenkins job, or an actual person, +must make the **autobuild** executable before calling it. +To facilitate direct execution, you need to start the script with a +[shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) sequence: + +* '#!/usr/bin/make -f' for Makefile format +* '#!/usr/bin/bash' for Bash format + +The calling convention is similar to the convention used in `make`. +To pass arguments, use environment variables. + +**NOTE:** For Bash, an evaluation of the arguments +sets the environment variables correctly. + +The following format shows the generic call: + +```bash +autobuild/agl/autobuild <command> [ARG1="value1" [ARG2="value2" ... ]] +``` + +The **autobuild** script can be invoked from any directory +with all paths considered to be relative to the +script's location. +For makefile scripts, this is the usual behavior. +For Bash scripts, a `cd $(dirname $0)` command must be run at +the beginning of the script. + +At build time, the following calls must be made in the following order: + +1. Initialize the build environment (e.g if the application uses + `cmake` the configure step runs CMake). + + ```bash + autobuild/agl/autobuild configure CONFIGURE_ARGS="..." + ``` + +2. Build the application (i.e. compile, link binaries, assembles javascript, + and so forth). + + ```bash + autobuild/agl/autobuild build BUILD_ARGS="...." + ``` + +3. Create the widget package(s) in the specified destination path + prepared by the caller. + + ```bash + autobuild/agl/autobuild package PACKAGE_ARGS="..." DEST=<path-for-resulting-wgt-files> + ``` + +4. Create the test widget package(s) in the specified destination path + prepared by the caller. + + ```bash + autobuild/agl/autobuild package-test PACKAGE_ARGS="..." DEST=<path-for-resulting-wgt-files> + ``` + +5. Clean the built files by removing the result of the **autobuild** build. + + ```bash + autobuild/agl/autobuild clean CLEAN_ARGS="..." + ``` + +6. Clean everything by removing the result of the **autobuild** build + and the **autobuild** configure. + + ```bash + autobuild/agl/autobuild distclean DISTCLEAN_ARGS="..." + ``` + +## Integrating **autobuild** into the Yocto Project Workflow + +If you want to integrate the **autobuild** script into the Yocto Project +workflow, you need to generate the script. +To generate the script, use the `autobuild` target. + +The following commands create the **autobuild** script in the +`autobuild/agl` directory: + +```bash +mkdir -p build +cd build +cmake .. && make autobuild +``` + +## Available Targets + +Following are the targets available from the **autobuild** script: + +- **clean**: Removes all the object files and target results generated by Makefile. +- **clean-{release,debug,coverage,test}**: Removes all the object files and target results generated by Makefile for the specified build type. +- **clean-all**: Deletes the build directories for all build types. +- **distclean**: Deletes the build directories for all build types. +- **configure**: Generates the project Makefile from the `CMakeLists.txt` files for the release build type. +- **configure-{release,debug,coverage,test}**: Generates the project Makefile from the `CMakeLists.txt` files for the specified build type. +- **build**: Compiles all project targets for the release build type. +- **build-{release,debug,coverage,test}**: Compiles all project targets for the specified build type. +- **build-all**: Compiles all project targets for all specified build types. +- **package**: Builds the widget (**wgt**) package for the release build type. +- **package-{release,debug,coverage}**: Builds the widget (**wgt**) package for the specified build type. +- **package-test**: Builds the test **wgt** package. +- **package-all**: Builds the widget (**wgt**) packages for all build types. +- **install**: Installs the project into your filesystem. + +Note that `aglwgt.bbclass` only will use the **package-{coverage,test}** targets (and thus the **build-{coverage,test}**, etc. targets) for service bindings by default, so **autobuild** scripts for applications may omit support for those. + +Specifying the following variables lets you modify compilation behavior: + +- **CLEAN_ARGS**: Variable used at **clean** time. +- **CONFIGURE_ARGS**: Variable used at **configure** time. +- **BUILD_ARGS**: Variable used at **build** time. +- **BUILD_DIR**: Build directory for release type build. + The default value is a "build" directory in the root of the project. +- **BUILD_DIR_DEBUG**: Build directory for debug type build. + The default value is a "build-debug" directory in the root of the project. +- **BUILD_DIR_TEST**: Build directory for test type build. + The default value is a "build-test" directory in the root of the project. +- **BUILD_DIR_COVERAGE**: Build directory for coverage type build. + The default value is a "build-coverage" directory in the root of the project. +- **DEST**: Directory in which to place the created ***wgt*** file(s). + The default directory is the build root directory. + +Note that the values of **BUILD_DIR_{DEBUG,TEST,COVERAGE}** are defined based on the value of **BUILD_DIR**, so this needs to be kept in mind if over-riding it and building those other widget types. + +When you provide a variable, use the CMake format (i.e. +BUILD_ARGS="-DC_FLAGS='-g -O2'"). +Following is an example: + +```bash +./autobuild/agl/autobuild package DEST=/tmp +``` diff --git a/docs/3_Developer_Guides/4_AppFW_-_Privileges_Management/03-AGL-AppFW-Privileges-Management.pdf b/docs/3_Developer_Guides/4_AppFW_-_Privileges_Management/03-AGL-AppFW-Privileges-Management.pdf Binary files differnew file mode 100644 index 0000000..d468610 --- /dev/null +++ b/docs/3_Developer_Guides/4_AppFW_-_Privileges_Management/03-AGL-AppFW-Privileges-Management.pdf diff --git a/docs/3_Developer_Guides/4_AppFW_-_Privileges_Management/3.5_AppFW_-_Privileges_Management.md b/docs/3_Developer_Guides/4_AppFW_-_Privileges_Management/3.5_AppFW_-_Privileges_Management.md new file mode 100644 index 0000000..a467085 --- /dev/null +++ b/docs/3_Developer_Guides/4_AppFW_-_Privileges_Management/3.5_AppFW_-_Privileges_Management.md @@ -0,0 +1 @@ +[**3.5 AppFW - Privileges Management**](03-AGL-AppFW-Privileges-Management.pdf) diff --git a/docs/3_Developer_Guides/5_Controller_Guides/3.6.1_Installation.md b/docs/3_Developer_Guides/5_Controller_Guides/3.6.1_Installation.md new file mode 100644 index 0000000..0234269 --- /dev/null +++ b/docs/3_Developer_Guides/5_Controller_Guides/3.6.1_Installation.md @@ -0,0 +1,84 @@ +--- +edit_link: '' +title: Installation +origin_url: >- + https://git.automotivelinux.org/src/libappcontroller/plain/docs/controller.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/libappcontroller-guides-devguides-book.yml --> + +# Controller + +* Object: Generic Controller to handle Policy,Small Business Logic, Glue in between components, ... +* Status: Release Candidate +* Author: Fulup Ar Foll fulup@iot.bzh +* Date : May-2018 +* Require : af-binder version >= FF (handle only bindings v3) + +## Features + +* Create a controller application from a JSON config file +* Each control (eg: navigation, multimedia, ...) is a suite of actions. When all actions succeed + control is granted, if one fails control access is denied. +* Actions can either be: + * Invocation of an other binding API, either internal or external (eg: a policy service, Alsa UCM, ...) + * C routines from a user provided plugin (eg: policy routine, proprietary code, ...) + * Lua script function. Lua provides access to every AGL appfw functionality and can be extended by + plugins written in C. + +## Installation + +* Controller can easily be included as a separate library in any AGL service or application binder. +* Dependencies: the only dependencies are [AGL application framework](https://gerrit.automotivelinux.org/gerrit/p/src/app-framework-binder.git) + and [libafb-helpers](https://gerrit.automotivelinux.org/gerrit/p/src/libafb-helpers.git). +* Controller relies on Lua-5.3, when not needed Lua might be removed at compilation time. + +The controller library is integrated by default in the AGL SDK since the Guppy +version (>=7) and is also available as a package for the AGL supported linux +distributions. + +You could find the SDK build from Yocto which embed the afb-helpers library +here: + +* For [releases](https://download.automotivelinux.org/AGL/release/) >= Guppy, in + the latest machine's deploy directory. (e.g for Guppy in + `latest/<yourmachine>/deploy/sdk` directory) +* For the [master](https://download.automotivelinux.org/AGL/snapshots/master/) + development branch, in the latest machine's deploy directory. (e.g in + `latest/<yourmachine>/deploy/sdk` directory) + +To install the native package please refer to [this chapter](../1-verify-build-host.html) +in the AGL documentation to install the AGL repository for your distribution. + +Then use your package manager to install the library. + +### OpenSuse + +```bash +sudo zypper ref +sudo zypper install agl-libappcontroller-devel +``` + +### Fedora + +```bash +sudo dnf ref +sudo dnf install agl-libappcontroller-devel +``` + +### Ubuntu/Debian + +```bash +sudo apt-get update +sudo apt-get install agl-libappcontroller-dev +``` + +## Monitoring + +* The default test HTML page expect the monitoring HTML page to be accessible under /monitoring with + the --monitoring option. +* The monitoring HTML pages are installed with the app framework binder in a subdirectory called + monitoring. +* You can add other HTML pages with the alias options e.g: + afb-daemon --port=1234 --monitoring --alias=/path1/to/htmlpages:/path2/to/htmlpages --ldpaths=. --workdir=. --roothttp=../htdocs +* The monitoring is accessible at http://localhost:1234/monitoring. diff --git a/docs/3_Developer_Guides/5_Controller_Guides/3.6.2_Controller_Configuration.md b/docs/3_Developer_Guides/5_Controller_Guides/3.6.2_Controller_Configuration.md new file mode 100644 index 0000000..cbb2d57 --- /dev/null +++ b/docs/3_Developer_Guides/5_Controller_Guides/3.6.2_Controller_Configuration.md @@ -0,0 +1,250 @@ +--- +edit_link: '' +title: Controller Configuration +origin_url: >- + https://git.automotivelinux.org/src/libappcontroller/plain/docs/controllerConfig.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/libappcontroller-guides-devguides-book.yml --> + +# Controller binding configuration + +By default the controller searches for a config filename with the same 'middlename' as the daemon process. As an example if your process name is afb-daemon then middle name is 'daemon'. In addition, if your process name is afb-daemon-audio the middle name is also 'daemon'. Moreover the prefix is chosen when you call the [CtlConfigSearch](<#4)_Do_controller_config_parsing_at_binding_pre-init>) function, see below: + +```bash +CtlConfigSearch(AFB_ApiT apiHandle, const char *dirList, const char *prefix) +``` + +```bash +# Middlename is taken from process middlename. +(prefix-)middlename*.json +``` + +You may overload the config search path with environment variables + +* **CONTROL_CONFIG_PATH**: change default reserch path for configuration. You may provide multiple directories separated by ':'. +* **CONTROL_LUA_PATH**: same as CONTROL_CONFIG_PATH but for Lua script files. + +Example: to load a config named '(prefix-)myconfig-test.json' do + +```bash +afb-daemon --name myconfig --verbose ...' +``` + +The configuration is loaded dynamically during startup time. The controller scans **CONTROL_CONFIG_PATH** for a file corresponding to the pattern +"(prefix-)bindermiddlename*.json". The first file found in the path is loaded, +any other file corresponding to the same path is ignored and only generates a warning. + +Each block in the configuration file is defined with + +* **uid**: mandatory, it is used either for debugging or as input for the action (eg: signal name, control name, ...) +* **info**: optional, it is used for documentation purpose only + +> **Note**: by default the controller config search path is defined at compilation time, but the path might be overloaded with the **CONTROL_CONFIG_PATH** +> environment variable. + +## Config is organised in sections + +* **metadata**: describes the configuration +* **plugins or resources**: defines the set of functions provided by the plugins allowing to load additionnal resources (compiled C or lua) +* **onload**: a collection of actions meant to be executed at startup time +* **control**: sets the controls with a collection of actions, in dynamic api it could also specify the verbs of the api +* **event**: a collection of actions meant to be executed when receiving a given signal +* **personnal sections**: personnal section + +Callbacks to parse sections are documented in [Declare your controller config section in your binding](./Usage.html#declare-your-controller-config-section-in-your-binding) section. You can use the callback defined in controller or define your own callback. + +## Metadata + +As today matadata is only used for documentation purpose. + +* **uid**: mandatory +* **version**: mandatory +* **api**: mandatory +* **info**: optional +* **require**: optional +* **author**: optional +* **date**: optional + +## OnLoad section + +Onload section defines startup time configuration. Onload may provide multiple initialisation +profiles, each with a different uid. + +You can define the following keys or arrays of the following keys: + +* **uid**: mandatory. +* **info**: optional +* **action**: mandatory +* **args**: optionnal + +## Control section + +Control section defines a list of controls that are accessible. + +You can define the following keys or arrays of the following keys, moreover +this section could be verb api: + +* **uid**: mandatory +* **info**: optional +* **action**: the list of actions is mandatory + +## Event section + +Event section defines a list of actions to be executed on event reception. Event can do +anything a controller can (change state, send back signal, ...) +eg: if a controller subscribes to vehicle speed, then speed-event may adjust +master-volume to speed. + +You can define the following keys or arrays of the following keys, moreover you can define an event from an another API with the following syntax "API/event". + +* **uid**: mandatory +* **info**: optional +* **action**: the list of actions is mandatory + +## Plugin section + +Plugin section defines plugins used with this controller. A plugin is a C/C++ program meant to +execute some tasks after an event or on demand. This easily extends intrinsec +binding logic for ad-hoc needs. + +You can define the following keys or arrays of the following keys: + +* **uid**: mandatory +* **info**: optionnal +* **spath**: optionnal, semicolon separated paths where to find the plugin. This could be a compiled shared library or LUA scripts. Could be specified using CONTROL_PLUGIN_PATH environment variable also. +* **libs**: mandatory, Plugin file or LUA scripts to load +* **lua**: optionnal, C functions that could be called from a LUA script + +## Personnal sections + +* **uid**: mandatory +* **info**: optionnal +* **action**: mandatory +* **any keys wanted**: optionnal + +You can define your own sections and add your own callbacks into the +CtlSectionT structure, see +[Declare your controller config section in your binding](<#3_Declare_your_controller_config_section_in_your_binding>) section. + +## Actions Categories + +Controller supports three categories of actions. Each action returns a status +where 0=success and 1=failure. + +* **AppFw API** provides a generic model to request other bindings. Requested bindings can be local (eg: ALSA/UCM) or external (eg: vehicle signalling). + * `"action": "api://API_NAME#verb_name"` +* C-API, when defined in the onload section, the plugin may provide C native API with `CTLP-CAPI(apiname, uid, args, query, context)`. Plugin may also create Lua command with `CTLP-LUA2C(LuaFuncName, uid, args, query, context)`. Where `args`+`query` are JSON-C object and context is the returned value from `CTLP_ONLOAD` function. Any missing value is set to NULL. + * `"action": "plugin://plugin_name#function_name"` +* Lua-API, when compiled with Lua option, the controller supports action defined directly in Lua script. During "*onload*" phase, the controller searches in `CONTROL_LUA_PATH` file with pattern "(prefix-)bindermiddlename*.lua". Any file corresponding to this pattern is automatically loaded. Any function defined in those Lua scripts can be called through a controller action. Lua functions receive three parameters (uid, args, query). + * `"action": "lua://plugin_name#function_name"` + +You also can add the **privileges** property that handles AGL permission +needed to be able to call this action. + +> **Note**: Lua added functions are systematically prefixed. AGL standard AppFw +functions are prefixed with AGL: (eg: AFB:notice(), AFB:success(), ...). +> User Lua functions added through the plugin and CTLP_LUA2C are prefixed with +the plugin uid or the one you defined in your config (eg: MyPlug:HelloWorld1). + +## Available Application Framework Commands + +Each Lua AppFw commands should be prefixed by AFB: + +* `AFB:notice ("format", arg1,... argn)` directly printed LUA tables as json string with '%s'. + `AFB:error`, `AFB:warning`, `AFB:info`, `AFB:debug` work on the same model. Printed messages are limited to 512 characters. + +* `AFB:service ('API', 'VERB', {query}, "Lua_Callback_Name", {context})` is an asynchronous call to another binding. When empty, query/context should be set to '{}' + and not to 'nil'. When 'nil', Lua does not send 'NULL' value but removes arguments to calling stack. WARNING:"Callback" + is the name of the callback as a string and not a pointer to the callback. (If someone as a solution to fix this, please + let me known). Callback is call as LUA "function Alsa_Get_Hal_CB (error, result, context)" where: + * error is a Boolean + * result is the full answer from AppFw (do not forget to extract the response) + * context is a copy of the Lua table pass as an argument (warning it's a copy not a pointer to original table) + +* `error,result=AFB:servsync('API', 'VERB', {query})` is saved as previous but for synchronous call. Note that Lua accepts multiple + returns. AFB:servsync returns both the error message and the response as a Lua table. Like for AFB:service, the user should not + forget to extract response from result. + +* `AFB:success(request, response)` is the success request. request is the opaque handle passes when Lua is called from (api="control", verb="docall"). + Response is a Lua table that will be returned to the client. + +* `AFB:fail(request, response)` is the same as for success. Note that LUA generates automatically the error code from Lua function name. + The response is transformed into a json string before being returned to the client. + +* `EventHandle=AFB:evtmake("MyEventName")` creates an event and returns the handle as an opaque handle. Note that due to a limitation + of json_object, this opaque handle cannot be passed as an argument in a callback context. + +* `AFB:subscribe(request, MyEventHandle)` subscribes a given client to a previously created event. + +* `AFB:evtpush (MyEventHandle, MyEventData)` pushes an event to every subscribed client. MyEventData is a Lua table that will be + sent as a json object to the corresponding clients. + +* `timerHandle=AFB:timerset (MyTimer, "Timer_Test_CB", context)` initialises a timer from MyTimer Lua table. This table should contains 3 elements: + MyTimer={[l"abel"]="MyTimerName", ["delay"]=timeoutInMs, ["count"]=nBOfCycles}. Note that if count==0 then timer is cycled + infinitely. Context is a standard Lua table. This function returns an opaque handle to be used to further control the timer. + +* `AFB:timerclear(timerHandle)` kills an existing timer. Returns an error when timer does not exit. + +* `MyTimer=AFB:timerget(timerHandle)` returns uid, delay and count of an active timer. Returns an error when timerHandle does not + point on an active timer. + +* `AFB:GetEventLoop()` retrieves the common systemd's event loop of AFB. + +* `AFB:RootDirGetFD()` gets the root directory file descriptor. This file descriptor can be used with functions 'openat', 'fstatat', ... + +> **Note**: Except for functions call during binding initialisation period. Lua calls are protected and should returned clean messages +> even when they are improperly used. If you find bug please report. + +## Adding Lua command from User Plugin + +User Plugin is optional and may provide either native C-action accessible directly from controller actions as defined in +JSON config file, or alternatively may provide a set of Lua commands usable inside any script (onload, control,event). A simple +plugin that provides both notice C API and Lua commands is provided as example (see ctl-plugin-sample.c). Technically a +plugin is a simple sharelibrary and any code fitting in sharelib might be used as a plugin. Developer should nevertheless +not forget that except when no-concurrency flag was at binding construction time, any binding should to be thread safe. + +A plugin must be declared with `CTLP_REGISTER("MyCtlSamplePlugin")`. This entry point defines a special structure that is checked +at plugin load time by the controller. Then you have an optional init routine declare with `CTLP_ONLOAD(plugin, handle)`. + The init routine may create +a plugin context that is later presented to every plugin API, this for both LUA and native C ones. Then each: + +* C API declare with `CTLP_CAPI(MyCFunction, source, argsJ, queryJ) {your code}`. Where: + * **MyFunction** is your function + * **source** is the structure config + * **argsJ** a json_object containing the argument attaches to this control in JSON config file + * **queryJ** a json_object + +* Lua API declare with `CTLP_LUA2C(MyLuaCFunction, source, argsJ, responseJ) {your code}`. Where + * **MyLuaCFunction** is both the name of your C function and Lua command + * **source** is the structure config + * **argsJ** the arguments passed this time from Lua script and not from Json config file. + * **responseJ** if success the argument is passed into the request. + +> **Warning**: Lua samples use with controller enforce strict mode. As a result every variable should be declared either as +> local or as global. Unfortunately "luac" is not smart enough to handle strict mode at build time and errors only appear +> at run time. Because of this strict mode every global variables (which include functions) should be prefixed by '_'. +> Note that LUA requires an initialisation value for every variables and declaring something like "local myvar" will not +> allocate "myvar". + +## Debugging Facilities + +Controller Lua scripts are checked for syntax from CMAKE template with Luac. When needed to go further, a developer API should be allowed to +execute directly Lua commands within the controller context from Rest/Ws (api=control, verb=lua_doscript). DoScript API takes two +other optional arguments func=xxxx where xxxx is the function to execute within Lua script and args, a JSON object to provide +input parameters. When funcname is not given by default, the controller tries to execute middle filename doscript-xxxx-????.lua. + +When executed from the controller, Lua script may use any AppFw Apis as well as any L2C user defines commands in plugin. + +## Running as Standalone Controller + +The controller is a standard binding. It can be started with the following command: + +```bash +afb-daemon --name=yourname --port=1234 --workdir=. --roothttp=./htdocs --tracereq=common --token= --verbose --binding=pathtoyourbinding.so --monitoring +``` + +Afb-Daemon only loads controller bindings without searching for the other +binding. In this case, the controller binding will search for a configuration file +name '(prefix-)bindermiddlename*.json'. This model can be used to implement for testing +purpose or simply to act as the glue between a UI and other binder/services. diff --git a/docs/3_Developer_Guides/5_Controller_Guides/3.6.3_Usage.md b/docs/3_Developer_Guides/5_Controller_Guides/3.6.3_Usage.md new file mode 100644 index 0000000..b28d8b2 --- /dev/null +++ b/docs/3_Developer_Guides/5_Controller_Guides/3.6.3_Usage.md @@ -0,0 +1,196 @@ +--- +edit_link: '' +title: Usage +origin_url: >- + https://git.automotivelinux.org/src/libappcontroller/plain/docs/Usage.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/libappcontroller-guides-devguides-book.yml --> + +# Usage + +## Add libappcontroller as a static library to your binding + +In your `config.cmake` file, add a dependency to the controller library, i.e: + +```cmake +set(PKG_REQUIRED_LIST + json-c + afb-daemon + appcontroller --> this is the controller library dependency name. +) +``` + +Or you can also use the [FIND_PACKAGE](https://cmake.org/cmake/help/v3.6/command/find_package.html?highlight=find_package) +CMake command to add it. + +## Declare your controller config section in your binding + +```C +// CtlSectionT syntax: +// key: "section name in config file" +// loadCB: callback to process section +// handle: a void* pass to callback when processing section +static CtlSectionT ctlSections[]= { + {.key="plugins" , .loadCB= PluginConfig, .handle= &halCallbacks}, + {.key="onload" , .loadCB= OnloadConfig}, + {.key="halmap" , .loadCB= MapConfigLoad}, + {.key=NULL} +}; + +``` + +## Do the controller config parsing at binding pre-init + +```C + // check if config file exist + const char *dirList= getenv("CTL_CONFIG_PATH"); + if (!dirList) dirList=CONTROL_CONFIG_PATH; + + const char *configPath = CtlConfigSearch(apiHandle, dirList, "prefix"); + if(!confiPath) return -1; + + ctlConfig = CtlConfigLoad(dirList, ctlSections); + if (!ctlConfig) return -1; +``` + +## Execute the controller config during binding init + +```C + int err = CtlConfigExec (ctlConfig); +``` + +## (Optional) Migrate from the git submodule version + +### Remove the git submodule version + +If you already use the controller component but use the submodule version then +you have to get rid of it to be sure to link and use the library version. To do +so, you have to do the following: + +* deinitialize the submodule using `git` + +```bash +# This example assumes that the git submodule is named app-controller-submodule +# and is located at your root project repository. +git submodule deinit app-controller-submodule +``` + +* remove the relative submodule lines from the `.gitmodules` file + +```bash +vim .gitmodules +``` + +* remove the `ctl-utilities` target link from any CMake target you specified. + Those lines look like: + +```bash +TARGET_LINK_LIBRARIES(${TARGET_NAME} + ctl-utilities # REMOVE THIS LINE + ${link_libraries} + ) +``` + +### Use the native af-binder functions + +The controller redefined some binder's functions to add an abstraction between +several binding versions. But now, as the controller is binding v3 only, the +abstraction layer from the controller has been removed and you should switch +your functions from the old controller's definitions to binder's definitions. + +You have to replace any `include` statements of `afb-definitions.h` by +`afb/afb-binding.h` if you included it somewhere. If you have only included +`ctl-config.h` file then you are fine. + +```diff +- #include <afb-definitions.h> ++ #include <afb/afb-binding.h> +``` + +To help migrating gracefully the old controller's definitions, you could use the +sed script to automate the migration for you. From your project root directory, +executes the following commands: + +```bash +wget -O controller-migration.sed https://iot.bzh/download/public/tools/controller-migration.sed +for f in $(find . -name *.c -o -name *.h) +do +sed -i -rf controller-migration.sed ${f} +done +``` + +> **NOTE**: `AFB_ServiceCall` and `AFB_ServiceSync` has been migrated to their +> homologue `afb_api_call_legacy` and `afb_api_call_sync_legacy` respectively +> but you have to be aware that they are *legacy* functions and you should use +> the news call functions `afb_api_call` and `afb_api_call_sync` instead. +> Cf [Binder API functions reference](../../../apis_services/reference/af-binder/reference-v3/func-api.html#calls-and-job-functions) +> for more details on these functions. + +As a reminder, here are the old controller's functions definitions that you +should migrate: + +```c + #define AFB_ReqNone NULL + typedef afb_req_t AFB_ReqT; + typedef afb_api_t AFB_ApiT; + typedef afb_event_t AFB_EventT; + + #define AFB_EventIsValid(eventid) eventid + #define AFB_EventPush afb_event_push + #define AFB_ReqSubscribe afb_req_subscribe + #define AFB_EventMake(api, name) afb_api_make_event(api, name) + + #define AFB_ReqJson(request) afb_req_json(request) + + #define AFB_ReqSuccess afb_req_success + #define AFB_ReqSuccessF afb_req_success_f + #define AFB_ReqFail afb_req_fail + #define AFB_ReqFailF afb_req_fail_f + + #define AFB_ReqNotice(request, ...) AFB_REQ_NOTICE (request, __VA_ARGS__) + #define AFB_ReqWarning(request, ...) AFB_REQ_WARNING (request, __VA_ARGS__) + #define AFB_ReqDebug(request, ...) AFB_REQ_DEBUG (request, __VA_ARGS__) + #define AFB_ReqError(request, ...) AFB_REQ_ERROR (request, __VA_ARGS__) + #define AFB_ReqInfo(request, ...) AFB_REQ_INFO (request, __VA_ARGS__) + + #define AFB_ApiVerbose(api, level, ...) afb_api_verbose(api, level, __VA_ARGS__) + #define AFB_ApiNotice(api, ...) AFB_API_NOTICE (api, __VA_ARGS__) + #define AFB_ApiWarning(api, ...) AFB_API_WARNING (api, __VA_ARGS__) + #define AFB_ApiDebug(api, ...) AFB_API_DEBUG (api, __VA_ARGS__) + #define AFB_ApiError(api, ...) AFB_API_ERROR (api, __VA_ARGS__) + #define AFB_ApiInfo(api, ...) AFB_API_INFO (api, __VA_ARGS__) + + #define AFB_GetApiSettings afb_api_settings + + #define AFB_ReqIsValid(request) request + #define AFB_EvtIsValid(evtHandle) evtHandle + + #define AFB_ServiceCall(api, ...) afb_api_call_legacy(api, __VA_ARGS__) + #define AFB_ServiceSync(api, ...) afb_api_call_sync_legacy(api, __VA_ARGS__) + + #define AFB_ApiCall(api, ...) afb_api_call(api, __VA_ARGS__) + #define AFB_ApiSync(api, ...) afb_api_call_sync(api, __VA_ARGS__) + + #define AFB_ReqVCBData afb_req_get_vcbdata + #define AFB_ReqGetApi afb_req_get_api + #define AFB_GetEventLoop(api) afb_api_get_event_loop(api) + #define AFB_RootDirGetFD(api) afb_api_rootdir_get_fd(api) + #define AFB_RequireApi(api, ...) afb_api_require_api(api, __VA_ARGS__) + + #define AFB_ClientCtxSet(request, replace, createCB, freeCB, handle) afb_req_context(request, replace, createCB, freeCB, handle) + #define AFB_ClientCtxClear(request) afb_req_context_clear(request) + + #define AFB_ReqSetLOA(request, level) afb_req_session_set_LOA(request, level) + + #define AFB_NewApi afb_api_new_api + + #define AFB_ApiAddVerb afb_api_add_verb + + #define AFB_ApiSetUserData afb_api_set_userdata + #define AFB_ApiGetUserData afb_api_get_userdata + + #define AFB_ApiOnEvent afb_api_on_event + #define AFB_ApiOnInit afb_api_on_init + #define AFB_ApiSeal afb_api_seal +```
\ No newline at end of file diff --git a/docs/3_Developer_Guides/5_Controller_Guides/3.6.4_Config_Sample.md b/docs/3_Developer_Guides/5_Controller_Guides/3.6.4_Config_Sample.md new file mode 100644 index 0000000..3e8020f --- /dev/null +++ b/docs/3_Developer_Guides/5_Controller_Guides/3.6.4_Config_Sample.md @@ -0,0 +1,107 @@ +--- +edit_link: '' +title: Config Sample +origin_url: >- + https://git.automotivelinux.org/src/libappcontroller/plain/docs/configSample.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/libappcontroller-guides-devguides-book.yml --> + +# Config Sample + +Here after a simple configuration sample. + +```json +{ + "$schema": "http://iot.bzh/download/public/schema/json/ctl-schema.json", + "metadata": { + "uid": "sample-audio-control", + "api": "audio-control", + "info": "Provide Default Audio Policy for Multimedia, Navigation and Emergency", + "version": "1.0", + "require": ["intel-hda", "jabra-usb", "scarlett-usb"] + }, + "plugins": { + "uid" : "MyPlug", + "spath":"./plugins/pluginname:../conf.d/project/lua.d", + "libs": ["ctl-audio-plugin-sample.ctlso", "softmixer-simple.lua"], + "lua": ["Lua2cHelloWorld1", "Lua2cHelloWorld2"] + }, + "onload": [{ + "uid": "onload-sample-cb", + "info": "Call control sharelib install entrypoint", + "action": "lua://MyPlug#SamplePolicyInit", + "args": { + "arg1": "first_arg", + "nextarg": "second arg value" + } + }, { + "uid": "onload-sample-api", + "info": "Assert AlsaCore Presence", + "action": "api://alsacore#ping", + "args": { + "test": "onload-sample-api" + } + } + ], + "controls":[{ + "uid": "multimedia", + "privileges": "urn:AGL:permission:audio:public:mutimedia", + "action": "lua://MyPlug#Audio_Set_Multimedia" + }, { + "uid": "navigation", + "privileges": "urn:AGL:permission:audio:public:navigation", + "action": "lua://MyPlug#Audio_Set_Navigation" + }, { + "uid": "emergency", + "privileges": "urn:AGL:permission:audio:public:emergency", + "action": "lua://MyPlug#Audio_Set_Emergency" + }, { + "uid": "multimedia-control-cb", + "info": "Call Sharelib Sample Callback", + "action": "plugin://MyPlug#sampleControlNavigation", + "args": { + "arg1": "snoopy", + "arg2": "toto" + } + }, { + "uid": "navigation-control-ucm", + "action": "api://alsacore#ping", + "args": { + "test": "navigation" + } + }, { + "uid": "navigation-control-lua", + "info": "Call Lua Script to set Navigation", + "action": "lua://MyPlug#Audio_Set_Navigation" + } + ], + "events":[{ + "uid": "speed-action-1", + "action": "plugin://MyPlug#Blink-when-over-130", + "args": { + "speed": 130, + "blink-speed": 1000 + } + }, { + "uid": "Adjust-Volume", + "action": "lua://MyPlug#Adjust_Volume_To_Speed" + }, { + "uid": "Display-Rear-Camera", + "action": "plugin://MyPlug#Display-Rear-Camera" + }, { + "uid": "Prevent-Phone-Call", + "action": "api://phone#status", + "args": { + "call-accepted": "false" + } + }, { + "uid": "Authorize-Video", + "action": "api://video#status", + "args": { + "tv-accepted": "true" + } + } + ] +} +```
\ No newline at end of file diff --git a/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.1_Usage.md b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.1_Usage.md new file mode 100644 index 0000000..62de818 --- /dev/null +++ b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.1_Usage.md @@ -0,0 +1,97 @@ +--- +edit_link: '' +title: Usage +origin_url: >- + https://git.automotivelinux.org/src/libafb-helpers/plain/docs/usage.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/afb-helpers-function-references-afb-helpers-book.yml --> + +# Usage + +## Installation + +The afb-helpers library is integrated by default in the AGL SDK since the Guppy +version (>=7) and is also available as a package for the AGL supported linux +distributions. + +You could find the SDK build from Yocto which embed the afb-helpers library +here: + +* For the [releases](https://download.automotivelinux.org/AGL/release/) >= Guppy + in the latest machine's deploy directory. (e.g for Guppy in + `latest/<yourmachine>/deploy/sdk` directory) +* For the [master](https://download.automotivelinux.org/AGL/snapshots/master/) + development branch, in the latest machine's deploy directory. (e.g in + `latest/<yourmachine>/deploy/sdk` directory) + +To install the native package please refer to [this chapter](../1-verify-build-host.html) +in the AGL documentation to install the AGL repository for your distribution. + +Then use your package manager to install the library. + +### OpenSuse + +```bash +sudo zypper ref +sudo zypper install agl-libafb-helpers-devel +``` + +### Fedora + +```bash +sudo dnf ref +sudo dnf install agl-libafb-helpers-devel +``` + +### Ubuntu/Debian + +```bash +sudo apt-get update +sudo apt-get install agl-libafb-helpers-dev +``` + +## (Optional) Remove the git submodule version + +If you already use the afb-helpers component but using the submodule version +then you have to get rid of it to be sure to link and use the library version. +To do so, you have to do the following: + +* Deinitialize the submodule using `git` + +```bash +# This example assumes that the git submodule is named app-afb-helpers-submodule +# and is located at your root project repository. +git submodule deinit app-afb-helpers-submodule +``` + +* Remove the submodule relatives lines from the `.gitmodules` file + +```bash +vim .gitmodules +``` + +* Remove the `afb-helpers` target link from any CMake target you specified. + Those lines look like: + +```bash +TARGET_LINK_LIBRARIES(${TARGET_NAME} + afb-helpers # REMOVE THIS LINE + ${link_libraries} + ) +``` + +## Add the libafb-helpers as a static library to your binding + +In your `config.cmake` file, add a dependency to the controller library, i.e: + +```cmake +set(PKG_REQUIRED_LIST + json-c + afb-daemon + afb-helpers --> this is the afb-helpers library dependency name. +) +``` + +Or you can also use the [FIND_PACKAGE](https://cmake.org/cmake/help/v3.6/command/find_package.html?highlight=find_package) +CMake command to add it if you don't use the [cmake-apps-module](../cmakeafbtemplates/dev_guide/cmake-overview.html) diff --git a/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.2_AFB_Timer.md b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.2_AFB_Timer.md new file mode 100644 index 0000000..65d805f --- /dev/null +++ b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.2_AFB_Timer.md @@ -0,0 +1,57 @@ +--- +edit_link: '' +title: AFB Timer +origin_url: >- + https://git.automotivelinux.org/src/libafb-helpers/plain/docs/afb-timer.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/afb-helpers-function-references-afb-helpers-book.yml --> + +# AFB Timer functions reference + +## TimerHandleT + +Members are: + +* `count`: integer representing the number of times the timers should run. +* `delay`: millisecond integer representing the delay to wait before and between + the callback run. +* `uid`: a string identifying the timer. +* `context`: an opaq pointer that could be used in the callback function. +* `evtSource`: a systemd event source struct. Should be NULL. +* `api`: the AFB api pointer. +* `callback`: a function pointer for the callback to call at timer expiration +* `freeCB`: a function pointer called after expiration of the timer. Mainly meant + to release the context pointer by example. + +## void TimerEvtStart(afb_api_t api, TimerHandleT *timerHandle, timerCallbackT callback, void *context) + +Start a timer which invokes the callback when the delay expires for `count` +times. + +* `api`: AFB api pointer. +* `timerHandle`: pointer to struct representing a timer. +* `callback`: a function pointer for the callback to call at timer expiration +* `context`: an opaq pointer that could be used in the callback function. + +## void TimerEvtStop(TimerHandleT *timerHandle) + +Manually stop the timer's run. If the `count` isn't finished then it will end +the timer and no other runs will occur. + +* `timerHandle`: pointer to struct representing a timer. + +## uint64_t LockWait(afb_api_t api, uint64_t utimeout) + +It is function acting like a non-blocking sleep for an API. It lets the main API +event loop runs while you are waiting and will unlock at the first received +event and returns the remaining time to wait if an event occurs or 0 if no events +occured and timeout hits. Then you have to manually ensure that once an event +has been received that it was the one you are waiting for and if not launch again +the wait with the remaining time returned. + +* `api`: AFB api pointer. +* `timeout`: timeout in microsecond. + +Returns the remaining time in microsecond to wait if an event occurs or 0 if no +events occured and timeout hits diff --git a/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.3_CURL_wrapper.md b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.3_CURL_wrapper.md new file mode 100644 index 0000000..eae1a45 --- /dev/null +++ b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.3_CURL_wrapper.md @@ -0,0 +1,120 @@ +--- +edit_link: '' +title: CURL wrapper +origin_url: >- + https://git.automotivelinux.org/src/libafb-helpers/plain/docs/curl-wrap.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/afb-helpers-function-references-afb-helpers-book.yml --> + +# CURL wrapping functions reference. + +## int curl_wrap_perform (CURL * curl, char **result, size_t * size) + +Perform the CURL operation for 'curl' and put the result in memory. If 'result' +isn't NULL it receives the returned content that then must be freed. If 'size' +isn't NULL, it receives the size of the returned content. Note that if not NULL, +the real content is one byte greater than the read size and the last byte +zero. This facility allows to handle the returned content as a null terminated +C-string. + +## void curl_wrap_do(CURL *curl, void (*callback)(void *closure, int status, CURL *curl, const char *result, size_t size), void *closure) + +Will perform the CURL operation and on success invokes the callback with the +result and size of the operation or error on a failure. + +## int curl_wrap_content_type_is (CURL * curl, const char *value) + +Request `Content-Type` information from the curl session with this function + +Returns non-zero value if the CURL content type match the `value` and 0 otherwize + +## long curl_wrap_response_code_get(CURL *curl) + +Request the response code to a CURL operation. + +Returns the response code received on success or 0 on failure. + +## CURL *curl_wrap_prepare_get_url(const char *url) + +Prepare a GET CURL operation on the url given as parameter and Returns the CURL +pointer. + +## CURL *curl_wrap_prepare_get(const char *base, const char *path, const char * const *args) + +Prepare a GET CURL operation on the decomposed url and escape it. The `url` has been +decomposed in 3 parts: + +* `base`: representing the FQDN of the url. +* `path`: the path to the requested page. +* `args`: optionnal array of arguments provided for the GET request. + +Returns the prepared CURL request. + +## int curl_wrap_add_header(CURL *curl, const char *header) + +Add a header to a CURL operation. + +Returns the prepared CURL request. + +## int curl_wrap_add_header_value(CURL *curl, const char *name, const char *value) + +Add a tuple `name`, `value` to the header of a CURL operation. + +Returns the prepared CURL request. + +## CURL *curl_wrap_prepare_post_url_data(const char *url, const char *datatype, const char *data, size_t szdata) + +Prepare a POST CURL operation on the provided `url`. + +* `url`: a HTTP url. +* `datatype`: HTTP `Content-Type` to use for the operation. +* `data`: data to send. +* `szdata`: size of the data to send. + +Returns the prepared CURL request. + +## CURL *curl_wrap_prepare_post_simple_unescaped(const char *base, const char *path, const char *args) + +Prepare a POST CURL operation on an unescaped `url` with arguments provided as +a simple string. + +* `base`: representing the FQDN of the url. +* `path`: the path to the requested page. +* `args`: optionnals argument for the POST http request. + +Returns the prepared CURL request. + +## CURL *curl_wrap_prepare_post_simple_escaped(const char *base, const char *path, char *args) + +Prepare a POST CURL operation on an escaped `url` with arguments provided as +a simple string. + +* `base`: representing the FQDN of the url. +* `path`: the path to the requested page. +* `args`: optionnals argument for the POST http request. + +Returns the prepared CURL request. + +## CURL *curl_wrap_prepare_post_unescaped(const char *base, const char *path, const char *separator, const char * const *args) + +Prepare a POST CURL operation on an unescaped `url` with arguments provided as +an array of string concatened with a provided separator string. + +* `base`: representing the FQDN of the url. +* `path`: the path to the requested page. +* `separator`: string used as a separator when concatening the arguments. +* `args`: optionnal array of arguments for the POST http request. + +Returns the prepared CURL request. + +## CURL *curl_wrap_prepare_post_escaped(const char *base, const char *path, const char * const *args) + +Prepare a POST CURL operation on an unescaped `url` with arguments provided as +an array of string concatened without any separator. + +* `base`: representing the FQDN of the url. +* `path`: the path to the requested page. +* `args`: optionnal array of arguments for the POST http request. + +Returns the prepared CURL request. diff --git a/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.4_URL_Escaping.md b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.4_URL_Escaping.md new file mode 100644 index 0000000..c6f411c --- /dev/null +++ b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.4_URL_Escaping.md @@ -0,0 +1,46 @@ +--- +edit_link: '' +title: URL escaping +origin_url: >- + https://git.automotivelinux.org/src/libafb-helpers/plain/docs/escape.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/afb-helpers-function-references-afb-helpers-book.yml --> + +# Escaping helpers functions reference + +## char *escape_url(const char *base, const char *path, const char * const *args, size_t *length) + +Escape an `url` and `arguments` and returned it as a string. + +* `base`: representing the FQDN of the url. +* `path`: the path to the requested page. +* `args`: optionnal array of arguments provided for the GET request. +* `length`: length of the returned `url`. + +Returns the escaped `url`. + +## const char *escape_args(const char * const *args, size_t *length) + +Escape an array of arguments and returned the lenght of the escaped arguments +string. + +* `args`: array of arguments provided for the GET request. +* `length`: length of the returned `arguments`. + +Returns the escaped `arguments`. + +## const char *escape_str(const char *str, size_t *length) + +Escape a string and returns it. + +* `str`: the string to escape. +* `length`: length of the returned string. + +Returns the escaped string. + +## const char **unescape_args(const char *args) + +Unescape an argument and returns it. + +* `args`: the argument to unescape. diff --git a/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.5_Filescan_Utils.md b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.5_Filescan_Utils.md new file mode 100644 index 0000000..2d8e388 --- /dev/null +++ b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.5_Filescan_Utils.md @@ -0,0 +1,89 @@ +--- +edit_link: '' +title: Filescan Utils +origin_url: >- + https://git.automotivelinux.org/src/libafb-helpers/plain/docs/filescan-utils.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/afb-helpers-function-references-afb-helpers-book.yml --> + +# Filescan utils functions reference + +## const char *GetMiddleName(const char *name) + +Get rid of the binder name prefix 'afbd-' + +* name will be typically the full binder name + +Returns the process middle name of the running binder. + +## const char *GetBinderName() + +Get the Binder Name without the prefix set by the AGL appfw 'afbd-' + +Returns the Binder name without the prefix. + +## json_object* ScanForConfig (const char* searchPath, CtlScanDirModeT mode, const char *prefix, const char *extension) + +Scan a directory searching all files matching pattern: 'prefix*extention'. + +* `searchPath`: directory where to begin the searching. +* `mode`: either or not the search will be recursive. +* `prefix`: file prefix that will be looking for. +* `extention`: file extention that will be looking for. + +Returns a json_object array of object with 2 parts a 'fullpath' describing the +fullpath to reach the file and 'filename' containing the matched files. + +## char *GetAFBRootDirPathUsingFd(int fd) + +Get the binder root directory path (the path specified with '--rootdir' option +at binder launch, if the option is not used, the path from where the binder +is launched) using binder root directory file descriptor. + +* `fd` : Binder root directory file descriptor. + +Returns a string representing the path to binder root directory. + +## char *GetAFBRootDirPath(afb_api_t apiHandle) + +For binding with a version >= 3, same as 'GetAFBRootDirPathUsingFd' function, +but use pointer to the AFB API as parameter instead of +binder root directory file descriptor. + +* `apiHandle` : pointer to the AFB API. + +Returns a string representing the path to binder root directory. + +## char* GetBindingDirPath() + +For binding with a version <= 2, same as 'GetAFBRootDirPath' function, +but the pointer to the AFB API is not needed. +Kept for compatibility issues. + +## char* GetBindingDirPath(afb_api_t api) + +For binding with a version >= 3, same as 'GetAFBRootDirPath' function. +Deprecated, please use 'GetAFBRootDirPath' function. +Kept for compatibility issues. + +## char *GetRunningBindingDirPath(afb_api_t api) + +For binding with a version >= 3, get the binding directory path +(the path to the directory that contains the binding). + +* `api` : pointer to the AFB API. + +Returns a string representing the path to the binding directory. + +## const char *getEnvDirList(const char *prefix, const char *suffix) + +Get the environment directory colon separated path list. This take the prefix +add the binder's name then the suffix as environment variable name and also +search for another variable without the binder's name (so only prefix+suffix). + +* `prefix`: Environment variable prefix +* `suffix`: Environment variable suffix + +Returns a string representing a colon separated path list or NULL is case of +error or none environment variables found. diff --git a/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.6_Qt_AFB_Websocket_client.md b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.6_Qt_AFB_Websocket_client.md new file mode 100644 index 0000000..17b4d2b --- /dev/null +++ b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.6_Qt_AFB_Websocket_client.md @@ -0,0 +1,48 @@ +--- +edit_link: '' +title: Qt AFB Websocket client +origin_url: >- + https://git.automotivelinux.org/src/libafb-helpers/plain/docs/qafbwebsocketclient.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/afb-helpers-function-references-afb-helpers-book.yml --> + +# A WebSocket client to an Application Framework Binder + +## QAfbWebsocketClient(QObject* parent = nullptr) + +Default constructor. + +* `parent`: Parent object. + +## QAbstractSocket::SocketError error() + +Get and return the last error code. + +## QString errorString() + +Get and return the last error as a string. + +## bool isValid() + +Check if connection is ready or not. + +Returns `true` if the connected is ready to read and write, `false` otherwise. + +## void call(const QString& api, const QString& verb, const QJsonValue& arg = QJsonValue(), closure_t closure = nullptr) + +Call an api's verb with an argument. + +* `api`: Api to call. +* `verb`: Verb to call. +* `arg`: Argument to pass. +* `closure`: callback function to call at the verb reply + +## void QAfbWebsocketClient::sendTextMessage(QString msg) + +Send a text message over the websocket. + +This is use for test only, you should not use this method because it sent text +**as-is**, so you have to follow the binder's protocol by your self. + +* `msg`: Message to send. diff --git a/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.7_JSON_library_for_modern_C++.md b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.7_JSON_library_for_modern_C++.md new file mode 100644 index 0000000..1f612f5 --- /dev/null +++ b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.7_JSON_library_for_modern_C++.md @@ -0,0 +1,919 @@ +--- +edit_link: '' +title: JSON library for modern C++ +origin_url: 'https://git.automotivelinux.org/src/libafb-helpers/plain/docs/json.md?h=master' +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/afb-helpers-function-references-afb-helpers-book.yml --> + +# JSON for Modern C++ + +- [Design goals](#design-goals) +- [Integration](#integration) +- [Examples](#examples) + - [JSON as first-class data type](#json-as-first-class-data-type) + - [Serialization / Deserialization](#serialization--deserialization) + - [STL-like access](#stl-like-access) + - [Conversion from STL containers](#conversion-from-stl-containers) + - [JSON Pointer and JSON Patch](#json-pointer-and-json-patch) + - [Implicit conversions](#implicit-conversions) + - [Conversions to/from arbitrary types](#arbitrary-types-conversions) + - [Binary formats (CBOR and MessagePack)](#binary-formats-cbor-and-messagepack) +- [Supported compilers](#supported-compilers) +- [License](#license) +- [Thanks](#thanks) +- [Used third-party tools](#used-third-party-tools) +- [Projects using JSON for Modern C++](#projects-using-json-for-modern-c) +- [Notes](#notes) +- [Execute unit tests](#execute-unit-tests) + +## Design goals + +There are myriads of [JSON](http://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals: + +- **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples) and you'll know what I mean. + +- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/src/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings. + +- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/blob/master/test/src/unit.cpp) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) that there are no memory leaks. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289). + +Other aspects were not so important to us: + +- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs. + +- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set. + +See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information. + +## Integration + +The single required source, file `json.hpp` is in the `src` directory or [released here](https://github.com/nlohmann/json/releases). All you need to do is add + +```cpp +#include "json.hpp" + +// for convenience +using json = nlohmann::json; +``` + +to the files you want to use JSON objects. That's it. Do not forget to set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang). + +:beer: If you are using OS X and [Homebrew](http://brew.sh), just type `brew tap nlohmann/json` and `brew install nlohmann_json` and you're set. If you want the bleeding edge rather than the latest release, use `brew install nlohmann_json --HEAD`. + +If you are using the [Meson Build System](http://mesonbuild.com), then you can wrap this repo as a subproject. + +If you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add `jsonformoderncpp/x.y.z@vthiery/stable` to your `conanfile.py`'s requires, where `x.y.z` is the release version you want to use. Please file issues [here](https://github.com/vthiery/conan-jsonformoderncpp/issues) if you experience problems with the packages. + +If you are using [hunter](https://github.com/ruslo/hunter/) on your project for external dependencies, then you can use the [nlohman_json package](https://github.com/ruslo/hunter/wiki/pkg.nlohmann_json). Please see the hunter project for any issues regarding the packaging. + +:warning: [Version 3.0.0](https://github.com/nlohmann/json/wiki/Road-toward-3.0.0) is currently under development. Branch `develop` is used for the ongoing work and is probably **unstable**. Please use the `master` branch for the last stable version 2.1.1. + +## Examples + +Beside the examples below, you may want to check the [documentation](https://nlohmann.github.io/json/) where each function contains a separate code example (e.g., check out [`emplace()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a602f275f0359ab181221384989810604.html#a602f275f0359ab181221384989810604)). All [example files](https://github.com/nlohmann/json/tree/develop/doc/examples) can be compiled and executed on their own (e.g., file [emplace.cpp](https://github.com/nlohmann/json/blob/develop/doc/examples/emplace.cpp)). + +### JSON as first-class data type + +Here are some examples to give you an idea how to use the class. + +Assume you want to create the JSON object + +```json +{ + "pi": 3.141, + "happy": true, + "name": "Niels", + "nothing": null, + "answer": { + "everything": 42 + }, + "list": [1, 0, 2], + "object": { + "currency": "USD", + "value": 42.99 + } +} +``` + +With the JSON class, you could write: + +```cpp +// create an empty structure (null) +json j; + +// add a number that is stored as double (note the implicit conversion of j to an object) +j["pi"] = 3.141; + +// add a Boolean that is stored as bool +j["happy"] = true; + +// add a string that is stored as std::string +j["name"] = "Niels"; + +// add another null object by passing nullptr +j["nothing"] = nullptr; + +// add an object inside the object +j["answer"]["everything"] = 42; + +// add an array that is stored as std::vector (using an initializer list) +j["list"] = { 1, 0, 2 }; + +// add another object (using an initializer list of pairs) +j["object"] = { {"currency", "USD"}, {"value", 42.99} }; + +// instead, you could also write (which looks very similar to the JSON above) +json j2 = { + {"pi", 3.141}, + {"happy", true}, + {"name", "Niels"}, + {"nothing", nullptr}, + {"answer", { + {"everything", 42} + }}, + {"list", {1, 0, 2}}, + {"object", { + {"currency", "USD"}, + {"value", 42.99} + }} +}; +``` + +Note that in all these cases, you never need to "tell" the compiler which JSON value you want to use. If you want to be explicit or express some edge cases, the functions `json::array` and `json::object` will help: + +```cpp +// a way to express the empty array [] +json empty_array_explicit = json::array(); + +// ways to express the empty object {} +json empty_object_implicit = json({}); +json empty_object_explicit = json::object(); + +// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]] +json array_not_object = { json::array({"currency", "USD"}), json::array({"value", 42.99}) }; +``` + +### Serialization / Deserialization + +#### To/from strings + +You can create an object (deserialization) by appending `_json` to a string literal: + +```cpp +// create object from string literal +json j = "{ \"happy\": true, \"pi\": 3.141 }"_json; + +// or even nicer with a raw string literal +auto j2 = R"( + { + "happy": true, + "pi": 3.141 + } +)"_json; +``` + +Note that without appending the `_json` suffix, the passed string literal is not parsed, but just used as JSON string value. That is, `json j = "{ \"happy\": true, \"pi\": 3.141 }"` would just store the string `"{ "happy": true, "pi": 3.141 }"` rather than parsing the actual object. + +The above example can also be expressed explicitly using `json::parse()`: + +```cpp +// parse explicitly +auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }"); +``` + +You can also get a string representation (serialize): + +```cpp +// explicit conversion to string +std::string s = j.dump(); // {\"happy\":true,\"pi\":3.141} + +// serialization with pretty printing +// pass in the amount of spaces to indent +std::cout << j.dump(4) << std::endl; +// { +// "happy": true, +// "pi": 3.141 +// } +``` + +#### To/from streams (e.g. files, string streams) + +You can also use streams to serialize and deserialize: + +```cpp +// deserialize from standard input +json j; +std::cin >> j; + +// serialize to standard output +std::cout << j; + +// the setw manipulator was overloaded to set the indentation for pretty printing +std::cout << std::setw(4) << j << std::endl; +``` + +These operators work for any subclasses of `std::istream` or `std::ostream`. Here is the same example with files: + +```cpp +// read a JSON file +std::ifstream i("file.json"); +json j; +i >> j; + +// write prettified JSON to another file +std::ofstream o("pretty.json"); +o << std::setw(4) << j << std::endl; +``` + +Please note that setting the exception bit for `failbit` is inappropriate for this use case. It will result in program termination due to the `noexcept` specifier in use. + +#### Read from iterator range + +You can also read JSON from an iterator range; that is, from any container accessible by iterators whose content is stored as contiguous byte sequence, for instance a `std::vector<std::uint8_t>`: + +```cpp +std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'}; +json j = json::parse(v.begin(), v.end()); +``` + +You may leave the iterators for the range [begin, end): + +```cpp +std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'}; +json j = json::parse(v); +``` + +### STL-like access + +We designed the JSON class to behave just like an STL container. In fact, it satisfies the [**ReversibleContainer**](http://en.cppreference.com/w/cpp/concept/ReversibleContainer) requirement. + +```cpp +// create an array using push_back +json j; +j.push_back("foo"); +j.push_back(1); +j.push_back(true); + +// also use emplace_back +j.emplace_back(1.78); + +// iterate the array +for (json::iterator it = j.begin(); it != j.end(); ++it) { + std::cout << *it << '\n'; +} + +// range-based for +for (auto& element : j) { + std::cout << element << '\n'; +} + +// getter/setter +const std::string tmp = j[0]; +j[1] = 42; +bool foo = j.at(2); + +// comparison +j == "[\"foo\", 1, true]"_json; // true + +// other stuff +j.size(); // 3 entries +j.empty(); // false +j.type(); // json::value_t::array +j.clear(); // the array is empty again + +// convenience type checkers +j.is_null(); +j.is_boolean(); +j.is_number(); +j.is_object(); +j.is_array(); +j.is_string(); + +// create an object +json o; +o["foo"] = 23; +o["bar"] = false; +o["baz"] = 3.141; + +// also use emplace +o.emplace("weather", "sunny"); + +// special iterator member functions for objects +for (json::iterator it = o.begin(); it != o.end(); ++it) { + std::cout << it.key() << " : " << it.value() << "\n"; +} + +// find an entry +if (o.find("foo") != o.end()) { + // there is an entry with key "foo" +} + +// or simpler using count() +int foo_present = o.count("foo"); // 1 +int fob_present = o.count("fob"); // 0 + +// delete an entry +o.erase("foo"); +``` + +### Conversion from STL containers + +Any sequence container (`std::array`, `std::vector`, `std::deque`, `std::forward_list`, `std::list`) whose values can be used to construct JSON types (e.g., integers, floating point numbers, Booleans, string types, or again STL containers described in this section) can be used to create a JSON array. The same holds for similar associative containers (`std::set`, `std::multiset`, `std::unordered_set`, `std::unordered_multiset`), but in these cases the order of the elements of the array depends how the elements are ordered in the respective STL container. + +```cpp +std::vector<int> c_vector {1, 2, 3, 4}; +json j_vec(c_vector); +// [1, 2, 3, 4] + +std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6}; +json j_deque(c_deque); +// [1.2, 2.3, 3.4, 5.6] + +std::list<bool> c_list {true, true, false, true}; +json j_list(c_list); +// [true, true, false, true] + +std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; +json j_flist(c_flist); +// [12345678909876, 23456789098765, 34567890987654, 45678909876543] + +std::array<unsigned long, 4> c_array {{1, 2, 3, 4}}; +json j_array(c_array); +// [1, 2, 3, 4] + +std::set<std::string> c_set {"one", "two", "three", "four", "one"}; +json j_set(c_set); // only one entry for "one" is used +// ["four", "one", "three", "two"] + +std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"}; +json j_uset(c_uset); // only one entry for "one" is used +// maybe ["two", "three", "four", "one"] + +std::multiset<std::string> c_mset {"one", "two", "one", "four"}; +json j_mset(c_mset); // both entries for "one" are used +// maybe ["one", "two", "one", "four"] + +std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"}; +json j_umset(c_umset); // both entries for "one" are used +// maybe ["one", "two", "one", "four"] +``` + +Likewise, any associative key-value containers (`std::map`, `std::multimap`, `std::unordered_map`, `std::unordered_multimap`) whose keys can construct an `std::string` and whose values can be used to construct JSON types (see examples above) can be used to create a JSON object. Note that in case of multimaps only one key is used in the JSON object and the value depends on the internal order of the STL container. + +```cpp +std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} }; +json j_map(c_map); +// {"one": 1, "three": 3, "two": 2 } + +std::unordered_map<const char*, double> c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} }; +json j_umap(c_umap); +// {"one": 1.2, "two": 2.3, "three": 3.4} + +std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; +json j_mmap(c_mmap); // only one entry for key "three" is used +// maybe {"one": true, "two": true, "three": true} + +std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; +json j_ummap(c_ummap); // only one entry for key "three" is used +// maybe {"one": true, "two": true, "three": true} +``` + +### JSON Pointer and JSON Patch + +The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address structured values. On top of this, **JSON Patch** ([RFC 6902](https://tools.ietf.org/html/rfc6902)) allows to describe differences between two JSON values - effectively allowing patch and diff operations known from Unix. + +```cpp +// a JSON value +json j_original = R"({ + "baz": ["one", "two", "three"], + "foo": "bar" +})"_json; + +// access members with a JSON pointer (RFC 6901) +j_original["/baz/1"_json_pointer]; +// "two" + +// a JSON patch (RFC 6902) +json j_patch = R"([ + { "op": "replace", "path": "/baz", "value": "boo" }, + { "op": "add", "path": "/hello", "value": ["world"] }, + { "op": "remove", "path": "/foo"} +])"_json; + +// apply the patch +json j_result = j_original.patch(j_patch); +// { +// "baz": "boo", +// "hello": ["world"] +// } + +// calculate a JSON patch from two JSON values +json::diff(j_result, j_original); +// [ +// { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] }, +// { "op": "remove","path": "/hello" }, +// { "op": "add", "path": "/foo", "value": "bar" } +// ] +``` + +### Implicit conversions + +The type of the JSON object is determined automatically by the expression to store. Likewise, the stored value is implicitly converted. + +```cpp +// strings +std::string s1 = "Hello, world!"; +json js = s1; +std::string s2 = js; + +// Booleans +bool b1 = true; +json jb = b1; +bool b2 = jb; + +// numbers +int i = 42; +json jn = i; +double f = jn; + +// etc. +``` + +You can also explicitly ask for the value: + +```cpp +std::string vs = js.get<std::string>(); +bool vb = jb.get<bool>(); +int vi = jn.get<int>(); + +// etc. +``` + +### Arbitrary types conversions + +Every type can be serialized in JSON, not just STL-containers and scalar types. Usually, you would do something along those lines: + +```cpp +namespace ns { + // a simple struct to model a person + struct person { + std::string name; + std::string address; + int age; + }; +} + +ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + +// convert to JSON: copy each value into the JSON object +json j; +j["name"] = p.name; +j["address"] = p.address; +j["age"] = p.age; + +// ... + +// convert from JSON: copy each value from the JSON object +ns::person p { + j["name"].get<std::string>(), + j["address"].get<std::string>(), + j["age"].get<int>() +}; +``` + +It works, but that's quite a lot of boilerplate... Fortunately, there's a better way: + +```cpp +// create a person +ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60}; + +// conversion: person -> json +json j = p; + +std::cout << j << std::endl; +// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} + +// conversion: json -> person +ns::person p2 = j; + +// that's it +assert(p == p2); +``` + +#### Basic usage + +To make this work with one of your types, you only need to provide two functions: + +```cpp +using nlohmann::json; + +namespace ns { + void to_json(json& j, const person& p) { + j = json{ {"name", p.name}, {"address", p.address}, {"age", p.age} }; + } + + void from_json(const json& j, person& p) { + p.name = j.at("name").get<std::string>(); + p.address = j.at("address").get<std::string>(); + p.age = j.at("age").get<int>(); + } +} // namespace ns +``` + +That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called. +Likewise, when calling `get<your_type>()`, the `from_json` method will be called. + +Some important things: + +- Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined). +- When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible). (There is a way to bypass this requirement described later.) +- In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a93403e803947b86f4da2d1fb3345cf2c.html#a93403e803947b86f4da2d1fb3345cf2c) to access the object values rather than `operator[]`. In case a key does not exists, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior. +- In case your type contains several `operator=` definitions, code like `your_variable = your_json;` [may not compile](https://github.com/nlohmann/json/issues/667). You need to write `your_variable = your_json.get<decltype your_variable>();` instead. +- You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these. + +#### How do I convert third-party types? + +This requires a bit more advanced technique. But first, let's see how this conversion mechanism works: + +The library uses **JSON Serializers** to convert types to json. +The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](http://en.cppreference.com/w/cpp/language/adl)). + +It is implemented like this (simplified): + +```cpp +template <typename T> +struct adl_serializer { + static void to_json(json& j, const T& value) { + // calls the "to_json" method in T's namespace + } + + static void from_json(const json& j, T& value) { + // same thing, but with the "from_json" method + } +}; +``` + +This serializer works fine when you have control over the type's namespace. However, what about `boost::optional`, or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`... + +To solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example: + +```cpp +// partial specialization (full specialization works too) +namespace nlohmann { + template <typename T> + struct adl_serializer<boost::optional<T>> { + static void to_json(json& j, const boost::optional<T>& opt) { + if (opt == boost::none) { + j = nullptr; + } else { + j = *opt; // this will call adl_serializer<T>::to_json which will + // find the free function to_json in T's namespace! + } + } + + static void from_json(const json& j, boost::optional<T>& opt) { + if (j.is_null()) { + opt = boost::none; + } else { + opt = j.get<T>(); // same as above, but with + // adl_serializer<T>::from_json + } + } + }; +} +``` + +#### How can I use `get()` for non-default constructible/non-copyable types? + +There is a way, if your type is [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload: + +```cpp +struct move_only_type { + move_only_type() = delete; + move_only_type(int ii): i(ii) {} + move_only_type(const move_only_type&) = delete; + move_only_type(move_only_type&&) = default; + + int i; +}; + +namespace nlohmann { + template <> + struct adl_serializer<move_only_type> { + // note: the return type is no longer 'void', and the method only takes + // one argument + static move_only_type from_json(const json& j) { + return {j.get<int>()}; + } + + // Here's the catch! You must provide a to_json method! Otherwise you + // will not be able to convert move_only_type to json, since you fully + // specialized adl_serializer on that type + static void to_json(json& j, move_only_type t) { + j = t.i; + } + }; +} +``` + +#### Can I write my own serializer? (Advanced use) + +Yes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohmann/json/blob/develop/test/src/unit-udt.cpp) in the test suite, to see a few examples. + +If you write your own serializer, you'll need to do a few things: + +- use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`) +- use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods +- use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL + +Here is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL. + +```cpp +// You should use void as a second template argument +// if you don't need compile-time checks on T +template<typename T, typename SFINAE = typename std::enable_if<sizeof(T) <= 32>::type> +struct less_than_32_serializer { + template <typename BasicJsonType> + static void to_json(BasicJsonType& j, T value) { + // we want to use ADL, and call the correct to_json overload + using nlohmann::to_json; // this method is called by adl_serializer, + // this is where the magic happens + to_json(j, value); + } + + template <typename BasicJsonType> + static void from_json(const BasicJsonType& j, T& value) { + // same thing here + using nlohmann::from_json; + from_json(j, value); + } +}; +``` + +Be **very** careful when reimplementing your serializer, you can stack overflow if you don't pay attention: + +```cpp +template <typename T, void> +struct bad_serializer +{ + template <typename BasicJsonType> + static void to_json(BasicJsonType& j, const T& value) { + // this calls BasicJsonType::json_serializer<T>::to_json(j, value); + // if BasicJsonType::json_serializer == bad_serializer ... oops! + j = value; + } + + template <typename BasicJsonType> + static void to_json(const BasicJsonType& j, T& value) { + // this calls BasicJsonType::json_serializer<T>::from_json(j, value); + // if BasicJsonType::json_serializer == bad_serializer ... oops! + value = j.template get<T>(); // oops! + } +}; +``` + +### Binary formats (CBOR and MessagePack) + +Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports [CBOR](http://cbor.io) (Concise Binary Object Representation) and [MessagePack](http://msgpack.org) to efficiently encode JSON values to byte vectors and to decode such vectors. + +```cpp +// create a JSON value +json j = R"({"compact": true, "schema": 0})"_json; + +// serialize to CBOR +std::vector<std::uint8_t> v_cbor = json::to_cbor(j); + +// 0xa2, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0xf5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x00 + +// roundtrip +json j_from_cbor = json::from_cbor(v_cbor); + +// serialize to MessagePack +std::vector<std::uint8_t> v_msgpack = json::to_msgpack(j); + +// 0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x00 + +// roundtrip +json j_from_msgpack = json::from_msgpack(v_msgpack); +``` + +## Supported compilers + +Though it's 2016 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work: + +- GCC 4.9 - 7.1 (and possibly later) +- Clang 3.4 - 5.0 (and possibly later) +- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later) +- Microsoft Visual C++ 2017 / Build Tools 15.1.548.43366 (and possibly later) + +I would be happy to learn about other compilers/versions. + +Please note: + +- GCC 4.8 does not work because of two bugs ([55817](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55817) and [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824)) in the C++11 support. Note there is a [pull request](https://github.com/nlohmann/json/pull/212) to fix some of the issues. +- Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default. + +```bb + APP_STL := c++_shared + NDK_TOOLCHAIN_VERSION := clang3.6 + APP_CPPFLAGS += -frtti -fexceptions +``` + +The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10. + +- For GCC running on MinGW or Android SDK, the error `'to_string' is not a member of 'std'` (or similarly, for `strtod`) may occur. Note this is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to [this site](http://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219). + +The following compilers are currently used in continuous integration at [Travis](https://travis-ci.org/nlohmann/json) and [AppVeyor](https://ci.appveyor.com/project/nlohmann/json): + +| Compiler | Operating System | Version String | +|-----------------|------------------------------|----------------| +| GCC 4.9.4 | Ubuntu 14.04.5 LTS | g++-4.9 (Ubuntu 4.9.4-2ubuntu1~14.04.1) 4.9.4 | +| GCC 5.4.1 | Ubuntu 14.04.5 LTS | g++-5 (Ubuntu 5.4.1-2ubuntu1~14.04) 5.4.1 20160904 | +| GCC 6.3.0 | Ubuntu 14.04.5 LTS | g++-6 (Ubuntu/Linaro 6.3.0-18ubuntu2~14.04) 6.3.0 20170519 | +| GCC 7.1.0 | Ubuntu 14.04.5 LTS | g++-7 (Ubuntu 7.1.0-5ubuntu2~14.04) 7.1.0 +| Clang 3.5.0 | Ubuntu 14.04.5 LTS | clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) | +| Clang 3.6.2 | Ubuntu 14.04.5 LTS | clang version 3.6.2-svn240577-1~exp1 (branches/release_36) | +| Clang 3.7.1 | Ubuntu 14.04.5 LTS | clang version 3.7.1-svn253571-1~exp1 (branches/release_37) | +| Clang 3.8.0 | Ubuntu 14.04.5 LTS | clang version 3.8.0-2ubuntu3~trusty5 (tags/RELEASE_380/final) | +| Clang 3.9.1 | Ubuntu 14.04.5 LTS | clang version 3.9.1-4ubuntu3~14.04.2 (tags/RELEASE_391/rc2) | +| Clang 4.0.1 | Ubuntu 14.04.5 LTS | clang version 4.0.1-svn305264-1~exp1 (branches/release_40) | +| Clang 5.0.0 | Ubuntu 14.04.5 LTS | clang version 5.0.0-svn310902-1~exp1 (branches/release_50) | +| Clang Xcode 6.4 | Darwin Kernel Version 14.3.0 (OSX 10.10.3) | Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) | +| Clang Xcode 7.3 | Darwin Kernel Version 15.0.0 (OSX 10.10.5) | Apple LLVM version 7.3.0 (clang-703.0.29) | +| Clang Xcode 8.0 | Darwin Kernel Version 15.6.0 | Apple LLVM version 8.0.0 (clang-800.0.38) | +| Clang Xcode 8.1 | Darwin Kernel Version 16.1.0 (macOS 10.12.1) | Apple LLVM version 8.0.0 (clang-800.0.42.1) | +| Clang Xcode 8.2 | Darwin Kernel Version 16.1.0 (macOS 10.12.1) | Apple LLVM version 8.0.0 (clang-800.0.42.1) | +| Clang Xcode 8.3 | Darwin Kernel Version 16.5.0 (macOS 10.12.4) | Apple LLVM version 8.1.0 (clang-802.0.38) | +| Clang Xcode 9 beta | Darwin Kernel Version 16.6.0 (macOS 10.12.5) | Apple LLVM version 9.0.0 (clang-900.0.26) | +| Visual Studio 14 2015 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 14.0.25420.1 | +| Visual Studio 2017 | Windows Server 2016 | Microsoft (R) Build Engine version 15.1.1012.6693 | + +## License + +The class is licensed under the [MIT License](http://opensource.org/licenses/MIT): + +Copyright © 2013-2017 [Niels Lohmann](http://nlohmann.me) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## Thanks + +I deeply appreciate the help of the following people. + +- [Teemperor](https://github.com/Teemperor) implemented CMake support and lcov integration, realized escape and Unicode handling in the string parser, and fixed the JSON serialization. +- [elliotgoodrich](https://github.com/elliotgoodrich) fixed an issue with double deletion in the iterator classes. +- [kirkshoop](https://github.com/kirkshoop) made the iterators of the class composable to other libraries. +- [wancw](https://github.com/wanwc) fixed a bug that hindered the class to compile with Clang. +- Tomas Åblad found a bug in the iterator implementation. +- [Joshua C. Randall](https://github.com/jrandall) fixed a bug in the floating-point serialization. +- [Aaron Burghardt](https://github.com/aburgh) implemented code to parse streams incrementally. Furthermore, he greatly improved the parser class by allowing the definition of a filter function to discard undesired elements while parsing. +- [Daniel Kopeček](https://github.com/dkopecek) fixed a bug in the compilation with GCC 5.0. +- [Florian Weber](https://github.com/Florianjw) fixed a bug in and improved the performance of the comparison operators. +- [Eric Cornelius](https://github.com/EricMCornelius) pointed out a bug in the handling with NaN and infinity values. He also improved the performance of the string escaping. +- [易思龙](https://github.com/likebeta) implemented a conversion from anonymous enums. +- [kepkin](https://github.com/kepkin) patiently pushed forward the support for Microsoft Visual studio. +- [gregmarr](https://github.com/gregmarr) simplified the implementation of reverse iterators and helped with numerous hints and improvements. In particular, he pushed forward the implementation of user-defined types. +- [Caio Luppi](https://github.com/caiovlp) fixed a bug in the Unicode handling. +- [dariomt](https://github.com/dariomt) fixed some typos in the examples. +- [Daniel Frey](https://github.com/d-frey) cleaned up some pointers and implemented exception-safe memory allocation. +- [Colin Hirsch](https://github.com/ColinH) took care of a small namespace issue. +- [Huu Nguyen](https://github.com/whoshuu) correct a variable name in the documentation. +- [Silverweed](https://github.com/silverweed) overloaded `parse()` to accept an rvalue reference. +- [dariomt](https://github.com/dariomt) fixed a subtlety in MSVC type support and implemented the `get_ref()` function to get a reference to stored values. +- [ZahlGraf](https://github.com/ZahlGraf) added a workaround that allows compilation using Android NDK. +- [whackashoe](https://github.com/whackashoe) replaced a function that was marked as unsafe by Visual Studio. +- [406345](https://github.com/406345) fixed two small warnings. +- [Glen Fernandes](https://github.com/glenfe) noted a potential portability problem in the `has_mapped_type` function. +- [Corbin Hughes](https://github.com/nibroc) fixed some typos in the contribution guidelines. +- [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. He further added support for unsigned integer numbers and implemented better roundtrip support for parsed numbers. +- [Volker Diels-Grabsch](https://github.com/vog) fixed a link in the README file. +- [msm-](https://github.com/msm-) added support for american fuzzy lop. +- [Annihil](https://github.com/Annihil) fixed an example in the README file. +- [Themercee](https://github.com/Themercee) noted a wrong URL in the README file. +- [Lv Zheng](https://github.com/lv-zheng) fixed a namespace issue with `int64_t` and `uint64_t`. +- [abc100m](https://github.com/abc100m) analyzed the issues with GCC 4.8 and proposed a [partial solution](https://github.com/nlohmann/json/pull/212). +- [zewt](https://github.com/zewt) added useful notes to the README file about Android. +- [Róbert Márki](https://github.com/robertmrk) added a fix to use move iterators and improved the integration via CMake. +- [Chris Kitching](https://github.com/ChrisKitching) cleaned up the CMake files. +- [Tom Needham](https://github.com/06needhamt) fixed a subtle bug with MSVC 2015 which was also proposed by [Michael K.](https://github.com/Epidal). +- [Mário Feroldi](https://github.com/thelostt) fixed a small typo. +- [duncanwerner](https://github.com/duncanwerner) found a really embarrassing performance regression in the 2.0.0 release. +- [Damien](https://github.com/dtoma) fixed one of the last conversion warnings. +- [Thomas Braun](https://github.com/t-b) fixed a warning in a test case. +- [Théo DELRIEU](https://github.com/theodelrieu) patiently and constructively oversaw the long way toward [iterator-range parsing](https://github.com/nlohmann/json/issues/290). He also implemented the magic behind the serialization/deserialization of user-defined types. +- [Stefan](https://github.com/5tefan) fixed a minor issue in the documentation. +- [Vasil Dimov](https://github.com/vasild) fixed the documentation regarding conversions from `std::multiset`. +- [ChristophJud](https://github.com/ChristophJud) overworked the CMake files to ease project inclusion. +- [Vladimir Petrigo](https://github.com/vpetrigo) made a SFINAE hack more readable and added Visual Studio 17 to the build matrix. +- [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file. +- [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function. +- [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](http://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser, improved the benchmarking code, and realized locale-independent number parsing and printing. +- [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan. +- [Jared Grubb](https://github.com/jaredgrubb) silenced a nasty documentation warning. +- [Yixin Zhang](https://github.com/qwename) fixed an integer overflow check. +- [Bosswestfalen](https://github.com/Bosswestfalen) merged two iterator classes into a smaller one. +- [Daniel599](https://github.com/Daniel599) helped to get Travis execute the tests with Clang's sanitizers. +- [Jonathan Lee](https://github.com/vjon) fixed an example in the README file. +- [gnzlbg](https://github.com/gnzlbg) supported the implementation of user-defined types. +- [Alexej Harm](https://github.com/qis) helped to get the user-defined types working with Visual Studio. +- [Jared Grubb](https://github.com/jaredgrubb) supported the implementation of user-defined types. +- [EnricoBilla](https://github.com/EnricoBilla) noted a typo in an example. +- [Martin Hořeňovský](https://github.com/horenmar) found a way for a 2x speedup for the compilation time of the test suite. +- [ukhegg](https://github.com/ukhegg) found proposed an improvement for the examples section. +- [rswanson-ihi](https://github.com/rswanson-ihi) noted a typo in the README. +- [Mihai Stan](https://github.com/stanmihai4) fixed a bug in the comparison with `nullptr`s. +- [Tushar Maheshwari](https://github.com/tusharpm) added [cotire](https://github.com/sakra/cotire) support to speed up the compilation. +- [TedLyngmo](https://github.com/TedLyngmo) noted a typo in the README, removed unnecessary bit arithmetic, and fixed some `-Weffc++` warnings. +- [Krzysztof Woś](https://github.com/krzysztofwos) made exceptions more visible. +- [ftillier](https://github.com/ftillier) fixed a compiler warning. +- [tinloaf](https://github.com/tinloaf) made sure all pushed warnings are properly popped. +- [Fytch](https://github.com/Fytch) found a bug in the documentation. +- [Jay Sistar](https://github.com/Type1J) implemented a Meson build description. +- [Henry Lee](https://github.com/HenryRLee) fixed a warning in ICC and improved the iterator implementation. +- [Vincent Thiery](https://github.com/vthiery) maintains a package for the Conan package manager. +- [Steffen](https://github.com/koemeet) fixed a potential issue with MSVC and `std::min`. +- [Mike Tzou](https://github.com/Chocobo1) fixed some typos. +- [amrcode](https://github.com/amrcode) noted a missleading documentation about comparison of floats. +- [Oleg Endo](https://github.com/olegendo) reduced the memory consumption by replacing `<iostream>` with `<iosfwd>`. +- [dan-42](https://github.com/dan-42) cleaned up the CMake files to simplify including/reusing of the library. +- [Nikita Ofitserov](https://github.com/himikof) allowed for moving values from initializer lists. +- [Greg Hurrell](https://github.com/wincent) fixed a typo. +- [Dmitry Kukovinets](https://github.com/DmitryKuk) fixed a typo. +- [kbthomp1](https://github.com/kbthomp1) fixed an issue related to the Intel OSX compiler. +- [Markus Werle](https://github.com/daixtrose) fixed a typo. +- [WebProdPP](https://github.com/WebProdPP) fixed a subtle error in a precondition check. + +Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone. + +## Used third-party tools + +The library itself contains of a single header file licensed under the MIT license. However, it is built, tested, documented, and whatnot using a lot of third-party tools and services. Thanks a lot! + +- [**American fuzzy lop**](http://lcamtuf.coredump.cx/afl/) for fuzz testing +- [**AppVeyor**](https://www.appveyor.com) for [continuous integration](https://ci.appveyor.com/project/nlohmann/json) on Windows +- [**Artistic Style**](http://astyle.sourceforge.net) for automatic source code identation +- [**benchpress**](https://github.com/sbs-ableton/benchpress) to benchmark the code +- [**Catch**](https://github.com/philsquared/Catch) for the unit tests +- [**Clang**](http://clang.llvm.org) for compilation with code sanitizers +- [**Cmake**](https://cmake.org) for build automation +- [**Codacity**](https://www.codacy.com) for further [code analysis](https://www.codacy.com/app/nlohmann/json) +- [**cotire**](https://github.com/sakra/cotire) to speed of compilation +- [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json) +- [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json) +- [**cppcheck**](http://cppcheck.sourceforge.net) for static analysis +- [**cxxopts**](https://github.com/jarro2783/cxxopts) to let benchpress parse command-line parameters +- [**Doxygen**](http://www.stack.nl/~dimitri/doxygen/) to generate [documentation](https://nlohmann.github.io/json/) +- [**git-update-ghpages**](https://github.com/rstacruz/git-update-ghpages) to upload the documentation to gh-pages +- [**Github Changelog Generator**](https://github.com/skywinder/github-changelog-generator) to generate the [ChangeLog](https://github.com/nlohmann/json/blob/develop/ChangeLog.md) +- [**libFuzzer**](http://llvm.org/docs/LibFuzzer.html) to implement fuzz testing for OSS-Fuzz +- [**OSS-Fuzz**](https://github.com/google/oss-fuzz) for continuous fuzz testing of the library +- [**send_to_wandbox**](https://github.com/nlohmann/json/blob/develop/doc/scripts/send_to_wandbox.py) to send code examples to [Wandbox](http://melpon.org/wandbox) +- [**Travis**](https://travis-ci.org) for [continuous integration](https://travis-ci.org/nlohmann/json) on Linux and macOS +- [**Valgrind**](http://valgrind.org) to check for correct memory management +- [**Wandbox**](http://melpon.org/wandbox) for [online examples](http://melpon.org/wandbox/permlink/4NEU6ZZMoM9lpIex) + +## Projects using JSON for Modern C++ + +The library is currently used in Apple macOS Sierra and iOS 10. I am not sure what they are using the library for, but I am happy that it runs on so many devices. + +## Notes + +- The code contains numerous debug **assertions** which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](http://en.cppreference.com/w/cpp/error/assert). In particular, note [`operator[]`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a2e26bd0b0168abb61f67ad5bcd5b9fa1.html#a2e26bd0b0168abb61f67ad5bcd5b9fa1) implements **unchecked access** for const objects: If the given key is not present, the behavior is undefined (think of a dereferenced null pointer) and yields an [assertion failure](https://github.com/nlohmann/json/issues/289) if assertions are switched on. If you are not sure whether an element in an object exists, use checked access with the [`at()` function](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a674de1ee73e6bf4843fc5dc1351fb726.html#a674de1ee73e6bf4843fc5dc1351fb726). +- As the exact type of a number is not defined in the [JSON specification](http://rfc7159.net/rfc7159), this library tries to choose the best fitting C++ number type automatically. As a result, the type `double` may be used to store numbers which may yield [**floating-point exceptions**](https://github.com/nlohmann/json/issues/181) in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions. +- The library supports **Unicode input** as follows: + - Only **UTF-8** encoded input is supported which is the default encoding for JSON according to [RFC 7159](http://rfc7159.net/rfc7159#rfc.section.8.1). + - Other encodings such as Latin-1, UTF-16, or UTF-32 are not supported and will yield parse errors. + - [Unicode noncharacters](http://www.unicode.org/faq/private_use.html#nonchar1) will not be replaced by the library. + - Invalid surrogates (e.g., incomplete pairs such as `\uDEAD`) will yield parse errors. + - The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs. +- The code can be compiled without C++ **runtime type identification** features; that is, you can use the `-fno-rtti` compiler flag. +- **Exceptions** are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by an `abort()` call. +- By default, the library does not preserve the **insertion order of object elements**. This is standards-compliant, as the [JSON standard](https://tools.ietf.org/html/rfc7159.html) defines objects as "an unordered collection of zero or more name/value pairs". If you do want to preserve the insertion order, you can specialize the object type with containers like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map). + +## Execute unit tests + +To compile and run the tests, you need to execute + +```sh +$ make json_unit -Ctest +$ ./test/json_unit "*" + +=============================================================================== +All tests passed (14504461 assertions in 48 test cases) +``` + +Alternatively, you can use [CMake](https://cmake.org) and run + +```sh +mkdir build +cd build +cmake .. +make +ctest +``` + +For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml). diff --git a/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.8_C_JSON_Wrapper.md b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.8_C_JSON_Wrapper.md new file mode 100644 index 0000000..e236248 --- /dev/null +++ b/docs/3_Developer_Guides/6_AFB_Helper_Guide/3.7.8_C_JSON_Wrapper.md @@ -0,0 +1,344 @@ +--- +edit_link: '' +title: C JSON Wrapper +origin_url: >- + https://git.automotivelinux.org/src/libafb-helpers/plain/docs/wrap-json.md?h=master +--- + +<!-- WARNING: This file is generated by fetch_docs.js using /home/boron/Documents/AGL/docs-webtemplate/site/_data/tocs/devguides/master/afb-helpers-function-references-afb-helpers-book.yml --> + +WRAP-JSON facility +================== + +The facility wrap-json is based on the pack/unpack API on the +library jansson. The two chapters below are copied from the +documentation of jansson library copyrighted by Petri Lehtinen +(see at end). + +Building Values +--------------- + +This section describes functions that help to create, or *pack*, complex +JSON values, especially nested objects and arrays. Value building is +based on a *format string* that is used to tell the functions about the +expected arguments. + +For example, the format string `"i"` specifies a single integer value, +while the format string `"[ssb]"` or the equivalent `"[s, s, b]"` +specifies an array value with two strings and a boolean as its items: + + /* Create the JSON integer 42 */ + wrap_json_pack(&result, "i", 42); + + /* Create the JSON array ["foo", "bar", true] */ + wrap_json_pack(&result, "[ssb]", "foo", "bar", 1); + +Here's the full list of format specifiers. The type in parentheses +denotes the resulting JSON type, and the type in brackets (if any) +denotes the C type that is expected as the corresponding argument or +arguments. + +`s` (string) \[const char \*\] + +: Convert a null terminated UTF-8 string to a JSON string. + +`s?` (string) \[const char \*\] + +: Like `s`, but if the argument is *NULL*, output a JSON null value. + +`s*` (string) \[const char \*\] + +: Like `s`, but if the argument is *NULL*, do not output any value. + This format can only be used inside an object or an array. If used + inside an object, the corresponding key is additionally suppressed + when the value is omitted. See below for an example. + +`s#` (string) \[const char \*, int\] + +: Convert a UTF-8 buffer of a given length to a JSON string. + +`s%` (string) \[const char \*, size\_t\] + +: Like `s#` but the length argument is of type size\_t. + +`+` \[const char \*\] + +: Like `s`, but concatenate to the previous string. Only valid after + `s`, `s#`, `+` or `+#`. + +`+#` \[const char \*, int\] + +: Like `s#`, but concatenate to the previous string. Only valid after + `s`, `s#`, `+` or `+#`. + +`+%` (string) \[const char \*, size\_t\] + +: Like `+#` but the length argument is of type size\_t. + +`y` (byte array) \[const uint8_t \*, size\_t\] + +: Convert the byte array whose length is given to + its base64url string representation. + +`Y` (byte array) \[const uint8_t \*, size\_t\] + +: Like 'y' but output is base64. + +`y?`, `Y?` (byte array or null) \[const uint8_t \*, size\_t\] + +: Like 'y' or 'Y' but allows to output a JSON null value + either when the buffer is *NULL* or when the size is *0*. + +`y*`, `y*` (optional byte array) \[const uint8_t \*, size\_t\] + +: Like 'y' or 'Y' but do not put JSON value + either when the buffer is *NULL* or when the size is *0*. + This format can only be used inside an object or an array. If used + inside an object, the corresponding key is additionally suppressed + when the value is omitted. See below for an example. + +`n` (null) + +: Output a JSON null value. No argument is consumed. + +`b` (boolean) \[int\] + +: Convert a C int to JSON boolean value. Zero is converted to `false` + and non-zero to `true`. + +`i` (integer) \[int\] + +: Convert a C int to JSON integer. + +`I` (integer) \[json\_int\_t\] + +: Convert a C json\_int\_t to JSON integer. + +`f` (real) \[double\] + +: Convert a C double to JSON real. + +`o` (any value) \[json\_t \*\] + +: Output any given JSON value as-is. If the value is added to an array + or object, the reference to the value passed to `o` is stolen by the + container. + +`O` (any value) \[json\_t \*\] + +: Like `o`, but the argument's reference count is incremented. This is + useful if you pack into an array or object and want to keep the + reference for the JSON value consumed by `O` to yourself. + +`o?`, `O?` (any value) \[json\_t \*\] + +: Like `o` and `O`, respectively, but if the argument is *NULL*, + output a JSON null value. + +`o*`, `O*` (any value) \[json\_t \*\] + +: Like `o` and `O`, respectively, but if the argument is *NULL*, do + not output any value. This format can only be used inside an object + or an array. If used inside an object, the corresponding key is + additionally suppressed. See below for an example. + +`[fmt]` (array) + +: Build an array with contents from the inner format string. `fmt` may + contain objects and arrays, i.e. recursive value building is + supported. + +`{fmt}` (object) + +: Build an object with contents from the inner format string `fmt`. + The first, third, etc. format specifier represent a key, and must be + a string (see `s`, `s#`, `+` and `+#` above), as object keys are + always strings. The second, fourth, etc. format specifier represent + a value. Any value may be an object or array, i.e. recursive value + building is supported. + +Whitespace, `:` and `,` are ignored. + +More examples: + + /* Build an empty JSON object */ + wrap_json_pack(&result, "{}"); + + /* Build the JSON object {"foo": 42, "bar": 7} */ + wrap_json_pack(&result, "{sisi}", "foo", 42, "bar", 7); + + /* Like above, ':', ',' and whitespace are ignored */ + wrap_json_pack(&result, "{s:i, s:i}", "foo", 42, "bar", 7); + + /* Build the JSON array [[1, 2], {"cool": true}] */ + wrap_json_pack(&result, "[[i,i],{s:b}]", 1, 2, "cool", 1); + + /* Build a string from a non-null terminated buffer */ + char buffer[4] = {'t', 'e', 's', 't'}; + wrap_json_pack(&result, "s#", buffer, 4); + + /* Concatenate strings together to build the JSON string "foobarbaz" */ + wrap_json_pack(&result, "s++", "foo", "bar", "baz"); + + /* Create an empty object or array when optional members are missing */ + wrap_json_pack(&result, "{s:s*,s:o*,s:O*}", "foo", NULL, "bar", NULL, "baz", NULL); + wrap_json_pack(&result, "[s*,o*,O*]", NULL, NULL, NULL); + +Parsing and Validating Values +----------------------------- + +This section describes functions that help to validate complex values +and extract, or *unpack*, data from them. Like building values +<apiref-pack>, this is also based on format strings. + +While a JSON value is unpacked, the type specified in the format string +is checked to match that of the JSON value. This is the validation part +of the process. In addition to this, the unpacking functions can also +check that all items of arrays and objects are unpacked. This check be +enabled with the format specifier `!` or by using the flag +`JSON_STRICT`. See below for details. + +Here's the full list of format specifiers. The type in parentheses +denotes the JSON type, and the type in brackets (if any) denotes the C +type whose address should be passed. + +`s` (string) \[const char \*\] + +: Convert a JSON string to a pointer to a null terminated UTF-8 + string. The resulting string is extracted by using + json\_string\_value() internally, so it exists as long as there are + still references to the corresponding JSON string. + +`s%` (string) \[const char \*, size\_t \*\] + +: Convert a JSON string to a pointer to a null terminated UTF-8 string + and its length. + +`y` (byte array) \[uint8_t \*\*, size\_t \*\] + +: Convert an input string base64url encoded to its + byte array representation. The result and its length + are stored. The returned buffer must be freed by the caller. + +`Y` (byte array) \[uint8_t \*\*, size\_t \*\] + +: Like 'y' but input is base64. + +`n` (null) + +: Expect a JSON null value. Nothing is extracted. + +`b` (boolean) \[int\] + +: Convert a JSON boolean value to a C int, so that `true` is converted + to 1 and `false` to 0. + +`i` (integer) \[int\] + +: Convert a JSON integer to C int. + +`I` (integer) \[json\_int\_t\] + +: Convert a JSON integer to C json\_int\_t. + +`f` (real) \[double\] + +: Convert a JSON real to C double. + +`F` (integer or real) \[double\] + +: Convert a JSON number (integer or real) to C double. + +`o` (any value) \[json\_t \*\] + +: Store a JSON value with no conversion to a json\_t pointer. + +`O` (any value) \[json\_t \*\] + +: Like `O`, but the JSON value's reference count is incremented. + +`[fmt]` (array) + +: Convert each item in the JSON array according to the inner format + string. `fmt` may contain objects and arrays, i.e. recursive value + extraction is supported. + +`{fmt}` (object) + +: Convert each item in the JSON object according to the inner format + string `fmt`. The first, third, etc. format specifier represent a + key, and must be `s`. The corresponding argument to unpack functions + is read as the object key. The second fourth, etc. format specifier + represent a value and is written to the address given as the + corresponding argument. **Note** that every other argument is read + from and every other is written to. + + `fmt` may contain objects and arrays as values, i.e. recursive value + extraction is supported. + +`!` + +: This special format specifier is used to enable the check that all + object and array items are accessed, on a per-value basis. It must + appear inside an array or object as the last format specifier before + the closing bracket or brace. + +`*` + +: This special format specifier is the opposite of `!`. This is the default. + It must appear inside an array or object as the last format specifier + before the closing bracket or brace. + +Whitespace, `:` and `,` are ignored. + +Examples: + + /* root is the JSON integer 42 */ + int myint; + wrap_json_unpack(root, "i", &myint); + assert(myint == 42); + + /* root is the JSON object {"foo": "bar", "quux": true} */ + const char *str; + int boolean; + wrap_json_unpack(root, "{s:s, s:b}", "foo", &str, "quux", &boolean); + assert(strcmp(str, "bar") == 0 && boolean == 1); + + /* root is the JSON array [[1, 2], {"baz": null} */ + wrap_json_check(root, "[[i,i], {s:n}]", "baz"); + /* returns 0 for validation success, nothing is extracted */ + + /* root is the JSON array [1, 2, 3, 4, 5] */ + int myint1, myint2; + wrap_json_unpack(root, "[ii!]", &myint1, &myint2); + /* returns -1 for failed validation */ + + /* root is an empty JSON object */ + int myint = 0, myint2 = 0, myint3 = 0; + wrap_json_unpack(root, "{s?i, s?[ii]}", + "foo", &myint1, + "bar", &myint2, &myint3); + /* myint1, myint2 or myint3 is no touched as "foo" and "bar" don't exist */ + +Copyright +--------- + +Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/3.8.1_How_to_write_tests_(overview_slides).md b/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/3.8.1_How_to_write_tests_(overview_slides).md new file mode 100644 index 0000000..70f817c --- /dev/null +++ b/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/3.8.1_How_to_write_tests_(overview_slides).md @@ -0,0 +1 @@ +[**How to write tests (overview slides)**](How_to_write_your_own_tests_for_AGL.pdf) diff --git a/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/3.8.2_How_to_write_tests_(detailed).md b/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/3.8.2_How_to_write_tests_(detailed).md new file mode 100644 index 0000000..162e64b --- /dev/null +++ b/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/3.8.2_How_to_write_tests_(detailed).md @@ -0,0 +1 @@ +[**How to write tests (detailed)**](Hands_on_lab_documentation.pdf) diff --git a/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/Hands_on_lab_documentation.pdf b/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/Hands_on_lab_documentation.pdf Binary files differnew file mode 100644 index 0000000..096780d --- /dev/null +++ b/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/Hands_on_lab_documentation.pdf diff --git a/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/How_to_write_your_own_tests_for_AGL.pdf b/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/How_to_write_your_own_tests_for_AGL.pdf Binary files differnew file mode 100644 index 0000000..4e37f7f --- /dev/null +++ b/docs/3_Developer_Guides/7_Continuous_Integration_-_Automated_Testing_(CIAT)/How_to_write_your_own_tests_for_AGL.pdf |