У меня есть проект на C, и из-за характера приложения, которое я создаю, я решил статически связать libconfig
с моим окончательным двоичным файлом, чтобы минимизировать внешние зависимости, необходимые для его использования. Раньше я динамически связывал библиотеки только с помощью стандартного метода, просто используя флаги, указывающие на /usr/lib
и /usr/include
, оставляя нетронутой структуру каталогов моего личного проекта.
Однако на этот раз я скомпилировал статический libconfig.a
и включил его в свою структуру каталогов, а Makefile
использовал его для связывания, а также необходимый файл заголовка для библиотеки, помещенный в мой каталог include/
, который содержит файлы заголовков для моей библиотеки. исходные .c
файлы проектов. Видеть:
project/
├── LICENSE
├── Makefile
├── README.md
├── bin/
├── include/
│ ├── headerfile1.h
│ ├── headerfile2.h
│ └── libs
│ └── libconfig.h
├── lib/
│ └── libconfig.a
├── obj/
└── src
├── srcfile1.c
└── srcfile2.c
Меня беспокоит, что это плохая практика, и мне интересно, существует ли более стандартный и элегантный способ справиться с тем, что я пытаюсь сделать, особенно если в будущем кто-то попытается скомпилировать это из исходного кода.
Вы можете рассмотреть Категорический императив: Что бы произошло, если бы все захотели свести к минимуму свои зависимости и поместить в свои пакеты статические сборки и замороженные заголовки своих зависимостей? В любом случае, вы предоставите пакет, который невозможно собрать из исходного кода, и какой смысл заставлять пользователей компилировать исходный код? Лучше просто снабдить свой исполняемый файл libconfig
статически связанным, если вы настаиваете на том, чтобы он не был динамической зависимостью, и вы будете рады отделить свою программу от исходного кода libconfig
.
@MikeKinghan Ну, это, по сути, то, что меня интересовало. Изначально меня беспокоили некоторые пользователи, которые захотят собрать его из исходного кода, поэтому я предоставил библиотеку библиотеки и заголовки, но я полагаю, что это было бы бессмысленно, если бы они сами не могли собрать ее из исходного кода.
У меня есть проект на C, и из-за характера приложения, которое я создаю, я решил статически связать libconfig с моим окончательным двоичным файлом, чтобы минимизировать внешние зависимости, необходимые для его использования.
Иногда это делается, чаще всего в форме статического связывания всех зависимостей.
Еще одна вещь, которая кажется более распространенной, — это динамическое связывание двоичного дистрибутива программного обеспечения с частными версиями общих библиотек, которые он предоставляет сам (включая сторонние библиотеки). Лично мне это не очень нравится, но у этого есть некоторые преимущества.
Однако это совершенно отдельные вопросы от того, как устроен исходник проекта и что в него входит.
Мне интересно, существует ли более стандартный и элегантный способ справиться с тем, что я пытаюсь сделать, особенно если в будущем кто-то попытается скомпилировать это из исходного кода.
Не существует стандартов для организации систем проектирования и сборки. В лучшем случае существуют свободные условности.
Один из способов, с помощью которого некоторые проекты справляются со сторонними зависимостями, которые, как они подозревают, у других могут возникнуть трудности с получением, — это объединение исходного кода для этих зависимостей. Затем они также настроят свою систему сборки для создания зависимости. Иногда у них будет (и, по моему мнению, они всегда должны быть) простые средства для сборки на основе библиотек, предоставляемых системой, вместо использования связанной копии. Это в значительной степени ортогонально связыванию — в сочетании с этим вы можете выполнять как статическое, так и динамическое связывание.
Другой способ работы проектов со сторонними зависимостями, особенно с теми, которые легко доступны, — это просто документировать их зависимости вместе с инструкциями о том, как их получить при необходимости.
НО если libconfig — единственная зависимость, которая вас беспокоит, то я думаю, вы делаете много шума из ничего. Это широко распространенная библиотека с открытым исходным кодом, с долгой историей и до сих пор поддерживаемая, с тщательно подобранными версиями, доступными во всех наиболее популярных дистрибутивах Linux, и при необходимости ее легко собрать из исходного кода.
libconfig
действительно моя единственная зависимость, как вы упомянули. Я решил просто задокументировать инструкции по ручной сборке libconfig, если кто-то действительно хочет скомпилировать программу из исходного кода. Это казалось «чище», чем наличие каталога с несколькими исходными кодами (или, скорее, просто моего исходного кода, сопровождаемого предварительно созданной статической библиотекой).
Кроме того, я не уверен, правильно ли я вас понял в отношении «Иногда у людей есть простые средства для сборки на основе библиотек, предоставляемых системой». Как это можно сделать, если пользователю необходимо установить внешнюю библиотеку типа libconfig
?
@Zsargul, «библиотеки, предоставляемые системой», следует отличать от тех, которые входят в комплект вашего программного обеспечения. Если вы используете, скажем, apt
или dnf
для установки библиотеки, то установленная библиотека интегрируется и предоставляется системой. Полагаю, можно выделить установки персональных библиотек как третью категорию, но на практике требования к их поддержке мало чем отличаются от требований к поддержке системных библиотек.
Не уверен, действительно ли это здесь по теме... Основная проблема, ИМХО, заключается в том, что у вас есть каталог со смешанным исходным кодом, содержащий внешний инструмент. Это означает, что 1/ вы привязываете свой исходный код к определенной цепочке сборки и 2/ вам придется следить за изменениями версий libconfig. Я понимаю, что это может облегчить перенос вашего кода на новую машину, использующую ту же систему, включая цепочку сборки, но что, если вам придется использовать его, скажем, в системе FreeBSD (при условии, что вы в настоящее время используете Linux)?