Gcc g что это
C, C++ и Objective C версии компилятора объединены; компилятор GNU C может компилировать программы написанные на C, C++ или Objective C.
«GCC» — общее стандартное обозначение для компилятора GNU C. Это как наиболее общее название компилятора, так и название, используемое, когда акцент делается на компиляции C программ.
Когда ссылаются на C++ компиляцию, обычно называют компилятор «G++». Поскольку есть только один компилятор, будет точным называть его «GCC» вне зависимости от языка; однако термин «G++» более полезен, когда ударение стоит на компиляции С++ программ.
Мы используем имя «GNU CC» для ссылки на всю систему компиляции в целом и более конкретно к языковонезависимой части компилятора. Например, мы говорим об опциях оптимизации, как о влияющих на поведение «GNU CC» или, иногда, просто «компилятора».
Внешние интерфейсы с других языков, таких как Ada 9X, Fortran, Modula-3 и Pascal, находятся в развитии. Эти front end’ы, также как и front end с C++, построенны в поддиректориях GNU CC и связанны с ним. В результате получается интегрированный компилятор, который может компилировать программы написанные на C, C++, Objective C или на любых других языках, для которых вы установили внешние интерфейсы.
В данном руководстве мы рассматриваем только опции для C, Objective C и C++ компиляторов, а также опции ядра GNU CC. Обращайтесь к документации по другим внешним интерфейсам, чтобы узнать об опциях, используемых при компиляции программ, написанных на других языках.
G++ — это компилятор, а не просто препроцессор. G++ строит объектный код прямо из вашей исходной C++ программы. Никакой промежуточной C версии программы не порождается. (К примеру, некоторые другие реализации напротив используют программу, которая порождает C программу из вашей C++ программы.) Избегание промежуточного C представления программы означает, что вы получаете более хороший объектный код и более хорошую отладочную информацию. Отладчик GNU, GDB, использует эту информацию в объектном коде, чтобы дать вам все возможности работы на уровне исходного C++ текста (см. раздел «C и C++» в «Отладка с GDB»).
Gcc g что это
Рассмотрим создание первой простейшей программы на C++ с помощью компилятора g++ , который на сегодняшний день является одним из наиболее популярных компиляторов для C++, доступен для разных платформ и который распространяется в рамках пакета компиляторов GCC. Более подробную информацию о g++ можно получить на официальном сайте проекта https://gcc.gnu.org/.
Набор компиляторов GCC распространяется в различных версиях. Для Windows одной из наиболее популярных версий является пакет средств для разработки от некоммерческого проекта MSYS2 . Следует отметить, что для MSYS2 требуется 64-битная версия Windows 7 и выше (то есть Vista, XP и более ранние версии не подходят)
Итак, загрузим программу установки MSYS2 с официального сайта MSYS2:
После загрузки запустим программу установки:
На первом шаге установки будет предложено установить каталог для установки. По умолчанию это каталог C:\msys64:
Оставим каталог установки по умолчанию (при желании можно изменить). На следующем шаге устанавливаются настройки для ярлыка для меню Пуск, и затем собственно будет произведена установка. После завершения установки нам отобразить финальное окно, в котором нажмем на кнопку Завершить
После завершения установки запустится консольное приложение MSYS2.exe. Если по каким-то причинам оно не запустилось, то в папке установки C:/msys64 надо найти файл usrt_64.exe :
Теперь нам надо установить собственно набор компиляторов GCC. Для этого введем в этом приложении следующую команду:
pacman -S mingw-w64-ucrt-x86_64-gcc
Для управления пакетами MSYS2 использует пакетный менеджер Packman. И данная команда говорит пакетному менеджеру packman установить пакет mingw-w64-ucrt-x86_64-gcc , который представляет набор компиляторов GCC (название устанавливаемого пакета указывается после параметра -S ).
и после завершения установки мы можем приступать к программированию на языке C++. Если мы откроем каталог установки и зайдем в нем в папку C:\msys64\ucrt64\bin , то найдем там все необходимые файлы компиляторов:
В частности, файл g++.exe как раз и будет представлять компилятор для языка С++.
Далее для упрощения запуска компилятора мы можем добавить путь к нему в Переменные среды. Для этого можно в окне поиска в Windows ввести «изменение переменных среды текущего пользователя»:
Нам откроется окно Переменных среды:
И добавим путь к компилятору C:\msys64\ucrt64\bin :
Чтобы убедиться, что набор компиляторов GCC успешно установлен, введем следующую команду:
gcc --version
В этом случае нам должна отобразиться версия компиляторов
Создание первой программы
Итак, компилятор установлен, и теперь мы можем написать первую программу. Для этого потребуется любой текстовый редактор для набора исходного кода. Можно взять распространенный редактор Visual Studio Code или даже обычный встроенный Блокнот.
Итак, создадим на жестком диске С папку для исходных файлов. А в этой папке создадим новый текстовый файл, который переименуем в hello.cpp . То есть по сути файлы исходного кода на С++ — это обычные текстовые файлы, которые, как правило, имеют расширение cpp .
В моем случае файл hello.cpp находится в папке C:\cpp.
Теперь определим в файле hello.cpp простейший код, который будет выводить строку на консоль:
#include // подключаем заголовочный файл iostream int main() // определяем функцию main < // начало функции std::cout // конец функции
Для вывода строки на консоль необходимо подключить нужный функционал. Для этого в начале файла идет строка
#include
Данная строка представляет директиву препроцессора, которая позволяет подключить библиотеку iostream. Эта библиотека нужна для вывода строки на консоль.
Далее идет определение функции main . Функция main должна присутствовать в любой программе на С++, с нее собственно и начинается выполнение приложения.
Функция main состоит из четырех элементов:
- Тип возвращаемого значения . В данном случае это тип int . Этот тип указывает, что функция должна возвращать целое число.
- Имя функции . В данном случае функция называется main.
- Список параметров . После имени функции в скобках идет список параметров. Но в данном случае скобки пустые, то есть функция main не принимает параметров.
- Тело функции . После списка параметров в фигурных скобках идет тело функции. Здесь и определяются собственно те действия, которые выполняет функция main.
В теле функции происходит вывод строки на консоль. Для обращения к консоли используется стандартный поток вывода std::cout . С помощью оператора
В конце осуществляем выход из функции с помощью оператора return . Так как функция должна возвращать целое число, то после return указывается число 0. Ноль используется в качестве индикатора успешного завершения программы.
После каждой инструкции в языке C++ ставятся точка с запятой.
Каждая строка снабжена комментарием. Все, что написано после двойного слеша // представляет комментарий. Комментарий не учитывается при компиляции приложения, и не является частью программного кода, а служат лишь для его описания. Комментарий позволяет понять, что делает программа.
Теперь скомпилируем этот файл. Для этого откроем командную строку Windows и вначале с помощью команды cd перейдем к папке с исходным файлом:
cd C:\cpp
Чтобы скомпилировать исходный код, необходимо компилятору gcc передать в качестве параметра файл hello.cpp:
g++ hello.cpp -o hello
Дополнительный необязательный параметр -o hello указывает, что скомпилированный файл будет называться hello.exe. Если не указать этот параметр, то файл будет называться по умолчанию - a.exe.
После выполнения этой команды будет скомпилирован исполняемый файл, который в Windows по умолчанию называется hello.exe. И мы можем обратиться к этому файлу, и в этом случае консоль выведет строку "Hello METANIT.COM!", собственно как и прописано в коде.
Если вместо командной строки используется оболочка PowerShell, то для запуска файла надо прописать "./hello".
Стоит отметить, что мы можем совместить компиляцию и выполнение следующей командой:
g++ hello.cpp -o hello.exe & hello.exe
Gcc g что это
Команда g++ предназначена для компиляции с помощью компилятора GCC кода на языке C++. Данная команда похожа на команду gcc, используемую для компиляции кода на языке C.
Базовый синтаксис команды выглядит следующим образом:
$ g++ [параметры] имена файлов
В качестве имен файлов могут использоваться как имена файлов исходного кода на языке C++ с расширениями .cpp и .cxx, так и имена файлов объектного кода с расширением .o. Компилятор поддерживает поистине огромное количество параметров, но наиболее важными из них являются такие параметры, как параметр -o, позволяющий задать имя результирующего исполняемого файла, параметр -c, позволяющий лишь скомпилировать файл без связывания (то есть, создать файл объектного кода, а не исполняемый файл), параметр -O, позволяющий задать уровень оптимизации и параметр -l, позволяющий указать библиотеку, которая должна быть связана с результирующим исполняемым файлом.
Примеры использования
Компиляция программы из одного файла исходного кода
Для компиляции простейшей программы из одного файла исходного кода достаточно передать компилятору имя файла исходного кода, а также имя результирующего исполняемого файла.
Это содержимое файла исходного кода test.cxx:
Gcc g что это
Изготовление исполнимых программ из исходных текстов выполняется с помощью компиляторов, переводящих исходный текст программы в эквивалентную ей результирующую программу на языке машинных команд. Основными языками программирования на высокопроизводительных вычислительных системах являются С/C++ и Фортран . Язык С создавался как язык для написания системных приложений, однако в последнее время широко применяется и для написания вычислительных программ. Язык программирования Фортран изначально разрабатывался для написания вычислительных программ. Для него разработано множество библиотек прикладных подпрограмм, в которых реализованы различные вычислительные алгоритмы. Например, библиотека LAPACK содержит широчайший набор подпрограмм для решения различных задач линейной алгебры.
Синтаксис команды компиляции имеет вид:
компилятор [опции] файлы [библиотеки]
- Здесь компилятор - команда вызова компилятора;
- основные опции:
- -o - создать выходной файл с заданным именем (без опции создается a.out);
- -c - не изготавливать исполнимый модуль (при компиляции подпрограмм);
- -O -O1,-O2,-O3 - задание уровня оптимизации;
- -g - выполнить компиляцию в отладочном режиме;
- файлы - компилируемые файлы;;
- библиотеки - подключаемые библиотеки.
В квадратных скобках указываются необязательные компоненты команды.
На UNIX-подобных системах имеется множество компиляторов. Большая часть из них является коммерческими продуктами. Для систем Linux пакет GCC является неотъемлемой частью дистрибутивов, поскольку является базовым компилятором сборки ядра системы и всех ее утилит.
Пакет компиляторов GCC
В него входят компиляторы:
- gcc - компилятор языка С;
- g++ - компилятор языка С++;
- gfortran - компилятор языка Фортран95.
Компиляторы GCC оптимизирующие, поддерживающие три уровня оптимизации (опции -O1, -O2, -O3). На разных программах более эффективной может оказаться та или другая опция. В большинстве случаев наиболее приемлемой бывает опция -O2, при этом ускорение программы может достигать 2-3 раз. Типичные команды компиляции:
- gcc -O2 -o prog prog.c - для языка С;
- gfortran -O2 -o prog prog.f - для языка Фортран.
Помимо этого, на Linux кластерах, являющихся сегодня основным видом высокопроизводительных вычислительных систем, широко используется пакет компиляторов Intel Compiler, наилучшим образом оптимизированный под платформу x86-64, являющуюся основной при построении вычислительных кластеров. Это коммерческй продукты и он приобретен Вычислительным центром СПбГУ.
Пакет компиляторов Intel
- icc - компилятор языка С;
- icpc - компилятор языка С++;
- ifort - компилятор языка f77, f90, f95.
Компиляторы также поддерживают три уровня оптимизации (опции -O1, -O2, -O3, задание опции -O соответствует уровню -O2). Сочетание опций -fast -On, задает режим максимального ускорения программы на соответствующем уровне оптимизации. Для отлаженных программ включение оптимизации обязательно. В большинстве случаев ускорение работы программы может достигать 2-3 раз.
- icc -O2 -o prog prog.c - для языка С;
- ifort -O2 -o prog prog.f - для языка Фортран.
Рассмотрим подробнее работу с компилятором gcc.
Создадим файл с именем ex1.c с помощью команды touch. Откроем его в текстовом редакторе и наберем текст программы на языке С.
Программа ex1.c #include int main(int argc, char* argv[])
Далее следует скомпилировать программу, т.е. перевести в исполнимый код. Для этого выполним следующую команду.
Если программа написана без ошибок, то никакой выдачи информации на терминал не будет, а в рабочем каталоге появится файл с именем a.out. Это исполнимый файл, полученный в результате компиляции программы. Его можно запустить на исполнение(поэтому файлы и называются исполнимыми), набрав в командной строке:
На терминал будет напечатана строка "Hello word".
Для того чтобы поменять имя создаваемого файла c a.out на любое другое необходимо использовать опцию -o:
gcc -o ex1 ex1.c
В результате будет создан исполнимый файл с именем ex1.
Приведем несколько важных опций компилятора gcc (они справедливы и для icc)
- -o файл - Поместить вывод в файл 'файл'. Эта опция применяется вне зависимости от вида порождаемого файла, является ли это выполнимый файл, объектный файл, ассемблерный файл или препроцессированный C код. Если '-o' не указано, по умолчанию выполнимый файл помещается в 'a.out', объектный файл для 'исходный.суффикс' - в 'исходный.o', его ассемблерный код в 'исходный.s' и все препроцессированные C файлы - в стандартный вывод.
- -c - Компилировать или ассемблировать исходные файлы, но не линковать. Стадия ликовки просто не выполняется. Конечный вывод происходит в форме объектного файла для каждого исходного файла.
- -g - Порождает отладочную информацию.
- -O,-O1,-O2,-O3 - Задание уровня оптимизации оптимизации
- -Iдиректория - Добавляет каталог 'директория' в начало списка каталогов, используемых для поиска заголовочных файлов. Ее можно использовать для подмены системных заголовочных файлов, подставляя ваши собственные версии, поскольку эти директории просматриваются до директорий системных заголовочных файлов. Если используется более чем одна опция '-I', директории просматриваются в порядке слева на право; стандартные системные директории просматриваются последними.
- -Lдиректория - Добавляет каталог 'директория' в начало списка каталогов, используемых для поиска библиотек
- -lбиблиотека - Подключает библиотеку с именем lib'библиотека'.so
Рассмотрим назначение опций более подробно на примерах.
В программах часто используются уже написанные ранее функции. Например, в приведенной выше программе, применялась системная функция вывода информации в стандартный поток printf. Для того чтобы транслятор на этапе создания программы, мог правильно обработать внешнюю функцию необходимо ее предварительно описать, либо внутри программы, либо в специальном заголовочном файле. Такие файлы еще называют include файлами, в языке С они подключаются с помощью специальной директивы #include. На первом этапе трансляции программы, запускается так называемый препроцессор, он находит файл с именем stdio.h, и вставляет его содержимое внутрь программы. Пути поиска задаются с помощью опции
-Iдиректория,
где директория - путь к каталогу, в котором расположен данный файл.
Если используется стандартный заголовочный файл, то опцию -I для его поиска в командной строке компиляции программы указывать необязательно. Существует специальный каталог, где располагаются стандартные заголовочные файлы. Препроцессор автоматически просматривает его при поиске заголовочных файлов. Все сказанное в полной мере относится и к компилятору с языка Фортран. Отличие состоит в синтаксисе подключения include файла:
include 'файл.h'
Если в команде компиляции не указана опция -c, то компилятор автоматически выполняет операцию компоновки, т.е. изготовление исполнимой программы. В примере для вывода строки "Hello word" применялась стандартная функция printf, следовательно, код этой функции должен быть вставлен в программу. Операцию объедения кода программы и кода внешних функций выполняет компоновщик. Компоновщик (или линковщик - linker) - программа, которая производит компоновку, принимает на вход один или несколько объектных модулей и собирает из них исполняемый модуль. Объектный модуль (или объектный файл - object file) - это файл с промежуточным представлением отдельного модуля программы, полученный в результате обработки исходного кода компилятором. Объектный файл содержит в себе особым образом подготовленный код (часто называемый бинарным), который может быть объединён с другими объектными файлами при помощи редактора связей (линковщика) для получения готового исполняемого модуля либо библиотеки.
В рассмотренном примере используется функция printf, находящаяся в стандартной библиотеке с именем libc. Для программ на языке С эта библиотека автоматически подключается к любой программе, поэтому не потребовалось подключать ее с помощью опций. В тех случаях, когда в программе используются функции входящие в другие библиотеки, то эти библиотеки необходимо указывать компоновщику, иначе компоновщик не сможет собрать исполнимый файл. Рассмотрим следующий пример.
Программа ex2.c #include #include int main(int argc, char *argv[])
Эта программа вычисляет результат возведения в степень 0.1 числа 2 и присваивает результат переменной res и затем выводит ее значение на стандартный поток вывода. Возведение в степень осуществляет функция pow. Заголовочный файл, в котором описан заголовок для этой функции, подключается директивой #include , являющимся стандартным заголовочным файлом для библиотеки математических подпрограмм.
Попробуем скомпилировать программу командой:
gcc -o ex2 ex2.c
В результате получим следующие сообщение об ошибке:
/tmp/ccgSk9AB.o(.text+0x49): In function `main':
ex2.c: undefined reference to `pow'
collect2: ld returned 1 exit status
Это сообщение говорит, что в функции main, файла ex2.c вызывается функция pow, для которой не найден машинный код на этапе сборки программы. Для того чтобы программа скомпоновалась, необходимо указать компилятору в какой библиотеке следует искать объектный код функции pow. Правильная строка компиляции будет выглядеть следующим образом.
gcc -o ex2 ex2.c -lm
В результате будет создана программа с именем ex2, которая при запуске напечатает:
Подключение библиотеки было выполнено с помощью опции -lm. Файл этой библиотеки находится в каталоге /usr/lib. Полное его название libm, имена файлов библиотек подпрограмм всегда начинаются с префикса lib, за которым идет название библиотеки. При подключении библиотеки к программе в строке компилятора префикс lib заменяется на -l. Таким образом, подключение библиотеки libm осуществляется опцией -lm. Поскольку библиотека стандартная, находится в специальном каталоге, то нет необходимости указывать путь поиска файла библиотеки математических подпрограмм с помощью опции -L. Компилятор сам найдет его в директории /usr/lib. Работа с библиотеками имеет ряд аспектов, которые нуждаются в более подробном рассмотрении.
В рассмотренном ранее примере было упомянуто, что стандартная математическая библиотека находится в системном каталоге /usr/lib. Однако если перейти в каталог /usr/lib, и попробовать найти там файл с именем libm, то такого файла там нет. Зато есть два файла с именами libm.a и libm.so. Почему два и с разными расширениями? Потому что большинство UNIX-подобных систем поддерживают два типа компоновки - статическую и динамическую.
Динамические библиотеки, называемые также библиотеками общего пользования или разделяемыми библиотеками (shared library), загружаются на этапе выполнения программы. Код вызываемых функций не встраивается внутрь исполняемой программы, а вызывается по мере необходимости при запуске программы на исполнение. Такой подход позволяет создавать программы значительно меньшего объема. Динамические библиотеки хранятся обычно в определенном месте и имеют стандартное расширение. В ОС Windows файлы библиотек общего пользования имеют расширение .dll, а в UNIX-подобных системах .so. Если на этапе загрузки программы система не смогла найти необходимый код, то программа не запустится. Будет выдано сообщение об ошибке:
error while loading shared libraries: libxxx.so: cannot open shared object file: No such file or directory
Статические библиотеки в виде пакетов объектных файлов, присоединяются (линкуются) к исполнимой программе на этапе компиляции (в Windows такие файлы имеют расширение .lib, а в UNIX-подобных .a). В результате этого программа включает в себя все необходимы функции, что делает её автономной, хорошо переносимой, но увеличивает размер.
Статическая библиотека создается специальной командой:
ar rc libимя.a список_объектных_файлов
Объектные файлы создаются компиляцией функций с опцией -c. Рекомендуется каждую функцию (или подпрограмму в Фортране) оформлять в отдельном файле.
Динамическая библиотека создаются компилятором:
gcc -shared -o libимя.so список_объектных_файлов
Для создания объектных файлов компиляция выполняется с опциями -fPIC -c. Опция -fPIC (PIC - Position Independent Code) означает создание позиционно-независимого кода.
Все библиотеки обычно хранятся в каталоге lib. Если с одним и тем же именем имеется две библиотеки и статическая и динамическая, то по умолчанию линковщик будет использовать динамическую библиотеку. Предположим, что в домашнем каталоге пользователя имеется подкаталог lib и в нем находятся два библиотечных файла: libmy.a и libmy.so. Подкаталог includeсодержит заголовочный файл. Тогда команда компиляции
gcc -o prog_shared prog.c -I~/include -L~/lib -lmy
будет использовать динамическую библиотеку.
Для создания исполнимого файла со статической библиотекой потребуется команда:
gcc -static -o prog_static prog.c -I~/include -L~/lib -lmy
Мы создали две версии программы: с использованием динамической и статической библиотек. Во втором случае использовалась опция -static, чтобы компилятор использовал статическую библиотеку libmy.a. Если бы динамической версии библиотеки не было, то эту опцию можно было бы не указывать. Компилятор, не найдя динамической библиотеки автоматически подключает статическую библиотеку. Опция -I~/include заставляет искать заголовочные файлы в пользовательском подкаталоге include. Заметим, что в Фортране использование заголовочных файлов не требуется, и include файлы используются для других целей - определения констант и параметров. Опция -L~/lib указывает компилятору, что при сборке программы, помимо стандартных путей, следует искать библиотеки и в директории lib домашнего каталога пользователя.
При запуске на исполнение разные версии программы, скорее всего, поведут себя по-разному:
- команда
- ./prog_static - выполнится без проблем;
- а при запуске
- ./prog_shared - программа завершится с ошибкой:
- prog_shared: error while loading shared libraries: libmy.so: cannot open shared object file: No such file or directory
Дело в том, что в момент загрузки программы, система ищет необходимые для запуска программы разделяемые библиотеки, чтобы собрать исполнимую программу. Поиск идет по заранее установленному списку директорий. Имена директорий перечислены в системном файле /etc/ld.so.conf. Очевидно, что в этот файл невозможно занести все индивидуальные каталоги пользователей. В этой ситуации на помощь приходят переменные окружения. Как уже говорилось ранее, в UNIX системах существует специальная переменная LD_LIBRARY_PATH, в которой каждый пользователь может перечислить директории для поиска разделяемых библиотек. Добавим к переменной LD_LIBRARY_PATH путь к директории lib, где находится библиотека libmy.so. Делается это командой
export LD_LIBRARY_PATH=$:~/lib (bash)
setenv LD_LIBRARY_PATH $:~/lib (tcsh)
Данной командой мы к ранее установленному значению добавили путь к персональному каталогу пользователя с библиотечными файлами. Если теперь запустить программу
./prog_shared
то она сработает корректно.
Предпочтительное использование динамических библиотек обусловлено тем, что размеры исполнимых модулей в десятки раз меньше, чем у статических. Все системные утилиты собираются с использованием динамических библиотек. А поскольку в системе их несколько тысяч, то экономятся гигантские объемы дискового пространства. Кроме того, исполнимые файлы с использованием динамических библиотек более мобильны. В качестве примера рассмотрим типичную ситуацию. В организации имеется два кластера с различной коммуникационной средой - Ethernet и Infiniband. Если использовать статические MPI библиотеки, то для каждого кластера нужно иметь свою версию программы, а если использовать динамические библиотеки, то программы становится совместимыми. При запуске программы на каждом кластере будет вызываться своя версия коммуникационной библиотеки. Еще одно преимущество динамических библиотек состоит в том, что при обновлении системной библиотеки не потребуется пересборка всех системных утилит и программ пользователей.
При использовании большого количества библиотек и include файлов команда компиляции может оказаться довольно длинной. Чтобы упростить компиляцию, часто используют командные файлы (скрипты), выступающих в качестве интерфейсов к стандартным компиляторам. Такой подход используется в пакете MPI. При сборке библиотек формируются командные файлы для вызова тех или иных компиляторов. Компиляция параллельных MPI-программ выполняется командами:
- mpif77 -O -o progname progname.f - на языке Фортран
- mpicc -O -o progname progname.c - на языке С
- mpicxx -O -o progname progname.cc - на языке С++
Здесь mpif77, mpicc, mpicxx - командные скрипты, вызывающие стандартные компиляторы с настройкой путей к необходимым include-файлам и подключением всех необходимых коммуникационных библиотек библиотек. Использование таких скриптов, в свою очередь, порождает некоторые проблемы. Дело в том, что практически на любом вычислительном кластере имеется множество версий коммуникационных библиотек. Это, во-первых, связано с необходимостью обновления установленных версий, а, во-вторых, с тем, что поставщики коммуникационного программного обеспечения, как правило, предоставляют множество реализаций коммуникационных библиотек. Например, в состав коммуникационного пакета OFED входят три различных реализации MPI (MVAPICH, MVAPICH2, OpenMPI), которые к тому же собираются всеми имеющимися в системе компиляторами. К сожалению, все эти версии не совместимы друг с другом, и поэтому очень важно при работе с MPI программами соблюсти синхронность в использовании коммуникационных библиотек. Это означает, что если программа откомпилирована с использованием некоторой версии MPI, то нужно быть уверенным, что при запуске программы на выполнение будет использована та же самая версия MPI, т.е. будет использована команда mpirun из этой же версии пакета, и будут подключены нужные версии динамических библиотек. Это достигается соответствующими настройками переменных окружения PATH и LD_LIBRARY_PATH.