2

我正在将一些东西移植到 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开始工作可能是唯一的解决方案。

4

1 回答 1

0

如果您使用的是 NDK make 文件,您可能会尝试LOCAL_WHOLE_STATIC_LIBRARIES链接而不是链接LOCAL_STATIC_LIBRARIES到主机库或可执行文件。这将避免从静态库中剥离任何内容。

虽然它没有太多的粒度......

于 2014-01-28T00:49:56.927 回答