БлогNot. Как собрать проект C++ с github из исходников и подключить его к Visual Studio

Как собрать проект C++ с github из исходников и подключить его к Visual Studio

P.S. В новых сборках Visual Studio проекты из репозиториев открываются просто из меню Файл - Клонировать репозиторий. В статье речь идёт о ситуации, когда так сделать невозможно.

Благодаря менеджеру пакетов winget, уже входящему в актуальные сборки масдайки, теперь в Windows 10 можно инсталлировать приложения одной простой консольной командой (см. также доку от Микрософта).

Но мы рассмотрим сейчас ситуацию, когда у нас есть только ссылка на исходники проекта, скажем, на Гитхабе (возьмём для примера библиотеку для простых чисел primesieve) и нужно каким-то образом "вручную" скомпилировать внешний проект в своей Studio, чтобы воспользоваться его возможностями в своём приложении.

В противном случае, конечно же, нестандартный include вроде этого, который вы нашли в коде-образце

#include <primesieve.hpp>

работать не будет ни за что.

Первым делом скачаем все исходники внешнего проекта "как есть" в архиве .zip, для этого у нас на гитхабе есть кнопка "Download ZIP":

Как загрузить проект с github в архиве .zip
Как загрузить проект с github в архиве .zip

Развернём проект, не создавая новой папки, если у вашего архиватора нет такого же пункта меню, просто сотрите предлагаемое архиватором имя новой папки, потому что папка уже есть в архиве:

Извлечь внешний проект из архива, не создавая новой папки
Извлечь внешний проект из архива, не создавая новой папки

Если покопаться в файле readme.md проекта, как правило, можно найти инструкцию по установке (Build instructions) и даже "Detailed build instructions", где говорится, в числе прочего, и о компиляции проекта под Microsoft Visual C++:

Команды cmake для компиляции проекта со страницы документации
Команды cmake для компиляции проекта со страницы документации

Откроем свой "некомпилируемый" без нужной библиотеки проект в Studio (я использую актуальную сборку версии 2019) и обратимся к команде меню Вид - Терминал. Выберем инструмент "Командная строка разработчика" (по умолчанию в новых сборках теперь выбран PowerShell, впрочем, если в документации приведены команды PowerShell, то применяйте их).

У Микрософта инструмент описан вот здесь.

Командная строка разработчика в Studio
Командная строка разработчика в Studio

В командной строке пишем команды из документации, но сначала, конечно, нужно перейти в ту папку, где у вас развёрнут скачанный проект. Мне понадобилось ввести в консоли следующее, завершая каждую команду нажатием Enter:

d:
cd \temp\primesieve-master

- теперь я в нужной папке, так как развернул свой архив в папку d:\temp

Далее как написано:

cmake -G "Visual Studio 16 2019" .
cmake --build . --config Release

Можно просто копировать команды со страницы документации, в окне консоли вверху есть стандартная кнопочка "Вставить". А вот точка в записи команд имеет значение, это ссылка на текущую папку!

Ну и, конечно, для другой версии Studio будет другое указание компилятора, узнать своё можно командой

cmake -G

Нужный генератор будет помечен в списке "звёздочкой".

Если что-то пошло не так, ошибаетесь в консольных командах и получаете сообщения об ошибках кэша - сотрите файл CMakeCache.txt из папки скопированного проекта и попробуйте снова.

Теперь проект можно открывать в Studio и работать с ним, все нужные файлы есть в папке d:\temp\primesieve-master

Но мы хотим подключить всё, что нужно, к своему имеющемуся проекту, а не пытаться модифицировать чужую библиотеку.

Примерный путь описан вот здесь, мне же пришлось сделать конкретно следующее:

  • Меню Проект - Свойства, слева выбираем Свойства конфигурации, C/C++, Общие, раскрываем поле "Дополнительные каталоги включаемых файлов", говорим "Изменить" и показываем на папку D:\Temp\primesieve-master\include . В вашем проекте, как правило, тоже будет вложенная папка include.
  • В том же окне выбираем Компоновщик - Общие - Дополнительные каталоги библиотек, "Изменить" и добавляем путь D:\Temp\primesieve-master\Release . Этого может оказаться мало, у вашего проекта и внешнего должны быть выбраны одинаковые конфигурации решения. Так как я выбрал Release для внешнего проекта, то и в своём проекте в списке "Конфигурации решения" (на стандартной панели инструментов) указал Release и платформу x64. Можно было работать и с Debug, но тогда и внешний проект компилируем как Debug и потом выбираем путь D:\Temp\primesieve-master\Debug .
  • В списке C/C++ - Создание кода - Библиотека времени выполнения выбрал Многопоточный DLL (/MD), иначе будет "LNK2038: обнаружено несоответствие для 'RuntimeLibrary': значение 'MT_StaticRelease' не соответствует значению 'MD_DynamicRelease' в file.obj".
  • Сам файл библиотеки, как правило имеющий тип .lib, тоже нужно прописать. Всё в том же окне свойства проекта выбираем список Компоновщик - Ввод, раскрываем список "Дополнительные зависимости", жмём "Изменить" и указываем в поле ввода имя файла библиотеки primesieve.lib
  • На всякий случай, проверяем, что у нас в списке Компоновщик - Система - Подсистема, у меня там просто Консоль (/SUBSYSTEM:CONSOLE), для других типов проектов может понадобиться изменение и этой настройки.

После этого у меня всё заработало.

Ну а конкретная задача, на которой я проверял библиотеку - печать самых длинных цепочек последовательных простых чисел, в которых разница между соседними значениями строго возрастает или строго убывает, предел счёта равен 1000000, вот сама программа:

#include <cstdint>
#include <iostream>
#include <vector>
#include <primesieve.hpp>

void print_diffs(const std::vector<uint64_t>& vec) {
 for (size_t i = 0, n = vec.size(); i != n; ++i) {
  if (i != 0)
   std::cout << " (" << vec[i] - vec[i - 1] << ") ";
  std::cout << vec[i];
 }
 std::cout << '\n';
}

int main() {
 std::vector <uint64_t> asc, desc;
 std::vector <std::vector<uint64_t>> max_asc, max_desc;
 size_t max_asc_len = 0, max_desc_len = 0;
 uint64_t prime;
 const uint64_t limit = 1000000;
 for (primesieve::iterator pi; (prime = pi.next_prime()) < limit; ) {
  size_t alen = asc.size();
  if (alen > 1 && prime - asc[alen - 1] <= asc[alen - 1] - asc[alen - 2])
   asc.erase(asc.begin(), asc.end() - 1);
  asc.push_back(prime);
  if (asc.size() >= max_asc_len) {
   if (asc.size() > max_asc_len) {
    max_asc_len = asc.size();
    max_asc.clear();
   }
   max_asc.push_back(asc);
  }
  size_t dlen = desc.size();
  if (dlen > 1 && prime - desc[dlen - 1] >= desc[dlen - 1] - desc[dlen - 2])
   desc.erase(desc.begin(), desc.end() - 1);
  desc.push_back(prime);
  if (desc.size() >= max_desc_len) {
   if (desc.size() > max_desc_len) {
    max_desc_len = desc.size();
    max_desc.clear();
   }
   max_desc.push_back(desc);
  }
 }
 std::cout << "Longest run(s) of ascending prime gaps up to " << limit << ":\n";
 for (const auto& v : max_asc)
  print_diffs(v);
 std::cout << "\nLongest run(s) of descending prime gaps up to " << limit << ":\n";
 for (const auto& v : max_desc)
  print_diffs(v);
 return 0;
}

Ответы вышли такие:

Longest run(s) of ascending prime gaps up to 1000000:
128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037
402581 (2) 402583 (4) 402587 (6) 402593 (8) 402601 (12) 402613 (18) 402631 (60) 402691
665111 (2) 665113 (4) 665117 (6) 665123 (8) 665131 (10) 665141 (12) 665153 (24) 665177

Longest run(s) of descending prime gaps up to 1000000:
322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249
752207 (44) 752251 (12) 752263 (10) 752273 (8) 752281 (6) 752287 (4) 752291 (2) 752293

За счёт хорошо оптимизированного кода библиотеки считается всё мгновенно.

Это задача из списка задач на простые числа

21.10.2021, 13:15 [13254 просмотра]


теги: c++ числа список windows памятка софт studio

К этой статье пока нет комментариев, Ваш будет первым