How to use GLM in Android using Cmake - android

I am trying to compile my OpenGL application in Android. I'm using [GLM library] (0.9.4)1
The compilation works until I include:
#include <glm/glm.hpp>
This header add cmath and linker complain about:
cmath:102:11: error: '::acos' has not been declared
...
cstdio:107:11: error: '::fprintf' has not been declared
It seems like std have some problem with using std, or libc++ of flags configuration on CMakeLists.txt
My CMakeLists.txt is:
status("")
status("* Adding module Core C++ ")
SET(PROJ_NAME CORE_CPP)
PROJECT(${PROJ_NAME})
# Helper to set libs & bin paths
INCLUDE(${PATH_MAIN}/cmake_tools/scripts/helperPaths.cmake)
# Include header from Module Core
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/include )
IF(DEP_GLM)
INCLUDE_DIRECTORIES( ${PATH_GLM} )
ENDIF(DEP_GLM)
# Source
#---------------------------------------------------#
file(GLOB CORE_CPP_SRC
"src/*.cpp"
)
file(GLOB CORE_CPP_HEADERS
"include/*.h"
)
# Create Library
ADD_LIBRARY(${PROJ_NAME} STATIC ${CORE_CPP_SRC} ${CORE_CPP_HEADERS})
#message("Link: ${LIBRARY_DEPS}")
SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -fPIC" )
SET( LIBRARY_DEPS GLESv2 log android)
TARGET_LINK_LIBRARIES(${PROJ_NAME} ${LIBRARY_DEPS})
status("- module ${PROJ_NAME} added! ")
In previous versions of gcc, It was needed to add #define _GLIBCXX_USE_C99_MATH 1 inside its includes, but it is already added in my version (4.8)
Any idea what is the problem?

I have found the problem, I was including the header INSIDE my namespace, so linker was looking for another namespace into std.
#ifndef MYNAME_MATH_H
#define MYNAME_MATH_H
#include <glm/glm.hpp> // Linker Work
namespace myname
{
//#define _GLIBCXX_USE_C99_MATH 1
//#include <glm/glm.hpp> // Make linker FAIL!
//typedef glm::vec2 Vector2;
//typedef glm::vec3 Vector3;
//typedef glm::vec4 Vector4;
}
#endif // MYNAME_MATH_H

Related

Build issue when including TFLite C API in Android app that uses C++ and Java

