НейроАгент

Полное руководство: Добавление каталогов включения для портов vcpkg в Visual Studio

Полное руководство по добавлению дополнительных каталогов включения для портов vcpkg в Visual Studio. Узнайте несколько подходов, включая конфигурацию оверлей-портов, модификацию vcxproj и свойства MSBuild для разрешения конфликтов путей включения.

Как добавить дополнительный каталог включения для порта vcpkg в файлах Visual Studio (vcxproj)?

Я работаю с оверлей-портом vcpkg, который требует наличия собственного каталога include/MYLIBRARY в путях включения системы C++. Хотя я легко могу добиться этого в CMake с помощью target_include_directories() в файле порта share/MYLIBRARY/MYLIBRARY-config.cmake, я не могу найти способ добавить этот каталог в каталоги включения при использовании файлов .vcxproj с Visual Studio 2022/MSBuild.

Что я уже пробовал:

  1. Модификация файлов в порте: исправление отдельных директив #include, но это нецелесообразно из-за большого количества файлов и обновлений версий.
  2. Добавление файлов включения оверлей-порта в файлы .vcxproj или .props потребляющих проектов через IncludePath: это приводит к конфликтам, когда функции определены как в файлах заголовков vcpkg_installed, так и в файлах заголовков оверлей-порта.
  3. Добавление $(VcpkgInstalledDir)include\MYLIBRARY\ в IncludePath: свойство VcpkgInstalledDir не оценивается и остается пустым.
  4. Добавление $(MSBuildThisFileDirectory)vcpkg_installed\x64-windows\include\MYLIBRARY\ в IncludePath: это не подходит, так как не работает для других триплетов сборки.

Я ищу либо решение на основе оверлей-порта, либо исправление на стороне потребляющего проекта.

НейроАгент

Добавление дополнительного каталога включений для порта vcpkg в файлах vcxproj Visual Studio

Чтобы добавить дополнительный каталог включений для порта vcpkg в файлах vcxproj Visual Studio, необходимо правильно настроить либо сам оверлейный порт, либо изменить конфигурацию сборки потребляющего проекта. Ключевым моментом является понимание того, как интеграция MSBuild vcpkg обрабатывает каталоги включений и где должен быть расположен ваш пользовательский путь в порядке поиска включений.


Содержание


Понимание обработки каталогов включений vcpkg

Интеграция MSBuild vcpkg автоматически добавляет установленные пакеты в свойства проекта Visual Studio, включая каталоги включений, каталоги компоновки и библиотеки компоновки источник. Когда вы используете оверлейные порты, vcpkg пытается загрузить этот каталог как порт в первую очередь, и в случае успеха рассматривает его как порт с именем, производным от файла CONTROL или vcpkg.json источник.

Проблема, с которой вы сталкиваетесь, заключается в том, что каталоги включений vcpkg могут иметь разные уровни приоритета, чем каталоги включений вашего пользовательского оверлейного порта. Согласно одному из отчетов о проблемах, путь поиска включений vcpkg уже добавляется до CUSTOM_INCLUDE_DIR, что может вызывать конфликты источник.


Решение 1: Настройка оверлейного порта Portfile.cmake

Для вашего оверлейного порта вы можете изменить portfile.cmake, чтобы обеспечить правильную установку и распознавание каталога включений. Вот как это структурировать:

cmake
include(vcpkg_common_functions)

# Скачивание и распаковка библиотеки
vcpkg_from_github(
    OUT_SOURCE_PATH SOURCE_PATH
    REPO your-repo/your-library
    REF specific-version
    SHA512 your-hash
)

# Настройка и сборка
vcpkg_configure_cmake(
    SOURCE_PATH ${SOURCE_PATH}
    PREFER_NINJA
)

# Установка библиотеки
vcpkg_install_cmake()

# Обеспечение правильной установки каталога включений
file(INSTALL ${SOURCE_PATH}/include/MYLIBRARY DESTINATION ${CURRENT_PACKAGES_DIR}/include)

# Установка файла авторских прав
file(INSTALL ${SOURCE_PATH}/COPYING DESTINATION ${CURRENT_PACKAGES_DIR}/share/MYLIBRARY RENAME copyright)

Ключевым моментом является обеспечение правильной установки папки include/MYLIBRARY в ${CURRENT_PACKAGES_DIR}/include в процессе сборки порта. Это сделает ее доступной через стандартную структуру каталогов включений vcpkg.


Решение 2: Модификация vcxproj потребляющего проекта

Вы можете изменить файлы проекта Visual Studio, чтобы включить пользовательский каталог. Рекомендуемый подход - использовать цели интеграции vcpkg:

xml
<!-- Добавьте это в ваш файл .vcxproj -->
<ImportGroup Label="ExtensionSettings">
  <Import Project="$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.targets" />
</ImportGroup>

Однако для добавления вашего пользовательского каталога включений с правильным приоритетом вам нужно изменить свойство “Дополнительные каталоги включений” проекта:

xml
<ItemDefinitionGroup>
  <ClCompile>
    <AdditionalIncludeDirectories>$(VcpkgInstalledDir)include\MYLIBRARY;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  </ClCompile>
