Reputation: 5901
I am working on a multi-platform project which, among others, supports Linux and Android. The code is mostly C; the Android port has a Java wrapper for the platform-specific parts, which calls the native code parts for the core functionality.
On Linux we build this project with CMake, followed by make. For Android we essentially use Gradle and call CMake through externalNativeBuild
. The CMakeFile.txt
can detect an Android build with a simple if (ANDROID)
, allowing us to
The project relies on some standard libraries, which we detect with the following in our CMakeLists.txt
:
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules ( FOO foo-42.0 )
if (FOO_FOUND)
set(HAVE_FOO 1)
include_directories(${FOO_INCLUDE_DIRS})
# …
When building for Android, this picks up either nothing or libraries for the host OS (somewhere underneath /usr/include/
) rather than those for Android (which would reside somewhere underneath $NDK/sysroot
). (Note $NDK
just denotes the NDK path, not necessarily an environment variable.)
According to this post, pkg-config
relies on a bunch of environment variables to determine where to look for libraries, namely CMAKE_SYSROOT
, PKG_CONFIG_DIR
, PKG_CONFIG_LIBDIR
and PKG_CONFIG_SYSROOT_DIR
. I checked them and they are empty (or unset).
Using the gradle/NDK/CMake toolchain, how can I either pass the correct variables to CMake, or otherwise have it find the libraries for which NDK supplies headers?
Upvotes: 1
Views: 964
Reputation: 5901
The NDK path is available to gradle as android.ndkDirectory
. Update build.gradle
like this:
android {
// ...
defaultConfig {
// ...
externalNativeBuild {
cmake {
// amend existing list of arguments, if you have one
arguments '-DCMAKE_SYSROOT='+android.ndkDirectory+'/sysroot'
}
}
}
}
Then, in CMakeLists.txt
, before the first use pf pkg-config, add:
if(ANDROID)
set(ENV{PKG_CONFIG_DIR} "")
set(ENV{PKG_CONFIG_LIBDIR} "${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig")
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
endif(ANDROID)
Upvotes: 0
Reputation: 1423
There are two options:
docker image
that includes all compiled and installed prebuilts and other prerequisites - SDK, NDK, AndroidStudio, etc.), you need to provide CMAKE_FIND_ROOT_PATH
where libraries
, includes
and cmake configs
are installed:list(APPEND CMAKE_FIND_ROOT_PATH ${THIRDPARTY_DIR}/${THIRDPARTY_ANDROID_PLATFORM}/${ANDROID_ABI}/boost)
Find<module>.cmake
, for example FindBoost.cmake
to serve find_package(Boost)
(here's an example of how it could be, also this project uses multi-platform parts).Upvotes: 1