我正在将一些东西移植到 Android,并且我有几个静态库应该链接到 .so 文件中(使用 Android NDK)。我尝试使用-Wl,-whole-archive
链接器(并由适当的 终止-Wl,-no-whole-archive
),但出现以下错误:
c:/android-ndk-r9/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe : error : C:/Users/Brent/Documents/git/gamelib/Core/Android/Android/Debug/Core-Android.a:
member at 25678 is not an ELF object [C:\Users\Brent\Documents\git\blackjack\blackjack-android.vcxproj]
还有许多对尚未实现的函数的未定义引用,但被其他已实现但未使用的函数调用(通常会被剥离)。整个事情还没有移植,但是我不能用 -whole-archive 测试(甚至构建)现有的代码。需要更细粒度的东西。
__attribute__((used))
所以,我决定在我的静态库中声明函数时尝试使用:
extern "C" {
void Java_com_brainium_blackjack_BlackjackJNILib_step(JNIEnv* _jni_env, jobject jthis) __attribute__ ((visibility ("default"))) __attribute__ ((used));
};
void Java_com_brainium_blackjack_BlackjackJNILib_step(JNIEnv* _jni_env, jobject jthis) {
}
但它仍然被剥离。将此代码放入直接编译到 .so 中的 .cpps 之一中可以正常工作,但是如果我将其放入静态库并将该库链接到 so 它不起作用。我使用 nm 来确保它实际上被排除在外,并且静态库的其他符号(正在被引用)存在(因此链接通常工作)。__attribute__((used))
没有按应有的方式工作,还是我只是使用错误?谢谢。
旁注:我没有使用 ndk-build(或制作文件)来构建这个项目。我正在使用(和扩展)vs-android。
编辑:经过更多搜索,似乎__attribute__((used))
没有做任何事情,因为如果链接器没有看到引用,甚至不会检查 .o 文件。这也向我表明,如果我只是通过其他方式强制它读取所有 .o 文件(将 .o 文件合并到一个 .o 文件中,或使用 -u 选项),它仍然会产生相同的效果作为--whole-archive。似乎--whole-archive
开始工作可能是唯一的解决方案。