got this strange behaviour with standalone Android NDK r10e Toolchain (built with --toolchain=x86-clang3.6 switch). Environment variables for cross compilation have been set before running makefile, SYSROOT points to Android toolchain location, CXX equals i686-linux-android-clang++. Basically, I have a bunch of cpp files that I would like to compile to Android executable. Sadly, clang++ keeps producing .so shared library (checked with readelf - it is indeed shared object). Is there a special switch to compiler / linker that I have forgotten?
Makefile: (main.cpp contains main function)
CFLAGS=-c -Wall -std=c++11 -Wextra --sysroot=${SYSROOT} -march=i686
LDFLAGS=-lc -lc++_shared -L${SYSROOT}/usr/lib
SOURCES=main.cpp File1.cpp File2.cpp File3.cpp File4.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=test
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS) ${CXX} $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o: ${CXX} $(CFLAGS) $< -o $@
clean: rm *.o test
clang++ keeps producing .so shared library (checked with readelf - it is indeed shared object). Is there a special switch to compiler / linker that I have forgotten?
My guess: readelf
is outputting Elf file type is DYN (shared object file)
, and you are interpreting that to mean a shared object :)
You probably did something like:
readelf -l test | grep -i "file type"
In reality, that's an artifact of Position Independent Executable (PIE) and readelf
reporting.
The important part is readelf
is reporting DYN
, and not reporting EXE
. EXE
means it lacks PIE, and that usually triggers a security related defect.
PIE was added at Android 4.1, but it was optional. PIE is required for Android 5.0 and above. From Security Enhancements in Android 5.0:
non-PIE linker support removed. Android now requires all dynamically linked executables to support PIE (position-independent
executables). This enhances Android’s address space layout
randomization (ASLR) implementation.
Also see Position Independent Executables on Stack Overflow. It discusses PIE and Android.