# Подключение внешних библиотек

Рассмотрим пример подключения внешней библиотеки OpenCV и сборку программы в терминале, а также в IDE Visual Studio и CLion, используя разные системы сборки.

{% hint style="info" %}
Все дальнейшие примеры проводились для компилятора `clang` под Windows. При использовании дргих компиляторов ключи будут другими. Под Unix-системами пути до бибилотеки после её установки и расширения файлов библиотек будут другими.
{% endhint %}

## OpenCV

Популярная библиотека для работы с изображениями. Будем рассматривать пример подключения библиотеки в программу, написанную на C. Для этого используется [OpenCV версии 3.4 (sources)](https://opencv.org/releases/), т.к. начиная с версии 4.0 C API было удалено из исходников библиотеки.

Структура баблиотеки выглядит следующим образом:

Общая структура библиотеки может поставляться в виде исходники (sources) + собранная версия библиотеки (build). OpenCV как раз можно скачать в таком варианте.

{% code title="opencv" overflow="wrap" %}

```powershell
Mode   Name
----   ----
d----- build
d----- sources
-a---- LICENSE.txt
-a---- LICENSE_FFMPEG.txt
-a---- README.md.txt
```

{% endcode %}

Нас интересует собранная версия, поэтому рассмотрим подробнее струкутуру директории build:

{% code title="opencv\build" overflow="wrap" %}

```powershell
Mode   Name
----   ----
d----- bin
d----- etc
d----- include
d----- java
d----- python
d----- x64
-a---- LICENSE
-a---- OpenCVConfig-version.cmake
-a---- OpenCVConfig.cmake
-a---- setup_vars_opencv3.cmd
```

{% endcode %}

Чаще всего в библиотеках/фреймворках встречаются директории `include`, `bin`, `lib`, `x86`, `x64`, `docs`, `3rdparty`, `samples` и прочие.

| Директория       | Назначение (что содержит)                                                       |
| ---------------- | ------------------------------------------------------------------------------- |
| `include`        | Заголовочные файлы, в которых описаны структуры/макросы/функции                 |
| `bin`            | Исполняемые файлы и файлы динамических библиотек                                |
| `lib`            | Файлы статических библиотек. Чаще всего внутри содержит директории `x86`, `x64` |
| `lib-32` / `x64` | Чаще всего файлы статических библиотек, собранных под разные битности           |
| `docs`           | Документация                                                                    |
| `3rdparty`       | Сторонние библиотеки                                                            |
| `samples`        | Примеры использования                                                           |

Рассмотрим структуру поддиректорий `include`, `bin`, `x64`

{% tabs %}
{% tab title="include" %}
{% code title="opencv\build\include" overflow="wrap" %}

```powershell
Mode   Name
----   ----
d----- opencv
d----- opencv2
```

{% endcode %}
{% endtab %}

{% tab title="include\opencv" %}
{% code title="opencv\build\include\opencv" overflow="wrap" %}

```powershell
Mode   Name
----   ----
-a---- cv.h
-a---- cv.hpp
-a---- cvaux.h
-a---- cvaux.hpp
-a---- cvwimage.h
-a---- cxcore.h
-a---- cxcore.hpp
-a---- cxeigen.hpp
-a---- cxmisc.h
-a---- highgui.h
-a---- ml.h
```

{% endcode %}
{% endtab %}

{% tab title="include\opencv2" %}
{% code title="opencv\build\include\opencv2" overflow="wrap" %}

```powershell
Mode   Name
----   ----
d----- calib3d
d----- core
d----- dnn
d----- features2d
d----- flann
d----- highgui
d----- imgcodecs
d----- imgproc
d----- ml
d----- objdetect
d----- photo
d----- shape
d----- stitching
d----- superres
d----- video
d----- videoio
d----- videostab
-a---- calib3d.hpp
-a---- core.hpp
-a---- cvconfig.h
-a---- dnn.hpp
-a---- features2d.hpp
-a---- flann.hpp
-a---- highgui.hpp
-a---- imgcodecs.hpp
-a---- imgproc.hpp
-a---- ml.hpp
-a---- objdetect.hpp
-a---- opencv.hpp
-a---- opencv_modules.hpp
-a---- photo.hpp
-a---- shape.hpp
-a---- stitching.hpp
-a---- superres.hpp
-a---- video.hpp
-a---- videoio.hpp
-a---- videostab.hpp
-a---- world.hpp
```

{% endcode %}
{% endtab %}

{% tab title="imgcodecs" %}
{% code title="opencv\build\include\opencv2\imgcodecs" overflow="wrap" %}

```powershell
Mode   Name
----   ----
-a---- imgcodecs.hpp
-a---- imgcodecs_c.h
-a---- ios.h
```

{% endcode %}
{% endtab %}

{% tab title="bin" %}
{% code title="opencv\build\bin" overflow="wrap" %}

```powershell
Mode   Name
----   ----
-a---- opencv_ffmpeg3415_64.dll
```

{% endcode %}
{% endtab %}

{% tab title="build\x64" %}
{% code title="opencv\build\x64" overflow="wrap" %}

```powershell
Mode   Name
----   ----
d----- vc14
d----- vc15
```

{% endcode %}
{% endtab %}

{% tab title="x64\vc15" %}
{% code title="opencv\build\x64\vc15" overflow="wrap" %}

```powershell
Directory: P:\demo_lib\library\opencv\build\x64\vc15

Mode   Name
----   ----
d----- bin
d----- lib


Directory: P:\demo_lib\library\opencv\build\x64\vc15\bin

Mode   Name
----   ----
-a---- opencv_annotation.exe
-a---- opencv_createsamples.exe
-a---- opencv_ffmpeg3415_64.dll
-a---- opencv_interactive-calibration.exe
-a---- opencv_traincascade.exe
-a---- opencv_version.exe
-a---- opencv_version_win32.exe
-a---- opencv_visualisation.exe
-a---- opencv_world3415.dll
-a---- opencv_world3415.pdb
-a---- opencv_world3415d.dll
-a---- opencv_world3415d.pdb


Directory: P:\demo_lib\library\opencv\build\x64\vc15\lib

Mode   Name
----   ----
-a---- OpenCVConfig-version.cmake
-a---- OpenCVConfig.cmake
-a---- OpenCVModules-debug.cmake
-a---- OpenCVModules-release.cmake
-a---- OpenCVModules.cmake
-a---- opencv_world3415.lib
-a---- opencv_world3415d.lib
```

{% endcode %}
{% endtab %}
{% endtabs %}

Как можно заметить, заголовочные файлы не обязаны все лежать в одной директории, а могут быть расположенны по разным поддиректориям. Также в OpenCV версии 3 видно, что рядом могут лежать заголовочные с C и C++ API.

В OpenCV исполняемые файлы и файлы динамических библиотек самой OpenCV располагаются не в корневой `bin` директории. Такое также встречается, когда `bin` директорий в проекте несколько и в таком случае необходимые файлы динамический библиотек следует искать в директориях `x86` и `x64`. Последняя в сброке OpenCV имеется.

`vc14` и `vc15` – директории, содержащие сборки под разными версиями Visual Studio. `vc15` – сборка под VS 2017 и позднее, `vc14` – VS 2015. Структура в директориях идентичная, так что будем рассматривать `vc15`.

Можно заметить, что и `dll`, и `lib` файлы представлены в двух вариациях, отличающихся суффиксом `d`. В OpenCV файлы библиотек с суффиксом `d` собраны с сохранением отладочной информации и их следует использовать при сборке программы в debug-конфигурации. Без суффикса – релизная сборка.

В качестве тестовой программы будем использовать код `main.c`, который позволяет открыть изображение, поданной через аргументы командной строки, в отдельном окне.

{% code title="main.c" overflow="wrap" lineNumbers="true" %}

```c
#include <stdio.h>

#ifdef OPENCV
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/imgcodecs/imgcodecs_c.h>

#define WINDOW_NAME "Example"
#endif

int main(int argc, char* argv[])
{
    printf("sizeof(size_t) = %zu\n", sizeof(size_t));

    if (argc != 2)
    {
        fprintf(stderr, "ERROR! Usage: %s image-file", argv[0]);
        return -1;
    }

#ifdef OPENCV
    IplImage* img = cvLoadImage(argv[1], CV_LOAD_IMAGE_COLOR);
    cvNamedWindow(WINDOW_NAME, CV_WINDOW_AUTOSIZE);
    cvShowImage(WINDOW_NAME, img);
    cvWaitKey(0);

    cvReleaseImage(&img);
    cvDestroyWindow(WINDOW_NAME);
#endif
    return 0;
}
```

{% endcode %}

### OpenCV (vcpkg)

Библиотеку можно установить при помощи пакетных менеджеров, например, [vcpkg](https://learn.microsoft.com/en-us/vcpkg/get_started/get-started-packaging?pivots=shell-powershell).

Для установки можно найти интсрукцию на [сайте](https://vcpkg.io/en/package/opencv3):

```shell
 vcpkg install opencv3
```

После установки в `vcpkg/packages` будут располагаться "установленные" (собранные из исходников под ваш таргет) библиотеки с их зависимостями. В названии также отображается битность прилагаемых библиотек.

Дополнительно в логах по окончании установки будет располагаться заклинание для CMake, например:

```cmake
# opencv3 is compatible with built-in CMake variables. In case of multiple OpenCV version installed, set OpenCV_ROOT *before* the find_package call:

    set(OpenCV_ROOT "${VCPKG_INSTALLED_DIR}/x64-windows/share/opencv3")
    find_package(OpenCV REQUIRED)
```

## Подключение внешних библиотек в терминале

Попробуем собрать программу без указания особых ключей компиляции:

```powershell
> clang -O2 .\main.c -o main.exe
```

При запуске программы получим:

```powershell
> .\main.exe
sizeof(size_t) = 8
ERROR! Usage: ..\cmd_test\main.exe image-file

> .\main.exe "..\chat.png"
sizeof(size_t) - 8
```

Попробуем указать сборку в другую битность (по умолчанию x64; установим x86):

```powershell
> clang -O2 .\main.c -o main.exe -m32

> .\main.exe
sizeof(size_t) = 4
ERROR! Usage: ..\cmd_test\main.exe image-file
```

Действительно, программа собрана как 32-битная. Т.к. в нашем распоряжении имеются собранные файлы библиотек только в варианте `x64`, то в дальнейшем будем собирать программу 64-битную.

Как можно заметить, в коде нигде явно не объявлен макрос `OPENCV` и соотственно код, связанный с использованием библиотеки был отброшен на этапе препроцессинга.

Объявим макрос `OPENCV` на этапе сборки программы:

```powershell
> clang -O2 .\main.c -o main.exe -m64 -D OPENCV

.\main.c:4:10: fatal error: 'opencv/cv.h' file not found
    4 | #include <opencv/cv.h>
      |          ^~~~~~~~~~~~~
1 error generated.
```

Ошибка гласит, что не удалось найти заголовочный файл. Мы не указали include directories, из-за чего на этапе препроцессинга поиск заголовочных файлов проводился только в директориях, заданных по умолчанию (директории компилятора и системные директории).

Исправим это. Примечание: в текущем примере директория `opencv` лежит относительно `main.c` по `..\library\opencv`.

{% code title="add -I" overflow="wrap" lineNumbers="true" %}

```powershell
> clang -O2 .\main.c -o main.exe -m64 -D OPENCV -I "..\library\opencv\build\include\"

main-f71563.o : error LNK2019: unresolved external symbol cvLoadImage referenced in function mainmain-f71563.o : error LNK2019: unresolved external symbol cvNamedWindow referenced in function main
main-f71563.o : error LNK2019: unresolved external symbol cvShowImage referenced in function main       
main-f71563.o : error LNK2019: unresolved external symbol cvWaitKey referenced in function main
main-f71563.o : error LNK2019: unresolved external symbol cvReleaseImage referenced in function main    
main-f71563.o : error LNK2019: unresolved external symbol cvDestroyWindow referenced in function main   
main.exe : fatal error LNK1120: 6 unresolved externals
clang: error: linker command failed with exit code 1120 (use -v to see invocation)
```

{% endcode %}

Теперь можно заметить, что компиляция прошла успешно, а вот на этапе линковки возникли проблемы `unresolved external symbol`. Линковщику необходимо указать пути до файлов и сами файлы статических библиотек:

{% code title="add -l .lib" overflow="wrap" lineNumbers="true" %}

```powershell
> clang -O2 .\main.c -o main.exe -m64 -D OPENCV -I "..\library\opencv\build\include\" -L "..\library\opencv\build\x64\vc15\lib\" -lopencv_world3416.lib 

clang: error: no such file or directory: '.lib'
```

{% endcode %}

Обратите внимание, если указать имя файла с расширением, то собрать программу не получится.

{% code title="add -l" overflow="wrap" lineNumbers="true" %}

```powershell
> clang -O2 .\main.c -o main.exe -m64 -D OPENCV -I "..\library\opencv\build\include\" -L "..\library\opencv\build\x64\vc15\lib\" -lopencv_world3416
```

{% endcode %}

Ура, никаких ошибок линковки не возникло. Попробуем запустить программу:

{% code title="add -l" overflow="wrap" lineNumbers="true" %}

```powershell
> .\main.exe ; "0x"+$LastExitCode.ToString("X")

0xC0000135
```

{% endcode %}

Теперь ошибка на старте программы. В таких случаях можно запустить программу через явное создание процесса или же из проводника:

{% tabs %}
{% tab title="Создание процесса из терминала" %}

```powershell
> Start-Process .\main.exe ; "0x"+$LastExitCode.ToString("X")
```

![](/files/ahVAhpf4SjV71Z95UHEq)
{% endtab %}

{% tab title="Запуск из проводника" %}
Двойной клик по `exe` файлу из проводника

![](/files/n9oOEOPfgtuxpkQ8En5T)
{% endtab %}
{% endtabs %}

В обоих случаях удаётся найти сообщение об ошибке – не найден файл динамической библиотеки.

В таком случае есть 2 варианта:

1. Скопировать `.dll`-файл рядом с `exe`-файлом.
2. Добавить директорию, в которой лежит необходимый `.dll`-файл в переменные окружения. В таком случае не нужно каждый раз копировать `dll` к `exe`-файлу.

В этом примере подложим `dll` файл к `exe`:

![](/files/o041uvVIsGZmxlnwa1Oh)

При запуске видно, что всё открылось успешно и в консоли также видно данные, выводимые в программе.

![](/files/R0MyXKiqdymrNCMRDKTd)

## Подключение внешних библиотек в системе сборки MSBuild (Visual Studio)

Система сборки **MSBuild** имеет консольный и пользовательский графический интерфейс. Рассмотрим настройку через графический интерфейс в среде разработки Visual Studio.

Добавим готовый файл `main.c` из начального примера в проект.

![](/files/zCkJoSS70eFHT8KNgIe5)

Все параметры и данные для сборки настраиваются через свойства решений и проектов в IDE Vusial Studio. Если в решении несколько проектов, то системе сборки MSBuild можно задать правила и порядок сборки проектов, что может быть полезно, если имеется зависимость между проектами в решении.

В нашем случае будет 1 проект в 1 решении и далее мы будем рассматривать только настройки проекта (ПКМ по проекту – Properties).

В первую очередь настоятельно рекомендуется установить общие для всех конфигураций и платформ настройки, установив **Configurations** и **Platforms** в **All**. Затем уже устанавливать параметры, различные для конфигураций и платформ. Это сильно сэкономит времени и нервов `:)`

В первой вкладке `General` можно настроить используемый `toolset`, название выходного файла, стандарт языка и пр.

![](/files/mQakXgKYwVOtYOhPKaPq)

**Toolset** – набор инструментов платформы, состоящий из компилятора C++ (cl.exe) и компоновщика (link.exe), а также стандартных библиотек C/C++.

![](/files/0YphfIQ0Tk27Sttacusk)

По умолчанию будет доступен 1 `toolset` той VS, которая была установлена (например 2022). Через Visual Studio Installer можно поставить `toolset` более ранних VS, а также поставить `clang` (LLVM-Clang на скрине). Помимо этого компилятор Intel имеет интеграцию в VS и после установки также будет доступен в выпадающем списке.

**Target name** – имя выходного файла. Аналог `-o` у clang-а.

Стандарт языка позволяет явно задать под какой стандарт будет собираться программа. аналог `-std=` у clang-а.

Во вкладке **Отладка** можно настроить рабочую директорию и аргументы командной строки.

![](/files/HabXiQ2xaTdgR5tAuqGU)

**Рабочая директория** – директория, относительно которой будет вестить поиск файлов. По умолчанию - каталог, содержащий файл проекта. Когда программа собирается из терминала, то рабочая директория – та, в которой вы находитесь в терминале.

На скриншотах выше вы могли заметить значения вида `$(ProjectDir)` и пр. Это **макросы VS**, которые будут раскрываться при сборке программы. Во что раскрываются макросы можно посмотреть при редактированнии полей:

![](/files/GaQ0Qj99q3gTGYDaf9B8)

Попробуем собрать и запустить нашу программу в `Release x64` и `Debug x86`.

![](/files/4aa784Ko0LOeoFMPzbKw)

![](/files/alJJdxZWNTd530PH57Iq)

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

Однако как в случае со сборкой в терминале мы видим, что код OpenCV не был задействован, т.к. мы не указали полезных данных для среды разработки про OpenCV.

В первую очередь посмотрим на подсказки самой среды разработки:

![](/files/Uh7Vt280uf6R1O5Kknun)

Видно, что фрагмент кода в `main()` показывается тусклым. Так среда разработки подсказывает, что этот код не будет исполняться – либо код недостижим, либо будет отброшен на этапе препроцессинга. Второй вариант как раз характеризует наш случай.

Если укажем `preprocessor defines`, то картина изменится:

![](/files/S566RQ9fl2mY0E1O1is5)

Теперь IDE явно подсказывает, что код будет исполняться, но про сами макросы и функции из OpenCV ничего не известно.

Укажем **include directories**:

![](/files/wXLlH9pxpYd8BAlcHj2u)

В разделе `C/C++/general` помимо include directories можно изменить ключ компиляции **warning levels** для отлавливания большего числа предупреждений и нужно отключить **SDL checks** для наступления счастья.

Теперь при попытке сборки ожидаемо будут возникать ошибки линковки:

{% code title="error LNK" overflow="wrap" lineNumbers="true" %}

```powershell
Build started at 16:33...
1>------ Build started: Project: OPENCV_VSProject, Configuration: Release x64 ------
1>main.c
1>main.obj : error LNK2001: unresolved external symbol cvWaitKey
1>main.obj : error LNK2001: unresolved external symbol cvReleaseImage
1>main.obj : error LNK2001: unresolved external symbol cvLoadImage
1>main.obj : error LNK2001: unresolved external symbol cvDestroyWindow
1>main.obj : error LNK2001: unresolved external symbol cvShowImage
1>main.obj : error LNK2001: unresolved external symbol cvNamedWindow
1>..\OPENCV_VSProject\x64\Release\OPENCV_VSProject.exe : fatal error LNK1120: 6 unresolved externals
1>Done building project "OPENCV_VSProject.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 16:33 and took 00.281 seconds ==========
```

{% endcode %}

Которые исправим указанием файлов статических бибилотек и директорий, где они расположены. Обратите внимание, что здесь мы явно указываем платформу `x64`, т.к. собрана библиотека у нас только в этом варианте; а при задании файла мы не забудем для сборки в debug указать debug-версию библиотеки, а для release – release-файл.

![](/files/DtFplRoI23mynXqhpc97)

![](/files/O3UkCAh9G4e1FimnxqFr)

![](/files/f8wmPZG7cY2oDTKFek3Q)

Теперь сборка будет проходить успешно:

{% code title="build succeeded" overflow="wrap" lineNumbers="true" %}

```powershell
Build started at 16:38...
1>------ Build started: Project: OPENCV_VSProject, Configuration: Release x64 ------
1>Generating code
1>1 of 5 functions (20.0%) were compiled, the rest were copied from previous compilation.
1>  0 functions were new in current compilation
1>  0 functions had inline decision re-evaluated but remain unchanged
1>Finished generating code
1>OPENCV_VSProject.vcxproj -> ..\OPENCV_VSProject\x64\Release\OPENCV_VSProject.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 16:38 and took 00.311 seconds ==========
```

{% endcode %}

А для корректного старта необходимо в корень проекта или к exe-файлам подложить `dll` файлы (подсказка: в корень проекта проще).

## Подключение внешних библиотек в системе сборки CMake (Visual Studio)

Visual Studio 2022 поддерживает CMake и позволяет писать CMake-проекты.

Также помимо запуска под Windows есть возможность настроить запуск под WSL (есл установлен) или же настроить запуск с удаленного хоста.

![](/files/o3WdTvHCISomYblhri7u)

По умолчанию создано несколько стандартных конфигураций сборки программы:

![](/files/g9dXwoO7PZJtVO5uirvz)

По умолчанию все проекты CMake в VS создаются как C++-проекты и при необходимости необходимо самостоятельно изменить в свойствах проекта язык с C++ (CXX) на C.

Свойства проекта представлены в виде `CMakeLists.txt` файла:

{% code overflow="wrap" lineNumbers="true" %}

```cmake
# CMakeList.txt : CMake project for OPENCV_CmakeProject, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.8)

# Enable Hot Reload for MSVC compilers if supported.
if (POLICY CMP0141)
  cmake_policy(SET CMP0141 NEW)
  set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()

add_executable(OPENCV_CmakeProject OPENCV_CmakeProject.c)
```

{% endcode %}

Для дальнейшей работы рекомендуется удалить из проекта автосгенерированные исходники и прописать CMakeLists.txt самостоятельно. В случаи использования OpenCV также рекомендуется убрать весь `if (POLICY CMP0141) ... endif()`.

После объявления минимально подходящей версии CMake следует явно указать переменную проекта (версия проекта опциональна):

{% code overflow="wrap" lineNumbers="true" %}

```cmake
project(OPENCV_CmakeProject VERSION 0.1)
```

{% endcode %}

Укажем явно, что мы хотим собирать проект под C17 и, например, что поддержка этого стандарта нам необходима для сборки (более ранние версии не подойдут):

{% code overflow="wrap" lineNumbers="true" %}

```cmake
set(CMAKE_C_STANDART 17)
set(CMAKE_C_STANDART_REQUIRED True)
```

{% endcode %}

Дополним его необходимыми сведениями про OpenCV.

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

{% code overflow="wrap" lineNumbers="true" %}

```cmake
set(SOURCES "OPENCV_CmakeProject.c")
```

{% endcode %}

2. Укажем макрос

{% code overflow="wrap" lineNumbers="true" %}

```cmake
add_definitions(-DOPENCV)
```

{% endcode %}

3. Дополним ключи компиляции по умолчанию ключом про уровень предупреждений (по умолчанию `/W3`, терминология компилятора MSVC)

{% code overflow="wrap" lineNumbers="true" %}

```cmake
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
```

{% endcode %}

4. Укажем include directories (здесь и далее полагаем, что OpenCV лежит рядом с нашим проектом)

{% code overflow="wrap" lineNumbers="true" %}

```cmake
include_directories("../library/opencv/build/include")
```

{% endcode %}

5. Укажем при сборке в `x64` library directories (32-битной версии библиотеки у нас нет, поэтому не будем рассматривать данную ветку)

{% code overflow="wrap" lineNumbers="true" %}

```cmake
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
	link_directories("../library/opencv/build/x64/vc15/lib")
endif()
```

{% endcode %}

6. Модифицируем аргументы конструкции `add_executable`

{% code overflow="wrap" lineNumbers="true" %}

```cmake
add_executable(OPENCV_CmakeProject ${SOURCES})
```

{% endcode %}

7. Дополним сведения о файлах статических библиотек

{% code overflow="wrap" lineNumbers="true" %}

```cmake
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
	if (CMAKE_BUILD_TYPE EQUAL "Debug")
		target_link_libraries(OPENCV_CmakeProject "opencv_world3415d.lib")
	els()
		target_link_libraries(OPENCV_CmakeProject "opencv_world3415.lib")
	endif()
endif()
```

{% endcode %}

`CMAKE_BUILD_TYPE` нам известен из файла `CMakePresets.json`, в котором указаны компилтор и подсистема сборки (по умолчанию Ninja), а также переменные каждой конфигурации, которые можно смело использовать в `CMakeLists.txt`.

Примечение: при изменении `CMakeLists.txt` они автоматически сохраняются и сразу происходит регенерация кеша сборки:

![](/files/OpoTcg0WdeuCazGLBnc2)

Там содержаться логи регенерации с ошибками (если они есть). В противном случае будет `CMake generation finished.`. Из полезного: `Command line:`, в которой можно посмотреть параметры, с которым вас по итогу собирают, и `Working directory:` – рабочая директория проекта (та, где лежит сформированный выходной файл).

Чтобы задать аргументы командной строки необходимо:

1. Переключить отображение в `Solution Explorer` на `Project View`

![](/files/6rkXekbTJImOoR2KsRvH)

2. Перейти в `Add Debug Configurations` (ПКМ по проекту)

![](/files/PtNpxQOBZx4nDTI26Xfh)

3. Прописать параметры `currentDir` (WorkingDirectory) и `args` (command-line arguments) в открывшемся `launch.json`:

{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "version": "0.2.1",
  "defaults": {},
  "configurations": [
    {
      "type": "default",
      "project": "CMakeLists.txt",
      "projectTarget": "OPENCV_CmakeProject.exe",
      "name": "OPENCV_CmakeProject.exe",
+     "currentDir": ".",
+     "args": [
        "../chat.png"
      ]
    }
  ]
}
```

{% endcode %}

После проделанных манипуляций при указании на верхней панели конфигураций `x64 Release` и `x64 Debug` будет собираться программа, запускаться с переданным аргументом и показываться картинка на экране, а при`x86 Release` и `x86 Debug` – ошибка линковки.

## Подключение внешних библиотек в системе сборки CMake (CLion)

Сам файл `CMakeLists.txt` почти ничем не будет отличаться, за исключением:

* `cmake_minimum_required (VERSION 3.8)` вероятно будет более новой версии
* `# Enable Hot Reload for MSVC compilers if supported.` и связанный с этим комментарием `if` будет отсутствовать
* флаги компиляции следует указывать те, которые нужны для используемого `toolchain` – если `toolchain` не VS, то `/W4` можно заменить на `-Wall -Wextra -Wpedantic`

Подробнее про `toolchain` в CLion: [clang-clion](/c-cpp-cookies/environments/compilers/clang-clion.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://skkv-itmo.gitbook.io/c-cpp-cookies/build/build-with-libs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
