how-to-write-makefile/conditionals.html

244 lines
18 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html class="writer-html5" lang="zh-CN" >
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>使用条件判断 &mdash; 跟我一起写Makefile 1.0 文档</title>
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/translations.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="索引" href="genindex.html" />
<link rel="search" title="搜索" href="search.html" />
<link rel="next" title="使用函数" href="functions.html" />
<link rel="prev" title="使用变量" href="variables.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home"> 跟我一起写Makefile
</a>
<div class="version">
1.0
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">目录</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="overview.html">概述</a></li>
<li class="toctree-l1"><a class="reference internal" href="introduction.html">makefile介绍</a></li>
<li class="toctree-l1"><a class="reference internal" href="rules.html">书写规则</a></li>
<li class="toctree-l1"><a class="reference internal" href="recipes.html">书写命令</a></li>
<li class="toctree-l1"><a class="reference internal" href="variables.html">使用变量</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">使用条件判断</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#id2">示例</a></li>
<li class="toctree-l2"><a class="reference internal" href="#id3">语法</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="functions.html">使用函数</a></li>
<li class="toctree-l1"><a class="reference internal" href="invoke.html">make 的运行</a></li>
<li class="toctree-l1"><a class="reference internal" href="implicit_rules.html">隐含规则</a></li>
<li class="toctree-l1"><a class="reference internal" href="archives.html">使用make更新函数库文件</a></li>
<li class="toctree-l1"><a class="reference internal" href="postscript.html">后序</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">跟我一起写Makefile</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>使用条件判断</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/conditionals.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="id1">
<h1>使用条件判断<a class="headerlink" href="#id1" title="永久链接至标题"></a></h1>
<p>使用条件判断可以让make根据运行时的不同情况选择不同的执行分支。条件表达式可以是比较变量的值或是比较变量和常量的值。</p>
<section id="id2">
<h2>示例<a class="headerlink" href="#id2" title="永久链接至标题"></a></h2>
<p>下面的例子,判断 <code class="docutils literal notranslate"><span class="pre">$(CC)</span></code> 变量是否 <code class="docutils literal notranslate"><span class="pre">gcc</span></code> 如果是的话则使用GNU函数编译目标。</p>
<div class="highlight-makefile notranslate"><div class="highlight"><pre><span></span><span class="nv">libs_for_gcc</span> <span class="o">=</span> -lgnu
<span class="nv">normal_libs</span> <span class="o">=</span>
<span class="nf">foo</span><span class="o">:</span> <span class="k">$(</span><span class="nv">objects</span><span class="k">)</span>
<span class="cp">ifeq ($(CC),gcc)</span>
<span class="k">$(</span>CC<span class="k">)</span> -o foo <span class="k">$(</span>objects<span class="k">)</span> <span class="k">$(</span>libs_for_gcc<span class="k">)</span>
<span class="cp">else</span>
<span class="k">$(</span>CC<span class="k">)</span> -o foo <span class="k">$(</span>objects<span class="k">)</span> <span class="k">$(</span>normal_libs<span class="k">)</span>
<span class="cp">endif</span>
</pre></div>
</div>
<p>可见,在上面示例的这个规则中,目标 <code class="docutils literal notranslate"><span class="pre">foo</span></code> 可以根据变量 <code class="docutils literal notranslate"><span class="pre">$(CC)</span></code> 值来选取不同的函数库来编译程序。</p>
<p>我们可以从上面的示例中看到三个关键字: <code class="docutils literal notranslate"><span class="pre">ifeq</span></code><code class="docutils literal notranslate"><span class="pre">else</span></code><code class="docutils literal notranslate"><span class="pre">endif</span></code><code class="docutils literal notranslate"><span class="pre">ifeq</span></code> 的意思表示条件语句的开始,并指定一个条件表达式,表达式包含两个参数,以逗号分隔,表达式以圆括号括起。 <code class="docutils literal notranslate"><span class="pre">else</span></code> 表示条件表达式为假的情况。 <code class="docutils literal notranslate"><span class="pre">endif</span></code> 表示一个条件语句的结束,任何一个条件表达式都应该以 <code class="docutils literal notranslate"><span class="pre">endif</span></code> 结束。</p>
<p>当我们的变量 <code class="docutils literal notranslate"><span class="pre">$(CC)</span></code> 值是 <code class="docutils literal notranslate"><span class="pre">gcc</span></code> 时,目标 <code class="docutils literal notranslate"><span class="pre">foo</span></code> 的规则是:</p>
<div class="highlight-makefile notranslate"><div class="highlight"><pre><span></span><span class="nf">foo</span><span class="o">:</span> <span class="k">$(</span><span class="nv">objects</span><span class="k">)</span>
<span class="k">$(</span>CC<span class="k">)</span> -o foo <span class="k">$(</span>objects<span class="k">)</span> <span class="k">$(</span>libs_for_gcc<span class="k">)</span>
</pre></div>
</div>
<p>而当我们的变量 <code class="docutils literal notranslate"><span class="pre">$(CC)</span></code> 值不是 <code class="docutils literal notranslate"><span class="pre">gcc</span></code> 时(比如 <code class="docutils literal notranslate"><span class="pre">cc</span></code> ),目标 <code class="docutils literal notranslate"><span class="pre">foo</span></code> 的规则是:</p>
<div class="highlight-makefile notranslate"><div class="highlight"><pre><span></span><span class="nf">foo</span><span class="o">:</span> <span class="k">$(</span><span class="nv">objects</span><span class="k">)</span>
<span class="k">$(</span>CC<span class="k">)</span> -o foo <span class="k">$(</span>objects<span class="k">)</span> <span class="k">$(</span>normal_libs<span class="k">)</span>
</pre></div>
</div>
<p>当然,我们还可以把上面的那个例子写得更简洁一些:</p>
<div class="highlight-makefile notranslate"><div class="highlight"><pre><span></span><span class="nv">libs_for_gcc</span> <span class="o">=</span> -lgnu
<span class="nv">normal_libs</span> <span class="o">=</span>
<span class="cp">ifeq ($(CC),gcc)</span>
<span class="nv">libs</span><span class="o">=</span><span class="k">$(</span>libs_for_gcc<span class="k">)</span>
<span class="cp">else</span>
<span class="nv">libs</span><span class="o">=</span><span class="k">$(</span>normal_libs<span class="k">)</span>
<span class="cp">endif</span>
<span class="nf">foo</span><span class="o">:</span> <span class="k">$(</span><span class="nv">objects</span><span class="k">)</span>
<span class="k">$(</span>CC<span class="k">)</span> -o foo <span class="k">$(</span>objects<span class="k">)</span> <span class="k">$(</span>libs<span class="k">)</span>
</pre></div>
</div>
</section>
<section id="id3">
<h2>语法<a class="headerlink" href="#id3" title="永久链接至标题"></a></h2>
<p>条件表达式的语法为:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;</span><span class="n">conditional</span><span class="o">-</span><span class="n">directive</span><span class="o">&gt;</span>
<span class="o">&lt;</span><span class="n">text</span><span class="o">-</span><span class="k">if</span><span class="o">-</span><span class="n">true</span><span class="o">&gt;</span>
<span class="n">endif</span>
</pre></div>
</div>
<p>以及:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;</span><span class="n">conditional</span><span class="o">-</span><span class="n">directive</span><span class="o">&gt;</span>
<span class="o">&lt;</span><span class="n">text</span><span class="o">-</span><span class="k">if</span><span class="o">-</span><span class="n">true</span><span class="o">&gt;</span>
<span class="k">else</span>
<span class="o">&lt;</span><span class="n">text</span><span class="o">-</span><span class="k">if</span><span class="o">-</span><span class="n">false</span><span class="o">&gt;</span>
<span class="n">endif</span>
</pre></div>
</div>
<p>其中 <code class="docutils literal notranslate"><span class="pre">&lt;conditional-directive&gt;</span></code> 表示条件关键字,如 <code class="docutils literal notranslate"><span class="pre">ifeq</span></code> 。这个关键字有四个。</p>
<p>第一个是我们前面所见过的 <code class="docutils literal notranslate"><span class="pre">ifeq</span></code></p>
<div class="highlight-makefile notranslate"><div class="highlight"><pre><span></span><span class="cp">ifeq (&lt;arg1&gt;, &lt;arg2&gt;)</span>
<span class="cp">ifeq &#39;&lt;arg1&gt;&#39; &#39;&lt;arg2&gt;&#39;</span>
<span class="cp">ifeq &quot;&lt;arg1&gt;&quot; &quot;&lt;arg2&gt;&quot;</span>
<span class="cp">ifeq &quot;&lt;arg1&gt;&quot; &#39;&lt;arg2&gt;&#39;</span>
<span class="cp">ifeq &#39;&lt;arg1&gt;&#39; &quot;&lt;arg2&gt;&quot;</span>
</pre></div>
</div>
<p>比较参数 <code class="docutils literal notranslate"><span class="pre">arg1</span></code><code class="docutils literal notranslate"><span class="pre">arg2</span></code> 的值是否相同。当然参数中我们还可以使用make的函数。如:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>ifeq ($(strip $(foo)),)
&lt;text-if-empty&gt;
endif
</pre></div>
</div>
<p>这个示例中使用了 <code class="docutils literal notranslate"><span class="pre">strip</span></code> 函数如果这个函数的返回值是空Empty那么
<code class="docutils literal notranslate"><span class="pre">&lt;text-if-empty&gt;</span></code> 就生效。</p>
<p>第二个条件关键字是 <code class="docutils literal notranslate"><span class="pre">ifneq</span></code> 。语法是:</p>
<div class="highlight-makefile notranslate"><div class="highlight"><pre><span></span><span class="cp">ifneq (&lt;arg1&gt;, &lt;arg2&gt;)</span>
<span class="cp">ifneq &#39;&lt;arg1&gt;&#39; &#39;&lt;arg2&gt;&#39;</span>
<span class="cp">ifneq &quot;&lt;arg1&gt;&quot; &quot;&lt;arg2&gt;&quot;</span>
<span class="cp">ifneq &quot;&lt;arg1&gt;&quot; &#39;&lt;arg2&gt;&#39;</span>
<span class="cp">ifneq &#39;&lt;arg1&gt;&#39; &quot;&lt;arg2&gt;&quot;</span>
</pre></div>
</div>
<p>其比较参数 <code class="docutils literal notranslate"><span class="pre">arg1</span></code><code class="docutils literal notranslate"><span class="pre">arg2</span></code> 的值是否相同,如果不同,则为真。和 <code class="docutils literal notranslate"><span class="pre">ifeq</span></code> 类似。</p>
<p>第三个条件关键字是 <code class="docutils literal notranslate"><span class="pre">ifdef</span></code> 。语法是:</p>
<div class="highlight-makefile notranslate"><div class="highlight"><pre><span></span><span class="cp">ifdef &lt;variable-name&gt;</span>
</pre></div>
</div>
<p>如果变量 <code class="docutils literal notranslate"><span class="pre">&lt;variable-name&gt;</span></code> 的值非空,那到表达式为真。否则,表达式为假。当然,
<code class="docutils literal notranslate"><span class="pre">&lt;variable-name&gt;</span></code> 同样可以是一个函数的返回值。注意, <code class="docutils literal notranslate"><span class="pre">ifdef</span></code> 只是测试一个变量是否有值,其并不会把变量扩展到当前位置。还是来看两个例子:</p>
<p>示例一:</p>
<div class="highlight-makefile notranslate"><div class="highlight"><pre><span></span><span class="nv">bar</span> <span class="o">=</span>
<span class="nv">foo</span> <span class="o">=</span> <span class="k">$(</span>bar<span class="k">)</span>
<span class="cp">ifdef foo</span>
<span class="nv">frobozz</span> <span class="o">=</span> yes
<span class="cp">else</span>
<span class="nv">frobozz</span> <span class="o">=</span> no
<span class="cp">endif</span>
</pre></div>
</div>
<p>示例二:</p>
<div class="highlight-makefile notranslate"><div class="highlight"><pre><span></span><span class="nv">foo</span> <span class="o">=</span>
<span class="cp">ifdef foo</span>
<span class="nv">frobozz</span> <span class="o">=</span> yes
<span class="cp">else</span>
<span class="nv">frobozz</span> <span class="o">=</span> no
<span class="cp">endif</span>
</pre></div>
</div>
<p>第一个例子中, <code class="docutils literal notranslate"><span class="pre">$(frobozz)</span></code> 值是 <code class="docutils literal notranslate"><span class="pre">yes</span></code> ,第二个则是 <code class="docutils literal notranslate"><span class="pre">no</span></code></p>
<p>第四个条件关键字是 <code class="docutils literal notranslate"><span class="pre">ifndef</span></code> 。其语法是:</p>
<div class="highlight-makefile notranslate"><div class="highlight"><pre><span></span><span class="cp">ifndef &lt;variable-name&gt;</span>
</pre></div>
</div>
<p>这个我就不多说了,和 <code class="docutils literal notranslate"><span class="pre">ifdef</span></code> 是相反的意思。</p>
<p><code class="docutils literal notranslate"><span class="pre">&lt;conditional-directive&gt;</span></code> 这一行上,多余的空格是被允许的,但是不能以 <code class="docutils literal notranslate"><span class="pre">Tab</span></code> 键作为开始(不然就被认为是命令)。而注释符 <code class="docutils literal notranslate"><span class="pre">#</span></code> 同样也是安全的。 <code class="docutils literal notranslate"><span class="pre">else</span></code><code class="docutils literal notranslate"><span class="pre">endif</span></code>
也一样,只要不是以 <code class="docutils literal notranslate"><span class="pre">Tab</span></code> 键开始就行了。</p>
<p>特别注意的是make是在读取Makefile时就计算条件表达式的值并根据条件表达式的值来选择语句所以你最好不要把自动化变量<code class="docutils literal notranslate"><span class="pre">$&#64;</span></code> 等)放入条件表达式中,因为自动化变量是在运行时才有的。</p>
<p>而且为了避免混乱make不允许把整个条件语句分成两部分放在不同的文件中。</p>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="variables.html" class="btn btn-neutral float-left" title="使用变量" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="functions.html" class="btn btn-neutral float-right" title="使用函数" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; 版权所有 2014-2019, 作者陈皓排版SeisMan.
<span class="lastupdated">最后更新于 2022年5月22日.
</span></p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>