diff --git a/CMakeLists.txt b/CMakeLists.txt index 0473b719e..bde4915fc 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,7 +277,17 @@ if(ANDROID) else() message(STATUS "FREERDP_ANDROID_EXTERNAL_SSL_PATH not set! - Needs to be set if openssl is not found in the android NDK (which usually isn't)") endif() + if(WITH_GPROF) + if (NOT FREERDP_ANDROID_EXTERNAL_PROFILER_PATH) + if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/android-ndk-profiler") + set(FREERDP_ANDROID_EXTERNAL_PROFILER_PATH + "${CMAKE_CURRENT_SOURCE_DIR}/external/android-ndk-profiler") + else() + message(STATUS "FREERDP_ANDROID_EXTERNAL_PROFILER_PATH not set!") + endif() + endif() endif() +endif() set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_ANDROID_EXTERNAL_SSL_PATH}) set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/client/Android/FreeRDPCore/libs/${ANDROID_ABI}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/scripts/regenerate_jni_headers.sh.cmake ${CMAKE_CURRENT_SOURCE_DIR}/scripts/regenerate_jni_headers.sh @ONLY) @@ -451,6 +461,16 @@ set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) set(CMAKE_INSTALL_RPATH "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}:\$ORIGIN/..") +# Android profiling +if(ANDROID) + if(WITH_GPROF) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg") + set(PROFILER_LIBRARIES + "${FREERDP_ANDROID_EXTERNAL_PROFILER_PATH}/obj/local/${ANDROID_ABI}/libandroid-ndk-profiler.a") + include_directories("${FREERDP_ANDROID_EXTERNAL_PROFILER_PATH}") + endif() +endif() + # Unit Tests include(CTest) diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index f0046dcc5..d3e3d2dd9 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -34,6 +34,10 @@ #include "android_debug.h" #include "android_cliprdr.h" +#if defined(WITH_GPROF) +#include "jni/prof.h" +#endif + struct thread_data { freerdp* instance; @@ -378,6 +382,10 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls) { freerdp* instance; +#if defined(WITH_GPROF) + monstartup("libfreerdp-android.so"); +#endif + // create instance instance = freerdp_new(); instance->PreConnect = android_pre_connect; @@ -401,6 +409,10 @@ JNIEXPORT void JNICALL jni_freerdp_free(JNIEnv *env, jclass cls, jint instance) { freerdp* inst = (freerdp*)instance; freerdp_free(inst); + +#if defined(WITH_GPROF) + moncleanup(); +#endif } JNIEXPORT jboolean JNICALL jni_freerdp_connect(JNIEnv *env, jclass cls, jint instance) diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake index c40e93a0a..943487d91 100644 --- a/cmake/ConfigOptions.cmake +++ b/cmake/ConfigOptions.cmake @@ -12,6 +12,7 @@ endif() option(WITH_MANPAGES "Generate manpages." ON) option(WITH_PROFILER "Compile profiler." OFF) +option(WITH_GPROF "Compile with GProf profiler." OFF) if((TARGET_ARCH MATCHES "x86|x64") AND (NOT DEFINED WITH_SSE2)) option(WITH_SSE2 "Enable SSE2 optimization." ON) diff --git a/config.h.in b/config.h.in index bbbe36102..d99b9a596 100755 --- a/config.h.in +++ b/config.h.in @@ -37,6 +37,7 @@ /* Options */ #cmakedefine WITH_PROFILER +#cmakedefine WITH_GPROF #cmakedefine WITH_SSE2 #cmakedefine WITH_NEON #cmakedefine WITH_IPP diff --git a/libfreerdp/CMakeLists.txt b/libfreerdp/CMakeLists.txt index 3a167bcf5..1dbdb2ce1 100644 --- a/libfreerdp/CMakeLists.txt +++ b/libfreerdp/CMakeLists.txt @@ -52,12 +52,13 @@ if(MONOLITHIC_BUILD) set(${MODULE_PREFIX}_OBJECTS ${${MODULE_PREFIX}_OBJECTS} "$") endforeach() - add_library(${MODULE_NAME} dummy.c ${${MODULE_PREFIX}_OBJECTS}) + add_library(${MODULE_NAME} dummy.c + ${${MODULE_PREFIX}_OBJECTS}) set_target_properties(${MODULE_NAME} PROPERTIES LINKER_LANGUAGE C) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION} PREFIX "lib") - target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS} ${PROFILER_LIBRARIES}) install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries) diff --git a/scripts/android_setup_build_env.sh b/scripts/android_setup_build_env.sh new file mode 100755 index 000000000..d96f5de72 --- /dev/null +++ b/scripts/android_setup_build_env.sh @@ -0,0 +1,78 @@ +#!/bin/sh +# +# This script checks out or updates and builds third party libraries +# required for the android build. +# +# Specifically these are: +# - OpenSSL +# - Android NDK Profiler +# +# Usage: +# android_setup_build_env.sh + +OPENSSL_SCM=https://github.com/bmiklautz/android-external-openssl-ndk-static +NDK_PROFILER_SCM=https://github.com/richq/android-ndk-profiler + +SCRIPT_NAME=`basename $0` + +if [ $# -ne 1 ]; then + + echo "Missing command line argument." + echo "$SCRIPT_NAME " + exit -1 +fi + +if [ ! -d $1 ]; then + echo "Argument '$1' is not a directory." + exit -2 +fi +SRC=`realpath $1` + +echo "Using '$SRC' as root." + +echo "Preparing OpenSSL..." +OPENSSL_SRC=$SRC/external/openssl +if [ -d $OPENSSL_SRC ]; then + cd $OPENSSL_SRC + git pull + RETVAL=$? +else + git clone $OPENSSL_SCM $OPENSSL_SRC + RETVAL=$? + cd $OPENSSL_SRC +fi +if [ $RETVAL -ne 0 ]; then + echo "Failed to execute git command [$RETVAL]" + exit -3 +fi +ndk-build +RETVAL=$? +if [ $RETVAL -ne 0 ]; then + echo "Failed to execute ndk-build command [$RETVAL]" + exit -4 +fi + +echo "Preparing NDK profiler..." +NDK_PROFILER_SRC=$SRC/external/android-ndk-profiler +if [ -d $NDK_PROFILER_SRC ]; then + cd $NDK_PROFILER_SRC + git pull + RETVAL=$? +else + git clone $NDK_PROFILER_SCM $NDK_PROFILER_SRC + RETVAL=$? + cd $NDK_PROFILER_SRC +fi +if [ $RETVAL -ne 0 ]; then + echo "Failed to execute git command [$RETVAL]" + exit -5 +fi +ndk-build +RETVAL=$? +if [ $RETVAL -ne 0 ]; then + echo "Failed to execute ndk-build command [$RETVAL]" + exit -6 +fi + +echo "Prepared external libraries, you can now build the application." +exit 0