Skip to content

Commit

Permalink
Android Build using NDK and android-cmake
Browse files Browse the repository at this point in the history
  • Loading branch information
Rainer Kuemmerle committed Aug 24, 2012
1 parent 047a27f commit db6c3a1
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 32 deletions.
37 changes: 28 additions & 9 deletions CMakeLists.txt
Expand Up @@ -56,13 +56,15 @@ IF(APPLE)
ENDIF(APPLE)

# Set the output directory for the build executables and libraries
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${g2o_SOURCE_DIR}/lib)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${g2o_SOURCE_DIR}/bin)
SET(g2o_RUNTIME_OUTPUT_DIRECTORY ${g2o_SOURCE_DIR}/bin CACHE PATH "Target for the binaries")
IF(WIN32)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${g2o_SOURCE_DIR}/bin)
SET(g2o_LIBRARY_OUTPUT_DIRECTORY ${g2o_SOURCE_DIR}/bin CACHE PATH "Target for the libraries")
ELSE(WIN32)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${g2o_SOURCE_DIR}/lib)
SET(g2o_LIBRARY_OUTPUT_DIRECTORY ${g2o_SOURCE_DIR}/lib CACHE PATH "Target for the libraries")
ENDIF(WIN32)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${g2o_LIBRARY_OUTPUT_DIRECTORY})
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${g2o_LIBRARY_OUTPUT_DIRECTORY})
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${g2o_RUNTIME_OUTPUT_DIRECTORY})

# Set search directory for looking for our custom CMake scripts to
# look for SuiteSparse, QGLViewer, and Eigen3.
Expand Down Expand Up @@ -94,6 +96,13 @@ ELSEIF(APPLE)
MESSAGE(STATUS "Compiling on OSX")
ENDIF(WIN32)

# detect Android Cross Compiler
# based on android-cmake which sets the variable ANDROID for us
IF(ANDROID)
ADD_DEFINITIONS(-DANDROID)
MESSAGE(STATUS "Cross compiling for Android")
ENDIF()

# For building the CHOLMOD / CSPARSE solvers
FIND_PACKAGE(Cholmod)
FIND_PACKAGE(BLAS)
Expand All @@ -114,6 +123,13 @@ ELSE(CSPARSE_FOUND)
SET(CSPARSE_FOUND TRUE)
ENDIF()
ENDIF(CSPARSE_FOUND)
OPTION(BUILD_LGPL_SHARED_LIBS "Build LGPL Code as Shared Libraries (LGPL Code)" ON)
SET (G2O_LGPL_LIB_TYPE STATIC)
IF (BUILD_LGPL_SHARED_LIBS)
SET (G2O_LGPL_LIB_TYPE SHARED)
ELSE()
MESSAGE(STATUS "Building LGPL code as static library (affects license of the binary)")
ENDIF()

# Eigen library parallelise itself, though, presumably due to performance issues
# OPENMP is experimental. We experienced some slowdown with it
Expand Down Expand Up @@ -155,9 +171,11 @@ ENDIF(G2O_BUILD_EXAMPLES)
IF(CMAKE_COMPILER_IS_GNUCXX)
MESSAGE(STATUS "Compiling with GCC")

