blob: 321893ab25270655f90a368cd52cdd9fdd78d651 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Build-Time Hooks &mdash; Apache Mynewt latest documentation</title>
<link rel="shortcut icon" href="../../../_static/mynewt-logo-only-newt32x32.png"/>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/sphinx_theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/bootstrap-3.0.3.min.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/v2.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/custom.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/restructuredtext.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/overrides.css" type="text/css" />
<link rel="index" title="Index"
href="../../../genindex.html"/>
<link rel="search" title="Search" href="../../../search.html"/>
<link rel="top" title="Apache Mynewt latest documentation" href="../../../index.html"/>
<link rel="up" title="OS User Guide" href="../../os_user_guide.html"/>
<link rel="next" title="File System Abstraction" href="../fs/fs.html"/>
<link rel="prev" title="System Initialization and System Shutdown" href="../sysinitdown/sysinitdown.html"/>
<script src="../../../_static/js/modernizr.min.js"></script>
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="not-front page-documentation" role="document" >
<div id="wrapper">
<div class="container">
<div id="banner" class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="../../../_static/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.11.0, Apache NimBLE 1.6.0 </a> released September 7, 2023)
</div>
</div>
</div>
</div>
<header>
<nav id="navbar" class="navbar navbar-inverse" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li class="important">
<a href="/quick-start/">Quick Start</a>
</li>
<li>
<a href="/about/">About</a>
</li>
<li>
<a href="/talks/">Talks</a>
</li>
<li class="active">
<a href="/documentation/">Documentation</a>
</li>
<li>
<a href="/download/">Download</a>
</li>
<li>
<a href="/community/">Community</a>
</li>
<li>
<a href="/events/">Events</a>
</li>
</ul>
<!-- Search, Navigation and Repo links -->
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
</div>
</nav>
</header>
<!-- STARTS MAIN CONTENT -->
<div id="main-content">
<div id="breadcrumb">
<div class="container">
<a href="/documentation/">Docs</a> /
<a href="../../os_user_guide.html">OS User Guide</a> /
Build-Time Hooks
<div class="sourcelink">
<a href="https://github.com/apache/mynewt-core/edit/master/docs/os/modules/extcmd/extcmd.rst" class="icon icon-github"
rel="nofollow"> Edit on GitHub</a>
</div>
</div>
</div>
<!-- STARTS CONTAINER -->
<div class="container">
<!-- STARTS .content -->
<div id="content" class="row">
<!-- STARTS .container-sidebar -->
<div class="container-sidebar col-xs-12 col-sm-3">
<div id="docSidebar" class="sticky-container">
<div role="search" class="sphinx-search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search documentation" class="search-documentation" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<!-- Note: only works when deployed -->
<select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest" selected>
Version: latest
</option>
<option value="/v1_11_0" >
Version: 1.11.0
</option>
<option value="/v1_10_0" >
Version: 1.10.0
</option>
<option value="/v1_9_0" >
Version: 1.9.0
</option>
<option value="/v1_8_0" >
Version: 1.8.0
</option>
<option value="/v1_7_0" >
Version: 1.7.0
</option>
<option value="/v1_6_0" >
Version: 1.6.0
</option>
<option value="/v1_5_0" >
Version: 1.5.0
</option>
<option value="/v1_4_0" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" >
Version: 0.9.0
</option>
</select>
<div class="region region-sidebar">
<div class="docs-menu">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../../index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../get_started/index.html">Setup &amp; Get Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../concepts.html">Concepts</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../tutorials/tutorials.html">Tutorials</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../external_links.html">Third-party Resources</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../os_user_guide.html">OS User Guide</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../../core_os/mynewt_os.html">Kernel</a></li>
<li class="toctree-l2"><a class="reference internal" href="../system_modules.html">System</a></li>
<li class="toctree-l2"><a class="reference internal" href="../hal/hal.html">Hardware Abstraction</a></li>
<li class="toctree-l2"><a class="reference internal" href="../bootloader/bootloader.html">Secure Bootloader</a></li>
<li class="toctree-l2"><a class="reference internal" href="../split/split.html">Split Images</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../core_os/porting/port_os.html">Porting Guide</a></li>
<li class="toctree-l2"><a class="reference internal" href="../baselibc.html">Baselibc</a></li>
<li class="toctree-l2"><a class="reference internal" href="../drivers/driver.html">Drivers</a></li>
<li class="toctree-l2"><a class="reference internal" href="../devmgmt/newtmgr.html">Device Management with Newt Manager</a></li>
<li class="toctree-l2"><a class="reference internal" href="../mcumgr/mcumgr.html">Device Management with MCUmgr</a></li>
<li class="toctree-l2"><a class="reference internal" href="../imgmgr/imgmgr.html">Image Manager</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sysinitconfig/sysinitconfig.html">Compile-Time Configuration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sysinitdown/sysinitdown.html">System Initialization and Shutdown</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Build-Time Hooks</a></li>
<li class="toctree-l2"><a class="reference internal" href="../fs/fs.html">File System</a></li>
<li class="toctree-l2"><a class="reference internal" href="../fcb/fcb.html">Flash Circular Buffer</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sensor_framework/sensor_framework.html">Sensor Framework</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testutil/testutil.html">Test Utilities</a></li>
<li class="toctree-l2"><a class="reference internal" href="../json/json.html">JSON</a></li>
<li class="toctree-l2"><a class="reference internal" href="../mfg/mfg.html">Manufacturing support</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../bsp/index.html">Board support</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../network/index.html">BLE User Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../newt/index.html">Newt Tool Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../newtmgr/index.html">Newt Manager Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mynewt_faq/index.html">Mynewt FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../misc/index.html">Appendix</a></li>
</ul>
</div>
</div>
</div>
<!-- ENDS STICKY CONTAINER -->
</div>
<!-- ENDS .container-sidebar -->
<div class="col-xs-12 col-sm-9">
<div class="">
<div class="rst-content">
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="build-time-hooks">
<h1>Build-Time Hooks<a class="headerlink" href="#build-time-hooks" title="Permalink to this headline"></a></h1>
<p>A package specifies custom commands in its <code class="docutils literal notranslate"><span class="pre">pkg.yml</span></code> file. There are
three types of commands:</p>
<ol class="arabic simple">
<li><p>pre_build_cmds (run before the build)</p></li>
<li><p>pre_link_cmds (run after compilation, before linking)</p></li>
<li><p>post_link_cmds (run after linking)</p></li>
</ol>
<div class="section" id="example">
<h2>Example<a class="headerlink" href="#example" title="Permalink to this headline"></a></h2>
<p>Example (apps/blinky/pkg.yml):</p>
<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="nt">pkg.pre_build_cmds</span><span class="p">:</span>
<span class="w"> </span><span class="nt">scripts/pre_build1.sh</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">100</span>
<span class="w"> </span><span class="nt">scripts/pre_build2.sh</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">200</span>
<span class="nt">pkg.pre_link_cmds</span><span class="p">:</span>
<span class="w"> </span><span class="nt">scripts/pre_link.sh</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">500</span>
<span class="nt">pkg.post_link_cmds</span><span class="p">:</span>
<span class="w"> </span><span class="nt">scripts/post_link.sh</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">100</span>
</pre></div>
</div>
<p>For each command, the string on the left specifies the command to run.
The number on the right indicates the command’s relative ordering. All
paths are relative to the project root.</p>
<p>When newt builds this example, it performs the following sequence:</p>
<ul class="simple">
<li><p>scripts/pre_build1.sh</p></li>
<li><p>scripts/pre_build2.sh</p></li>
<li><p>[compile]</p></li>
<li><p>scripts/pre_link.sh</p></li>
<li><p>[link]</p></li>
<li><p>scripts/post_link.sh</p></li>
</ul>
<p>If other packages specify custom commands, those commands would also be
executed during the above sequence. For example, if another package
specifies a pre build command with an ordering of 150, that command
would run immediately after <code class="docutils literal notranslate"><span class="pre">pre_build1.sh</span></code>. In the case of a tie,
the commands are run in lexicographic order (by path).</p>
<p>All commands are run from the project’s base directory. In the above
example, the <code class="docutils literal notranslate"><span class="pre">scripts</span></code> directory is a sibling of <code class="docutils literal notranslate"><span class="pre">targets</span></code>.</p>
</div>
<div class="section" id="custom-build-inputs">
<h2>Custom Build Inputs<a class="headerlink" href="#custom-build-inputs" title="Permalink to this headline"></a></h2>
<p>A custom pre-build or pre-link command can produce files that get fed
into the current build.</p>
<p><em>Pre-build</em> commands can generate any of the following:</p>
<ol class="arabic simple">
<li><p><code class="docutils literal notranslate"><span class="pre">.c</span></code> files for newt to compile.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">.a</span></code> files for newt to link.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">.h</span></code> files that any package can include.</p></li>
</ol>
<p><em>Pre-link</em> commands can only generate .a files.</p>
<p><code class="docutils literal notranslate"><span class="pre">.c</span></code> and <code class="docutils literal notranslate"><span class="pre">.a</span></code> files should be written to the
<code class="docutils literal notranslate"><span class="pre">$MYNEWT_USER_SRC_DIR</span></code> environment variable (defined by newt), or any
subdirectory within.</p>
<p><code class="docutils literal notranslate"><span class="pre">.h</span></code> files should be written to <code class="docutils literal notranslate"><span class="pre">$MYNEWT_USER_INCLUDE_DIR</span></code>. The
directory structure used here is directly reflected by the includer.
E.g., if a script writes to <code class="docutils literal notranslate"><span class="pre">$MYNEWT_USER_INCLUDE_DIR/foo/bar.h</span></code>,
then a source file can include this header with:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&quot;foo/bar.h&quot;</span>
</pre></div>
</div>
</div>
<div class="section" id="details">
<h2>Details<a class="headerlink" href="#details" title="Permalink to this headline"></a></h2>
<div class="section" id="environment-variables">
<h3>Environment Variables<a class="headerlink" href="#environment-variables" title="Permalink to this headline"></a></h3>
<p>In addition to the usual environment variables defined for debug and
download scripts, newt defines the following env vars for custom
commands:</p>
<table class="docutils align-default">
<colgroup>
<col style="width: 19%" />
<col style="width: 59%" />
<col style="width: 22%" />
</colgroup>
<tbody>
<tr class="row-odd"><td><p>Environment variable</p></td>
<td><p>Description</p></td>
<td><p>Notes</p></td>
</tr>
<tr class="row-even"><td><p>MYNEWT_APP_BIN_DIR</p></td>
<td><p>The directory where the current target’s binary gets written.</p></td>
<td></td>
</tr>
<tr class="row-odd"><td><p>MYNEWT_PKG_BIN_ARCHIVE</p></td>
<td><p>The path to the current package’s <code class="docutils literal notranslate"><span class="pre">.a</span></code> file.</p></td>
<td></td>
</tr>
<tr class="row-even"><td><p>MYNEWT_PKG_BIN_DIR</p></td>
<td><p>The directory where the current package’s <code class="docutils literal notranslate"><span class="pre">.o</span></code> and <code class="docutils literal notranslate"><span class="pre">.a</span></code> files get written.</p></td>
<td></td>
</tr>
<tr class="row-odd"><td><p>MYNEWT_PKG_NAME</p></td>
<td><p>The full name of the current package.</p></td>
<td></td>
</tr>
<tr class="row-even"><td><p>MYNEWT_USER_INCLUDE_DIR</p></td>
<td><p>Path where globally-accessible headers get written.</p></td>
<td><p>Pre-build only.</p></td>
</tr>
<tr class="row-odd"><td><p>MYNEWT_USER_SRC_DIR</p></td>
<td><p>Path where build inputs get written.</p></td>
<td><p>Pre-build and pre-link only.</p></td>
</tr>
<tr class="row-even"><td><p>MYNEWT_USER_WORK_DIR</p></td>
<td><p>Shared temp directory; used for communication between commands.</p></td>
<td></td>
</tr>
</tbody>
</table>
<p>These environment variables are defined for each process that a custom
command runs in. They are <em>not</em> defined in the newt process itself.
So, the following snippet will not produce the expected output:</p>
<p>BAD Example (apps/blinky/pkg.yml):</p>
<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="nt">pkg.pre_cmds</span><span class="p">:</span>
<span class="w"> </span><span class="s">&#39;echo</span><span class="nv"> </span><span class="s">$MYNEWT_USER_SRC_DIR&#39;</span><span class="p p-Indicator">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">100</span>
</pre></div>
</div>
<p>You can execute <code class="docutils literal notranslate"><span class="pre">sh</span></code> here instead if you need access to the
environment variables, but it is probably saner to just use a script.</p>
</div>
<div class="section" id="detect-changes-in-custom-build-inputs">
<h3>Detect Changes in Custom Build Inputs<a class="headerlink" href="#detect-changes-in-custom-build-inputs" title="Permalink to this headline"></a></h3>
<p>To avoid unnecessary rebuilds, newt detects if custom build inputs have
changed since the previous build. If none of the inputs have changed,
then they do not get rebuilt. If any of them have changed, they all
get rebuilt.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">$MYNEWT_USER_[...]</span></code> directories are actually temp directories.
After the pre-build commands have run, newt compares the contents of
the temp directory with those of the actual user directory. If any
differences are detected, newt replaces the user directory with the
temp directory, triggering a rebuild of its contents. The same
procedure is used for pre-link commands.</p>
</div>
<div class="section" id="paths">
<h3>Paths<a class="headerlink" href="#paths" title="Permalink to this headline"></a></h3>
<p>Custom build inputs get written to the following directories:</p>
<ul class="simple">
<li><p>bin/targets/&lt;target&gt;/user/pre_build/src</p></li>
<li><p>bin/targets/&lt;target&gt;/user/pre_build/include</p></li>
<li><p>bin/targets/&lt;target&gt;/user/pre_link/src</p></li>
</ul>
<p>Custom commands should not write to these directories. They should use
the <code class="docutils literal notranslate"><span class="pre">$MYNEWT_USER_[...]</span></code> environment variables instead.</p>
</div>
</div>
</div>
</div>
</div>
<div class="rst-footer-buttons row" role="navigation" aria-label="footer navigation">
<a href="../fs/fs.html" class="btn btn-neutral float-right" title="File System Abstraction" accesskey="n">Next: File System Abstraction <span class="fa fa-arrow-circle-right"></span></a>
<a href="../sysinitdown/sysinitdown.html" class="btn btn-neutral" title="System Initialization and System Shutdown" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous: System Initialization and System Shutdown</a>
</div>
</div>
</div>
</div>
<!-- ENDS CONTENT SECTION -->
</div>
<!-- ENDS .content -->
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<img src="../../../_static/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt project logo are either
registered trademarks or trademarks of the Apache Software Foundation in the United States and other countries.
</small>
<a href="">
<img src="../../../_static/img/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
</div>
</div>
</footer>
</div>
<!-- ENDS #wrapper -->
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'latest',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
LINK_SUFFIX: '.html'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/bootstrap-3.0.3.min.js"></script>
<script type="text/javascript" src="../../../_static/js/affix.js"></script>
<script type="text/javascript" src="../../../_static/js/main.js"></script>
</body>
</html>