Building#
Oasis application development and building are primarily conducted on a host PC (such as x86_64 Ubuntu).
Since Oasis is modularly structured by component, applications are built using only the specific component libraries they require.
If the processor of the target device where the Oasis application will run differs from the host PC's processor or lacks binary compatibility, cross-compilation is performed.
This section explains how to build using a Makefile and how to build using CMake.
It is assumed that the target device processor is aarch64 and the GCC cross-toolchain is installed at /opt/vtcs_toolchain/leipzig on the host PC.
The Oasis SDK is assumed to be located in the following directories on the host PC:
- Libraries:
/opt/oasis/sdk-4.3.29/lib - Header Files:
/opt/oasis/sdk-4.3.29/include
hello.cpp#
The following code (hello.cpp) is an application code provided to demonstrate the build process.
Once the build is complete, the Oasis application named hello will be generated.
#include "OasisAPI.h"
#include "OasisLog.h"
#include "OasisUI.h"
#include "OasisUtil.h"
#include "OasisDisplay.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <thread>
#include <mutex>
#include <memory>
#include <condition_variable>
#undef DLOG_TAG
#define DLOG_TAG "Hello"
using namespace oasis;
bool got_interrupt = false;
#include <signal.h>
// SIGINT handler. Terminates the program.
void cancel_handler(int sig)
{
got_interrupt = true;
}
// Function called when the "Capture Me!" button is clicked. Captures the screen and saves it to /tmp.
void captureMeClicked(ui::WidgetRef widget)
{
ui::ScreenRef screen = ui::getDefaultScreen();
std::vector<uint8_t> png_data;
char image_path[PATH_MAX];
time_t t;
struct tm tm_t;
time(&t);
localtime_r(&t, &tm_t);
sprintf(image_path, "/tmp/snapshot_%4d-%02d-%02d-%02d-%02d-%02d.png", tm_t.tm_year + 1900, tm_t.tm_mon + 1, tm_t.tm_mday, tm_t.tm_hour, tm_t.tm_min, tm_t.tm_sec);
if(ui::takeScreenShot(screen, png_data) > 0) {
printf("saved to %s\n", image_path);
writeFile(png_data.data(), png_data.size(), image_path);
}
}
// Function called when the "Goodbye!" button is clicked. Terminates the program.
void goodbyeClicked(ui::WidgetRef widget)
{
got_interrupt = true;
}
int main(int argc, char *argv[])
{
int32_t err;
signal(SIGINT, cancel_handler);
oasis::key_value_map_t parameters;
// Initializes Oasis. Disables the Oasis file system.
parameters["offs-disable"] = "1";
if(oasis::initialize(parameters) < 0) {
DLOG(DLOG_ERROR, "Oasis init failed\n");
return -1;
}
// Initializes the display device.
parameters.clear();
parameters["memory-type"] = "ion"; // cma
parameters["screen-width"] = "480";
parameters["screen-height"] = "320";
display::setup(parameters);
// Initializes the GUI.
parameters.clear();
parameters["system-font-size"] = "11";
parameters["system-font-path"] = "/mnt/sd/NanumGothicCoding.ttf";
parameters["display-rotation"] = "0";
parameters["enable-touch"] = "1";
parameters["touch-cal-data-path"] = "/mnt/sd/cal.dat";
err = ui::setup(parameters);
if (err < 0) {
DLOG(DLOG_ERROR, "Oasis ui::setup failed\n");
oasis::finalize();
return -1;
}
// Obtains the default screen object.
ui::ScreenRef screen = ui::getDefaultScreen();
// Creates the top-level Window. It is hidden upon creation.
ui::WindowRef window = ui::createWindow("Hello");
// Creates a vertical Box layout object inside the top-level Window.
ui::BoxRef vbox = ui::createBox(ui::kOrientationVertical, false, 6);
// Ensures the Box layout is centered after being added to the Window.
ui::setVAlign(vbox, ui::kAlignCenter);
// Creates Labels 1, 2, and 3, and adds each to the Box layout.
ui::LabelRef label = ui::createLabelWithText("Hello, World!");
ui::setVAlign(label, ui::kAlignCenter);
ui::setHAlign(label, ui::kAlignCenter);
ui::setLabelHorzJustification(label, ui::kJustificationCenter);
ui::setLabelVertJustification(label, ui::kJustificationCenter);
ui::setLabelFontPointSize(label, 16);
ui::boxPackStart(vbox, label, true, true, 0);
ui::LabelRef label2 = ui::createLabelWithText("μλ
νμΈμ!");
ui::setVAlign(label2, ui::kAlignCenter);
ui::setHAlign(label2, ui::kAlignCenter);
ui::setLabelHorzJustification(label2, ui::kJustificationCenter);
ui::setLabelVertJustification(label2, ui::kJustificationCenter);
ui::setLabelFontPointSize(label2, 13);
ui::boxPackStart(vbox, label2, true, true, 0);
ui::LabelRef label3 = ui::createLabelWithText("γγγ«γ‘γ―!");
ui::setVAlign(label3, ui::kAlignCenter);
ui::setHAlign(label3, ui::kAlignCenter);
ui::setLabelHorzJustification(label3, ui::kJustificationCenter);
ui::setLabelVertJustification(label3, ui::kJustificationCenter);
ui::setLabelFontPointSize(label3, 13);
ui::boxPackStart(vbox, label3, true, true, 0);
// Creates the "Goodbye!" button and adds it starting from the end of the Box layout.
ui::ButtonRef close_button = ui::createButtonWithLabel("Goodbye!", true);
ui::setID(close_button, "close_button");
ui::setLabelFontPointSize(ui::getButtonLabel(close_button), 13);
ui::setLabelTextColor(ui::getButtonLabel(close_button), Color(255, COLOR_YELLOW));
ui::setVAlign(close_button, ui::kAlignCenter);
ui::setHAlign(close_button, ui::kAlignCenter);
ui::boxPackEnd(vbox, close_button, false, true, 0);
// Creates the "Capture Me!" button and adds it starting from the end of the Box layout.
ui::ButtonRef capture_button = ui::createButtonWithLabel("Capture Me!", true);
ui::setID(capture_button, "capture_me_button");
ui::setLabelFontPointSize(ui::getButtonLabel(capture_button), 13);
ui::setLabelTextColor(ui::getButtonLabel(capture_button), Color(255, COLOR_YELLOW));
ui::setVAlign(capture_button, ui::kAlignCenter);
ui::setHAlign(capture_button, ui::kAlignCenter);
ui::boxPackEnd(vbox, capture_button, false, true, 20);
// Connects the callback function for the "Capture Me!" button click event.
ui::connectSignal(capture_button, "clicked", clicked_slot_t(sig::ptr_fn(&captureMeClicked)), 0);
// Connects the callback function for the "Goodbye!" button click event.
ui::connectSignal(close_button, "clicked", clicked_slot_t(sig::ptr_fn(&goodbyeClicked)), 0);
// Adds the Box layout to the top-level Window.
ui::containerAdd(window, vbox);
// Adds the Window to the screen.
ui::screenAdd(screen, window);
// Makes the top-level Window visible.
ui::setVisible(window, true);
// Keeps the main thread waiting until a termination signal is received.
do {
usleep(100000);
} while(got_interrupt == false);
// Releases the GUI.
err = ui::cleanup();
// Releases Oasis.
oasis::finalize();
return 0;
}
Building with a Makefile#
-
Create a
Makefilewith the following content in the source directory containinghello.cpp.# Set up the cross-toolchain environment. CROSS_COMPILER_PREFIX = aarch64-linux- EXTERNAL_TOOLCHAIN_ROOT = /opt/vtcs_toolchain/leipzig/usr/ EXTERNAL_TOOLCHAIN_PATH = $(EXTERNAL_TOOLCHAIN_ROOT)bin/ SYSROOT = $(EXTERNAL_TOOLCHAIN_ROOT)/aarch64-buildroot-linux-gnu/sysroot CC = $(EXTERNAL_TOOLCHAIN_PATH)$(CROSS_COMPILER_PREFIX)gcc CXX = $(EXTERNAL_TOOLCHAIN_PATH)$(CROSS_COMPILER_PREFIX)g++ LD = $(EXTERNAL_TOOLCHAIN_PATH)$(CROSS_COMPILER_PREFIX)ld AR = $(EXTERNAL_TOOLCHAIN_PATH)$(CROSS_COMPILER_PREFIX)ar # Set up the Oasis SDK environment. OASIS_SDK_ROOT = /opt/oasis/sdk-4.3.29/ OASIS_INC_PATH = $(OASIS_SDK_ROOT)/include OASIS_LIB_PATH = $(OASIS_SDK_ROOT)/lib OASIS_LIBS = -loasis_codec -loasis_fs -loasis_pipe -loasis_media -loasis_ui -loasis_util -loasis_certs -loasis_disp -loasis OASIS_DEFS = -DOASIS_NO_NVWA # Configure the target. TARGET = hello SRCS = hello.cpp OBJS = $(SRCS:.cpp=.o) CXXFLAGS += -I$(OASIS_INC_PATH) --sysroot=$(SYSROOT) LDFLAGS += -s -L$(OASIS_LIB_PATH) $(OASIS_LIBS) CXXFLAGS += -std=c++17 -O2 -g $(OASIS_DEFS) # Configure other dependent libraries. LIBS = -lexif -lpng16 -ljpeg -lfreetype -lz -ljsoncpp -lrt -lpthread -lcva -lvmf_nnm -lvmf -lvdec -lutil -liniparser .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJS) $(CXX) $(LDFLAGS) $^ $(LIBS) -o $@ %.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ clean: rm -f $(OBJS) $(TARGET) -
Build the application inside the source directory using the
makecommand.$ make $ ls -l total 1144 -rwxrwxr-x 1 cobenhan cobenhan 133176 Mar 14 00:59 hello -rw-rw-r-- 1 cobenhan cobenhan 5121 Mar 14 00:43 hello.cpp -rw-rw-r-- 1 cobenhan cobenhan 1023288 Mar 14 00:59 hello.o -rw-rw-r-- 1 cobenhan cobenhan 1446 Mar 14 00:59 Makefile
Building with CMake#
-
Create a
toolchain.cmakefile with the following content in the source directory containinghello.cpp.# this one is important SET(CMAKE_SYSTEM_NAME Linux) #this one not so much SET(CMAKE_SYSTEM_VERSION 1) SET(CMAKE_SYSTEM_PROCESSOR aarch64) SET(EXTERNAL_TOOLCHAIN_ROOT /opt/vtcs_toolchain/leipzig/usr/) SET(EXTERNAL_TOOLCHAIN_PATH ${EXTERNAL_TOOLCHAIN_ROOT}/bin) SET(CROSS_COMPILER_PREFIX aarch64-linux-) # specify the cross compiler SET(CMAKE_C_COMPILER /opt/vtcs_toolchain/leipzig/usr/bin/aarch64-linux-gcc) SET(CMAKE_CXX_COMPILER ${EXTERNAL_TOOLCHAIN_PATH}/aarch64-linux-g++) SET(CMAKE_AR_COMPILER ${EXTERNAL_TOOLCHAIN_PATH}/aarch64-linux-ar) SET(CMAKE_STRIP_COMPILER ${EXTERNAL_TOOLCHAIN_PATH}/aarch64-linux-strip) SET(CMAKE_SYSROOT ${EXTERNAL_TOOLCHAIN_ROOT}/aarch64-buildroot-linux-gnu/sysroot) # where is the target environment SET(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${EXTERNAL_TOOLCHAIN_ROOT}) SET(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${EXTERNAL_TOOLCHAIN_ROOT}/aarch64-buildroot-linux-gnu) SET(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${EXTERNAL_TOOLCHAIN_ROOT}/aarch64-buildroot-linux-gnu/sysroot/lib) # search for programs in the build host directories SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # for libraries and headers in the target directories SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # SET(TOOLSDIR /opt/vtcs_toolchain/leipzig) SET(CMAKE_ASM_COMPILER ${EXTERNAL_TOOLCHAIN_PATH}/${CROSS_COMPILER_PREFIX}gcc) # Override ar and ranlib tools that CMake should use for linking lib SET(CMAKE_AR ${EXTERNAL_TOOLCHAIN_PATH}/${CROSS_COMPILER_PREFIX}ar CACHE STRING "") SET(CMAKE_RANLIB ${EXTERNAL_TOOLCHAIN_PATH}/${CROSS_COMPILER_PREFIX}ranlib CACHE STRING "") -
Create a
CMakeLists.txtfile with the following content in the source directory containinghello.cpp.cmake_minimum_required (VERSION 3.5.1) project (Hello) # Configure the Oasis SDK environment. include_directories(SYSTEM "/opt/oasis/sdk-4.3.29/include") #-Wl,-rpath,path1:path2:path3... link_directories(/opt/oasis/sdk-4.3.29/lib) add_definitions(-DOASIS_NO_NVWA -DOFFS_NO_NVWA) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -O2 -g") # strip set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s") # Configure the target. add_executable(hello hello.cpp) target_link_libraries(hello oasis_codec oasis_fs oasis_pipe oasis_media oasis_ui oasis_util oasis_certs oasis_disp oasis) target_link_libraries(hello cva vmf_nnm vmf vdec util iniparser) target_link_libraries(hello exif png16 jpeg freetype z jsoncpp) target_link_libraries(hello rt pthread) -
Proceed with the build as follows:
$ mkdir build $ ls -l total 20 drwxrwxr-x 3 cobenhan cobenhan 4096 Mar 14 01:46 build -rw-rw-r-- 1 cobenhan cobenhan 751 Mar 14 01:44 CMakeLists.txt -rw-rw-r-- 1 cobenhan cobenhan 5121 Mar 14 00:43 hello.cpp -rwxrwxr-x 1 cobenhan cobenhan 1679 Dec 11 16:27 toolchain.cmake $ cd build build$ cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake .. build$ make build$ ls -l total 164 -rw-rw-r-- 1 cobenhan cobenhan 14549 Mar 14 01:46 CMakeCache.txt drwxrwxr-x 6 cobenhan cobenhan 4096 Mar 14 01:46 CMakeFiles -rw-rw-r-- 1 cobenhan cobenhan 1716 Mar 14 01:46 cmake_install.cmake -rwxrwxr-x 1 cobenhan cobenhan 133176 Mar 14 01:46 hello -rw-rw-r-- 1 cobenhan cobenhan 5246 Mar 14 01:46 Makefile
Execution Result#
Following the build, install the application on the target device by referring to the Installation guide.
Below is the captured image generated by touching the Capture Me! button after running the application on the target device.