I am using TFLite through C++ building my app with the NDK and would appreciate help in addressing a linkage error. The guide I'm following is https://www.tensorflow.org/lite/guide/android#use_tflite_c_api
I have included the TFLite C API header files and dynamic shared library in my program, which I build using CMake.
I get the following error:
../../../../src/main/cpp/TFLiteExample.cpp:17: error: undefined reference to 'TfLiteModelCreateFromFile'
Some additional information: I included the header files in app/src/main/includes and the .so dynamic library in app/src/main/jni. The CMakeLists.txt file is in app/src/main. Below are the relevant components of CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
set(CMAKE_VERBOSE_MAKEFILE ON)
###Internal Linking
#Add internal C++ libraries
add_library( native-lib SHARED src/main/cpp/native-lib.cpp )
add_library( TFLiteExample SHARED src/main/cpp/TFLiteExample.cpp)
add_library( tensorflowlite_jni SHARED IMPORTED )
set_property(TARGET tensorflowlite_jni
PROPERTY IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jni/libtensorflowlite_jni.so)
#Make directories visible to all C++ files
include_directories(src/main/includes)
include_directories(src/main/cpp)
include_directories(src/main/jni)
# Specify the libraries which our native library is dependent on, including Oboe
target_link_libraries (native-lib tensorflowlite_jni TFLiteExample)
target_link_libraries(TFLiteExample tensorflowlite_jni)
Here is TFLiteExample.h:
#ifndef TEST2_TFLITEEXAMPLE_H
#define TEST2_TFLITEEXAMPLE_H
// TFLite include files
#include <builtin_ops.h>
#include <c_api.h>
#include <c_api_experimental.h>
#include <common.h>
class TFLiteExample {
public:
TFLiteExample();
static void TFLitePredict();
};
#endif //TEST2_TFLITEEXAMPLE_H
Here is TFLiteExample.cpp:
#include "TFLiteExample.h"
TFLiteExample::TFLiteExample(){
}
void TFLiteExample::TFLitePredict() {
TfLiteModel* model = TfLiteModelCreateFromFile("/src/main/assets/_quant.tflite");
}
Headers common.h and c_api.h are both code from Tensorflow. I haven't modified the code except for replacing relative include paths such as #include "../../../../../../../../../../../Library/Android/sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include/c++/v1/stdbool.h" with #include <cstdbool>.
common starts with the following includes:
#ifndef TENSORFLOW_LITE_C_COMMON_H_
#define TENSORFLOW_LITE_C_COMMON_H_
#include <cstdbool>
#include <stddef>
#include <stdint>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
...
And c_api with:
#ifndef TENSORFLOW_LITE_C_C_API_H_
#define TENSORFLOW_LITE_C_C_API_H_
#include <stdarg>
#include <stdint>
#include "common.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
...
Update: the program was built successfully following these instructions:
https://stackoverflow.com/a/63372486/4008884.
I made the following modifications:
First, I replaced file structure
app/src/main/jni/libtensorflowlite_jni.so
with
app/src/main/jni/arm64-v8a/libtensorflowlite_jni.so
app/src/main/jni/armeabi-v7a/libtensorflowlite_jni.so
app/src/main/jni/x86_64/libtensorflowlite_jni.so
app/src/main/jni/x86/libtensorflowlite_jni.so
Second, I moved the TFLite C API headers to the same directory, app/src/main/jni/.
Third, I included the following to the build.gradle in the android { section:
ndk {
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
}
Finally, I added ${ANDROID_ABI} to the linking in CMakeLists.txt:
set(JNI_DIR ${PROJECT_SOURCE_DIR}/src/main/jni)
add_library( tensorflowlite_jni SHARED IMPORTED)
set_target_properties(tensorflowlite_jni
PROPERTIES IMPORTED_LOCATION
${JNI_DIR}/${ANDROID_ABI}/libtensorflowlite_jni.so)
include_directories( ${JNI_DIR} )
target_link_libraries(native-lib tensorflowlite_jni)
I have a problem with the function
the displayed error is undefined reference to TfLiteModelCreateFromFile; I want to use API C for TensorFlow in a program in C. this is my Program
int32_t main(int32_t argc, char *argv[])
{
TfLiteModel* model = TfLiteModelCreateFromFile("iris.tflite");
TfLiteInterpreterOptions*options =TfLiteInterpreterOptionsCreate();
}

How to Fix the Error One of CERES_USE_OPENMP, CERES_USE_CXX11_THREADS or CERES_NO_THREADS must be defined in Ceres Solver Android

I am integrating Ceres Solver Library in my Android Application. I have created the prebuilt shared library (.so files) for all the architecture using CMakeLists.txt in Android Studio. Now I want to implement the Bundle adjustment in Java/Kotlin with OpenCV java wrappers.
To consume Ceres Solver in Android application we have to write the ceres solver logic in C++ using .so file and header files of the Ceres Solver and its dependency libraries. Then we have to write the wrappers to our own methods to consume in Java / Kotlin.
For this I am using the following CMakeLists.txt file
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
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).
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 )
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
include_directories( C:/eigen-eigen-323c052e1731 )
include_directories( C:/My_Data/Ceres-Solver-Builder/ceres-solver/include )
include_directories( C:/My_Data/Ceres-Solver-Builder/ceres-solver/config )
include_directories( C:/My_Data/Ceres-Solver-Builder/ceres-solver/internal/ceres/miniglog )
include_directories( C:/My_Data/Ceres-Solver-Builder/ceres-solver/internal )
add_library( ceres-lib SHARED IMPORTED)
set_target_properties( # Specifies the target library.
ceres-lib
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
C:/My_Data/AS_Workspace/JNIApplication/app/src/main/jniLibs/${ANDROID_ABI}/libceres.so )
target_link_libraries( native-lib ceres-lib ${log-lib})
Sample C++ file that uses Ceres Solver classes and methods native-lib.cpp
#include <jni.h>
#include <string>
#include <bitset>
#include "ceres/ceres.h"
#include "glog/logging.h"
using ceres::AutoDiffCostFunction;
using ceres::CostFunction;
using ceres::Problem;
using ceres::Solver;
using ceres::Solve;
int test();
extern "C" JNIEXPORT jstring JNICALL
Java_com_trimble_jniapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
test();
return env->NewStringUTF(hello.c_str());
}
// A templated cost functor that implements the residual r = 10 -
// x. The method operator() is templated so that we can then use an
// automatic differentiation wrapper around it to generate its
// derivatives.
struct CostFunctor {
template<typename T>
bool operator()(const T *const x, T *residual) const {
residual[0] = 10.0 - x[0];
return true;
}
};
int test() {
//google::InitGoogleLogging(argv[0]);
// The variable to solve for with its initial value. It will be
// mutated in place by the solver.
double x = 0.5;
const double initial_x = x;
// Build the problem.
Problem problem;
// Set up the only cost function (also known as residual). This uses
// auto-differentiation to obtain the derivative (jacobian).
CostFunction *cost_function = new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor);
problem.AddResidualBlock(cost_function, NULL, &x);
// Run the solver!
Solver::Options options;
options.minimizer_progress_to_stdout = true;
Solver::Summary summary;
Solve(options, &problem, &summary);
std::cout << summary.BriefReport() << "\n";
std::cout << "x : " << initial_x
<< " -> " << x << "\n";
return 0;
}
When I build the application I am getting the following error.
error One of CERES_USE_OPENMP, CERES_USE_CXX11_THREADS or CERES_NO_THREADS must be defined.
I am new to NDK, Cmake, and Ceres Solver, So I don't know how to fix this problem. Someone please suggest me how to fix the problem or point me what I am doing wrong. Thanks in advance.
As commented, you need to define at least one of these preprocessor definitions when using Ceres (see logic here). You can add definitions to the compilation with CMake using target_compile_definitions():
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).
native-lib.cpp )
target_compile_definitions(native-lib PRIVATE CERES_USE_CXX11_THREADS=1)
...

