Заключение проекта BIG C ++ в статическую библиотеку iOS: зависимости, удаление и скрытие - PullRequest
2 голосов
/ 21 марта 2012

У нас есть огромная кодовая база с множественными зависимостями (например, tinyxml, fft и т. Д.), Шаблонами ... в C / C ++, которые аккуратно заключены в очень простой интерфейс на языке C.

Создание динамической библиотеки для OSX было просто замечательно, потому что мы могли легко убрать все ненужные символы из библиотеки (используя strip -S -x), оставив только нужный интерфейс C и скрыв все классы C ++ / templates / dependencies /. .. Таким образом, в итоге единственными экспортируемыми / видимыми символами являются наши вызовы API: OUR_LIBNAME_FUNC1, OUR_LIBNAME_FUNC2 и т. Д. И т. Д.

Однако теперь мы хотим сделать то же самое для статической библиотеки iOS, и у нас заканчиваются идеи. Есть ли способ скрыть все ненужные / нужные символы, не возвращаясь к большому беспорядку слияния кода, переписывания кода, objdump-ing, запутывания ...? Особенно для внешних библиотек, которые могут быть повторно использованы другими и которые приведут к нескольким определениям символов!

После долгих исследований (в основном переполнение стека :-)) я становлюсь безнадежным ...

приветствует

Ответы [ 2 ]

0 голосов
/ 18 февраля 2013

Отвечая на мой собственный вопрос: в конце концов мы прибегли к анонимному пространству имен и объединению кода.

Т.е. весь код cpp / c был объединен в большой C-файл с использованием большого и относительно сложного / уродливого питонаскрипт.Все функции в файле CPP были обернуты в анонимное пространство имен, оставляя только экспортированные функции вне пространства имен.

После этого выполнение полосы -S -x в библиотеке очищает большую часть мусора.

Т.е.

/************** 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 ...

  • Брэм
0 голосов
/ 03 августа 2012

ОК, я просто потратил много времени, делая что-то похожее на это. Это не идеально, но это сработало достаточно для наших целей.

  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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...