Developing mobile application for Aurora OS: investigating build errors or how to add a library the right way
Intro
This post continues the exploration of developing mobile applications for Aurora OS. This time, I investigate the case of building and deploying a mobile app, focusing on build errors that occur when a new library appears to be added correctly. This example illustrates nuances of CMake and RPM workflows.
Adding a New Library
Our team needed to enable WebView in our application. Research showed that the WebView engine varies across the versions we target: on 5.1.3 and above, it uses Chromium, while on 5.1.1 it uses Gecko. This difference affects the API, supported features, and the choice of the correct library package.
We switched from qmake to CMake for more flexibility.
While qmake hides some of CMake's complexity, it also imposes limits that
eventually become problematic. Using CMake requires identifying the correct
library and declaring it properly in the CMakeLists.txt
file.
Before that, we had to decide whether to include the library inside the RPM package or declare a dependency on the existing system library. The first approach guarantees the library exists but significantly increases the package size, making it less preferable. The second approach declares a dependency on the system library in the target device environment.
How to Find the Actual Package Name and Check Its Existence
In general, the following commands can help identify possible packages:
$ zypper se webview
$ pkcon search name webview # alternative
These commands are not available in the standard development environment and
should be run under the PSDK.
Since the library name can often be guessed from its key component, I first searched
the target device for shared libraries:
$ find /usr/lib /lib -name "*webview*.so*"
This provides candidate libraries. To find the RPM package that provides a specific library:
$ rpm -qf /usr/lib/libaurorawebview.so
In this case, however, neither the .so nor the RPM names matched our requirements.
If the library is included in the RPM package, it usually has a pkg-config file:
$ pkg-config --list-all | grep webview
This command is only available in the PSDK. Since the target environment already has the
necessary library, it is sufficient to declare a dependency in the CMake file using the
RPM package name discovered in the previous step.
Declaring the Dependency in CMake
It is possible to hardcode the library path in CMakeLists.txt
, but it is better
to search for it. This allows vendors to customize library locations in future releases
and makes the app more robust across different versions:
find_library(WEBVIEW_LIB aurorawebview REQUIRED)
Since find_library()
does not guarantee the correct library is returned,
an extra verification step is required:
find_library(WEBVIEW_LIB aurorawebview REQUIRED)
if (WEBVIEW_LIB)
execute_process(
COMMAND rpm -qf ${WEBVIEW_LIB}
OUTPUT_VARIABLE WEBVIEW_RPM
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
message(STATUS "Library found: ${WEBVIEW_LIB}")
message(STATUS "Provided by package: ${WEBVIEW_RPM}")
if (NOT WEBVIEW_RPM MATCHES "ru\\.auroraos\\.webview")
message(FATAL_ERROR "Incorrect library found: ${WEBVIEW_LIB} (${WEBVIEW_RPM})")
endif()
endif()
In practice, launching the app showed that WebView could not find a dependency
on another library. As a workaround, the library was included inside the RPM package
and the RPATH was adjusted:
set(CMAKE_SKIP_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/../lib/cef")
install(FILES /usr/lib/cef/libcef.so DESTINATION share/${PROJECT_NAME}/lib/cef)
The Role of the Spec File
When CMake builds the application, the spec file defines the necessary dependencies.
Dependencies are divided into two groups: required for build and required at runtime.
BuildRequires: pkgconfig(aurorawebview)
Requires: ru.auroraos.webview
It was discovered that pkgconfig()
can sometimes return the wrong library.
Using the exact RPM name is preferable:
BuildRequires: ru.auroraos.webview-devel
It is important to note the difference between runtime libraries and -devel
packages.
Some libraries are only needed for building and not at runtime, so their -devel
packages
are required during the build stage.
Summary
In this post, I have shown the process of investigating build errors and
choosing the right library.
It sheds light on internal details of the CMake build system
and Linux package management, helping developers better understand, use,
and build programs in C and on Linux.
A few related publications:
Developing mobile application for Aurora OS
Principles behind my work