使用独立的Android NDK r10e工具链(使用--toolchain = x86-clang3.6开关构建)获得了这种奇怪的行为。在运行makefile之前已经设置了交叉编译的环境变量,SYSROOT指向Android工具链位置,CXX等于i686-linux-android-clang ++。基本上,我有一堆cpp文件,我想编译成Android可执行文件。遗憾的是,clang ++不断生成.so共享库(用readelf检查 - 它确实是共享对象)。我忘记了编译器/链接器的特殊切换吗?
Makefile :( main.cpp包含main函数)
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
答案 0 :(得分:1)
clang ++继续生成.so共享库(使用readelf检查 - 它确实是共享对象)。我忘记了编译器/链接器的特殊切换吗?
我的 猜测 :readelf
正在输出Elf file type is DYN (shared object file)
,而您正在将其解释为共享对象:)
你可能做过类似的事情:
readelf -l test | grep -i "file type"
实际上,这是位置独立可执行(PIE)和readelf
报告的工件。
重要的部分是readelf
报告 DYN
,而不报告 EXE
即可。 EXE
表示它缺少PIE,并且通常会触发与安全相关的缺陷。
PIE是在Android 4.1上添加的,但它是可选的。 Android 5.0及更高版本需要PIE。来自Security Enhancements in Android 5.0:
删除了非PIE链接器支持。 Android现在需要所有动态链接的可执行文件来支持PIE(与位置无关 可执行文件)。这增强了Android的地址空间布局 随机化(ASLR)实施。
另请参阅Stack Overflow上的Position Independent Executables。它讨论了PIE和Android。