Error:(49) undefined reference to 'cv::Stitcher::createDefault(bool)' in using OpenCV native in Android

I am developing an Android application that involves some image processing. I am now stitching images using OpenCV. I am doing it in c++. So, I integrated the OpenCV (both native c++ and Java) into my Android project. But when I use the stitching features in c++ and run my project, it is giving me the compilation error.
This is my whole c++ library (native-lib) for stitching images.
//
// Created by Acer on 3/28/2018.
//
#include <jni.h>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <iostream>
#include <fstream>
#include <opencv2/stitching.hpp>
using namespace std;
using namespace cv;
extern "C" {
jstring
Java_media_memento_memento_SphereCameraActivity_stitchPhotos(
JNIEnv *env,
jobject /* this */, jlong addrMat, jlong addrNewMat, jlongArray addrsPreviews) {
Mat &in = *(Mat *) addrMat;
Mat &newMat = *(Mat *) addrNewMat;
int size = env->GetArrayLength(addrsPreviews);
jlong *addrPreviewArray = env->GetLongArrayElements(addrsPreviews, NULL);
vector<Mat> imgs(size);
for (long i = 0; i < size; i++) {
jlong previewAddress = addrPreviewArray[i];
imgs[i] = *(Mat *) previewAddress;
}
bool try_use_gpu = false;
Mat pano;
Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
Stitcher::Status status = stitcher.stitch(imgs, pano);
if (status != Stitcher::OK) {
//the return map would be null
} else {
//copy the map.
pano.copyTo(newMat);
newMat = pano;
}
env->ReleaseLongArrayElements(addrsPreviews, addrPreviewArray, 0);
}
}
This is my CMakeList.txt file
set(pathToProject C:/Users/iljim/Desktop/memento/memento-android)
set(pathToOpenCv C:/Users/iljim/Desktop/OpenCV-3.1.0-android-sdk/OpenCV-android-sdk)
# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
include_directories(C:/Users/iljim/Desktop/OpenCV-3.1.0-android-sdk/OpenCV-android-sdk/sdk/native/jni/include)
# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add_library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.
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).
src/main/cpp/native-lib.cpp )
add_library( # Specifies the name of the library.
cubemap
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/cubemap.cpp )
add_library( lib_opencv SHARED IMPORTED )
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so)
# 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
# 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 the
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# OpenCV lib
lib_opencv
# Cubemap lib
cubemap
# Links the target library to the log library
# included in the NDK.
${log-lib} )
When I run, I got the mentioned error.
Error:error: linker command failed with exit code 1 (use -v to see invocation)
Error:(49) undefined reference to 'cv::Stitcher::createDefault(bool)'
Error:(50) undefined reference to 'cv::Stitcher::stitch(cv::_InputArray const&, cv::_OutputArray const&)'
I found this link - undefined reference to `cv::Stitcher::createDefault(bool)'. But I believe I integrated the c++ opencv native lib properly. That is why I can use other libraries. When I check the file in the SDK folder, the stitching.hpp exists. So, what might be possible and how can I solve it?
I had a quite similar problem and solved it with linking "libopencv_stitching.a" static library from OpenCV SDK in my CMakeLists.txt file.
file(GLOB CVLIBS
path/to/your/opencv/sdk/staticlibs/${ANDROID_ABI}/libopencv_stitching.a)
...
target_link_libraries( # Specifies the target library.
...
${CVLIBS}
# Links the target library to the log library
# included in the NDK.
${log-lib})
Also this answer can be useful as well: Building OpenCV for Android and using it with the NDK

Compiling 1 library with 2 sub-libraries with Android Studio's CMake and NDK

Working on an Android NDK project. The project is using CMake to build the C++ libraries.
The library has the following structue -
Main Library
main.cpp
CMakeLists.txt
hello (sub library)/
CMakeLists.txt
include/
hello.h
src/
hello.c
world (sub library)/
CMakeLists.txt
include/
world.h
src/
world.c
The contents are the following:
main.cpp
#include <jni.h>
#include <string>
#include <hello.h>
#include <world.h>
extern "C"
JNIEXPORT jstring
JNICALL
Java_com_test_myapplication_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string str = hello() + world();
return env->NewStringUTF(str.c_str());
}
CMakeLists.txt for main.cpp
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_subdirectory(src/main/cpp/hello)
include_directories(src/main/cpp/hello)
add_subdirectory(src/main/cpp/world)
include_directories(src/main/cpp/world)
target_link_libraries( # Specifies the target library.
native-lib
hello
world)
world.h
#include <string>
std::string world();
world.c
#include "world.h"
std::string world() {
return std::string("world");
}
CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
project (world)
add_definitions(/DVERSION="0.4.0")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os")
include_directories(include/)
set(SOURCES
src/world.c
include/world.h
)
add_library(world STATIC IMPORTED
${SOURCES}
)
target_include_directories(world PUBLIC ./)
The content is the same for the "hello" library as the only difference is the output returned from hello's function.
Now, my experience with CMake is close to non-existent and I can't get this to work. I'm constantly getting errors upon building it. Latest error is the following -
CMake Error at src/main/cpp/hello/CMakeLists.txt:19
(target_include_directories): Cannot specify include directories for
imported target "hello". CMake Error at
src/main/cpp/world/CMakeLists.txt:19 (target_include_directories):
Cannot specify include directories for imported target "world".
I just can't find a way to compile all of it into a simple library that will be used in the app. Sometimes I get " not found", sometimes it can't find the header files and etc.
I'd appericiate if someone will be able to post a simple structure and CMake of the correct way of doing so as I'm lost.
In the actual project I try to use libmicrohttpd, but again, can't make it work. I've tried using CentOS's libraries but Android Studio seems to use the system's libraries which causes things to get messed up. This is the reason for which I download the library and try to compile it via Android Studio.
So, again, if anyone will be able to find a way to compile all of the 3 libraries together into a single library (main) which connected the other 2 (hello, world), I'd greatly appericiate it.
Much appericiated.

Android Studio IDE can't find NDK header files

I'm using OpenGL ES2 inside an android app inside C++ code.
Compiling and executing the program works as planned, however the IDE itself cannot find the NDK header files leaving my code files ugly:
My cmake file:
cmake_minimum_required(VERSION 3.4.1)
add_library(native-lib
SHARED
openGLRenderer.cpp
androidInterface.cpp
)
target_link_libraries(native-lib
android
log
EGL
GLESv2
)
build.gradle:
...
externalNativeBuild {
cmake {
cppFlags "-frtti"
arguments '-DANDROID_PLATFORM=android-21',
'-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'
}
...
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
What do I have to do to fix this? Thank you!
I can't believe this.
The fix is to use the other slashes.
So instead of:
#include <GLES2\gl2.h>
do
#include <GLES2/gl2.h>
It still compiled fine and both preview and compile worked in Visual Studio where I had it before.
Have you added the header files to your cmake file with "include_directories"?
cmake_minimum_required(VERSION 3.4.1)
project(GL3Lib)
# now build app's shared lib
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wc++11-extensions -Werror -Wno-deprecated -std=c++11")
add_subdirectory(freetype)
include_directories(freetype/include)
include_directories(common)
include_directories(utils)
include_directories(rendering/text)
file(GLOB UTILS_HEADERS "utils/*.h")
file(GLOB COMMON_HEADERS "common/*.h")
file(GLOB TEXT_HEADERS "rendering/text/*.h")
file(GLOB UTILS_HEADERS "utils/*.h")
set(JNI_SRCS
JNI_Api.cpp)
set(TEXT_SRCS
rendering/text/Font.cpp
)
set(UTIL_SRCS
common/Utils.cpp
)
add_library(gl3 SHARED
${JNI_SRCS}
${TEXT_SRCS}
${UTIL_SRCS}
${UTILS_HEADERS}
)
# MESSAGE( STATUS "CMAKE_SOURCE_DIR: " ${CMAKE_SOURCE_DIR} )
# add lib dependencies
target_link_libraries(gl3
android
freetype
log
EGL
GLESv3
)

Categories

Resources