</ItemDefinitionGroup>

Проблему с тем, что $(VcpkgInstalledDir) не оценивается, можно решить, используя шаблон полного пути:

xml
<ItemDefinitionGroup>
  <ClCompile>
    <AdditionalIncludeDirectories>$(VcpkgRoot)installed\$(VcpkgTriplet)\include\MYLIBRARY;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  </ClCompile>
</ItemDefinitionGroup>

Решение 3: Использование Directory.build.props

Для более элегантного решения, которое работает с различными тройками сборки, создайте файл Directory.build.props в корне вашего решения:

xml
<Project>
  <PropertyGroup>
    <VcpkgRoot Condition="'$(VcpkgRoot)' == ''">$(USERPROFILE)\vcpkg</VcpkgRoot>
  </PropertyGroup>
  
  <ItemDefinitionGroup>
    <ClCompile>
      <AdditionalIncludeDirectories>
        $(VcpkgRoot)installed\$(VcpkgTriplet)\include\MYLIBRARY;
        %(AdditionalIncludeDirectories)
      </AdditionalIncludeDirectories>
    </ClCompile>
  </ItemDefinitionGroup>
</Project>

Этот подход автоматически применяется ко всем проектам в вашем решении и адаптируется к различным тройкам сборки (x64-windows, x86-windows, arm64-windows и т.д.) источник.


Решение 4: Пользовательские свойства MSBuild

Вы также можете создать пользовательские свойства MSBuild для более гибкой обработки каталогов включений:

xml
<!-- В вашем Directory.build.props -->
<Project>
  <PropertyGroup>
    <CustomIncludeDir>$(VcpkgRoot)installed\$(VcpkgTriplet)\include\MYLIBRARY</CustomIncludeDir>
  </PropertyGroup>
  
  <ItemDefinitionGroup>
    <ClCompile>
      <AdditionalIncludeDirectories>
        $(CustomIncludeDir);
        %(AdditionalIncludeDirectories)
      </AdditionalIncludeDirectories>
    </ClCompile>
  </ItemDefinitionGroup>
</Project>

Это упрощает управление и изменение пути к каталогу включений в вашем решении.


Обработка конфликтов приоритета включений

Когда у вас возникают конфликты между файлами заголовков, установленными vcpkg, и файлами заголовков вашего оверлейного порта, вам нужно контролировать порядок включений. Ключевым моментом является обеспечение соответствующего приоритета для вашего пользовательского каталога включений:

  1. Высокий приоритет по сравнению с vcpkg: Добавьте ваш каталог включений перед каталогами включений vcpkg
  2. Низкий приоритет по сравнению с vcpkg: Добавьте ваш каталог включений после каталогов включений vcpkg

Для достижения высокого приоритета измените AdditionalIncludeDirectories следующим образом:

xml
<ItemDefinitionGroup>
  <ClCompile>
    <AdditionalIncludeDirectories>
      $(VcpkgRoot)installed\$(VcpkgTriplet)\include\MYLIBRARY;
      $(VcpkgRoot)installed\$(VcpkgTriplet)\include;
      %(AdditionalIncludeDirectories)
    </AdditionalIncludeDirectories>
  </ClCompile>
</ItemDefinitionGroup>

Согласно исследованиям, каталоги включений vcpkg добавляются автоматически, поэтому вам необходимо правильно расположить ваш пользовательский каталог в последовательности источник.


Заключение и рекомендации

На основе проведенных исследований и анализа, вот рекомендуемые подходы:

  1. Лучшее решение: Используйте Directory.build.props для определения вашего пользовательского каталога включений. Этот подход является чистым, автоматически работает с различными тройками сборки и может быть легко управляемым.

  2. Улучшение оверлейного порта: Убедитесь, что ваш оверлейный пор правильно устанавливает каталог включений в процессе сборки. Это делает ваш порт более самодостаточным и легким в использовании.

  3. Управление приоритетом: Будьте целенаправленны в порядке каталогов включений для избежания конфликтов между заголовками, установленными vcpkg, и вашими пользовательскими заголовками.

  4. Избегайте жестко заданных путей: Никогда не используйте жестко заданные пути, такие как $(MSBuildThisFileDirectory)vcpkg_installed\x64-windows\include\MYLIBRARY\, так как они не работают с различными конфигурациями сборки.

Наиболее надежное решение сочетает правильную настройку оверлейного порта с гибким управлением свойствами MSBuild через файлы Directory.build.props. Этот подход обеспечивает правильную интеграцию ваших пользовательских каталогов включений при сохранении совместимости с автоматическим управлением каталогами включений vcpkg.

Источники

  1. vcpkg в проектах MSBuild | Microsoft Learn
  2. Оверлейные порты | Microsoft Learn
  3. Как добавить каталог включений для импортируемой библиотеки с более высоким приоритетом, чем каталоги включений vcpkg · Проблема #8071 · microsoft/vcpkg
  4. Существует ли способ для CMake (или Visual Studio) игнорировать системную интеграцию vcpkg? · microsoft/vcpkg
  5. Оверлейные порты · MicrosoftDocs/vcpkg-docs
  6. Структура каталога установки | Microsoft Learn