How to use alchemy toolchain?

Hi,
I want to build a library from source to use in my mission. I wanted to know if it is possible to pre-build a library using the alchemy toolchain and if it’s possible how can i do it ?

Best,
Thomas

Hi @thomC,

I assume that what you mean by pre-build is build and link your library sources and use them into your mission.
It is possible but it can require a considerable amount of work if your library has a lot of dependencies.

To build a library with the Alchemy toolchain you should use an atom.mk file that describes how to build the library. Alchemy can build libraries using autotools, cmake or even custom commands. Alchemy can build static/shared libraries as well as executables.
More information about alchemy you can find here.

Detailed example
I assume a AirSdk mission workspace as described in Cloning the workspace.

The workspace contains the following directory structure:

build/
build.sh
packages/
└── airsdk-samples
    ├── README.md
    └── hello
        ├── atom.mk            <-- the atom.mk file that we will modify
        ├── autopilot-plugins
        ├── messages
        ├── product
        └── services
products/
README

Say we want to add a library dependency (mydep) to the airsdk-hello-cv-service of the HelloDrone mission.
First thing, would be to add the dependency to the LOCAL_LIBRARIES variable.

LOCAL_LIBRARIES := \
	libairsdk-hello-cv-service-msghub \
	libmsghub \
	libpomp \
	libtelemetry \
	libulog \
	libvideo-ipc \
	libvideo-ipc-client-config \
	opencv4 \
	protobuf \
	libmydep \

Then we should define to Alchemy the dependency and also describe how to compile it. This can be achieved by adding in the atom.mk the following declarations:

# define and build libmydep
include $(CLEAR_VARS)

LOCAL_MODULE := libmydep
LOCAL_CATEGORY_PATH := airsdk/missions/samples/hello
# LOCAL_CFLAGS := any c flags to pass to the compiler
# LOCAL_LIBRARIES := any other libraries libmydep depends on. This should be a whitespace separated list of LOCAL_MODULES i.e. libmydepB libmydepC etc

# find all source files of the library. Source files are considered to be in directory `src`
LOCAL_SRC_FILES := $(call all-cpp-files-in,src)
)

include $(BUILD_LIBRARY)

Should your library have other dependencies (like libmydepB, libmydepC) then this process of defining and describing to Alchemy how to build them should be repeated for each dependency.

Examples

Different atom.mk exemples follow to describe the different Alchemy capabilities.

Example of autotools atom.mk
to build sqlite version 3190300 from source code .tar.gz:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := sqlite
LOCAL_DESCRIPTION := Self-contained, serverless, zero-configuration, transactional SQL database engine library
LOCAL_CATEGORY_PATH := libs

LOCAL_AUTOTOOLS_VERSION := 3190300
LOCAL_AUTOTOOLS_ARCHIVE := $(LOCAL_MODULE)-autoconf-$(LOCAL_AUTOTOOLS_VERSION).tar.gz
LOCAL_AUTOTOOLS_SUBDIR := $(LOCAL_MODULE)-autoconf-$(LOCAL_AUTOTOOLS_VERSION)

LOCAL_CFLAGS := -DSQLITE_ENABLE_UNLOCK_NOTIFY=1 -DSQLITE_ENABLE_JSON1=1
LOCAL_LDFLAGS := -ldl

LOCAL_AUTOTOOLS_CONFIGURE_ARGS := \
	--disable-readline

LOCAL_EXPORT_LDLIBS := \
	-lsqlite3

include $(BUILD_AUTOTOOLS)

Example of custom build atom.mk (LOCAL_CMD_INSTALL)
to build libgeojson from source code .tar.gz:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := libgeojson
LOCAL_DESCRIPTION := A C++14 library for converting GeoJSON into (mapbox) geometry.hpp representation
LOCAL_CATEGORY_PATH := libs
LOCAL_ARCHIVE_VERSION := 0.5.1
LOCAL_ARCHIVE := geojson-cpp-v$(LOCAL_ARCHIVE_VERSION).tar.gz
LOCAL_ARCHIVE_SUBDIR := geojson-cpp-$(LOCAL_ARCHIVE_VERSION)

define LOCAL_CMD_INSTALL
	@mkdir -p $(TARGET_OUT_STAGING)/usr/include
	cp -Raf $(PRIVATE_SRC_DIR)/include/* $(TARGET_OUT_STAGING)/usr/include/
endef

include $(BUILD_CUSTOM)

Exemple of CMake atom.mk
to build eigen version 3.2.0 from source code .tar.bz2:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := eigen
LOCAL_DESCRIPTION := C++ template library for linear algebra
LOCAL_CATEGORY_PATH := libs

LOCAL_ARCHIVE_VERSION := 3.2.0
LOCAL_ARCHIVE := $(LOCAL_MODULE)-$(LOCAL_ARCHIVE_VERSION).tar.bz2
LOCAL_ARCHIVE_SUBDIR := eigen-eigen-ffa86ffb5570

# Tests might require Fortran which we don't provide in cross-platform toolchains
LOCAL_CMAKE_CONFIGURE_ARGS += -DBUILD_TESTING=OFF

# Only use MPL2/BSD licenses
# Do not pass EIGEN_QUATERNIONBASE_PLUGIN to LOCAL_CFLAGS cmake choke to death on it...
LOCAL_CFLAGS := \
	-DEIGEN_MPL2_ONLY
LOCAL_EXPORT_CFLAGS := \
	$(LOCAL_CFLAGS) \
	-DEIGEN_QUATERNIONBASE_PLUGIN=\"QuaternionBaseAddons.hpp\"

# Do not warn about uses of deprecated std::bind2nd
LOCAL_EXPORT_CXXFLAGS := \
	-Wno-deprecated-declarations

# Only if gcc >= 5.0.0
ifneq ("$(call check-version,$(TARGET_CC_VERSION),5)","")
  LOCAL_EXPORT_CXXFLAGS += -Wno-error=maybe-uninitialized
endif

# Template only library, no .a or .so to link with
LOCAL_C_INCLUDES := \
	$(LOCAL_PATH) \
	$(TARGET_OUT_STAGING)/usr/include/eigen3
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)

define LOCAL_CMAKE_CMD_POST_CLEAN
	$(Q) rm -f $(TARGET_OUT_STAGING)/usr/lib/pkgconfig/eigen3.pc
	$(Q) rm -rf $(TARGET_OUT_STAGING)/usr/include/eigen3
endef

include $(BUILD_CMAKE)

Exemple of library build atom.mk
to build any library based on source files (no autotools/cmake or other build system):

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := libmylibrary
LOCAL_DESCRIPTION := My library description
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
# c++ flags
LOCAL_CXXFLAGS := -std=c++17
# any dependencies also described in same atom.mk or other atom.mk
LOCAL_LIBRARIES := \
	libdependencyA \
	libdependencyB \


LOCAL_CATEGORY_PATH := libs
# find all source files of the library. Source files are considered to be in directory `src`
LOCAL_SRC_FILES := $(call all-cpp-files-in,src)

include $(BUILD_LIBRARY)

Thanks for your answer, I wanted to use the cpp version of pytorch on the Anafi.
I managed to compile it without alchemy and it work with the drone, but I will try to do it with alchemy.

Thanks
Thomas

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.