Внешние зависимости visual studio

Обновлено: 06.07.2024

Я работаю в организации с пакетом продуктов, основанным на нескольких сотнях решений Visual Studio (в основном C ++). Некоторые из этих решений создают библиотеки, которые используются другими решениями, а также существует общая папка «include», содержащая заголовки, которые совместно используются несколькими модулями.

Проблема в том, что зависимости нигде явно не указаны, и система сборки разрешает зависимости, задав линейный порядок сборки, который гарантирует, что зависимые модули будут построены в нужное время. Это хорошо работает для системы сборки, но оставляет разработчиков в невыгодном положении, когда они пытаются работать с компонентами со многими прямыми и косвенными внешними зависимостями. Например, я мог бы захотеть отредактировать один из проектов библиотеки или общих заголовков, а затем построить все затронутые модули, не обязательно заранее зная, какие из них затронуты. Другой вариант использования включает создание модуля после выполнения свежего извлечения из TFS и создание модулей, от которых он зависит, в первую очередь без необходимости сборки всей системы.

Мне интересно, есть ли какие-либо инструменты, которые могут автоматизировать создание зависимостей для создания больших проектов. Я подумал о создании нескольких действительно больших решений, которые инкапсулируют другие решения, но это кажется действительно неудобным и неуклюжим. Кроме того, мне не нравится идея о том, чтобы разработчики вручную указывали зависимости, поскольку это может привести к ошибкам, особенно с такой большой базой кода. Я работал со scons несколько лет назад, и мне очень понравилось, как он может анализировать исходные файлы и автоматически обнаруживать все зависимости зависимостей. Есть ли сегодня что-нибудь, что может сделать то же самое с решениями Visual Studio?

Мне нужно подчеркнуть масштаб проблемы, которую я пытаюсь решить. Это очень большая существующая кодовая база. В основном каталоге есть несколько сотен подпапок, каждая из которых содержит одно или несколько решений VS (не проекты). Каждое решение, в свою очередь, содержит один или несколько проектов. Как я уже сказал, я не пытаюсь установить зависимости между несколькими проектами в решении. Проблема гораздо серьезнее. Я пытаюсь найти способ установить зависимости между самими решениями (их несколько сотен). Например, одно решение может содержать некоторые проекты, которые генерируют библиотеки для безопасности, другие - для связи и т. Д. Могут быть, например, десятки решений, использующих библиотеки связи. По сути, я пытаюсь создать ориентированный циклический граф с сотнями узлов и потенциально десятками тысяч ребер.

Если в решении есть проекты, которые зависят друг от друга, т. е. один проект зависит от типов другого проекта и использует их, то Visual Studio должна знать порядок сборки про­ектов. Для примера рассмотрим проект приложения Windows, который использует типы, предоставляемые проектом библиотеки классов. Если в последовательности сборки сначала не будет собрана библиотека классов, то процесс сборки закончится неудачно.

В большинстве случаев Visual Studio способна сама определить правильную последователь­ность сборки. Однако иногда вам может понадобиться вручную указать, что некий проект зависит от других проектов. Для предоставления такой информации используйте страницу свойств Project Dependencies (рис. 4.7). Выберите проект в раскрывающемся списке, а за­тем укажите, от каких решений он зависит (для этого нужно отметить проекты в окне списка Depends on).

Местоположение файлов исходных кодов для отладки

В определенных ситуациях вам может понадобиться явно указать отладчику Visual Studio файлы исходных кодов для использования в процессе работы отладчика.

Настройка зависимостей проекта
Описание: image63

Настройка зависимостей проекта

Одна из таких ситуаций — это когда вы пытаетесь отлаживать решение, которое ссылается на объект на удаленном компьютере. Если файл исходного кода для этого удаленного объ­екта на локальном компьютере отсутствует, то вы можете явно указать для Visual Studio файлы исходных кодов.

Для того чтобы добавить элемент в любое из полей, сначала поместите ваш курсор в поле, а затем щелкните кнопку New Line (вверху справа в диалоговом окне). Это позволит вам вве­сти полностью квалифицированный путь к нужному каталогу. Удаляется элемент путем его выделения и последующего щелчка по кнопке Cut Line. Кнопка Check Entries позволяет вам еще раз перепроверить, что все элементы указывают на правильные и доступные пути к каталогам.

Если вы загрузили решение с проектами на языке Visual C++, то, вероятно, сразу же увидите несколько элементов в списке Directories containing source code.

Я работаю над проектом C ++ в Visual Studio, большая часть которого была разработана кем-то другим, и у меня ограниченные знания в области компьютерного программирования, кроме написания простых классов и их использования. В обозревателе решений есть папка «Внешние зависимости», в которой содержится тонна файлов .h и .hpp, но нет файлов .cpp.

В редакторе кода, если я перейду к некоторому блоку кода, содержащему вызов функции к функции, объявленной в файле в папке «Внешние зависимости», и я щелкну правой кнопкой мыши> Перейти к определению этой функции, он приведет меня к декларация, а не определение. Как будто проект не знает, где находятся файлы .cpp, но он должен, иначе эти функции не будут работать.

Какая папка является Внешними Зависимостями?

Как происходит настройка одного из них в Visual Studio, чтобы компилятор знал определение функций, которые вы используете в своей программе?

