blob: 2aa718e491fa8d4d939d847136c2a9eccb128ace [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="keywords" content="NetBeans, IDE, Oracle Solaris Studio, integrated development environment, user, documentation, open source">
<meta name="description" content="This article describes the Make Dependency Checking feature for C and C++
projects in NetBeans IDE and Oracle Solaris Studio IDE. ">
<meta name="author" content="Alexey Vladykin">
<link rel="stylesheet" type="text/css" href="../../../netbeans.css">
<title>Проверка зависимостей с помощью утилиты make - IDE NetBeans</title>
</head>
<body>
<a name="top"></a>
<h1>Проверка зависимостей с помощью утилиты make</h1>
<div class="articledate" style="margin-left: 0px;font-style:italic;">
Составитель: Алексей Владыкин<br> Март 2014 г. [Номер версии: V8.0-1]
</div>
<!-- maintained by susanm -->
<p>В этом практическом руководстве показано, как включить проверку зависимостей файлов при сборке проектов в IDE NetBeans. Проверка зависимостей выполняется утилитой <tt>make</tt> в соответствии с инструкциями в файле <tt>Makefile</tt>.</p>
<p><b>Содержание</b></p>
<img alt="Содержимое на этой странице применимо к IDE NetBeans 7.3, 7.4 и 8.0" class="stamp" src="../../../images_www/articles/73/netbeans-stamp-80-74-73.png" title="Содержимое этой страницы применимо к IDE NetBeans 7.3, 7.4 и 8.0">
<ul class="toc">
<li><a href="#requirements" title="Требования">Требования</a></li>
<li><a href="#introduction" title="Введение">Введение</a></li>
<li><a href="#build" title="Процесс сборки (утилита make и файлы Makefile)">Процесс сборки (утилита make и файлы Makefile)</a></li>
<li><a href="#basics" title="Основы создания зависимостей">Основы создания зависимостей</a></li>
<li><a href="#implementation" title="Реализация">Реализация</a></li>
</ul>
<h2><a NAME="requirements"></a>Требования</h2>
<p><b>Для работы с этим учебным курсом требуется следующее программное обеспечение и ресурсы.</b> </p>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Программное обеспечение</th>
<th class="tblheader" scope="col">Требуемая версия</th>
</tr>
<tr>
<td class="tbltd1">IDE NetBeans (включая поддержку C/C++)</td>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">версия 7.3, 7.4 или 8.0 с подключаемым модулем NetBeans C/C++</a></td>
</tr>
<tr>
<td class="tbltd1">Комплект для разработчика на языке Java (JDK)</td>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">версия 7 или 8</a></td>
</tr>
</tbody>
</table>
<br>
<p>Дополнительные сведения о загрузке и установке необходимого программного обеспечения см. в разделах <a href="../../../community/releases/80/install.html">Инструкции по установке IDE NetBeans</a> и <a HREF="../../../community/releases/80/cpp-setup-instructions.html">Настройка IDE NetBeans для C/C++/Fortran</a><br>.</p>
<h2><a name="introduction"></a>Введение</h2>
<p>
Крупные проекты C/C++ могут содержать тысячи файлов. Например, в ядре Linux насчитывается около 20 000 файлов. Если вы работаете над таким проектом и хотите пересобрать его после внесения небольшого изменения, например исправления в одной строке кода, у вас есть два варианта.
<ul>
<li>
Полная повторная сборка (команда 'Очистить и собрать'). На выполнение этой команды затрачивается больше времени, но она гарантирует более стабильные результаты сборки.
</li>
<li>
Инкрементальная сборка (команда 'Собрать'). Эта команда выполняется быстрее, но сможет ли она корректно пересобрать все, что необходимо?
</li>
</ul>
<p>
Главная проблема инкрементальной сборки заключается в наличии инструкций <tt>#include</tt>, которые используются для включения содержимого одного файла в другой файл. Включенный файл называется файловой зависимостью. Изменение включенного файла предполагает изменение всех файлов, в которые он включен. Опосредованные включения (A включает в себя B, B включает в себя C => A включает в себя C) создают еще более сложную проблему.
</p>
<p>
IDE NetBeans поддерживает автоматическую проверку файловых зависимостей для получения максимально корректных результатов повторной инкрементальной сборки. Если изменить файл заголовка, включенный в какой-либо другой исходный файл, и нажать кнопку 'Собрать', IDE пересоберет только те части проекта, которые находятся в зависимости от измененного заголовка. Эта функция позволяет сэкономить время и обеспечивает стабильные результаты сборки.
</p>
<h3>Включение проверки зависимостей для проекта</h3>
<p>
Проверку зависимостей можно включить для каждой отдельной части проекта. Проверка не всегда включена по умолчанию, и в этом следует убедиться.
</p>
<p><b>Включение проверки зависимостей для проекта:</b></p>
<ol>
<li>Щелкните правой кнопкой мыши окно &quot;Проекты&quot; и выберите команду &quot;Свойства&quot;.</li>
<li>
В диалоговом окне &quot;Свойства проекта&quot; выберите в списке &quot;Категории&quot; узел &quot;Сборка&quot;.
</li>
<li>В свойствах сборки установите флажок 'Разрешить проверку зависимостей с помощью make'.</li>
</ol>
<br> <img alt="Флажок &apos;Проверка зависимостей с помощью make&apos; в свойствах проекта" class="margin-around" src="../../../images_www/articles/73/cnd/depchecking/project-checkbox.png"> <br>
<h3>Включение проверки зависимостей по умолчанию для новых проектов</h3>
<p>Для проверки зависимостей можно задать состояние по умолчанию, чтобы эта проверка автоматически включалась при создании новых проектов.</p>
<p><b>Включение проверки зависимостей для всех новых проектов, создаваемых в IDE:</b></p>
<ol>
<li>Выберите Сервис > Параметры в главном меню IDE.</li>
<li>
Нажмите кнопку 'C/C++' на верхней панели.
</li>
<li>Перейдите на вкладку 'Свойства проекта'.</li>
<li>Установите флажок 'Включить проверку зависимостей в созданных файлах makefile'</li>
</ol>
<br> <img alt="Флажок &apos;Проверка зависимостей&apos; в параметрах NetBeans" class="margin-around" src="../../../images_www/articles/73/cnd/depchecking/global-checkbox.png">
<h3 class="notes">Примечания</h3>
<ul>
<li>
Автоматическая проверка зависимостей работает в проектах C/C++, созданных в IDE (управляемые проекты). Логика выполнения проверки зависимостей в IDE содержится в созданном файле <tt>Makefile</tt>. Для проектов, созданных на основе существующих исходных файлов, при проверке зависимостей используется существующий файл <tt>Makefile</tt> (при его наличии).
</li>
<li>
Для проверки зависимостей требуется определенный набор средств (утилита <tt>make</tt> и компиляторы). Функция проверки зависимостей была протестирована с наборами средств Oracle Solaris Studio и GNU, в том числе Cygwin и MinGW.
</li>
<li>
Проверка зависимостей работает, когда компиляторы Oracle Solaris Studio используются совместно с утилитой <tt>make</tt> для Oracle Solaris и когда компиляторы GNU используются с утилитой <tt>gmake</tt> для GNU. Совместное использование утилиты <tt>make</tt> для Oracle Solaris с компиляторами GNU и наоборот не поддерживается.
</li>
</ul>
<p>
Последующая часть статьи предназначена для опытных пользователей, которых интересует, какие процессы происходят внутри IDE.
</p>
<h2><a name="build"></a>Процесс сборки (утилита make и файлы makefile)</h2>
<p>
Процесс сборки каждого проекта C/C++ в NetBeans описывается в файле <tt>Makefile</tt>, имеющем специальный формат и обрабатываемом утилитой <tt>make</tt>. Когда в графическом интерфейсе выбирается команда сборки или очистки проекта, IDE вызывает утилиту <tt>make</tt>, которая исполняет файл Makefile. Такой подход позволяет с легкостью собирать проекты за пределами IDE с помощью утилиты <tt>make</tt>: достаточно перейти в каталог проекта, ввести команду <tt>make help</tt> и выполнить полученные инструкции.
</p>
<p>
Ниже приведены файлы Makefile, используемые в IDE NetBeans для проектов C/C++.
</p>
<img alt="Файлы Makefile, используемые в NetBeans для проектов C/C++" class="margin-around" src="../../../images_www/articles/73/cnd/depchecking/makefiles.png">
<p>
Главный файл <tt>Makefile</tt> создается один раз, и его можно редактировать вручную. Файлы Makefile в каталоге <tt>nbproject</tt> не предназначены для редактирования вручную; они автоматически обновляются средой IDE. Файл <tt>Makefile-<i>CONF</i>.mk</tt>, показанный на иллюстрации, представляет собой множество файлов для всех конфигураций проекта, таких как <tt>Makefile-Release.mk</tt>, <tt>Makefile-Debug.mk</tt> и т.д.
</p>
<p>
Для управляемых проектов IDE создает все файлы makefile самостоятельно и включает в них соответствующие инструкции для проверки зависимостей. В проектах, созданных на основе существующих исходных файлов, проверка зависимостей работает, только если существующий файл <tt>Makefile</tt> содержит соответствующие инструкции. IDE NetBeans не вносит изменения в существующий файл <tt>Makefile</tt>.
</p>
<h2><a name="basics"></a>Основы создания зависимостей</h2>
<p>
Если требуется, чтобы утилита <tt>make</tt> проверяла зависимости включенных файлов при сборке, необходимо включить данные об этих зависимостях в файл <tt>Makefile</tt>. К сожалению, единого способа создания инструкций для всех утилит <tt>make</tt> и компиляторов не существует. Во-первых, следует проверить тип используемой утилиты <tt>make</tt>, а затем создать соответствующие инструкции для проверки зависимостей.
</p>
<p>
Утилита <tt>make</tt> для Oracle Solaris представляет собой очень простую программу. Специальное правило <tt>.KEEP_STATE:</tt> в файле <tt>Makefile</tt> заставляет утилиту <tt>make</tt> запрашивать файловые зависимости у компилятора и сохранять их во временном файле. При следующей повторной сборке проекта утилита <tt>make</tt> загружает этот временный файл, анализирует сохраненные в нем зависимости и определяет, какие заголовки были изменены и какие файлы объекта подлежат повторной сборке.
</p>
<p>
В основе утилиты <tt>make</tt> GNU (<tt>gmake</tt>) лежит более сложный механизм. В этом случае потребуется явно попросить компилятор создать данные о зависимостях и явно включить их в файл <tt>Makefile</tt>. Смысл заключается в том, что компилятору передаются специальные флаги, чтобы он создал данные о зависимостях для каждого скомпилированного исходного файла. При следующей повторной сборке проекта осуществляется сбор данных о зависимостях и их включение в файл <tt>Makefile</tt>.
</p>
<h2><a name="implementation"></a>Реализация</h2>
<p>
В <tt>nbproject/Makefile-impl.mk</tt> добавляется следующий код. Он определяет тип утилиты <tt>make</tt> и помещает соответствующий код проверки зависимостей в файл <tt>.dep.inc</tt>. На присутствие утилиты <tt>make</tt> для GNU указывает переменная <tt>MAKE_VERSION</tt>. Если для переменной <tt>MAKE_VERSION</tt> не задано значение, создаются инструкции для утилиты <tt>make</tt> Solaris.
</p>
<pre class="examplecode"># dependency checking support
.depcheck-impl:
@echo "# This code depends on make tool being used" &gt;.dep.inc
@if [ -n "${MAKE_VERSION}" ]; then \
echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" &gt;&gt;.dep.inc; \
echo "ifneq (\$${DEPFILES},)" &gt;&gt;.dep.inc; \
echo "include \$${DEPFILES}" &gt;&gt;.dep.inc; \
echo "endif" &gt;&gt;.dep.inc; \
else \
echo ".KEEP_STATE:" &gt;&gt;.dep.inc; \
echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" &gt;&gt;.dep.inc; \
fi</pre>
<p>
В файл <tt>nbproject/Makefile-${CONF}.mk</tt> добавляется следующий код. Он заставляет утилиту <tt>make</tt> читать ранее созданный файл <tt>.dep.inc</tt> и выполнять инструкции из этого файла.
</p>
<pre class="examplecode"># Enable dependency checking
.dep.inc: .depcheck-impl
include .dep.inc</pre>
<p>
Правило <tt>.dep.inc: .depcheck-impl</tt> добавлено с целью предотвращения сбоя при сборке, если файл <tt>.dep.inc</tt> не существует. Это может произойти только в одном случае: при компиляции одиночного файла в окне 'Проекты'. В этом случае утилита <tt>make</tt> непосредственно исполняет файл <tt>nbproject/Makefile-${CONF}.mk</tt>.
</p>
<h2>Ссылки</h2>
<ol>
<li>
<a href="http://en.wikipedia.org/wiki/Make_%28software%29" target="_blank">Статья об утилите <tt>make</tt></a> в Википедии
</li>
<li>
<a href="http://make.paulandlesley.org/autodep.html" target="_blank">Расширенные возможности создания автоматических зависимостей</a>
</li>
</ol>
<h2>См. также</h2>
<p>Дополнительные статьи о разработке с помощью C/C++/Fortran в IDE NetBeans см. в разделе <a href="https://netbeans.org/kb/trails/cnd.html">Учебные карты C/C++</a>.</p>
<div class="feedback-box"><a href="mailto:users@cnd.netbeans.org?subject=Feedback:%20Make%20Dependency%20Checking%20-%20NetBeans%20IDE%208.0%20Tutorial">Отправить отзыв по этому учебному курсу</a></div>
</body></html>