I'm trying to add another cmake project which has CMakeLists.txt file as a compilation dependency which i can use in another .cpp file.
Location of project which i want to add: Users/brainfreak/Downloads/assimp-master/
Location of main project: /Users/brainfreak/AndroidStudioProjects/ModelShow/app/src/main/cpp/hellojni.cpp
This is used as a native code in a Android Studio project. I followed the tutorial in https://developer.android.com/studio/projects/add-native-code.html#create-cmake-script under "Include other CMake projects"
This is the main CMakeLists.txt that i came up with:
/Users/brainfreak/AndroidStudioProjects/ModelShow/app/src/main/cpp/CMakeLists.txt
cmake_minimum_required( VERSION 2.6 )
add_library(model-lib SHARED hellojni.cpp)
set (src_dir Users/brainfreak/Downloads/assimp-master/)
set (output_dir Users/brainfreak/Downloads/assimp-master/output)
file(MAKE_DIRECTORY ${output_dir})
add_subdirectory(${src_dir} ${output_dir})
add_library(assimp STATIC IMPORTED)
set_target_properties( assimp PROPERTIES IMPORTED_LOCATION
${output_dir}/${ANDROID_ABI}/assimp)
include_directories(${src_dir}/include)
target_link_libraries(model-lib assimp)
The error i always get:
Execution failed for task ':app:externalNativeBuildDebug'.
> Build command failed.
Error while executing process /Users/brainfreak/Android/sdk/cmake/3.6.3155560/bin/cmake with arguments {--build /Users/brainfreak/AndroidStudioProjects/ModelShow/app/.externalNativeBuild/cmake/debug/x86 --target model-lib}
ninja: error: 'Users/brainfreak/Downloads/assimp-master/output/x86/assimp', needed by '/Users/brainfreak/AndroidStudioProjects/ModelShow/app/build/intermediates/cmake/debug/obj/x86/libmodel-lib.so', missing and no known rule to make it
I don't know what file to place under "${output_dir}/${ANDROID_ABI}/" for the script to find. Can you tell where i'm going wrong?
Assuming that you got one of the latest releases from https://github.com/assimp and followed the instructions (note that this was tested with NDK r14, available for download from https://developer.android.com/ndk/downloads/older_releases), you have produced file libassimp.so inside project "Code" folder. Make sure that you build the x86 version of the library.
Copy this file to /Users/brainfreak/Downloads/assimp-master/output/x86/, and prepare your CMakeLists.txt:
cmake_minimum_required( VERSION 2.6 )
add_library(model-lib SHARED hellojni.cpp)
set (src_dir /Users/brainfreak/Downloads/assimp-master/)
set (output_dir /Users/brainfreak/Downloads/assimp-master/output)
file(MAKE_DIRECTORY ${output_dir})
add_subdirectory(${src_dir} ${output_dir})
add_library(assimp STATIC IMPORTED)
set_target_properties( assimp PROPERTIES IMPORTED_LOCATION
${output_dir}/${ANDROID_ABI}/libassimp.so)
include_directories(${src_dir}/include)
target_link_libraries(model-lib assimp)
Note that the file that your script was missing slash (/) before Users which could cause the confusion.
Don't forget to set abiFilters in your app/build.gradle:
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
abiFilters 'x86'
}
Related
I am creating an Android library that uses OpenCV via NDK. It doesn't require any Java parts of OpenCV, native parts only, so I decided not to use OpenCV for Android to reduce the size of the OpenCV code the library needs.
Now I need to download and build the native (C++) part of OpenCV using CMake so that the library won't require its users to download and install OpenCV on their own.
Currently my module's build.gradle contains this:
externalNativeBuild {
cmake {
cppFlags '-std=c++11 -frtti -fexceptions'
arguments '-DANDROID_ARM_NEON=TRUE'
}
}
And my CMakeLists.txt is:
cmake_minimum_required(VERSION 3.18.1)
project("mylib")
set(OPENCV_INSTALL_DIR ${CMAKE_BINARY_DIR}/opencv-install)
include(ExternalProject)
ExternalProject_Add(opencv
GIT_REPOSITORY https://github.com/opencv/opencv.git
GIT_TAG 4.5.5
UPDATE_DISCONNECTED TRUE
CMAKE_ARGS
<OpenCV arguments I need>
-DCMAKE_INSTALL_PREFIX=${OPENCV_INSTALL_DIR}
)
include_directories(${OPENCV_INSTALL_DIR}/include)
link_directories(${OPENCV_INSTALL_DIR}/lib)
set(OPENCV_LIBRARIES <OpenCV modules I use>)
add_library(mylib SHARED mylib.cpp)
add_dependencies(mylib opencv)
find_library(log-lib log)
target_link_libraries(mylib ${log-lib} ${OPENCV_LIBRARIES})
I am using Android Studio. When I try to build the library, the downloading process goes fine, but at the configure step I get the following error:
FAILED: opencv-prefix/src/opencv-stamp/opencv-configure
cmd.exe /C "cd /D <my lib module path>\.cxx\Debug\612145b5\x86_64\opencv-prefix\src\opencv-build && <my Android SDK path>\cmake\3.18.1\bin\cmake.exe -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_opencv_apps=OFF -DBUILD_JAVA=OFF -DBUILD_FAT_JAVA_LIB=OFF -DBUILD_opencv_python2=OFF -DBUILD_opencv_python3=OFF -DWITH_GTK=OFF -DWITH_WIN32UI=OFF -DWITH_FFMPEG=OFF -DWITH_V4L=OFF -DCPU_BASELINE=NEON -DCMAKE_INSTALL_PREFIX=<my lib module path>/.cxx/Debug/612145b5/x86_64/opencv-install -GNinja <my lib module path>/.cxx/Debug/612145b5/x86_64/opencv-prefix/src/opencv && <my Android SDK path>\cmake\3.18.1\bin\cmake.exe -E touch <my lib module path>/.cxx/Debug/612145b5/x86_64/opencv-prefix/src/opencv-stamp/opencv-configure"
CMake Error: CMake was unable to find a build program corresponding to "Ninja". CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool.
CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
As I see, CMake cannot find the following components:
Ninja
C++ compiler
C compiler
I can get rid of the first error, if I add ninja's path from NDK to the PATH variable, I don't think thats how it should be done though. Neither do I want to pass CMAKE_CXX_COMPILER and CMAKE_C_COMPILER to CMake manually, as it seems like it should be done automatically by Android Studio.
So, how can I fix this?
I'm trying to build an Android lib with Gradle and CMake. I'm adding OpenSSL like that:
add_library(Ssl STATIC IMPORTED)
set_target_properties(Crypto PROPERTIES IMPORTED_LOCATION
/Users/user/dev/android_openssl/static/lib/${ANDROID_ABI}/lib/libssl.a)
But the build is failing with this message:
ninja: error: 'Ssl-NOTFOUND', needed by 'lib/libmylib.so', missing and no known rule to make it
In build.ninja file the lib is appearing as is: Ssl-NOTFOUND before libssl.a with the right path
Any idea about why I have this dependency which is created by CMake?
EDIT
The issue was a bad target property:
add_library(Ssl STATIC IMPORTED)
set_target_properties(Ssl PROPERTIES IMPORTED_LOCATION
/Users/user/dev/android_openssl/static/lib/${ANDROID_ABI}/lib/libssl.a)
I'm trying to start a native app project with Android Studio and CMake on Windows 10, but I'm stuck at including libpng.
For starters it's the first time I've seen a CMakeLists.txt file. It took me a day to figure out target_link_libraries(native-activity ... png) could not be target_link_libraries(png native-activity ...) since all the error messages were about files not being created and commands failing due to missing requirements from the toolchain (why were the essential errors at the end of the list? not cool!).
After finally managing to include libpng in the project I now get a build error:
Error:Execution failed for task ':app:externalNativeBuildDebug'.
...
error: unknown target CPU 'armv5te'
CMake Error at scripts/genout.cmake:78 (message):
Failed to generate
C:/APP_PATH/app/libpng-1.6.28/build/scripts/symbols.out.tf1
ninja: build stopped: subcommand failed.
I've recursively grep'ed my project, .android, .AndroidStudio2.2 directories, as well as filenames, and found absolutely nothing with armv5te except for the genout.cmake. My abiFilters line is abiFilters 'x86'.
How do I build libpng to link to my native app? Also, in Android Studio it shows the project now includes the libpng source files (with no less than 9 projects dedicated to it!). Is there any way to remove it?
Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
# build native_app_glue as a static lib
add_library(app-glue STATIC ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
set(png_src_dir ../../../../libpng-1.6.28)
set(PNG_STATIC ON)
add_subdirectory(${png_src_dir} ${png_src_dir}/build)
# now build app's shared lib
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14")
add_library(native-activity SHARED
main.cpp logger.cpp logger.h game.cpp game.h
shaders.cpp shaders.h assets.cpp assets.h)
target_include_directories(native-activity PRIVATE ${ANDROID_NDK}/sources/android/native_app_glue
C:/devlibs/include
${png_src_dir})
# add lib dependencies
target_link_libraries(native-activity app-glue android log EGL GLESv2 png)
I've managed libpng to work with android NDK app (CMake build system instead of Android.mk) as static library. I used libpng-android repackaging. Here are things I've done:
git clone https://github.com/julienr/libpng-android.git into ${YOUR_LIBS_FOLDER} (I used ${ANDROID_NDK_ROOT_DIRECTORY}/sources/android).
Add ${ANDROID_NDK_ROOT_DIRECTORY} (home/username/Android/sdk/ndk-bundle for me) to global $PATH variable which is needed for build script).
Build lib with ndk-build (there is ./build.sh for that in directory with lib). Library will be built for different ABI targets ( arm64-v8a, armeabi, x86_64 etc).
At this point you have library headers at ${YOUR_LIBS_FOLDER}/libpng-android/jni and libpng.a at ${YOUR_LIBS_FOLDER}/libpng-android/obj/local/${ANDROID_ABI}/, where ${ANDROID_ABI} is target platform.
Finally you could include lib at CMakeLists.txt. libpng requires zlib compression library so you need to link against it aswell (zlib is provided by android studio so just add -lz flag).
Here is related piece from my CMakeLists.txt:
add_library(libpng STATIC IMPORTED)
set_target_properties(libpng PROPERTIES IMPORTED_LOCATION
${YOUR_LIBS_FOLDER}/libpng-android/obj/local/${ANDROID_ABI}/libpng.a)
add_library(appManager SHARED src/main/cpp/appManager.cpp)
target_include_directories(appManager PRIVATE ${YOUR_LIBS_FOLDER}/libpng-android/jni/)
target_link_libraries(appManager
android
libpng
z)
Few things to note there:
${ANDROID_ABI} is a variable set by Android Studio build system.
Once again: you need to link against zlib, that is why we have libpng z instead of libpng in target_link_libraries.
With Android Studio 3.6, including libpng into your project is rather easy.
Download the latest sources from sourceforge and unpack the zip file.
In Android Studio, make sure you have NDK and CMake installed (in SDK Manager)
Create a new Android Library module, call it pngAndroid (I would recommend
to set the Package Name to org.libpng.libpng, same as MacOS). Keep it Java, and choose the min SDK that fits your app.
For this module, choose File/Link C++ Project with Gradle. Find CMakleLists.txt of libpng that you downloaded as step 1.
In the pngAndroid's build.gradle, add
android.defaultConfig.externalNativeBuild.cmake.targets "png_static"
In Project Structure dialog, specify module dependency between your Module and pngAndroid.
When you build the pngAndroid Module, you will see files libpng16d.a in build/intermediates/cmake/debug/obj directory under pngAndroid.
In your Module, you also have CMakleLists.txt. In this script, you have a target, e.g.
add_library(native-library SHARED …
You should add libpng as dependency of native-library:
target_link_libraries(native-library libpng)
Elsewhere in this CMakleLists.txt you should define the imported libpng:
add_library(libpng STATIC IMPORTED)
set_target_properties(libpng PROPERTIES IMPORTED_LOCATION
../pngAndroid/build/intermediates/cmake/debug/obj/${ANDROID_ABI}/libpng16d.a)
set_target_properties(libpng PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
../../lpng1637)
set_target_properties(libpng PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES
z)
Note that here I used relative paths a) to the pngAndroid Module that you added to your Android Studio project, and b) to the libpng sources that you downloaded. In your setup, the relative paths may be different.
For completeness, here is a cleaned-up build.gradle script for pngAndroid to build shared library libpng16d.so:
apply plugin: 'com.android.library'
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
externalNativeBuild {
cmake {
arguments "-DSKIP_INSTALL_ALL=YES"
targets "png"
}
}
}
externalNativeBuild {
cmake {
path file('../../lpng1637/CMakeLists.txt')
}
}
}
When you build the module, you get in build/outputs an aar file that contains the jni directory with armeabi-v7a/libpng16d.so and all other ABI variants.
Last, it's worth mentioning that Google is working on an easier native package manager. Unfortunately, it's still not released.
I have an Android project with a app/src/CMakeLists.txt file like this
cmake_minimum_required(VERSION 3.4.1)
add_library( # Specifies the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
main/cpp/native-lib.cpp )
I also have a app/src/main/cpp/native-lib.cpp file in my project.
When I run ninja in a terminal I get this error
ninja: error: loading 'build.ninja': No such file or directory
I'm not familiar with the NDK and I'm trying to run the project with ninja but I'm not able to find any clear documentation or example.
Android NDK uses CMake to build projects, but instead of run ninja separately, you should run below gradle command to trigger your NDK project build.
./gradlew externalNativeBuild
Internally, CMake will use the ninja build system to compile and link the C/C++ sources for your apps.
CMake is failing to find a library and I don't know why. This is the portion of my CMakeLists.txt that is supposed to find the library:
set(SODIUM_DIR ${PROJECT_SOURCE_DIR}/../../../deps/install/libsodium/android-${ANDROID_ABI}/lib)
message(STATUS SODIUM_DIR=${SODIUM_DIR})
find_library(sodium-lib
libsodium.a
PATHS ${SODIUM_DIR}
NO_DEFAULT_PATH)
Part of CMake's output is:
-- SODIUM_DIR=/Users/csimmons/Documents/repos/onedoclily/client/Android/app/../../../deps/install/libsodium/android-armeabi-v7a/lib
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
-- Configuring incomplete, errors occurred!
Please set them or make sure they are set and tested correctly in the CMake files:
See also "/Users/csimmons/Documents/repos/onedoclily/client/Android/app/.externalNativeBuild/cmake/debug/armeabi-v7a/CMakeFiles/CMakeOutput.log".
sodium-lib
linked by target "native-lib" in directory /Users/csimmons/Documents/repos/onedoclily/client/Android/app
Build command failed.
Running "ls" on SODIUM_DIR shows that the library is there:
$ ls /Users/csimmons/Documents/repos/onedoclily/client/Android/app/../../../deps/install/libsodium/android-armeabi-v7a/lib
libsodium.a libsodium.la libsodium.so pkgconfig
I believe that I've been able to solve the problem by using add_library and set_property instead of find_library.
set(SODIUM_PATH ${PROJECT_SOURCE_DIR}/../../../deps/install/libsodium/android-${ANDROID_ABI}/lib/libsodium.a)
add_library(sodium-lib STATIC IMPORTED)
set_property(TARGET sodium-lib PROPERTY IMPORTED_LOCATION ${SODIUM_PATH})
target_link_libraries( # My code's library.
native-lib
sodium-lib
)
The tag NAMES is missing before the list of possible names.
Fixed:
find_library(sodium-lib
NAMES libsodium.a
PATHS ${SODIUM_DIR}
NO_DEFAULT_PATH)
See How can I find a library name of .so file?