Решение

это позволило бы компилятору иметь доступ к методам класса, который вы пытаетесь использовать.

Если заголовочные файлы не включают фактическую реализацию (я думаю, что обычная практика — разделять классы на заголовочные файлы .h и файлы реализации .cpp), вам также необходимо поместить директивы include в файлы реализации .cpp.

Интересно, почему в одном из моих проектов VDSERR.h указан в разделе "Внешние зависимости", а другой нет и дает мне ошибку компилятора "undefined" о символе, который определен там. Как включить этот файл в другой проект? (Возможно, с помощью drag & drop, но я хотел бы узнать точную настройку здесь.)

Папка "Внешние зависимости" заполняется IntelliSense: содержимое папки вообще не влияет на сборку (вы фактически можете отключить папку в пользовательском интерфейсе).


Недавно наткнулся на CodeProject’е на статью Марка Клифтона, посвященную поиску зависимостей между проектами в солюшне. К сожалению самого графа представленная программа не генерилровла и поэтому, будучи вдохновленным подходом Евгения Кучерука к визуализации содержимого Windsor-контейнера решил быстренько реализовать тот же функционал для зависимостей между проектами. Вот, собственно, что получилось.

Прежде всего нужен впечатлительный пример, поэтому я решил показать как выглядят проекты разных IoC-фреймворков (картинки здесь и далее кликабельны):


Unity:


StructureMap:


NInject:


Autofac:

Графы выше сформированы путем анализа проектных файлов и не включают “внешние” зависимости (зависимости вне солюшна). Сформированы они путем разбора .csproj-файлов, т.е. файлов проектов. Далее, когда вся информация получена в отдельный Dictionary , ее можно записать в формате .dot, и отрендерить используя GraphViz.

Спрашивается – зачем это нужно? Точно так же, как IoC контейнер полезно отрендерить чтобы получить обозрение того, что на что завязано, так и обычный солюшн хочется иногда проанализировать на тему связанности. Как например делает тот же NDepend. Также иногда хочется просто увидеть все решение с высоты птичьего полета, и моя тулза поможет сделать именно это.

Ну что, не захотелось попробовать? Если да, то качайте GraphViz, а потом исходники. Интерфейс объяснять не буду, ибо там итак все понятно – все равно вы (как и я) будете кастомизировать программу для ваших целей, так что советую почитать документацию к формату dot. Удачи!

В качестве примера мы рассмотрим подключение библиотеки SDL к нашему проекту в Visual Studio 2017 (работать будет и с более новыми версиями Visual Studio).

Шаг №1: Создаем папку для хранения библиотеки

Создаем папку Libs на диске C ( C:\Libs ).

Шаг №2: Скачиваем и устанавливаем библиотеку



Шаг №3: Указываем путь к заголовочным файлам библиотеки

Открываем свой любой проект в Visual Studio или создаем новый, переходим в "Обозреватель решений" > кликаем правой кнопкой мыши (ПКМ) по названию нашего проекта > "Свойства" :


В "Свойства конфигурации" ищем вкладку "С/С++" > "Общие" . Затем выбираем пункт "Дополнительные каталоги включаемых файлов" > нажимаем на стрелочку в конце > "Изменить" :


В появившемся окне кликаем на иконку с изображением папки, а затем на появившееся троеточие:


Заголовочные файлы находятся в папке include внутри нашей библиотеки, поэтому переходим в нее ( C:\Libs\SDL2-2.0.9\include ) и нажимаем "Выбор папки" , а затем "ОК" :



Шаг №4: Указываем путь к файлам с реализацией библиотеки

Переходим на вкладку "Компоновщик" > "Общие" . Ищем пункт "Дополнительные каталоги библиотек" > нажимаем на стрелочку в конце > "Изменить" :


Опять же, нажимаем на иконку с папкой, а затем на появившееся троеточие. Нам нужно указать следующий путь: C:\Libs\SDL2-2.0.9\lib\x86 . Будьте внимательны, в папке lib находятся две папки: x64 и x86 . Даже если у вас Windows разрядности x64, указывать нужно папку x86 . Затем "Выбор папки" и "ОК" :


После этого переходим в "Компоновщик" > "Ввод" . Затем "Дополнительные зависимости" > нажимаем на стрелочку в конце > "Изменить" :


В появившемся текстовом блоке вставляем:


Затем переходим в "Компоновщик" > "Система" . После этого "Подсистема" > нажимаем на стрелочку вниз > выбираем "Консоль (/SUBSYSTEM:CONSOLE)" > "Применить" > "ОК" :



Шаг №5: Копируем dll-ку в папку с проектом

Переходим в папку x86 ( C:\Libs\SDL2-2.0.9\lib\x86 ), копируем SDL2.dll и вставляем в папку с вашим проектом в Visual Studio. Чтобы просмотреть папку вашего проекта в Visual Studio, нажмите ПКМ по названию вашего проекта > "Открыть содержащую папку" :


Затем вставляем скопированный файл (SDL2.dll) в папку с проектом (где находится рабочий файл .cpp):


Шаг №6: Тестируем

Теперь, чтобы проверить, всё ли верно мы сделали — копируем и запускаем следующий код:

Читайте также: