For my project, I am trying to integrate a c++ library into an Android app. This library uses PyTorch.
For the first test implementation I used the example from https://github.com/ademar111190/CppAndroidIosExample and try to add my PyTorch Lib.
Building it outside of Android Studio worked, but as soon as I build it internally the error comes up:
Your installed Caffe2 version uses CUDA but I cannot find the CUDA
libraries. Please set the proper CUDA prefixes and / or install CUDA.
Call Stack (most recent call first):
C:/DEV/libtorch/share/cmake/Torch/TorchConfig.cmake:40 (find_package)
CMakeLists.txt:16 (find_package)
I compared both builds in the cmake-gui and found that the Android build was missing the CUDA_TOOLKIT_ROOT_DIR entry.
Solution attempts
1:
I tried to enter the whole thing via the GUI, however when generating outside of Android Studio the error came up:
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
log-lib
linked by target "native-lib" in directory
2:
I try to add the PATH to Windows, but it did not work
3:
I try to add to CMakeLists.txt:
set(CUDA_TOOLKIT_ROOT_DIR "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.2")
System: Win 10 64
CUDA Version: 11.2
CMAKE Version: 3.19.2
Changed Files
./Android/app/CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
project(native-lib)
list(APPEND CMAKE_PREFIX_PATH C:/DEV/libtorch)
set(Torch_DIR C:/DEV/libtorch/share/cmake/Torch)
set(Caffe2_DIR C:/DEV/libtorch/share/cmake/Caffe2)
set(CMAKE_CUDA_COMPILER "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.2/bin/nvcc")
find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
include_directories (
../../CPP/
)
add_library(
native-lib
SHARED
src/main/cpp/native-lib.cpp
../../CPP/Core.h
../../CPP/Core.cpp
)
find_library(
log-lib
log
)
target_link_libraries(
native-lib
${log-lib}
${TORCH_LIBRARIES}
)
set_property(TARGET native-lib PROPERTY CXX_STANDARD 14)
if (MSVC)
file(GLOB TORCH_DLLS "${TORCH_INSTALL_PREFIX}/lib/*.dll")
add_custom_command(TARGET native-lib
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${TORCH_DLLS}
$<TARGET_FILE_DIR:native-lib>)
endif (MSVC)
Related
I have an ndk project with a CMakeLists.txt that looks like so
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror")
add_library( # Specifies the name of the library.
main
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
main.c)
target_link_libraries(
android
log
)
it follows the pattern laid out in all of the NDK example projects listed on the googlesamples github repo. I keep getting CMake Error at CMakeLists.txt (target_link_libraries), and it seems like most people are solving it with this line
add_library(debug <files Name>)
but no one is adding that for logging. What am I doing wrong?
add below to your CMakeLists.txt above the line of target_link_libraries.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
Then modify target_link_libraries as below for linking android log lib
target_link_libraries( # Specifies the target library.
main
# Links the target library to the log library
# included in the NDK.
${log-lib} )
1) in your code source folder, look for something like "Android.mk" or "project.mk", then remember the path of it.
2) go to android studio and click File ==> link c++ project with gradle ==> choose build system ndk-build , then look for the .mk file you found first.
click ok , and sync project.
As the title suggests I am trying to link a native .so to an android studio project. I have gone through the docs in android developer website and some more articles but unsuccessful in connecting the .so file with the project.
Whenever I try to run the code I get the following error
CMake Error: The following variables are used in this project, but
they are set to NOTFOUND. Please set them or make sure they are set
and tested correctly in the CMake files: testlib
Here is my CMake file
cmake_minimum_required(VERSION 3.4.1)
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
add_library(testlib SHARED IMPORTED)
set_property(TARGET testlib PROPERTY IMPORTED_LOCATION "E:/project/Remote_Native/remote_attempt_1/app/libs/armeabi-v7a/libremotedesktop_client.so")
#find_path(testlib E:/project/Remote_Native/remote_attempt_1/app/libs/armeabi-v7a/RemoteDesktop.h)
find_library(testlib E:/project/Remote_Native/remote_attempt_1/app/libs/armeabi-v7a/libremotedesktop_client.so)
#add_library(remote SHARED IMPORTED)
#set_target_properties(remote PROPERTIES IMPORTED_LOCATION libs/${ANDROID_ABI}/libremotedesktop_client.so )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib}
${testlib})
target_include_directories()
I have four .so files each for arm64, armeabi, armeabi-v7a, x86. I have harcoded the armeabi-v7a lib in the path, android studio is throwing the above mentioned error when I do that. My actual aim is to dynamically load the library based on the chip in the phone. I am pretty sure that my current code is not achieving that.
Here are my queries
How to solve the error that I am getting? I have tried giving both relative and absolute path but to no avail I am getting the same error.
How do I add a .so and a .h file into a native android studio project? That has variations based on the chip on which the code is running?
When I directly add the .h file to the native folder I can reference the classes and functions in that header in my C code but I am unable to run the code. I have a getInstance() method in the .h file. Whenever I call the
getInstance() function it says undefined refernce to getInstance(). What I understand from that is the '.h' file is linked correctly but the definition of the function of the .h files which are actually present in the .so files are not linked. I believe this will be solved if question 1 and 2 are answered.
Is it necessary for all native android projects to have a .mk file? I didn't add one to my project and think it might be one of the cause for the error that I am getting.
You don't need find_library in your case. For log, the library is resolved by NDK for you; for libremotedesktop_client.so, you know the exact path.
Here is the CMakeLists.txt that will work for you:
cmake_minimum_required(VERSION 3.4.1)
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
add_library(remote SHARED IMPORTED)
set_property(TARGET remote PROPERTY IMPORTED_LOCATION "E:/project/Remote_Native/remote_attempt_1/app/libs/${ANDROID_ABI}/libremotedesktop_client.so")
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
log
remote)
Note that using full path (E:/project…) in CMake script is not the best practice; you probably can express the path to this library somehow relative to the path of your CMakeLists.txt, which is ${CMAKE_CURRENT_SOURCE_DIR}.
1-2). First of all, add set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) at the start of your CMakeLists.txt (just after cmake_minimum_required(...)) to allow another search paths for libraries. After this you can find lib just using standard find_library:
find_library(FOO_LIBRARY
foo # Lib's full name in this case - libfoo.so
PATHS path/to/lib/)
if (NOT FOO_LIBRARY)
message(FATAL_ERROR "Foo lib not found!")
endif()
You can use variable ANDROID_ABI to get particular library version, if directory with libraries organised in this way:
- path/to/lib
- armeabi-v7a
- libfoo.so
- arm64-v8a
- libfoo.so
- x86
- libfoo.so
- x86_64
- libfoo.so
So, search path in this case:path/to/lib/${ANDROID_ABI}/
To include headers in project just use include_directories:
include_directories(path/to/headers)
4). .mk files only needed if you use ndk-build (so you don't need any)
Question Update:
Linker error
I installed Intel OpenCL SDK with Android Support on dev pc.
Difficulty building Android Studio Solution with C++ support using CMakelists.txt
OpenCL & OpenCV in Android Studio using CMakeLists.txt
CMakeLists.txt:
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
#Added 2 path definitions to support 20160825 additions
set(pathToProject C:/Users/eogha/Desktop/HelloOpenCV)
set(pathToOpenCv C:/OpenCV-3.1.0-android-sdk)
set(pathToOpenCL "C:/Program Files (x86)/Intel/OpenCL SDK/5.3")
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
#Addition suggested by Bruno Alexandre Krinski 20160825
include_directories(${pathToOpenCv}/sdk/native/jni/include )
include_directories(${pathToOpenCL}/include)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( native-lib SHARED src/main/cpp/native-lib.cpp )
#Addition suggested by Bruno Alexandre Krinski 20160825
add_library( lib_opencv SHARED IMPORTED )
#Addition suggested by Bruno Alexandre Krinski 20160825
set_target_properties( lib_opencv PROPERTIES IMPORTED_LOCATION
${pathToProject}/app/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so )
add_library( lib_opencl SHARED IMPORTED )
set_target_properties( lib_opencl PROPERTIES IMPORTED_LOCATION "C:/Program
Files (x86)/Intel/OpenCL SDK/5.3/lib/android64/libOpenCL.so" )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( native-lib $\{log-lib} lib_opencv lib_opencl )
Android Studio Error: linker command failed with exit code 1 (use -v to see invocation)
Finally !! The OpenCL Shared Object library seems to be imported into the android project structure. But now I have this linker error. How do I resolve this in Windows 10 ??
Maybe there is already some answers on this forum about this problem, but i tried a lot of solutions already, and i still didnt solve this problem.
I have to make an android application using C++, wich uses libcurl.
And whatever i do, i can't run my program because it doenst find the library.
In my .cpp, i use this line :
#include <curl/curl.h>
And this is my CMakeLists.txt
# Sets the minimum version of CMake required to build the native
# library. You should either keep the default value or only pass a
# value of 3.4.0 or lower.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds it for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
# Associated headers in the same location as their source
# file are automatically included.
src/main/cpp/native-lib.cpp )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because system libraries are included in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
-lcurl
# Specifies the name of the NDK library that
# you want CMake to locate.
log
-lcurl )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in the
# build script, prebuilt third-party libraries, or system libraries.
INCLUDE_DIRECTORIES($/usr/include/)
target_link_libraries( # Specifies the target library.
native-lib
-lcurl
# Links the target library to the log library
# included in the NDK.
${log-lib} )
I used the commands :
sudo aptitude install libcurl4-gnutls-dev
and
sudo aptitude install libcurl-dev
You should rather use the built-in functionality to integrate libcurl:
[...]
find_package(CURL REQUIRED)
include_directories(${CURL_INCLUDE_DIRS})
add_library(native-lib SHARED src/main/cpp/native-lib.cpp)
target_link_libraries(native-lib ${CURL_LIBRARIES})
As it seems you are cross-compiling for Android, the following will make the curl library that you installed for your Ubuntu available for the compilation (add it before what is above).
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
But it might then be problematic in the linking step, since you installed the library for your Ubuntu and the program you want to compile it with is for Android.
If this does not work, try to have the curl library in your cross-compiling toolset (but I don't know enough about it to tell you how to do it).
I think you need to instruct cmake to find the libcurl dependency.
Please read How_To_Find_Libraries.
And look at find_package and FindCURL module
As a quick-start, add the following to your CMakeLists.txt:
find_package(CURL REQUIRED)
include_directories(${CURL_INCLUDE_DIRS})
add_library(native-lib SHARED ... )
target_link_libraries(native-lib ${CURL_LIBRARIES})
(even better: use target_include_directories() instead of include_directories()).
I am using Android Studio 2.2.2 with cmake and Android NDK. I have a problem linking .a library (Static lib).
Here is my cmake:
# Sets the minimum version of CMake required to build the native
# library. You should either keep the default value or only pass a
# value of 3.4.0 or lower.
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_VERBOSE_MAKEFILE on)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds it for you.
# Gradle automatically packages shared libraries with your APK.
add_library(lib_webp SHARED IMPORTED )
set_target_properties(lib_webp PROPERTIES IMPORTED_LOCATION
src/main/jni/${ANDROID_ABI}/libwebp.so)
add_library( # Sets the name of the library.
game-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
# Associated headers in the same location as their source
# file are automatically included.
src/main/cpp/main.cpp
src/main/cpp/android_native_app_glue.c
)
target_include_directories(game-lib PRIVATE
../../../../libs/headers/android
)
include_directories($ENV{NDK_MODULE_PATH}/sources/android/native_app_glue/)
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in the
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
game-lib
# Links the target library to the log library
# included in the NDK.
# ${log-lib}
# Specifies the name of the NDK library that
# you want CMake to locate.
log
android
OpenSLES
z
GLESv2
EGL
dl
)
add_definitions(-g -DANDROID -Wno-write-strings -fsigned-char -Wno-conversion-null)
TARGET_LINK_LIBRARIES(game-lib libtheoraplayer.a)
My linker reports an error
arm-linux-androideabi/bin\ld: error: cannot find -ltheoraplayer
error: undefined reference to 'TheoraVideoManager::TheoraVideoManager(int)'
which is a part of libtheoraplayer.a. Did anyone had similar problem? Any idea how to solve this?
I have the Static lib libtheoraplayer.a present at that location. I even have the Shared lib also, libtheoraplayer.so but I can`t link it either.
Any advice would be appreciated.
Cheers.
To post the answer. As Tsyvarev said, the problem with non-absolute file name for library. When I used absoulte path it worked like a charm.
Thank you.
Cheers.