2

我们有一个庞大的代码库,其中包含多个依赖项(如 tinyxml、fft 等)、模板……在 C/C++ 中,所有这些都整齐地包装在一个非常简单的 C 接口后面。

为 OSX 构建一个动态库就好了,因为我们可以轻松地从库中删除所有不需要的符号(使用 strip -S -x)只留下想要的 C 接口并隐藏所有 C++ 类/模板/依赖项/...所以最后,唯一导出/可见的符号是我们的 API 调用:OUR_LIBNAME_FUNC1、OUR_LIBNAME_FUNC2 等

然而,我们现在想对 iOS 静态库做同样的事情,但我们的想法已经不多了。有没有办法隐藏所有不需要/想要的符号,而不会恢复到一大堆代码合并、重写代码、objdump-ing、混淆......?特别是对于可能被其他人重用的外部库,这将导致多个符号定义!

经过大量研究(主要是堆栈溢出:-))我有点绝望......

打招呼

4

2 回答 2

0

好的,我只是花了很多时间做类似的事情。这是不完美的,但这对于我们的目的来说已经足够好了。

  1. 将您的 C api 顶级入口点放在一个文件“c_api.c”中。
  2. 创建一个文件“c_api.symbols”,其中每个入口点的名称单独在一行上,并带有链接器添加的“_”
  3. 使用链接器将您的 api 预链接到您的内部库

像这样的东西:

% cat c_api.c
#include "libA.h"
#include "libB.h"
#include "libC.h"

void init()
{
    libA_startup();
}

void run()
{
    libB_execute(libA_context());
}

void stop()
{
    libA_shutdown();
    libB_end();
    libC_log();
}
% cat c_api.symbols
_init
_run
_stop
% cc -c a_api.c
% ld -x -r c_api.o libA.a libB.a libC.a -exported_symbols_list c_api.symbols -o c_api_hidden.o
% ar r c_api.a c_api_hidden.o
于 2012-08-03T19:40:52.170 回答
0

回答我自己的问题:最后我们采用了匿名命名空间和代码合并。

即所有cpp/c 代码都使用一个大且相对复杂/丑陋的python 脚本合并到大C 文件中。CPP 文件中的所有函数都包装在一个匿名命名空间中,只将导出的函数留在命名空间之外。

之后在库上执行 strip -S -x 清除了大部分垃圾。

IE

/************** AMALGAMATED CPP FILE **************/

/************** STD HEADERS **************/
#include "OurLibraryHeader.h"
#include <cmath>
#include <string>
// more standard includes here and includes that aren't possible to do in the anonymous namespace

/************** AMALGAM **************/
namespace {
#include "OneofOurheaders1.h"
#include "OneofOurheaders2.h"
#include "SomeExternalLib.h"

/************************* OneofOurImplementations.cpp *************************/
// included literally

/************************* OneofOurImplementations2.cpp *************************/
// included literally

// etc
}

int OneOfOurLibraryFunctions()
{
}

// etc

这是相当肮脏的,但它可以完成工作。我确信有一些更好的方法可以通过一些 LLVM 技巧来做到这一点......

  • 布拉姆
于 2013-02-18T15:58:47.123 回答