Библиотека нашлась только архивом на GitHub: в менеджере её нет, автор не выложил релиз, а проект ждать не собирается. Путь через меню — Скетч → Подключить библиотеку → Добавить .ZIP библиотеку — распаковывает архив в папку libraries скетчбука, и через минуту скетч собирается. Через минуту — потому что половина архивов едет с сюрпризом: папка называется Name-main, а заголовок ищется как Name.h, и компилятор упирается в отсутствие файла, который на диске лежит. Сюрприз второй ждёт при сборке: у архива нет паспорта версии, и менеджер показывает его как незнакомца, даже когда папка лежит рядом с индексными соседями.
Разбираю анатомию: что должно лежать в папке библиотеки, зачем нужен library.properties и почему две копии одной библиотеки — это предупреждение в логе, а не тихая удача. Клик-путь менеджера и поиск по индексу показаны в уроке про Library Manager, а базовая установка из архива — в уроке про zip без интернета; здесь — что происходит внутри папки и с версиями, когда менеджеру помочь нечем. Дальше — по убыванию сложности: паспорт, версии, конфликты имён, и финальная развилка — что делать, когда два источника претендуют на одно имя.
Анатомия папки libraries
Скетчбук живёт в Документах: Documents/Arduino/libraries, и каждая библиотека — папка с заголовком внутри. Три совпадения обязательны: имя папки, имя в поле name из library.properties и имя главного заголовка, который вы пишете в #include. Хоть одно расхождение — include не найдётся, при том что файлы на диске видны и руки чешутся всё переустановить. Лечится переименованием папки без суффикса -main: GitHub пакует архив ветки под именем RepoName-main, и этот хвост в меню Include Library вписывать не нужно — нужно убрать. Поиск мест установки прячется в настройках: строка sketchbook location показывает корень, от которого растут и скетчи, и libraries.
library.properties — паспорт библиотеки в формате ключ=значение: name, version, author, depends. Минимальный рабочий паспорт — четыре строки: name, version, author, sentence; остальные поля менеджер простит, а без name и version индексация ломается. Версия записывается строкой вида 1.4.3 — три числа через точку, старшая, минорная и патч. Поле depends перечисляет зависимости, и менеджер подтянет их сам — если библиотека в индексе. Архивная — нет: менеджер о ней не знает, обновления только руками, заново скачанным архивом в чистую папку.
Обходной путь существует для библиотек из одного файла: заголовок без props-паспорта можно положить прямо в папку скетча, рядом с .ino, и include найдёт его раньше всех прочих мест. Такой ход уместен для крошечных вспомогательных хедеров, но для полноценной библиотеки я его не люблю: файл не делится между проектами, попадает в каждый архив бэкапа и путает поиск источников при конфликте. Папка libraries одна на все проекты — заплатка в скетче размазывает проблему по копиям.
Версии вспоминают тогда, когда скетч уже написан под чужой API. Библиотека IRremote после четвёртой версии сменила половину имён функций: скетч с v3 собирается, тот же текст с v4 валится на первой строке. Поэтому к каждому проекту я прикладываю текстовый файл со списком: имя библиотеки, версия, откуда брал. Пять слов в строке — а вечер перепробованных версий экономят целиком. Свою первую библиотеку с нуля я собирал по шагам в уроке про свою библиотеку, а структура скетчбука целиком — в уроке про папку sketchbook.
// Типичный клиент zip-библиотеки: датчик DHT и заголовок DHT.h.// DHT от Adafruit часто ставится архивом: в менеджере рядом лежит// другая DHT с тем же именем заголовка — классический источник дублей. #include <DHT.h> #define DHTPIN 2#define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); dht.begin(); Serial.println("DHT: start, opros raz v 2 s");} void loop() { float t = dht.readTemperature(); float h = dht.readHumidity(); if (isnan(t) || isnan(h)) { Serial.println("DHT: otveta net, proveryayte pin 2"); } else { Serial.print("t="); Serial.print(t); Serial.print(" hum="); Serial.println(h); } delay(2000);}Дубли: как IDE выбирает копию
Дубль рождается легко: библиотека лежит в комплекте IDE, вы добавили её же архивом в sketchbook — имя одно, копии две. Компилятор такого не прощает молча: в логе вылезает предупреждение, что найдено несколько библиотек, со списком путей и пометкой, какая взята. Выбор у IDE строгий: приоритет у копии из скетчбука, комплект идёт запасным. Предупреждение печатается один раз на имя библиотеки, и списка путей хватает для решения: две строки — два места, одно из них лишнее. Собралось — хорошо, но собралось не из тех файлов, что вы правили вчера, и поиск причин растянется на вечер. Мой случай: правлю заголовок в одной папке, а компилируется вторая, свежая, из архива — дважды ловил, прежде чем научился читать предупреждение сразу. Второй признак двойной установки: скетч собирается, а правки в заголовке не подхватываются — это вы правите неиспользуемую копию.
Лечение — наведение порядка: лишнюю копию удалить, оставить одну. Куда смотреть в стене текста при сборке — я разбирал в уроке про лог компиляции, а переключатель подробного вывода прячется в настройках IDE: с ним список путей печатается всегда, а не только при конфликте.
Третий источник дублей тихий: вы скачали архив дважды с интервалом в месяц, GitHub назвал папки по-разному — RepoName-main и RepoName-1.2 — а поле name внутри одно. Внешне библиотека одна, при сборке предупреждение печатается дважды. Ловится поиском по папке libraries: ищите значение name из properties, а не имя папки. Удалять копии безопасно, когда ни один скетч на них не ссылается — иначе компилятор сразу скажет, где include перестал находиться. Быстрая проверка после чистки: соберите снова и найдите в логе строку с путём библиотеки — одна папка на имя, предупреждение уходит само.
Сводка по четырём источникам: где файлы лежат, кто их обновляет и какая заноза типична. Последний столбец собран не из теории: каждая строка — с чужих граблей, включая мои собственные с архивом-хвостом -main и с двумя копиями одной библиотеки в один день. Две нижние строки — про приоритеты: комплект IDE всегда запасной, скетчбук всегда первым. Средний столбец — ответ на вопрос «куда скачивать руками»: всегда в libraries скетчбука, и никак иначе.
Когда архив лучше менеджера, у меня три случая. Первый: фикс уже в репозитории, а релиза нет — менеджер отдаёт последний релиз, архив с нужным коммитом приносит исправление сегодня. Второй: проект пинится под старую версию, потому что обновление ломало API — архив той версии лежит в папке проекта и не трогается, а индекс пусть отдаёт новое кому-то ещё. Третий: закрытая сеть без доступа к индексу, и архив приносит флешка; или когда свежая версия индекса несёт регрессию, а откат через меню недоступен.
Обратная сторона та же: менеджер хотя бы напоминает об обновлениях, архив живёт в пузыре. Поэтому в моём README рядом с .ino живут три строки: имя библиотеки, версия, ссылка на источник. Список переезжает на новую машину вместе с папками, и сборка на новом месте повторяет старую построчно.
| Источник установки | Куда ложится | Кто обновляет | Типовая заноза |
|---|---|---|---|
| Library Manager | sketchbook/libraries | IDE по кнопке, версии из индекса | редко: путь чистый |
| Архив .zip | sketchbook/libraries/<Имя> | вручную, новым архивом | имя папки с хвостом -main |
| Комплект IDE | папка установки IDE | только вместе с версией IDE | дубль с копией в скетчбуке |
| Своя библиотека | sketchbook/libraries | вы сами | properties без поля version |
- 1. Куда ложится библиотека, установленная из архива через меню IDE?
- 2. Архив с GitHub распаковался папкой Name-main, компилятор не находит Name.h. Что делать?
- 3. В системе две копии библиотеки с одним именем. Что сделает компилятор?
- 4. Как обновить библиотеку, которую ставили архивом?
- 5. Что записано в поле version внутри library.properties?
- Архив .zip ложится в Documents/Arduino/libraries/<Имя>; имя папки, name в properties и заголовок обязаны совпасть
- Хвост -main от GitHub ломает include: папку переименовать до сборки
- library.properties: version вида 1.4.3 и depends для зависимостей; менеджер про архив не знает — обновление руками
- Две копии с одним именем — предупреждение Multiple libraries: IDE берёт скетчбук, компилируется не та папка, что вы правили
- Обновление поверх старой папки оставляет мусор: удалять целиком, потом распаковывать
Частые вопросы по теме урока
- Куда ложится библиотека, установленная из архива через меню IDE?
- Добавить .ZIP библиотеку распаковывает архив в sketchbook/libraries/<Имя>. Папка скетча остаётся чистой — библиотеки в ней не живут: это ваш проект, зависимости держат отдельно. в libraries внутри скетчбука, обычно Documents/Arduino
- Архив с GitHub распаковался папкой Name-main, компилятор не находит Name.h. Что делать?
- GitHub пакует ветку с суффиксом -main, а три имени — папка, name в properties, заголовок — обязаны совпасть. Переименование папки лечит в одно движение. переименовать папку в Name и собрать заново
- В системе две копии библиотеки с одним именем. Что сделает компилятор?
- Несколько копий — предупреждение Multiple libraries со списком путей: IDE выбирает скетчбук, комплект идёт запасным. Собраться может не из тех файлов, что вы правили. возьмёт копию из скетчбука и напишет предупреждение в лог
- Как обновить библиотеку, которую ставили архивом?
- Менеджер знает только индексные библиотеки. Архивная обновляется руками: чистая папка, новый архив, пересборка — распаковка поверх оставляет устаревшие файлы. удалить старую папку целиком и распаковать новый архив
- Что записано в поле version внутри library.properties?
- Версия — строка вида 1.4.3 по правилам SemVer: мажорный номер меняют при ломающем API, минорный — при добавлении функций, патч — при исправлениях. Мажорный скачок у IRremote сменил половину имён — скетч под v3 после апгрейда до v4 часто не собирается. три числа через точку: старшая, минорная, патч-версия