# Generic settings for optimisation
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse4")
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse4")
IF(NOT ANDROID)
# Generic settings for optimisation
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse4")
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse4")
ENDIF()
# switch off optimization for debug builds
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
Expand All @@ -168,10 +186,10 @@ IF(CMAKE_COMPILER_IS_GNUCXX)
#SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
#ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# Linux
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
IF(NOT ANDROID AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -march=native")
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -march=native")
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
ENDIF()
# activate warnings !!!
SET(g2o_C_FLAGS "${g2o_C_FLAGS} -Wall -W")
SET(g2o_CXX_FLAGS "${g2o_CXX_FLAGS} -Wall -W")
Expand Down Expand Up @@ -209,6 +227,7 @@ SET(G2O_OPENGL_FOUND ${OPENGL_FOUND})
SET(G2O_HAVE_CHOLMOD ${CHOLMOD_FOUND})
SET(G2O_HAVE_CSPARSE ${CSPARSE_FOUND})
SET(G2O_SHARED_LIBS ${BUILD_SHARED_LIBS})
SET(G2O_LPGL_SHARED_LIBS ${BUILD_LPGL_SHARED_LIBS})
SET(G2O_CXX_COMPILER "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER}")
configure_file(config.h.in ${PROJECT_BINARY_DIR}/g2o/config.h)
include_directories(${PROJECT_BINARY_DIR})
Expand Down
8 changes: 8 additions & 0 deletions EXTERNAL/ceres/fpclassify.h
Expand Up @@ -52,6 +52,14 @@ inline bool IsNormal (double x) {
return classification == _FPCLASS_NN ||
classification == _FPCLASS_PN;
}
#elif defined(ANDROID)
// On Android, the C++ fpclassify functions are not available. Strictly
// speaking, the std functions are are not standard until C++11. Instead use
// the C99 macros on Android.
inline bool IsFinite (double x) { return isfinite(x); }
inline bool IsInfinite(double x) { return isinf(x); }
inline bool IsNaN (double x) { return isnan(x); }
inline bool IsNormal (double x) { return isnormal(x); }
#else
// TODO(keir): Test the "else" with more platforms.
inline bool IsFinite (double x) { return std::isfinite(x); }
Expand Down
3 changes: 2 additions & 1 deletion EXTERNAL/csparse/CMakeLists.txt
Expand Up @@ -4,7 +4,7 @@ PROJECT(csparse)

SET(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")

ADD_LIBRARY(csparse SHARED
ADD_LIBRARY(csparse ${G2O_LGPL_LIB_TYPE}
cs_add.c
cs_amd.c
cs_chol.c
Expand Down Expand Up @@ -60,6 +60,7 @@ ADD_LIBRARY(csparse SHARED
)

SET_TARGET_PROPERTIES(csparse PROPERTIES OUTPUT_NAME ${LIB_PREFIX}ext_csparse)
TARGET_LINK_LIBRARIES(csparse m)

INSTALL(TARGETS csparse
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
Expand Down
6 changes: 6 additions & 0 deletions EXTERNAL/csparse/cs_api.h
Expand Up @@ -26,14 +26,20 @@
#ifndef G2O_CSPARSE_API_H
#define G2O_CSPARSE_API_H

#include "g2o/config.h"

#ifdef _MSC_VER

// We are using a Microsoft compiler:
#ifdef G2O_LGPL_SHARED_LIBS
# ifdef csparse_EXPORTS
# define G2O_CSPARSE_API __declspec(dllexport)
# else
# define G2O_CSPARSE_API __declspec(dllimport)
# endif
#else
#define G2O_CSPARSE_API
#endif

#else
// Not Microsoft compiler so set empty definition:
Expand Down
1 change: 1 addition & 0 deletions config.h.in
Expand Up @@ -5,6 +5,7 @@
#cmakedefine G2O_OPENGL_FOUND 1
#cmakedefine G2O_OPENMP 1
#cmakedefine G2O_SHARED_LIBS 1
#cmakedefine G2O_LGPL_SHARED_LIBS 1

// available sparse matrix libraries
#cmakedefine G2O_HAVE_CHOLMOD 1
Expand Down
12 changes: 5 additions & 7 deletions g2o/apps/g2o_cli/g2o_common.cpp
Expand Up @@ -48,9 +48,11 @@ using namespace ::std;

// This is used to determine where this library is
#if defined (UNIX) || defined(CYGWIN)
# ifdef UNIX
# if (defined UNIX)
// dladdr is not available on a recent installation of Cygwin
# define _GNU_SOURCE
# ifndef _GNU_SOURCE
# define _GNU_SOURCE
# endif
# include <dlfcn.h>
static Dl_info info;
# endif
Expand Down Expand Up @@ -131,24 +133,20 @@ void loadStandardTypes(DlWrapper& dlTypesWrapper, int argc, char** argv)
void loadStandardSolver(DlWrapper& dlSolverWrapper, int argc, char** argv)
{
char * envSolversPath = getenv("G2O_SOLVERS_DIR");
string solversPath;
string solversPath = G2O_DEFAULT_SOLVERS_DIR_;

if (envSolversPath != NULL) {
solversPath = envSolversPath;
} else {
#if (defined UNIX)
if (dladdr(&info, &info) != 0) {
solversPath = getDirname(info.dli_fname);
} else {
solversPath = G2O_DEFAULT_SOLVERS_DIR_;
}
#elif (defined WINDOWS)
char libFilename[MAX_PATH + 1];
HMODULE instance = getMyInstance();
if (instance && GetModuleFileName(instance, libFilename, MAX_PATH) > 0) {
solversPath = getDirname(libFilename);
} else {
solversPath = G2O_DEFAULT_SOLVERS_DIR_;
}
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion g2o/solvers/csparse/CMakeLists.txt
@@ -1,6 +1,6 @@
INCLUDE_DIRECTORIES(${CSPARSE_INCLUDE_DIR})

ADD_LIBRARY(csparse_extension SHARED
ADD_LIBRARY(csparse_extension ${G2O_LGPL_LIB_TYPE}
csparse_helper.cpp csparse_helper.h
g2o_csparse_extension_api.h
)
Expand Down
6 changes: 6 additions & 0 deletions g2o/solvers/csparse/g2o_csparse_extension_api.h
Expand Up @@ -17,13 +17,19 @@
#ifndef G2O_CSPARSE_EXTENSION_API_H
#define G2O_CSPARSE_EXTENSION_API_H

#include "g2o/config.h"

#ifdef _MSC_VER
// We are using a Microsoft compiler:
#ifdef G2O_LGPL_SHARED_LIBS
#ifdef csparse_extension_EXPORTS
#define G2O_CSPARSE_EXTENSION_API __declspec(dllexport)
#else
#define G2O_CSPARSE_EXTENSION_API __declspec(dllimport)
#endif
#else
#define G2O_CSPARSE_EXTENSION_API
#endif

#else
// Not Microsoft compiler so set empty definition:
Expand Down
2 changes: 1 addition & 1 deletion g2o/stuff/CMakeLists.txt
Expand Up @@ -31,7 +31,7 @@ IF(OPENGL_FOUND)
SET_TARGET_PROPERTIES(opengl_helper PROPERTIES OUTPUT_NAME ${LIB_PREFIX}opengl_helper)
ENDIF()

IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND NOT ANDROID)
TARGET_LINK_LIBRARIES(stuff rt)
ENDIF()

Expand Down
4 changes: 2 additions & 2 deletions g2o/stuff/filesys_tools.cpp
Expand Up @@ -44,7 +44,7 @@
#include <WinBase.h>
#endif

#if defined (UNIX) || defined(CYGWIN)
#if (defined (UNIX) || defined(CYGWIN)) && !defined(ANDROID)
#include <wordexp.h>
#endif

Expand Down Expand Up @@ -134,7 +134,7 @@ std::vector<std::string> getFilesByPattern(const char* pattern)
FindClose(hFind);
}

#elif defined (UNIX) || defined (CYGWIN)
#elif (defined (UNIX) || defined (CYGWIN)) && !defined(ANDROID)

wordexp_t p;
wordexp(pattern, &p, 0);
Expand Down
12 changes: 9 additions & 3 deletions g2o/stuff/macros.h
Expand Up @@ -47,9 +47,15 @@
# define G2O_ATTRIBUTE_WARNING(func) func __attribute__((warning))
# define G2O_ATTRIBUTE_DEPRECATED(func) func __attribute__((deprecated))

#define g2o_isnan(x) std::isnan(x)
#define g2o_isinf(x) std::isinf(x)
# define g2o_isfinite(x) std::isfinite(x)
#ifdef ANDROID
# define g2o_isnan(x) isnan(x)
# define g2o_isinf(x) isinf(x)
# define g2o_isfinite(x) isfinite(x)
#else
# define g2o_isnan(x) std::isnan(x)
# define g2o_isinf(x) std::isinf(x)
# define g2o_isfinite(x) std::isfinite(x)
#endif

// MSVC on Windows
#elif defined _MSC_VER
Expand Down
12 changes: 4 additions & 8 deletions g2o/stuff/string_tools.cpp
Expand Up @@ -37,7 +37,7 @@
#include <iostream>
#include <iterator>

#if (defined UNIX) || (defined CYGWIN)
#if (defined (UNIX) || defined(CYGWIN)) && !defined(ANDROID)
#include <wordexp.h>
#endif

Expand Down Expand Up @@ -123,8 +123,7 @@ int strPrintf(std::string& str, const char* fmt, ...)

std::string strExpandFilename(const std::string& filename)
{

#if (defined UNIX) || (defined CYGWIN)
#if (defined (UNIX) || defined(CYGWIN)) && !defined(ANDROID)
string result = filename;
wordexp_t p;

Expand All @@ -134,14 +133,11 @@ std::string strExpandFilename(const std::string& filename)
}
wordfree(&p);
return result;
#endif

#ifdef WINDOWS
#else
(void) filename;
std::cerr << "WARNING: " << __PRETTY_FUNCTION__ << " not implemented" << std::endl;
return std::string();
#endif

#endif
}

std::vector<std::string> strSplit(const std::string& str, const std::string& delimiters)
Expand Down

0 comments on commit db6c3a1

Please sign in to comment.