Build Android NDK project with Cmake - gcc

I would like to generate my android native application with the android NDK and Cmake, so, I've downloaded the android-cmake toolchain.
Cmake generate my project successfully, but when I try to go in the generate directory and try to run "make", I've got the following error:
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/ldz/Desktop/myProject
[ 1%] Building CXX object Project/src/Main/Core/CMakeFiles/Core.dir/Main/Main.cpp.o
arm-linux-androideabi-g++: error: unrecognized command line option '-stdlib=libc++'
I don't know what is wrong here, my project use C++11, here is my g++ --version result:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix
Thanks!

To build an Android NDK project with Cmake and create APK, you should do :
Instead of using android-cmake, you should use the fork from taka-no-me.
Then use Apk.cmake from pixellight. Copy also [AndroidManifest.xml.in, LoadLibraries.java.in, strings.xml.in] from this repo.
Have a CMakeLists.txt like this :
cmake_minimum_required(VERSION 2.8.3)
project(testBuilder)
include("Apk.cmake" REQUIRED)
include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
set(TEST_SRC
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c
src/Main.cpp
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -ffor-scope -fno-rtti -fno-exceptions -pipe -ffunction-sections -fdata-sections -ffast-math -Wnon-virtual-dtor -Wreorder -Wsign-promo -fvisibility=hidden -fvisibility-inlines-hidden -Wstrict-null-sentinel -Os -funroll-all-loops -fpeel-loops -ftree-vectorize")
set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,--as-needed -Wl,--gc-sections -Wl,--no-undefined -Wl,--strip-all -Wl,-rpath-link=${ANDROID_NDK_SYSROOT}/usr/lib/ -L${ANDROID_NDK_SYSROOT}/usr/lib/")
add_library(test SHARED ${TEST_SRC})
target_link_libraries(test log android)
set_target_properties(test PROPERTIES COMPILE_DEFINITIONS "ANDROID")
set(APP_SHARED_LIBRARIES ${LIBRARY_OUTPUT_PATH}/libtest.so)
android_create_apk(test "${CMAKE_BINARY_DIR}/apk" "${APP_SHARED_LIBRARIES}" "" "Data")
This is Main.cpp
#include <android_native_app_glue.h>
#include <android/log.h>
#define APPNAME "TestApp"
void android_main(struct android_app* state)
{
app_dummy(); // Make sure glue isn't stripped
__android_log_print(ANDROID_LOG_INFO, APPNAME, "HolyShit you did it !");
ANativeActivity_finish(state->activity);
}

Based on Vi.:s answer I did a clone of android-cmake on github and added a modified Apk.cmake called android.apk.cmake. I use NativeActivity instead of pixellight:s LoadLibraries.java.
The clone is here:
https://github.com/Discordia/android-cmake
I created the example in Vi.:s answer:
https://github.com/Discordia/android-cmake-example

Related

Why is CMake putting "std=gnu++14" in Clang invocations when I don't specify GCC?

I have a pretty simple CMake-based project that builds one lib and a small executable that uses it. It builds fine on Linux with GCC, but fails on Mac OS with loads of errors of the following kind. The inciting line of code in main.cpp is the second one here:
#include <cstdlib>
#include <memory>
The first of many similar errors:
[build] In file included from /Users/me/data/series2server/main.cpp:2:
[build] In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/memory:671:
[build] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/__algorithm/search.h:34:19: error: no member named 'make_pair' in namespace 'std::__1'
[build] return _VSTD::make_pair(__first1, __first1); // Everything matches an empty sequence
This appears to be a mismatch between Clang and GCC uses of std. But I can't figure out why CMake is configuring things to call clang++ but putting "std=gnu++14" in the compiler invocation. I did a full-text search for "std=gnu" in the whole source tree and didn't find it. I do see this in various CMakeLists.txt files:
set( CMAKE_CXX_STANDARD 14 )
A compiler invocation is below. Where might I look for where this gnu option is specified? Thanks!
[build] cd /Users/me/data/series2server/build/restbed && /usr/bin/clang++ -DBUILD_SSL -I/Users/me/data/series2server/restbed/source -isystem /Users/me/data/series2server/restbed/dependency/asio/asio/include -isystem /Users/me/data/series2server/restbed/dependency/openssl/include -Wall -Wextra -Weffc++ -pedantic -Wno-unknown-pragmas -Wno-deprecated-declarations -Wno-non-virtual-dtor -DASIO_STANDALONE=YES -Wno-deprecated-declarations -g -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++14 -MD -MT restbed/CMakeFiles/restbed-static.dir/source/corvusoft/restbed/detail/service_impl.cpp.o -MF CMakeFiles/restbed-static.dir/source/corvusoft/restbed/detail/service_impl.cpp.o.d -o CMakeFiles/restbed-static.dir/source/corvusoft/restbed/detail/service_impl.cpp.o -c /Users/me/data/series2server/restbed/source/corvusoft/restbed/detail/service_impl.cpp
From n.m.'s comment 10 years ago, for clarity:
set( CMAKE_CXX_STANDARD 14 ) sets gcc or clang flag to -std=gnu++14, unless CXX_EXTENSIONS property (or CMAKE_CXX_EXTENSIONS variable) is set to OFF.

How to use NDK wth gcc on Android?

I need to compile OpenCV 2 to test some things and it can only be built with gcc. I tried downloading the oldest NDK in Android Studio which is version 16, however it still tries to use clang. How can I force it to use gcc?
Error on version 16:
ERROR: /home/user/AndroidStudioProjects/opencv2builder/app/src/main/cpp/CMakeLists.txt : C/C++ debug|x86 : CMake Error at /home/user/Android/Sdk/cmake/3.10.2.4988404/share/cmake-3.10/Modules/CMakeTestCCompiler.cmake:52 (message):
The C compiler
"/home/user/Android/Sdk/ndk/16.1.4479499/toolchains/llvm/prebuilt/linux-x86_64/bin/clang"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: /home/user/AndroidStudioProjects/opencv2builder/app/.cxx/cmake/debug/x86/CMakeFiles/CMakeTmp
Run Build Command:"/home/user/Android/Sdk/cmake/3.10.2.4988404/bin/ninja" "cmTC_ed369"
[1/2] Building C object CMakeFiles/cmTC_ed369.dir/testCCompiler.c.o
FAILED: CMakeFiles/cmTC_ed369.dir/testCCompiler.c.o
/home/user/Android/Sdk/ndk/16.1.4479499/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --target=i686-none-linux-android --gcc-toolchain=/home/user/Android/Sdk/ndk/16.1.4479499/toolchains/x86-4.9/prebuilt/linux-x86_64 --sysroot=/home/user/Android/Sdk/ndk/16.1.4479499/sysroot -isystem /home/user/Android/Sdk/ndk/16.1.4479499/sysroot/usr/include/i686-linux-android -D__ANDROID_API__=16 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -Wa,--noexecstack -Wformat -Werror=format-security -fPIE -o CMakeFiles/cmTC_ed369.dir/testCCompiler.c.o -c testCCompiler.c
/home/user/Android/Sdk/ndk/16.1.4479499/toolchains/llvm/prebuilt/linux-x86_64/bin/clang: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory
ninja: build stopped: subcommand failed.
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt
Affected Modules: app

Compiling OpenMP to WebAssembly

I am trying to compile a multi threaded application to WebAssembly. The application uses OpenMP for multithreading.
To compile I am using the Emscripten framework.
I have already downloaded the source files for OpenMP and compiled it for my host machine using make. With the following command I can get it to link with a simple demo application on my machine:
g++ -Wall -Werror -pedantic main.o -o main.x /$PATH_TO_OPENMP/build/runtime/src/libgomp.a -pthread -lstdc++ -Wl,--no-as-needed -ldl
I then tried to compile OpenMP to the llvm bytecode format used by Emscripten. To do so I tried to run 'emmake make', so that the emscripten framework executes the OpenMP makefiles with a suitable compiler. As emscripten does not like shared object files I compiled it to static library .a files.
This works and actually gives me object files to which I can link.
I then wanted to link my demo application with the following command
em++ -Wall -Werror -pedantic main.o -o main.html /home/main/data/Programming/openMP/openmp_web/build/runtime/src/libgomp.a -pthread -lstdc++ -Wl,--no-as-needed -ldl
But I get these warnings, that it couldn't link to OpenMP files:
shared:WARNING: object /tmp/emscripten_temp_ONa0eU_archive_contents/kmp_atomic.cpp.o is not a valid object file for emscripten, cannot link
.
.
shared:WARNING: object /tmp/emscripten_temp_ONa0eU_archive_contents/kmp_str.cpp.o is not a valid object file for emscripten, cannot link
shared:WARNING: object /tmp/emscripten_temp_ONa0eU_archive_contents
So I figured I must have compiled OpenMP with the wrong compiler. I then tried to change the compiler when building the library by using the following commands:
cmake -DCMAKE_C_COMPILER=emcc -DCMAKE_CXX_COMPILER=em++ -DLIBOMP_LIB_TYPE=normal -DLIBOMP_ENABLE_SHARED=OFF -DCMAKE_BUILD_TYPE=Release -DLIBOMP_ARCH=x86_64 OPENMP_STANDALONE_BUILD=1 ..
emmake make
But this just gives strange errors on some missing system variables
/home/main/data/Programming/openMP/openmp_web/runtime/src/kmp_platform.h:82:2: error: Unknown OS
/home/main/data/Programming/openMP/openmp_web/runtime/src/kmp_platform.h:203:2: error: Unknown or unsupported architecture
In file included from /home/main/data/Programming/openMP/openmp_web/runtime/src/kmp_alloc.cpp:13:
In file included from /home/main/data/Programming/openMP/openmp_web/runtime/src/kmp.h:77:
/home/main/data/Programming/openMP/openmp_web/runtime/src/kmp_os.h:171:2: error: "Can't determine size_t printf format specifier."
Does anyone have an idea on what I could do differently?

Can compile and link use different compilers when cross-compile?

I'd like to know if I can use different compilers for compile and link.
For example ,I have two files ,a.c and b.c,
I use clang to compile a.c and b.c:
clang -c a.c -o a.o
clang -c b.c -o b.o
and then use gcc to link the two .o file as a so library:
gcc -lm -lz -shared a.o b.o -o libad.so
I generate the so file successfully,but the app will crash when using this library.
Update:
More detailed information: What I have done is cross-compile , and target platform is armv7a.I use android-NDK and compile the codes on MAC.So the gcc is arm-linux-androideabi-gcc and clang is arm-linux-androideabi-clang.
Unless special flags are specified at link time (-fuse-ld=xxx[1][2]), both clang and gcc call the default system linker (which on macOS is lld and will probably be gold on linux). So running the second statement with either gcc or clang will produce the same linked binary.
[1] https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
[2] http://clang-developers.42468.n3.nabble.com/LLD-to-be-the-default-linker-in-Clang-td4053949.html

Compile C++ code containing OpenMP with manually built gcc compiler

I've downloaded from github and built gcc. After that I've tried to compile a code with OpenMP:
../GCC/build/gcc/xgcc -B./../GCC/build/gcc/ -I./../GCC/build/x86_64-unknown-linux-gnu/libgomp -Wno-write-strings -O3 -Wall -fopenmp -lpng -o mandelbrot-omp mandelbrot-omp.cpp​
Then I got the following error message:
xgcc: error: libgomp.spec: No such file or directory​
I've checked and found out that libgomp directory contains the libgomp.spec file. The directory is included with -I option. What's wrong?

Resources