написать систему сборки для библиотеки под linux windows с использование cmake на примере sqlite
Создание проекта CMake для Linux в Visual Studio
Поддержка Linux реализована в Visual Studio версии 2017 и выше. Чтобы увидеть документацию для этих версий, установите в расположенном над содержанием раскрывающемся списке Версия пункт Visual Studio 2017 или Visual Studio 2019.
Рекомендуется использовать CMake для проектов, которые являются кроссплатформенными или будут создаваться с открытым кодом. Проекты CMake можно использовать для сборки и отладки одного и того же исходного кода в Windows, подсистеме Windows для Linux (WSL) и удаленных системах.
Перед началом
Сначала убедитесь, что вы установили рабочую нагрузку Visual Studio для Linux, включая компонент CMake. Она является рабочей нагрузкой Разработка для Linux на C++ в Visual Studio Installer. Если вы не уверены в том, что она установлена, см. статью Загрузка, установка и настройка рабочей нагрузки Linux.
Также убедитесь, что на удаленном компьютере установлены следующие компоненты:
Для поддержки CMake в Visual Studio требуется поддержка режима сервера, введенная в CMake 3.8. Для версии CMake от Майкрософт скачайте последние готовые двоичные файлы по адресу https://github.com/Microsoft/CMake/releases.
Двоичные файлы устанавливаются в каталог
Visual Studio 2017 не может создать проект CMake с нуля, но можно открыть папку, содержащую имеющийся проект CMake, как описано в следующем разделе.
Visual Studio 2019 можно использовать для сборки и отладки в удаленной системе Linux или WSL, и в этой системе будет вызываться CMake. На целевом компьютере должен быть установлен Cmake версии 3.14 или более поздней.
Убедитесь, что на целевом компьютере установлена последняя версия CMake. Часто в дистрибутиве версия, которую предлагает диспетчер пакетов по умолчанию, не является актуальной и не поддерживает все функции, необходимые для работы с Visual Studio. Visual Studio 2019 определяет, установлена ли последняя версия CMake в системе Linux. Если такая версия не найдена, Visual Studio отображает информационную панель в верхней части области редактора. В ней предлагается установить CMake из https://github.com/Microsoft/CMake/releases.
С помощью Visual Studio 2019 можно создать проект CMake с нуля или открыть имеющийся. Чтобы создать проект CMake, следуйте приведенным ниже инструкциям. Или перейдите к разделу Открытие папки проекта CMake, если у вас уже есть проект CMake.
Создание нового проекта CMake в Linux
Чтобы создать проект Linux CMake в Visual Studio 2019, сделайте следующее:
Кроме того, можно открыть собственный проект CMake в Visual Studio 2019. Подробные сведения см. в следующем разделе.
Visual Studio создает минимальный файл CMakeLists.txt, в котором содержится только имя исполняемого файла и минимальная требуемая версия CMake. При необходимости вы можете вручную изменить этот файл. Visual Studio никогда не переопределяет пользовательские изменения.
Чтобы получить представление об изменении и создании сценариев CMake в Visual Studio 2019, ознакомьтесь со следующими материалами:
Открытие папки проекта CMake
Когда вы открываете папку, содержащую существующий проект CMake, Visual Studio автоматически настраивает IntelliSense и сборки, используя переменные в кэше CMake. Локальные параметры конфигурации и отладки хранятся в файлах JSON. При желании вы можете предоставить доступ к этим файлам другим пользователям Visual Studio.
Visual Studio не изменяет файлы CMakeLists.txt. Это позволяет вашим коллегам, работающим над тем же проектом, продолжать использовать имеющиеся инструменты. После того как вы сохраните изменения в файле CMakeLists.txt и (в некоторых случаях) в файле CMakeSettings.json, Visual Studio повторно создает кэш. Если вы используете конфигурацию Существующий кэш, то Visual Studio не изменяет содержимое кэша.
Общие сведения о поддержке CMake в Visual Studio см. в статье о проектах CMake в Visual Studio. Прочитайте статью, прежде чем продолжить чтение этого раздела.
Написать систему сборки для библиотеки под linux windows с использование cmake на примере sqlite
На первом шаге проект нужно сконфигурировать, то есть создать финальный скрипт сборки, запустив cmake в будущем каталоге сборки.
Структура CMakeLists.txt
В начале главного файла CMakeLists.txt ставят метаинформацию о минимальной версии CMake и названии проекта:
Затем следует список инструкций, служащих для вычисления различных переменных, создания целей сборки, подключения проектов из подкаталогов и так далее. Например, подключить дополнительный CMakeLists.txt из подкаталога можно так:
Целью может стать исполняемый файл, собираемый из исходного кода
Целью также может быть библиотека, статическая или динамическая.
Автогенерация проекта для Visual Studio (Windows)
Если используется Visual C++, то путь немного другой: на шаге конфигурирования создаётся проект для Visual Studio, который затем можно собрать из IDE либо так же из командной строки.
Созданный проект Visual Studio нельзя изменять и использовать постоянно, потому что при генерации проекта используются абсолютные пути и другие неприемлемые для постоянной работы вещи.
Зависимости между библиотеками и приложениями
Вы можете выбирать область видимости настройки:
Пример использования областей видимости:
Схема зависимостей условного проекта:
Выбор стандарта и диалекта C++
Для настройки стандарта и флагов языка C++ не добавляйте флаги напрямую!
В CMake версии 3.8+ вы можете прямо потребовать включить нужный стандарт:
В CMake версии до 3.7 включительно можно использовать set_target_properties (если не работает, то у вас слишком старый CMake):
Для разработчиков библиотек есть более тонкий контроль над возможностями языка:
Функции в CMake
Добавление исходников к цели с target_sources
Лучше добавлять специфичные исходники с помощью target_sources, а не с помощью дополнительных переменных.
Интерфейс к утилитам командной строки
Функция find_package
Функция find_package принимает имя библиотеки как аргумент и обращается к CMake, чтобы найти скрипт для настройки переменных данной библиотеки. В итоге при сборке либо возникает ошибка из-за того что пакет не найден, либо добавляются переменные, хранящие пути поиска заголовков, имена библиотек для компоновщика и другие параметры.
Пример подключения Boost, вызывающего встроенный в CMake скрипт FindBoost:
Пример подключения библиотеки Bullet с помощью встроенного скрипта FindBullet и компоновки с приложением my_app:
CMake Tutorial
Содержание
Что это и зачем нужно [ править ]
CMake — кроссплатформенная автоматизированная система сборки проектов. Непосредственно сборкой она не занимается, а только генерирует Makefile, который потом будет выполнен утилитой make.
CMake может проверять наличие необходимых библиотек и подключать их, собирать проекты под разными компиляторами и операционными системами. Т.е. у вас есть куча кода и файлик, содержащий информацию для cmake, и чтобы скомпилить это дело где-нибудь еще, вам нужно просто запустить там cmake, который сделает всё сам. Удобно, полезно, просто.
Краткое описание [ править ]
Если нет желания/времени/сил читать весь туториал и Вы используете какой-нибудь QtCreator (или любая другая IDE, умеющая работать с cmake), то:
Про подключение библиотек рекомендуется все-таки прочитать целиком.
Старт [ править ]
Предполагается, что найти и скачать сам cmake ты, %username%, в состоянии. //а если нет?
Предположим, у Вас есть исходничек «test.cpp» (// а если нет?)(А если нет, то CMake тебе трогать рано). Для начала нужно создать файлик для cmake, который обычно называют «CMakeLists.txt», и написать туда вот это:
Теперь запускаем (из консоли) в этой папке команду «cmake CMakeLists.txt» (аргументом можно передавать не только файл, но и директорию, в которой он лежит, тогда cmake найдет его сам).
А у Вас в папочке появится исполняемый файл «test». Запустите, убедитесь, что это действительно то, что ожидается от компиляции файла «test.cpp».
Подробное описание [ править ]
Поразбираемся с различными возможностями cmake.
Указание необходимой версии cmake [ править ]
Название проекта [ править ]
Указывает, что этот cmake-файл является корневым для некоторого проекта. С проектами связаны определенные переменные и поведение cmake (читайте документацию).
Переменные [ править ]
В cmake можно создавать текстовые переменные. Команда
Чтобы добавить к переменной некий текст, можно сделать так:
Пример коше’гного проекта со списком сорцов в отдельной переменной:
Устанавливаем команды компилятору [ править ]
Эта команда используется для установки дефайнов, которыe можно проверить в коде через, например, #ifdef SOME_IMPORTANT_DEFINITION.
Кто не знает: «-std=c++11» включает в gcc поддержку стандарта c++11, «-Wall» говорит gcc выводить все предупреждения (очень советую, помогает отловить много глупых багов и писать аккуратный код).
Папка с хедерами [ править ]
Допустим, Вы хотите, чтобы хедеры (файлики, подключаемые через #include) искались еще и в каталогах «headers/» и «more_headers/»:
Надеюсь, и это понятно.
Научимся искать и подключать библиотеки при помощи cmake на примере Boost. Для начала установим переменные для буста:
Итак, мы установили флаги. Давайте найдем буст!
Допустим, нам нужны компоненты буста под названием chrono (библиотека для работы со временем) и filesystem (библиотека для работы с файловой системой):
Win, будут искаться только нужные библиотеки, и их расположение будет записано в переменную Boost_LIBRARIES.
Добавим директории с хедерами буста для поиска в них хедеров:
Итак, осталось найденные библиотеки подключить к исполняемому файлу.
В качестве библиотек нужно указать пути к необходимым собранным библиотекам. cmake нашел указанные нами библиотеки и записал в переменную, чем мы и пользуемся.
Заметим, что эту команду нужно вызывать после того, как создан target сборки (через add_executable).
Пример хорошего CMakeLists.txt и где он будет лежать [ править ]
Итак, полный пример использования всего этого. У нас есть некая директория (отныне считаем ее «/sources»), и в ней лежат исходники
В корне «/» лежит файл «/CMakeLists.txt»:
Таким образом, в корне у нас есть:
Все разделено, автоматизировано и удобно.
Как создать библиотеку в поддиректории и слинковать ее с основной программой [ править ]
Теперь можно в файлах основного проекта делать #include «lib.h» (см. документацию по target_include_directories).
Как использовать CMake в связке с QtCreator [ править ]
Интеграция с cmake у QtCreator не очень тесная, тем не менее, работать с ним можно.
Создаем новый проект без использования Qt, выбираем «Проект на С++ с использованием CMake». Создастся дефолтный файл сборки, который просто добавляет все исходники в директории проекта и компилирует их в один бинарник.
Как добавить header в проект, чтобы его было видно в списке файлов [ править ]
Если вы создали файл header.h в директорию проекта, просто строчку
Используем Cmake для автоматической генерации makefile в проектах
Вступление
Компилирование проекта руками — пустая трата времени. Это фактически аксиома и об этом знают те, кто программирует. Но чтобы всё скомпилировалось автоматически необходимо задать правила, так ведь? Часто и по-старинке используют makefile для *nix или какой-нибудь nmake для windows.
Я хоть и не первый год программирую, и руками составлял простые автосборщики проектов на основе makefile, но стоит немного подзабыть и приходится заново изучать как же составить эту хитрую схему. В основном приходится делать проекты расчитанные на какую-то одну систему, будь то linux или windows, и часто между собой не кросскомпилируемые. Для переносимости makefile используется automake и autogen, но их синтаксис ещё более запутан. Не скажу, что выбор идеальный, но для себя я решил перейти на cmake, благо он портирован под всё доступное. Мне он показался более человекопонятным. Попробую объяснить основы. Вы пишите словами правила, а из них генерируется makefile, который вы уже запускаете стандартным способом.
Ликбез
Приступая к работе
Пусть у нас есть некий source.cpp из которого получаем софт — положим его в папку src. Но у нас же проект, поэтому есть ещё несколько файлов core.cpp, core.hpp, common.hpp, types.hpp, которые тоже положим в src и нужна какая-нибудь библиотека, например pthread. Разобрались с исходниками, приступаем к описанию проекта и подготовке его к автокомпилированию.
Начинается всё с создания в корне проекта файла CMakeLists.txt. Правила cmake похожи на скриптовый язык, среднее между javascript и php. Только проще гораздо. Есть условия, функции, переменные, константы, подключаемые модули.
Файл CMakeLists.txt я разобью на несколько частей, чтобы объяснять их. Часть 1:
Тут cmake_minimum_required функция проверки версии.
Операторы записываются как if () открывающий и endif() закрывающий. Аналогично foreach() и endforeach().
Функция message выводит наше сообщение. Я использовал флаг FATAL_ERROR для обозначения типа сообщения.
Заметьте так же, что не ставится точка с запятой (;) в конце команд. Тут одна строка — одна команда. Скобки отодвинуты от операторов просто для удобства чтения.
Каждая команда обычно имеет несколько вариантов задания параметров, поэтому без заглядывания в мануал не обходится никак.
Быстрое ознакомление и простой пример есть в документации, но на мой взгляд слишком простые.
Функция set() создаёт или перезаписывает переменные. Если нет значения, то переменная будет пустой. Заданные здесь переменные названы по смыслу, который они несут в генерации.
include() подключает внешний файл с куском конфигурации в текущее место. Тут без объяснений.
И add_subdirectory (src) указывает где продолжить работу по сборке makefile проекта.
Если здесь задавались только общие правила, то внутри директории src в CMakeLists.txt будут заданы опции объединения конкретных исходных файлов.
Не упомянул ещё о cmake_policy(). Решил не озадачивать сейчас вниканием в это. Пускай тут повесит © Просто облегчает сборку.
Про foreach() цикл и библитеки будет рассказано дальше. Пропустим пока.
Что же такого было вынесено в отдельный cmake файл? Давайте рассмотрим:
В блоке if ( CMAKE_COMPILER_IS_GNUCXX ) определили какие флаги используются для компиляции. Пока что не кроссплатформенной, но используя ветвления и различные созданные при старте переменные-флаги можно нагородить разные зависимые билды для разных платформ и компиляторов. Весь список переменных находится в разделе Variables и раздел этот довольно большой. В прочем, этот блок можно убрать совсем из конфига или подготовить с помощью обширного функционала cmake. Но тут заняло бы слишком много места.
Работа с исходным кодом
Вот и добрались до папки src. В ней тоже необходим CMakeLists.txt, рассмотрим его детальнее.
Здесь записаны конкретные файлы и их сборка. Вначале определили версию программы. Дальше определяем группы (или как их тут называют, списки) исходников, все названия записываются через пробел. MAIN_SOURCES — один основной исходник, PRIVATE_CLASSES — список пар исходников (исходник.cpp-заголовок.hpp с общим названием), PUBLIC_CLASSES — для данного проекта пустой, HEADERS_ONLY — список лишь заголовочных файлов, ADDITIONAL_LIBRARIES — подключаемые в проект С++ библиотеки.
Следующими циклами объединяются списки заголовков и исходников в один подключаемый список (замечу, что предыдущее разделение на публичный и скрытый было чисто условным). И, наконец, правило обозначающее «собрать проект в запускаемый файл» add_executable(). После сборки бинарника к нему нужно добавить «прилинковать» подключаемые библиотеки с помощью target_link_libraries() и всё. Правила проекта определены.
Для удобства можно добавить правила установки-инсталяции с помощью install().
Переходим в директорию build, что в корне проекта, и запускаем
— Configuring done
— Generating done
— Build files have been written to: /home/username/tmp/fooproj/build
Вместо заключения
Я нашёл данный способ более простым и удобным, нежели конфигурирование configure. Если вдруг захочется по спорить на этот счёт, то я воздержусь от комментирования. Потому что зачем?
Если вы что-то поменяли и cmake выдаёт ошибки, то сперва удалите весь кеш файлов из директории build (грубо говоря всё) или как минимум CMakeCache.txt из той же директории билда.
Что было не рассмотрено в обучалке:
1) Подключение библиотек Qt или Boost
2) Поиск установленных библиотек
3) Мультиплатформенность
4) Опции различных компиляторов
Как создавать, собирать, устанавливать и использовать пакеты с программами и библиотеками для UNIX-подобных систем
Речь пойдёт о программах и библиотеках для UNIX-подобных систем, распространяемых в виде исходного кода (в том числе в виде тарболлов), написанных обычно на C и C++ (хотя этот же порядок работы может применяться к софту на любом языке). Многие вещи в этой статье написаны применительно конкретно к GNU/Linux, хотя многое из статьи может быть обобщено и на другие UNIX-подобные ОС.
Под словом «пакет» я понимаю в этой статье пакет с исходными текстами, причём не пакет конкретного дистрибутива GNU/Linux, а просто пакет, исходящий от оригинальных авторов софта (UPD от 2017-02-09: кроме тех случаев, где из контекста ясно, что слово «пакет» употреблено в другом смысле).
В этой статье я разберу следующие вопросы:
И ещё одно предупреждение. Я написал эту статью наскоро для одного человека. А после написания подумал, мол, раз уж написал, выложу уж на Хабр, чтоб не пропала. Поэтому в статье есть недочёты типа нечёткого структуирования статьи, фраз типа «не осуществляет сама инклудивание» и пр. Я это исправлять не буду. Может когда-нибудь в следующей жизни, когда руки дойдут. Выбор был между тем, чтобы публиковать так или не публиковать вовсе.
Итак, начнём мы с того, что создадим пакет с программой Hello, world. Для начала определимся с системой сборки.
Собственно, сама сборка пакета обычно осуществляется с помощью программы make (хотя это не единственный путь). Конфиг для make обычно лежит в файле под названием Makefile.
Есть несколько вариантов: просто использовать make либо использовать совместно с make некую высокоуровневую систему сборки (обычно autotools или cmake), которая будет, собственно, генерировать конфиги для make.
Мы в нашем примере будет использовать только make для простоты. Итак, создаём hello.c:
Внимание! Работает на GNU/Linux. Работа под macOS не гарантируется! Этот Makefile не является портируемым вообще на все UNIX-подобные системы! Подробнее будет дальше.
здесь означает символ табуляции.
Это далеко не единственный способ написать этот Makefile. Вообще, цель всей моей статьи — дать некую базу. Что ещё можно в этом Makefile изменить, вы можете потом узнать из других источников.
Итак, теперь давайте разбирать наш Makefile.
Для начала скажу следующее. Допустим, пользователь скачал пакет. Ему нужно сперва собрать его, т. е. получить бинарники в каталоге с самим пакетом (либо в случае out of tree build получить их в неком другом каталоге, что не меняет сути), а затем установить, т. е. скопировать полученные бинарники в место их окончательного хранения в системе.
То есть смотрите. Вы залогинены под юзером user. Ваш домашний каталог /home/user. Вы скачали пакет, распаковали его, скажем в /home/user/Desktop/foo. Далее вы его собрали. Собрали в этой же папке, /home/user/Desktop/foo. Либо, если речь идёт об out of tree build, вы создали ещё одну папку /home/user/Desktop/foo-build и собрали в ней. Теперь, после сборки вы решаете установить её в /usr/local. Вот тут уже вам нужны права root. Вы при помощи sudo устанавливаете эту программу в /usr/local.
Пара слов о размещении каталогов в системе. Разберу лишь некоторые каталоги. Более подробную информацию можно найти в Filesystem Hierarchy Standard (поддержан многими дистрибутивами GNU/Linux) и по команде «man 7 hier» в GNU/Linux и, возможно, других ОС. Во всяком случае я расскажу, как они были устроены, скажем, лет пять назад (т. е. где-то в 2012-м году), всякие новые веяния типа недавнего нововведения в Fedora «давайте-ка мы всё переместим в /usr» я рассматривать не буду.
То есть, например, вы устанавливаете пакет, указывая ему prefix /usr/local. Тогда бинарники пойдут в /usr/local/bin, бинарные файлы библиотек — в /usr/local/lib и так далее.
Теперь вернусь к разбору Makefile. PREFIX — это и есть тот prefix, про который я сейчас говорил. В качестве дефолтного префикса (пользователь сможет его переопределить) у нас указан /usr/local — хороший дефолтный выбор. Обычно его всегда указывают в качестве дефолтного префикса при создании пакетов (к сожалению, некоторые пакеты этого всё же не делают, дальше будет подробнее). Далее идёт CC. Это стандартное название для переменной make, в которую кладут компилятор, в данном случае cc. cc — это в свою очередь обычно используемая команда для запуска компилятора по умолчанию в данной системе. Это может быть gcc или clang. На некоторых системах команда cc может отсутствовать. CFLAGS — стандартное название для переменной с флагами компиляции.
Если просто набрать make, то будет выполнена та цель, которая идёт в Makefile первой. Обычная практика в том, чтобы называть её all. И такая цель обычно собирает весь проект, но ничего не устанавливает. Эта цель обычно «виртуальная», т. е. у нас нет файла под названием all. Т. к. наша задача собрать лишь один бинарник hello, то мы просто делаем all зависящим от hello. Далее идёт описание цели сборки hello. Его можно было в принципе разбить на два этапа: сборка hello.o из hello.c и сборка hello из hello.o. Я так делать не стал для простоты.
Что делает install? Это почти то же, что и cp. Точные отличия я и сам не знаю. Для установки программ нужно использовать install, а не cp.
Здесь я предполагаю, что у вас на системе установлен так называемый BSD install. В GNU/Linux’е он есть. В некоторых системах его может не быть. Может быть какой-нибудь другой install, который в этой ситуации не сработает. Именно это я имел в виду, когда сказал, что работа в разных ОС не гарантируется.
Здесь я не рассматривал DESTDIR, который, между прочим, крайне рекомендуется использовать в Makefile. Я даже не рассматривал цель clean.
Это создаст архив, внутри которого есть каталог hello-1.0, который содержит hello.c и Makefile. Таков способ распространения пакетов.
C++-вариант пакета. Исходник будет тем же, его нужно будет назвать hello.cpp. Makefile будет таким:
Обратите внимание, что стандартное название переменной для флагов к компилятору C++ — это CXXFLAGS, а не CPPFLAGS. CPPFLAGS же — это название переменной для флагов к препроцессору C.
Теперь разберём, как устанавливать пакеты из сорцов (любые, программы и библиотеки). Независимо от системы сборки. Этот алгоритм будет пригоден в том числе для тарболла, который мы создали только что. Допустим, что пакет, который нужно собрать, тоже называется hello.
Первый шаг: скачать и зайти в папку с сорцами. Тут два варианта: скачиваем из системы контроля версий (я разберу для примера git) или скачиваем тарболл.
Первый вариант. git. Делаем clone:
Теперь нужно собрать. Будем считать для простоты, что мы не будем делать out of tree build (если автор пакета требует out of tree build, там обычно будут написаны инструкции, как это сделать). А значит, собирать мы будем в этой же папке, где сорцы. Т. е. в этой папке, в которую мы сейчас сделали cd.
Дальнейшие действия зависят от системы сборки, выбранной в проекте. Но независимо от системы сборки мы в процессе сборки должны будем указать prefix. Причём обычно его нужно будет указать именно на этапе сборки, а не на этапе установки, т. к. часто prefix захардкоживается внутрь бинарника. А это значит, что после установки программы в определённое место её нельзя просто так взять и передвинуть.
Я дам здесь примерные инструкции, работающие в большинстве случаев. Точные инструкции вы увидите у автора проекта, там могут быть разные нюансы.
Обязательно указывайте prefix при сборке (что бы там не писал в инструкции автор). Если вы не укажите, то будет выбран дефолтный. Обычно это /usr/local, и это достаточно хороший выбор. А если нет? Что если автор пакета указал какой-то другой дефолтный префикс? Вы установите непонятно куда. В частности libqglviewer использует в качестве дефолтного префикса /usr, что совершенно неправильно (я отправил автору баг репорт). Итак, совершенно всегда указывайте префикс. Читайте инструкции, которые автор указывает на своём сайте и прикидывайте, куда впихнуть prefix.
Итак, какие могут быть системы сборки. Во-первых, может быть просто make. Такой вариант с голым make встречается редко. Один из немногих пакетов с «голым» make — bzip ( www.bzip.org ). В случае с нашим hello-1.0.tar.xz, который мы создали, у нас именно такой вариант.
Итак, собирать в случае голого make нужно так:
(Конкретно в случае с bzip на этапе сборки указывать PREFIX не надо. Но теоретически можно представить себе пакет, который захардкоживает PREFIX внутрь бинарника. Поэтому в общем случае PREFIX нужен.)
Следующий вариант — это autotools. В этом случае собираем так:
Следующий вариант — cmake. Собираем так (обратите внимание на точку в конце команды cmake):
Откуда точка в конце? Дело в том, что cmake’у нужно передавать путь к сорцам. А поскольку у нас не out of tree build, мы собираем здесь же. Сорцы находятся там же, где находимся мы. Поэтому точка, т. е. текущий каталог.
Итак, собрали одним из этих способов. Что дальше? Теперь нужно установить.
В случае голого make это делается так:
Нужно будет указать тот же prefix, который вы указывали при сборке.
В случае autotools и cmake так:
В случае, если для записи в prefix вам нужен sudo, то вот эту команду для установки нужно будет набирать с sudo. Вообще, сборка всегда осуществляется с обычными правами, а вот установка осуществляется с теми правами, которые нужны, чтобы записать в prefix.
В результате бинарник положился в /foo/bin.
Теперь хочу ещё немного поговорить про префиксы. Какие префиксы вообще есть?
Префикс /. Вряд ли когда-нибудь вам придётся его выбирать. Он используется для программ, критичных для ранних стадий загрузки ОС (т. е. критичные элементы для загрузки находятся в /bin, /lib и т. д.) (впрочем, даже если вам нужно установить программу в /, её сперва устанавливают в /usr, т. е. собирают и устанавливают с префиксом /usr, а потом перемещают необходимое в / [т. е. перемещают из /usr/bin в /bin, скажем], во всяком случае именно так поступают авторы Linux From Scratch 7.10 с пакетом, скажем, bash).
Префикс /usr. Стандартный префикс, используемый обычно для программ, установленных через менеджер пакетов. То есть если вы установили программу через менеджер пакетов, она ведёт себя так, словно она собрана и установлена на вашей системе с префиксом /usr. Самому устанавливать пакеты с префиксом /usr нельзя.
Префикс /usr/local. Отличный префикс для установки туда программ самостоятельно. Хорош тем, что /usr/local/bin есть в дефолтном PATH (во всяком случае в дебиане). То есть сразу после установки программы вы сможете просто запускать программу по названию. Потому что бинарник лежит в /usr/local/bin, а /usr/local/bin есть в PATH. Плох тем, что там все программы лежат смешанно. Вот допустим, вы установили библиотеку foo, а потом библиотеку bar. Обе в этот prefix. Тогда дерево может выглядеть так (в совсем упрощённом виде):
Видите? Всё смешано. Нет единой папки, которая бы содержала «всё, связанное с foo» и другой папки, которая бы содержала «всё, связанное с bar». (Хотя это ваше дело, считать, что это действительно плохо или нет). Понятное дело, что такая же проблема присутствует при любой установке разных пакетов в один префикс. То есть префикс /usr страдает от того же: пакеты «размазаны» по системе (здесь уже речь идёт о пакетах, поставленных через менеджер пакетов, т. е. тех, которые, собственно, составляют систему). Собственно, это и есть одно из бросающихся отличий большинства UNIX-подобных систем от Windows. В Windows каждая программа находится в своей папке в Program Files. В большинстве UNIX-подобных систем она «размазана» по системе. (UPD от 2017-02-09: в Windows программы на самом деле тоже «размазаны», скажем, по реестру, просто это не так бросается в глаза.) Существуют дистибутивы GNU/Linux, «решающие» эту проблему, например, GoboLinux. Там каждый пакет в своём каталоге, как в Windows.
Префиксы вида /opt/XXX. Папку /opt предполагается использовать следующим образом: в ней нужно создавать подкаталоги, называть их названиями пакетов и использовать эти подкаталоги как префиксы. При таком подходе указанная выше проблема /usr/local (если считать её проблемой) исчезает. Каждый пакет будет установлен в свой каталог. Приведённый выше пример с foo и bar будет выглядеть так (я бы посоветовал в названии подкаталогов в /opt указывать ещё и номер версии):
Недостаток у такого решения тоже есть. Вам придётся самому добавлять все эти бесчисленные каталоги /opt/foo-1.0/bin (для каждого пакета) в PATH.
Префиксы, соответствующие домашним каталогам. Т. е., скажем, /home/user. Советую в случае, когда хочется поставить «только для себя», т. е. только для одного юзера. Или когда нет прав root. Возможно, ваши конфиги, поставляемые с ОС уже настроены таким образом, чтобы помещать
/bin в PATH при условии, что такой каталог есть. Так что PATH будет настроен как надо.
Каждый префикс может содержать в себе свои bin, sbin, lib, include и т. д.
Итак, что из этого выбрать? Если нужно поставить на всей системе, то я бы посоветовал /opt/XXX. Я сам так обычно ставлю.
Допустим, нужно собрать некий файл a.c с этой библиотекой. Как это сделать?
Во-первых, вверху файла нужно написать #include, соответствующий подключаему хедеру. Ну а собирать нужно так:
Давайте разбираться. Для начала скажу, что I (большая английская и) и l (маленькая английская эль) — это две разные буквы. Не перепутайте их в приведённых командах.
Первая команда производит компиляцию, то есть создаёт a.o на основе a.c. Вторая — линковку, то есть окончательный бинарник на основании a.o.
Можно соединить две наши команды в одну, тогда будет что-то такое:
Если вы установите у себя на машине libfoo и libfoo-dev, то результат будет как если бы вы сами собрали пакет foo из исходных кодов с префиксом /usr. У вас на системе будут, скажем, файлы: