Может ли созданная Visual Studio статическая библиотека быть лишена символов?

Я разделю эти вопросы на 3 части:

  1. Я хотел бы создать статическую библиотеку и удалить ее символы. (Отладочная информация уже не включена) Аналогично команде strip в linux. Можно ли это сделать?

  2. Есть ли инструмент в среде Windows, эквивалентный инструменту nm в Linux?

  3. При создании статической библиотеки с помощью VS2008. Можно ли определить сценарий, который будет исключать некоторые созданные файлы .obj из сборки и из статической библиотеки?
    Может ли он быть динамическим? Я имею в виду, что я бы определил режим компиляции в скрипте, и это привело бы к исключению определенных объектных файлов из сборки.


person Ita    schedule 17.01.2011    source источник
comment
Библиотека без символов так же полезна, как и постоянная память.   -  person TonyK    schedule 17.01.2011


Ответы (4)


Если видно что-то, чего, по вашему мнению, быть не должно, попробуйте объявить это с помощью ключевого слова «static». Это сообщает компилятору, что он доступен только текущему модулю.

person Jimbo    schedule 17.01.2011
comment
Это делает только половину работы. В библиотеке еще есть символы, но их можно удалить: на линуксе strip -x ..., на винде не знаю как - вот в чем вопрос! - person anatolyg; 17.01.2011
comment
На самом деле я только что скомпилировал простой файл, в котором объявлены две функции, одна статическая, а другая нет, и статическая функция не появляется в файле .lib (проверено с помощью шестнадцатеричного редактора). Похоже, это делает то, что хочет ОП. - person Jimbo; 17.01.2011
comment
Я не могу найти способ удалить отдельные символы из окончательной библиотеки, параметр /REMOVE, упомянутый в другом ответе, кажется, только удаляет целые файлы .obj из выходной библиотеки. - person Jimbo; 17.01.2011
comment
@Jimbo, если вы просто объявите (и определите) статическую функцию, она не появится в скомпилированном файле. Хотя, если вы действительно используете его, он включается. - person binaryLV; 20.04.2015

Бывают случаи, когда было бы удобно иметь возможность удалить все, кроме небольшого количества «экспортируемых» общедоступных символов, но на самом деле это невозможно.

Статическая библиотека — это не более чем набор файлов .obj. Внутренние зависимости еще не разрешены и не будут разрешены до времени компоновки.

Например, если ваш .lib состоит из foo.obj и bar.obj, а в foo.obj есть вызов функции, определенной в bar.obj, то этот символ должен быть доступен во время компоновки, даже если ничего за пределами библиотека должна его видеть.

По этой причине вы не можете удалить символы (за возможным исключением статических символов файловой области). Даже методы класса, которые являются защищенными или закрытыми (в смысле C++), будут существовать в таблице символов, поскольку обеспечение видимости является проблемой времени компиляции, а не времени компоновки.

Напротив, динамическая библиотека — это автономный двоичный файл, который уже был связан. Ссылки с foo.obj на bar.obj уже разрешены. Таким образом, DLL может быть лишена символов, за исключением тех, которые должны быть экспортированы (и даже они могут быть переименованы или заменены порядковыми номерами).

Если ваша DLL предоставляет простой C API, то все готово. Но если вы хотите предоставить класс C++, вы, вероятно, в конечном итоге экспортируете все его методы, даже защищенные и частные (поскольку встраивание во внешнее приложение может привести к прямым вызовам частных методов).

person Adrian McCarthy    schedule 04.06.2013
comment
Мне любопытно насчет отрицательного голоса. Кто-нибудь хочет прокомментировать, чтобы я мог улучшить свой ответ? - person Adrian McCarthy; 05.11.2014
comment
Первое предложение в вашем ответе - это то, чего мы также пытаемся достичь. Пока варианты кажутся: 1) объявить все ненужные символы статическими, 2) поместить ненужные символы в безымянное пространство имен, 3) переименовать ненужные символы в какой-нибудь мусор (если ваша цель - запутывание). Первые два варианта следует комбинировать с единством сборки, чтобы убедиться, что приватные кросс-объектные символы больше не нужны. - person astraujums; 17.04.2015

  1. Нет, как вы думаете, как пользователи статической библиотеки будут ссылаться на нее, не зная, где определены символы, которые они используют?
  2. Да, попробуйте утилиту DUMPBIN.
  3. Ну да. Вы можете запустить утилиту LIB с помощью /REMOVE:foo.

Тем не менее, я думаю, что вы делаете что-то, что либо не стоит делать, либо может быть сделано намного проще, чем удаление членов библиотеки.

person wilx    schedule 17.01.2011

Я продолжал находить имена некоторых (но не всех) статических функций в файлах .obj, созданных VS2010. Интересно, что они были видны в моих файлах Release .obj, но не в файлах Debug .obj. Я просто использовал строки cygwin для поиска:

$ strings myObjectFile.obj | grep myStaticFunctionName

Я отследил его до параметра «Оптимизация всей программы = Да» («/GL»). Когда я переключил это на «Нет», имена функций больше не отображаются.

Обновление: в качестве последующего теста я открыл «очищенный» файл myObjectFile.obj в vim и все еще могу найти его (с помощью :set encoding=utf-8 или :set encoding=latin1). Я не уверен, почему в строках отсутствовали совпадения. Ну что ж.

person Mike Laughton    schedule 14.10.2011