Quick-Start
The Quick-Start guide explains how in a few steps you get from an API definition to a functional c++ example.
Steps one and two are universal for other technologies. In the step two you will choose a concrete cpp17 template. For more general information about first steps with ApiGear First Steps
The quick start enables only basic features: the api generation and simple stub implementation. For all available features check the overview.
1. Install the Code Generator
ApiGear provides two powerful tools: a Studio and a Command Line Interface (CLI). The Studio is a graphical tool for creating, editing API modules and projects, while the CLI is a command-line tool for generating code from API modules. Both offer comprehensive functionality, including SDK template management, API project creation, code generation, API monitoring, and API simulation.
Install ApiGear Studio
ApiGear Studio is available for macOS, Windows, and Linux. You can download it from the ApiGear Studio GitHub releases page.
For more detailed information on ApiGear Studio, refer to the dedicated studio documentation.
Install ApiGear CLI
The ApiGear CLI is a versatile command-line tool for generating code from API modules. It's available for macOS, Windows, and Linux. Download the latest version from the ApiGear CLI GitHub releases page.
The CLI offers all the features available in the Studio.
For more detailed information on the ApiGear CLI, consult the dedicated CLI documentation.
2. Obtain the Template
There are several methods to obtain the template: installation via the Studio, installation via the CLI, or cloning/downloading from GitHub.
The ApiGear Studio and the CLI detect the specified template in the solution document and install it automatically.
Optional steps (click to expand)
Installation via CLI
When using the CLI, only the highlighted line needs to be executed. You can verify the successful installation using the template cache
command.
- Unreal Engine
- C++14
- Qt6
- Python
$ apigear template install apigear-io/template-unreal@v3.2.2
$ apigear template cache
list of templates from the local cache
source | url | installed | latest
apigear-io/template-unreal@v3.2.2 | https://github.com/apigear-io/template-unreal.git | <sha1> | v3.2.2
...
$ apigear template install apigear-io/template-cpp14@v3.6.0
$ apigear template cache
list of templates from the local cache
source | url | installed | latest
apigear-io/template-cpp14@v3.6.0 | https://github.com/apigear-io/template-cpp14.git | <sha1> | v3.6.0
...
$ apigear template install apigear-io/template-qtcpp@v0.4.0
$ apigear template cache
list of templates from the local cache
source | url | installed | latest
apigear-io/template-qtcpp@v0.4.0 | https://github.com/apigear-io/template-qtcpp.git | <sha1> | v0.4.0
...
$ apigear template install apigear-io/template-python@v1.0.0
$ apigear template cache
list of templates from the local cache
source | url | installed | latest
apigear-io/template-python@v1.0.0 | https://github.com/apigear-io/template-python.git | <sha1> | v1.0.0
...
Installation via Studio
Installing the template through the Studio is straightforward:
- Unreal Engine
- C++14
- Qt6
- Python
- Open an existing project or create a new one
- Navigate to the
Templates
tab - Click
Install
on theapigear-io/template-unreal
entry
- Open an existing project or create a new one
- Navigate to the
Templates
tab - Click
Install
on theapigear-io/template-cpp14
entry
- Open an existing project or create a new one
- Navigate to the
Templates
tab - Click
Install
on theapigear-io/template-qtcpp
entry
- Open an existing project or create a new one
- Navigate to the
Templates
tab - Click
Install
on theapigear-io/template-python
entry
Cloning from GitHub
If you need to inspect or modify the template's source code, cloning or downloading the repository is recommended. The repository doesn't need to be part of your project and can be stored anywhere on your computer.
- Unreal Engine
- C++14
- Qt6
- Python
$ git clone https://github.com/apigear-io/template-unreal.git
$ git clone https://github.com/apigear-io/template-cpp14.git
$ git clone https://github.com/apigear-io/template-qtcpp.git
$ git clone https://github.com/apigear-io/template-python.git
You can then configure the solution file to use your template by providing the relative path from the solution file to the template directory.
3. Set Up the Project
A typical project requires two files: a solution file specifying the APIs and the template to use, and at least one API module file. Ideally, both should be placed in a folder named apigear
, adjacent to each other.
Alternatively, you can use the Studio to create a new project and modify the two example files provided.
Solution File
Create a solution file. The example below specifies:
- Module files in line 8, here the
helloworld.module.yaml
module with theHello
API - The output directory for generated files in line 9
- The template used to generate the code in line 10 (this can also be a path to a local copy of the template)
- The enabled features of the template in line 13, here the
stubs
feature, which provides a simple implementation of interfaces.
- Unreal Engine
- C++14
- Qt6
- Python
schema: "apigear.solution/1.0"
name: hello_world_example
version: "0.1.0"
targets:
- name: ue_docs
inputs:
- helloworld.module.yaml
output: ../ue_docs
template: apigear-io/template-unreal@v3.2.2
force: true
features:
- stubs
schema: "apigear.solution/1.0"
name: hello_world_example
version: "0.1.0"
targets:
- name: cpp_hello_world
inputs:
- helloworld.module.yaml
output: ../cpp_hello_world
template: apigear-io/template-cpp14@v3.6.0
force: true
features:
- stubs
schema: "apigear.solution/1.0"
name: hello_world_example
version: "0.1.0"
targets:
- name: qt_hello_world
inputs:
- helloworld.module.yaml
output: ../qt_hello_world
template: apigear-io/template-qtcpp@v0.4.0
force: true
features:
- stubs
schema: "apigear.solution/1.0"
name: hello_world_example
version: "0.1.0"
targets:
- name: hello_world
inputs:
- helloworld.module.yaml
output: ../py_hello_world
template: apigear-io/template-python@v1.0.0
force: true
features:
- stubs
You can extend this solution file with additional targets, each for a different technology with a different template. The module.yaml
file is technology-independent and can be used with any template.
We highly recommend specifying the exact version of the template. Otherwise, a newer version will be automatically downloaded and used for code generation. This can lead to unexpected behavior if file structures or code changes in the template.
Set the force
parameter to true
if you want to always override all generated files. When set to false
, some files, such as implementations (stub feature), won't be updated. API files are always updated regardless of this setting.
API Module File
Use your preferred text editor to create the helloworld.module.yaml
file with the following example content:
schema: apigear.module/1.0
name: io.world
version: "1.0.0"
interfaces:
- name: Hello
properties:
- { name: last, type: Message }
operations:
- name: say
params:
- { name: msg, type: Message }
- { name: when, type: When }
return:
type: int
signals:
- name: justSaid
params:
- { name: msg, type: Message }
enums:
- name: When
members:
- { name: Now, value: 0 }
- { name: Soon, value: 1 }
- { name: Never, value: 2 }
structs:
- name: Message
fields:
- { name: content, type: string }
4. Generate Code
Generate via CLI
The following snippet demonstrates how to run the CLI and provides an example output:
$ apigear generate solution apigear/helloworld.solution.yaml
10:52:20 INF generated 21 files in 30ms. (20 write, 0 skip, 1 copy) topic=gen
- The
generate
command instructs the CLI to generate code - The
solution
parameter specifies that we want to process a solution file
Generate via Studio
- Open the project
- Navigate to the
Solutions
tab - Click
Run
on thehelloworld.solution.yaml
entry
5. Use the generated cpp project
Project folder structure
With the output directory set as in the example, both ApiGear files reside in an apigear
subfolder next to the cpp generated files.
In this case the folder structure should look similar to this
📂hello-world
┣ 📂apigear
┃ ┣ 📜helloworld.solution.yaml
┃ ┗ 📜helloworld.module.yaml
┣ 📂cpp_hello_world
┃ ┣ 📂modules
┃ ┃ ┗ 📂io_world
┃ ┃ ┃ ┣ 📂generated
┃ ┃ ┃ ┣ 📂implementation
┃ ┃ ┃ ┃ ┣ 📜CMakeLists.txt
┃ ┃ ┃ ┃ ┣ 📜hello.cpp
┃ ┃ ┃ ┃ ┣ 📜hello.h
┃ ┃ ┃ ┃ ┗ 📜hello.test.cpp
┃ ┗ 📜CMakeLists.txt
Using the solution file from the previous paragraph the code will be generated in the cpp_hello_world
folder.
With subfolder for each module, here io_world
as the name of module (defined in line 2 of helloworld.module.yaml
).
It contains both features generated: a basic api and a stub implementation.
The generated code provides cpp C++ implementations. The following paragraphs show how you can use it.
You can start your project loading the top level CMakeLists.txt in cpp_hello_world
folder.
The 'io_world/io_world/generated/api/' folder contains all definitions of the enums and structs for your module, as well as the interface classes for your Interfaces. From now on you can simply include the header files for the api interface or the stub implementation and use it. For more details on generated features please check api, stubs.
Check our "examples" with all features enabled to get more working examples.
For the simulation check the olink feature which provides middle layer on your code side and the simulation explained.
Create and run an example
Prepare an examples
folder in the hello-world/cpp_hello_world
directory with a main.cpp
like this:
#include "io_world/implementation/hello.h"
#include <iostream>
int main(){
HelloWorldExample::IoWorld::Hello myHelloInstance;
// Try out properties: subscribe for changes
myHelloInstance._getPublisher().subscribeToLastChanged(
[](const HelloWorldExample::IoWorld::Message& last) { std::cout << "last property changed "; });
// and ask for change.
HelloWorldExample::IoWorld::Message messageForProperty;
messageForProperty.m_content "New message";
myHelloInstance.setLast(messageForProperty);
// Check the signals with subscribing for its change
myHelloInstance._getPublisher().subscribeToJustSaid(
[](const HelloWorldExample::IoWorld::Message& msg) { qDebug() << "justSaid signal emitted "; });
// and emit one.
HelloWorldExample::IoWorld::Message messageForSignal;
messageForSignal.m_content "Message from signal";
emit myHelloInstance.justSaid(messageForSignal);
// Play around executing operations, maybe they emit signals? or change the properties?
auto method_result = myHelloInstance.say(HelloWorldExample::IoWorld::Message(), HelloWorldExample::IoWorld::When::Now);
return 0;
}
add a CMakeLists.txt
to the examples
folder:
cmake_minimum_required(VERSION 3.1)
project(MyExample)
# append local binary directory for conan packages to be found
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(MyExample main.cpp)
# ensure maximum compiler support
if(NOT MSVC)
target_compile_options(app PRIVATE -Wall -Wextra -Wpedantic -Werror -fvisibility=hidden)
else()
target_compile_options(app PRIVATE /W4 /WX /wd4251)
endif()
find_package(io_world QUIET COMPONENTS io_world-core io_world-implementation )
target_link_libraries(app
io_world::io_world-core
io_world::io_world-implementation
)
install(TARGETS app
RUNTIME DESTINATION bin COMPONENT Runtime)
Add the examples
subdirectory to the hello-world/cpp_hello_world/CMakeLists.txt
. Now you can build the application and the libraries with it and run your example.
If generating all features, you'll need Poco library (websockets library used by OLink feature) or Paho (Mqtt library used by mqtt feature)'. You then may want to use conan feature, which will get all necessary dependencies.
Otherwise you might want to add
set(CMAKE_MODULE_PATH "path/to/your/poco_or_paho_build")
to your CMakeLists
or use option -DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/path/to/poco_or_paho_build
.
You might want also use conan for first time - to get you all those dependencies and then use paths provided by conan.