Как Вы поступаете с зависимостями в виде third-party libraries в случае проектов, написанных на C++, и почему? Кладёте их рядом с исходниками самого проекта в директорию dependencies / добавляете информацию о необходимых библиотеках в README.md / что-то ещё?
On 15.04.2014 12:04, FrozenHeart wrote:
> Как Вы поступаете с зависимостями в виде third-party libraries в случае > проектов, написанных на C++,
Компилируем их, если это надо, и устанавливаем в соотв. каталоги ФС, где
лежать INCLUDE, LIB и PATH. Прописываем их, если надо, в этих трёх
вышеперечисленных переменных.
и почему?
А почему бы и нет ?
Кладёте их рядом с исходниками > самого проекта в директорию dependencies / добавляете информацию о > необходимых библиотеках в README.md / что-то ещё?
Что такое dependencies и README.md , вероятно, знаешь только ты, тогда
объясни нам, почему же нужно туда что-то класть ?
Здравствуйте, FrozenHeart, Вы писали:
FH>Как Вы поступаете с зависимостями в виде third-party libraries в случае проектов, написанных на C++, и почему? Кладёте их рядом с исходниками самого проекта в директорию dependencies / добавляете информацию о необходимых библиотеках в README.md / что-то ещё?
FH>Прежде всего интересует Windows, Visual Studio.
It depends, как говорится.
Какие-то библиотеки (MKL, WTL, WMQ) ставятся на машину и пути прописываются либо в Студии, либо в проекте через переменные окружения, если надо поддерживать работу с разными версиями. Они большие, меняются редко, разными проектами могут использоваться без изменений (пересборки), в репозиторий их складывать нет смысла.
Какие-то библиотеки (htmlayout, sqlite, например) живут рядом с проектом в отдельном каталоге. У каждого проекта будет свой комплект этих библиотек. Они в таком виде и в репозиторий попадают. В них могут вноситься изменения, не предусмотренные авторами, они могут сильно меняться от версии к версии и их изменения могут сильно сказываться на коде проекта. Дополнительный плюс — при переносе на очередную машину не надо готовить окружение, достаточно достать проект из репозитория и нажать <F7>.
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, FrozenHeart, Вы писали:
FH>Как Вы поступаете с зависимостями в виде third-party libraries в случае проектов, написанных на C++, и почему? Кладёте их рядом с исходниками самого проекта в директорию dependencies / добавляете информацию о необходимых библиотеках в README.md / что-то ещё?
использую пакетный менеджер в ubuntu
FH>Прежде всего интересует Windows, Visual Studio.
FH>Как Вы поступаете с зависимостями в виде third-party libraries в случае проектов, написанных на C++, и почему? Кладёте их рядом с исходниками самого проекта в директорию dependencies / добавляете информацию о необходимых библиотеках в README.md / что-то ещё?
FH>Прежде всего интересует Windows, Visual Studio.
FH>Заранее благодарю за возможные ответы.
Все левые либы (их под 30 штук) лежат в одной директории, путь к которой записан в специальную переменную окружения (назовем ее, к примеру, DEPS). Для разруливания зависимостей заведен отдельный .props файл, в котором из имени конфигурации, переменной DEPS и пользовательских макросов собираются пути к отдельным библиотекам, их имена и т.п., и все это подсовывается компилятору и линкеру. Соответственно, в новом проекте достаточно добавить 1 props файл, чтобы оказались настроены пути ко всем библиотекам. Имена некоторых библиотек приходится задавать как макросы, типа $(mylibname), т.к. в разных конфигурациях это может быть mylib32.lib или mylib64d.lib.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Все лежит в отдельной папке Libraries, для которой создается пропертя, подключаемая ко всем проектам. Есть отдельный человек, который имеет право что-то писать в корень Libraries, если что нужно кому отдельно -- кладет в свой пакет <Libraries/workername/some_lib> и дает или не дает пользоваться другим. Периодически по папкам ходит скрипт, который разруливает перемещение библиотек туда-сюда.
Здравствуйте, FrozenHeart, Вы писали:
FH>Как Вы поступаете с зависимостями в виде third-party libraries в случае проектов, написанных на C++, и почему? Кладёте их рядом с исходниками самого проекта в директорию dependencies / добавляете информацию о необходимых библиотеках в README.md / что-то ещё?
Зависит от типа проекта.
В некоторых случаях в под-папку проекта, прям в VCS. А иногда нужные файлы подкачиваются системой сборки, например через ExternalProject_Add
Здравствуйте, FrozenHeart, Вы писали:
FH>Приветствую.
FH>Как Вы поступаете с зависимостями в виде third-party libraries в случае проектов, написанных на C++, и почему? Кладёте их рядом с исходниками самого проекта в директорию dependencies / добавляете информацию о необходимых библиотеках в README.md / что-то ещё?
FH>Прежде всего интересует Windows, Visual Studio.
FH>Заранее благодарю за возможные ответы.
В чистом линукс (не кроссплатформенном) таких проблем нет, там есть три уровня куда нужно помещать библиотеки.
В Windows логично создать одну папку и по возможности перемещать библиотеки туда.
А можно оставлять библиотеки там, куда их поместит установщик.
Можно поместить библиотеки так же как в Linux.
А вот хранить библиотеки с исходниками программы думаю не стоит. Проект на мой взгляд не должен нести с собой чужой код не являющийся частью его самого.
Корень проблемы на самом деле в том, что в проекте существуют внешние зависимости и они прописаны в виде путей. Если проектов много, каждый такой путь придётся переписывать при изменении папки с библиотекой.
И вот здесь Windows и Linux имеют нечто общее, это переменные окружения (environments variables) или системная среда:
Для примера Qt Creator:
В целом нужно понимать, что современные IDE скрывают при настройке множество параметров. В Linux это уже дошло до того, что скоро хакером будет считаться пользователь Windows, а не наоборот.
Очень хорошо иллюстрирует работу о том, как правильно прописывать пути — кроссплатформенный подход. Внутри Visual Studio, Qt Creator и других IDE лучше всего прописывать переменные окружения которые будут заменены путями, а не абсолютные или относительные пути напрямую. Тогда не будет необходимости хранить библиотеки вместе с кодом проекта ссылаясь на них относительно, потому что преимуществ нет, а недостатков масса.
Visual Studio чисто виндовая поделка, поэтому внимание на этом не акцентируется, тем не менее эта среда разработки прекрасно позволяет работать подобным образом.
Для прописывания путей в проекте существует стандартный (как и в других IDE) синтаксис, на вроде $(QTDIR), где QTDIR эта та самая переменная окружения. Для каждой библиотеки можно установить свою переменную, причём для многих есть устоявшиеся имена. Присмотритесь внимательно к настройкам проекта Visual Studio и многое станет понятным.
Здравствуйте, velkin, Вы писали:
V>Очень хорошо иллюстрирует работу о том, как правильно прописывать пути — кроссплатформенный подход. Внутри Visual Studio, Qt Creator и других IDE лучше всего прописывать переменные окружения которые будут заменены путями, а не абсолютные или относительные пути напрямую. Тогда не будет необходимости хранить библиотеки вместе с кодом проекта ссылаясь на них относительно, потому что преимуществ нет, а недостатков масса.
Библиотеки хранят вместе с кодом проекта отнюдь не из-за каких-то трудностей с путями. А, например, потому что это позволяет легко получить необходимые и пропатченные зависимости всем членам команды, при простом обновлении VCS.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Библиотеки хранят вместе с кодом проекта отнюдь не из-за каких-то трудностей с путями. А, например, потому что это позволяет легко получить необходимые и пропатченные зависимости всем членам команды, при простом обновлении VCS.
Такое решение привносит много лишнего в проект. Внешние зависимости, опять же на мой взгляд, лучше передавать отдельно. Если уж речь о команде, то поставить помимо контроля версий ещё и систему непрерывной интеграции и разместить там обновлённые зависимости. Изменение сторонних библиотек, особенно если они ещё и меняются, без постоянного контроля может привести к неприятным последствиям.
Но давайте уточним о чём речь. Раз уж речь о Visual Stuido я это представляю как:
Отладочные версии библиотек ведь могут занимать сотни мегабайт, мало ли кто как компилирует. И вот представьте делают несколько больших проектов, а может быть даже десятков и сотен мелких проектов, и в каждом лежат эти библиотеки. Решение кажущееся простым с одним проектом может показаться тяжёлым уже с двумя проектами.
Просто представьте, что изменив одну зависимость, например, проапгрейдив библиотеку, теперь нужно заходить в каждый проект и всё там менять. Потом отправлять изменения в систему контроля версий, которая и так от этого объёма уже опухла. Тот же git несёт в себе всё что было изменено, вместо 1 мегабайта проекта придётся скачать по несколько версий зависимостей одной и той же библиотеки, а библиотек может быть много, то есть гигабайты.
Потому такой подход может быть хоть как-то приемлем только в таком случае:
Причём проекты от которых зависит решение не должны быть большими библиотеками, типа Qt, Boost и прочих, это попросту нерационально. К примеру, есть библиотеки, которые содержат в себе код для работы с теми же изображениями, но если есть подходящая скомпилированная библиотека, то по умолчанию обращаются к ней, а не во вложенные в third-party проекты. Но это уже скорее вопрос распространения огромных проектов.
В той же /Qt/4.8.5/src/3rdparty/ под Windows одна из папок называется webkit:
9638 файлов, 662 вложенные папки, 138.1 МиБ
С другой стороны там же есть папка md5:
2 файла, 0 вложенных папок, 9.3 КиБ
Тот же md5 (хотя есть решение и получше в лице Crypto++) можно положить в проект в систему контроля версий. Нужно ли так делать с webkit? А может лучше везде следовать одному и тому же подходу, типа include+lib, как бы ни была мала библиотека?
Лично мне подход линуксов не то чтобы ближе, но чувствуется, что он правильный, да и вменяемой альтернативы нет. Майкрософт на мой взгляд зря тупит и не делает свой менеджер пакетов с репозиториями. В результате этого винда становится вторичной по отношению к программированию системой. Это так же к вопросу о dll hell.
Меры против DLL hell
Данные меры рекомендуют предпринимать одновременно для получения наилучшего результата:
подсчитать контрольную сумму кода функции вызываемой из DLL — сравнить с контрольной суммой функции используемой при написании программы.
Операционная система должна поставляться совместно с менеджером пакетов, чтобы иметь возможность прослеживать все взаимозависимости DLL, при этом использование менеджера пакетов должно поощряться, а индивидуальная инсталляция DLL — по возможности отвергаться.
Централизованное распространение библиотек
Допустить возможность параллельного использования нескольких версий одной и той же DLL [1].
При модификации программного обеспечения для частного использования поставлять также модифицированные версии DLL.
Во время проектирования DLL должна тщательно продумываться концепция функций и версий. DLL не должны использоваться без необходимости, а библиотеки, связанные только с одним приложением, должны подключаться статически (в EXE-файл).
Здравствуйте, velkin, Вы писали:
EP>>Библиотеки хранят вместе с кодом проекта отнюдь не из-за каких-то трудностей с путями. А, например, потому что это позволяет легко получить необходимые и пропатченные зависимости всем членам команды, при простом обновлении VCS. V>Такое решение привносит много лишнего в проект.
Почему же? Отдельная и аккуратная папка, куда складываются зависимости.
V>Внешние зависимости, опять же на мой взгляд, лучше передавать отдельно.
Куда отдельно? Кто их будет скачивать, настраивать и т.п. на каждой машине?
V>Если уж речь о команде, то поставить помимо контроля версий ещё и систему непрерывной интеграции и разместить там обновлённые зависимости.
Как именно размещать?
Например, размещение зависимостей в VCS, даёт полезный эффект — можно спокойно переходить на старые ревизии, и там сразу будут все необходимые зависимости, нужных версий, с нужными патчами.
V>Изменение сторонних библиотек, особенно если они ещё и меняются, без постоянного контроля может привести к неприятным последствиям.
Понятное дело, что при обновлении нужно аккуратно применять пачти, смотреть что изменилось.
V>Отладочные версии библиотек ведь могут занимать сотни мегабайт, мало ли кто как компилирует. И вот представьте делают несколько больших проектов, а может быть даже десятков и сотен мелких проектов, и в каждом лежат эти библиотеки. Решение кажущееся простым с одним проектом может показаться тяжёлым уже с двумя проектами.
А я не говорил о том, что нужно хранить бинарные библиотеки. Пусть собираются вместе с проектом. Это особенно важно при разработке кросс-платформенных библиотек, которые должны работать в нескольких десятках разных конфигураций.
V>Просто представьте, что изменив одну зависимость, например, проапгрейдив библиотеку, теперь нужно заходить в каждый проект и всё там менять.
Что за "каждый проект"? Мы говорим про один проект.
V>Причём проекты от которых зависит решение не должны быть большими библиотеками, типа Qt, Boost и прочих, это попросту нерационально.
Вот как раз, в одном из проектов, Boost у меня и включён как зависимость в VCS, причём пропатченный (переименованный namespace+alias). Полёт нормальный.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
V>>Внешние зависимости, опять же на мой взгляд, лучше передавать отдельно.
EP>Куда отдельно? Кто их будет скачивать, настраивать и т.п. на каждой машине?
Например, скачивать зависимости на каждую машину клиента с того же сервера, где находится система контроля версий проекта.
V>>Причём проекты от которых зависит решение не должны быть большими библиотеками, типа Qt, Boost и прочих, это попросту нерационально.
EP>Вот как раз, в одном из проектов, Boost у меня и включён как зависимость в VCS, причём пропатченный (переименованный namespace+alias). Полёт нормальный.
И остальные программисты реагируют нормально, что им подсовывают boost в исходниках, да ещё с изменениями? Давайте тогда не будем спорить, у каждого свой подход, порой радикально несовместимый, но имеющий право на жизнь.
Здравствуйте, velkin, Вы писали:
V>>>Внешние зависимости, опять же на мой взгляд, лучше передавать отдельно. EP>>Куда отдельно? Кто их будет скачивать, настраивать и т.п. на каждой машине? V>Например, скачивать зависимости на каждую машину клиента с того же сервера, где находится система контроля версий проекта.
Это же нужно писать скрипт для скачивания и настройки, контролировать версии при переходе на старые ревизии и т.п. И во многих случаях это ничем принципиальным не будет отличаться от хранения в VCS.
V>>>Причём проекты от которых зависит решение не должны быть большими библиотеками, типа Qt, Boost и прочих, это попросту нерационально. EP>>Вот как раз, в одном из проектов, Boost у меня и включён как зависимость в VCS, причём пропатченный (переименованный namespace+alias). Полёт нормальный. V>И остальные программисты реагируют нормально, что им подсовывают boost в исходниках, да ещё с изменениями?
Нормально — они же работают над одним проектом. В крайнем случае могут приготовить его тем же скриптом и сравнить результат.
Это даже удобно, что каждому программисту не нужно делать никаких действий по настройке и сборке Boost — работает из коробки.
V>Давайте тогда не будем спорить, у каждого свой подход, порой радикально несовместимый, но имеющий право на жизнь.
Так я и использую разные подходы, в том числе "отдельное скачивание вручную" (например, в случае дефицитных библиотек, с ограничениями по лицензии) — всё зависит от конкретных условий.
Но не вижу каких-либо принципиальных проблем с жизнеспособностью у варианта "папка с зависимостями в VCS"
Здравствуйте, FrozenHeart, Вы писали:
FH>Как Вы поступаете с зависимостями в виде third-party libraries в случае проектов, написанных на C++, и почему?