【问题标题】:C++ Prevent linker from discarding functionsC++ 防止链接器丢弃函数
【发布时间】:2020-09-23 14:35:26
【问题描述】:

我正在为 android 构建一个 C++ 库。我有 X.so 共享库,它最终出现在 android 应用程序中,并通过 JNI 访问。我还有一个 Y.a 静态库,它几乎没有 X.so 使用的通用函数。 Y.a 也有一些 JNI 接口函数,Android 应用程序应该可以访问这些函数。 目前我遇到的问题是,在构建 Y.a 之后,我可以看到我需要导出的所有符号。但是在将它链接到 X.so 之后,链接器会丢弃所有 JNI 接口函数,因为它们没有在内部使用。我尝试了以下 2 个选项,但没有任何运气,

1.

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void JNICALL myImportantFunction(JNIEnv*, jclass);
.
.
.

void* volatile tmp = (void*)&myImportantFunction;
#ifdef __cplusplus
}
#endif

2.

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void __attribute__((used)) JNICALL myImportantFunction(JNIEnv*, jclass);
.
.
.

#ifdef __cplusplus
}
#endif

如果有任何 clang 属性或 hack 可以强制链接器不丢弃我需要的特定功能(当我构建 Y.a 时),那将是理想的。感谢大家在这方面的任何帮助。

【问题讨论】:

  • 参见例如stackoverflow.com/questions/7253801/… 虽然听起来你这样做是错误的。为什么不直接将所有导出的函数放在共享库的代码中呢?
  • 嗨迈克尔,感谢您的参考。但是,X.so 所需的函数与应导出的函数不在同一个目标文件中。所以我认为 --whole-archive 不应该工作?另外分离的原因是 Y.a 被多个共享库使用(基本上 Y.a 是我的所有产品都使用的许可库)
  • 每个产品(X.so 等)都将使用许可库来检查状态。 Android 端 (Java) 应访问许可库以使用其许可密钥进行初始化。

标签: android c++ linker java-native-interface clang


【解决方案1】:

如果你想保留整个Y.a,那么-Wl,--whole-archive -lY -Wl,--no-whole-archive确实是要走的路。

如果您只想保留来自Y.a 的特定符号,但让链接器从中丢弃其他(未使用的)目标文件,那么您需要告诉链接器这些函数已被使用,如下所示:

g++ -u myImportantFunction x1.o x2.o ... -lY -shared -o X.so

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    • 1970-01-01
    相关资源
    最近更新 更多