I was wondering what is the "intended" workflow of using CMake build system and shared runtime libraries (libcrystax.so, libgnustl_shared.so and libboost_*.so ahd others); and, more generally, what are the "intended" semantics of build- and install-trees when using CMake with Android NDK.
Cc: @rpavlik — you are the author of the only Android/CMake toolchain file which at least somehow considers boost, so I'd like to hear your comments as well.
Part 1. Shared runtime libraries and CMake
So far, the CrystaX CMake toolchain file copies libcrystax.so and libgnustl_shared.so into the build-tree, and that's all. This has three problems:
- Bundled third-party libraries (Boost, at least) are simply left out. A project which uses CMake and shared boost is non-functional after building.
- This behavior depends on the
${LIBRARY_OUTPUT_PATH} variable which is deprecated and not even set by default. Considering that ${ANDROID_STL} defaults to gnustl_shared and libcrystax.so is available only as a shared library, a project built with CMake with default settings is non-functional after building (!).
- This contradicts the workflow described below (see below).
Part 2. Build- and install-tree semantics with Android
In the CMake toolchain file I find some rudimentary code that sets ${LIBRARY_OUTPUT_PATH} to something containing libs/${ANDROID_NDK_ABI_NAME}. This means that the authors intended the build-tree to become the final location of the libraries. That is — if the CMake project is correctly placed within the Android project, you can just cmake . && make and the libraries will end up in the correct places for Android packaging. (I hope I am clear here.)
However, I find this pretty unusable. First, any typical cross-compilation effort will include multiple projects which will try to find each other. By default (with existing toolchain file), CMake won't search libraries in ${LIBRARY_OUTPUT_PATH}, but it will search in ${CMAKE_INSTALL_PREFIX}/lib. Same holds for find_package(CONFIG).
Second, almost no projects are written with Android/CMake in mind, so vast majority of existing projects will install their libraries in $prefix/lib.
Hence, to make projects find each other (without extensively patching their build systems), I typically build in a temporary directory and then install to a common prefix, with libraries installed in $prefix/lib and exported configs in $prefix/lib/cmake/Project/ProjectConfig.cmake. Then I symlink $prefix/lib from $android_project/libs/$ABI and run Android packaging.
The described workflow allows to cross-compile any "chains" of projects without altering their build systems (provided that they can build for Linux).
With all this in mind, there should be a way to install the shared runtime libraries alongside the project's library destination, typically ${CMAKE_INSTALL_PREFIX}/lib. I'd expect a parameter of kind ANDROID_SHARED_HELPER_DESTINATION, which, when set, will make the toolchain file install the shared runtime libraries to ${CMAKE_INSTALL_PREFIX}/${ANDROID_SHARED_HELPER_DESTINATION}.
This parameter should be honoured by the toolchain file itself (to install libcrystax.so and libgnustl_shared.so), and custom Find*.cmake modules should be written for all bundled 3rd-party projects (boost, ...) which will chain to real find modules and install the found libraries afterwards (an example of such "chaining" already exists in the tree as FindBoost.cmake).
Comments? Maybe I'm horribly wrong somewhere and using CMake with shared runtime already works well?
I was wondering what is the "intended" workflow of using CMake build system and shared runtime libraries (
libcrystax.so,libgnustl_shared.soandlibboost_*.soahd others); and, more generally, what are the "intended" semantics of build- and install-trees when using CMake with Android NDK.Cc: @rpavlik — you are the author of the only Android/CMake toolchain file which at least somehow considers boost, so I'd like to hear your comments as well.
Part 1. Shared runtime libraries and CMake
So far, the CrystaX CMake toolchain file copies
libcrystax.soandlibgnustl_shared.sointo the build-tree, and that's all. This has three problems:${LIBRARY_OUTPUT_PATH}variable which is deprecated and not even set by default. Considering that${ANDROID_STL}defaults tognustl_sharedandlibcrystax.sois available only as a shared library, a project built with CMake with default settings is non-functional after building (!).Part 2. Build- and install-tree semantics with Android
In the CMake toolchain file I find some rudimentary code that sets
${LIBRARY_OUTPUT_PATH}to something containinglibs/${ANDROID_NDK_ABI_NAME}. This means that the authors intended the build-tree to become the final location of the libraries. That is — if the CMake project is correctly placed within the Android project, you can justcmake . && makeand the libraries will end up in the correct places for Android packaging. (I hope I am clear here.)However, I find this pretty unusable. First, any typical cross-compilation effort will include multiple projects which will try to find each other. By default (with existing toolchain file), CMake won't search libraries in
${LIBRARY_OUTPUT_PATH}, but it will search in${CMAKE_INSTALL_PREFIX}/lib. Same holds forfind_package(CONFIG).Second, almost no projects are written with Android/CMake in mind, so vast majority of existing projects will install their libraries in
$prefix/lib.Hence, to make projects find each other (without extensively patching their build systems), I typically build in a temporary directory and then install to a common prefix, with libraries installed in
$prefix/liband exported configs in$prefix/lib/cmake/Project/ProjectConfig.cmake. Then I symlink$prefix/libfrom$android_project/libs/$ABIand run Android packaging.The described workflow allows to cross-compile any "chains" of projects without altering their build systems (provided that they can build for Linux).
With all this in mind, there should be a way to install the shared runtime libraries alongside the project's library destination, typically
${CMAKE_INSTALL_PREFIX}/lib. I'd expect a parameter of kindANDROID_SHARED_HELPER_DESTINATION, which, when set, will make the toolchain file install the shared runtime libraries to${CMAKE_INSTALL_PREFIX}/${ANDROID_SHARED_HELPER_DESTINATION}.This parameter should be honoured by the toolchain file itself (to install
libcrystax.soandlibgnustl_shared.so), and customFind*.cmakemodules should be written for all bundled 3rd-party projects (boost, ...) which will chain to real find modules and install the found libraries afterwards (an example of such "chaining" already exists in the tree as FindBoost.cmake).Comments? Maybe I'm horribly wrong somewhere and using CMake with shared runtime already works well?